1070 lines
27 KiB
C++
1070 lines
27 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1995 - 2000.
|
|
//
|
|
// File: pathstor.cxx
|
|
//
|
|
// Classes: CSplitPath, CSplitPathCompare, CPathStore
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 5-02-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
#include "pch.cxx"
|
|
#pragma hdrstop
|
|
|
|
#include "pathstor.hxx"
|
|
#include "pathcomp.hxx"
|
|
#include "tabledbg.hxx"
|
|
|
|
|
|
const WCHAR CSplitPath::_awszPathSep[] = L"\\";
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CSplitPath
|
|
//
|
|
// Synopsis: ~ctor for CSplitPath which can be initialized given the
|
|
// "pathId".
|
|
//
|
|
// Arguments: [pathStore] - Reference to the path store.
|
|
// [pathid] - PathId to be used for initialization.
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CSplitPath::CSplitPath( CPathStore & pathStore, PATHID pathid )
|
|
{
|
|
const CShortPath & path = pathStore.GetShortPath( pathid );
|
|
|
|
CStringStore & strStore = pathStore.GetStringStore();
|
|
|
|
if ( stridInvalid != path.GetParent() )
|
|
{
|
|
_pParent = strStore.GetCountedWStr( path.GetParent(), _cwcParent );
|
|
}
|
|
else
|
|
{
|
|
_pParent = 0;
|
|
_cwcParent = 0;
|
|
}
|
|
|
|
if ( stridInvalid != path.GetFileName() )
|
|
{
|
|
_pFile = strStore.GetCountedWStr( path.GetFileName(), _cwcFile );
|
|
}
|
|
else
|
|
{
|
|
_pFile = 0;
|
|
_cwcParent = 0;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CSplitPath
|
|
//
|
|
// Synopsis: ~ctor - initialized using a NULL terminated path.
|
|
//
|
|
// Arguments: [pwszPath] - The null terminated path.
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CSplitPath::CSplitPath( const WCHAR * pwszPath )
|
|
{
|
|
const ULONG cwcPath = wcslen( pwszPath );
|
|
Win4Assert( 0 != cwcPath );
|
|
|
|
const WCHAR * pwszFinalComponent = wcsrchr(pwszPath, wchPathSep);
|
|
|
|
if ( 0 == pwszFinalComponent )
|
|
{
|
|
_pParent = 0;
|
|
_cwcParent = 0;
|
|
|
|
_pFile = pwszPath;
|
|
_cwcFile = cwcPath;
|
|
}
|
|
else
|
|
{
|
|
_pParent = pwszPath;
|
|
_cwcParent = (DWORD)(pwszFinalComponent - pwszPath);
|
|
|
|
_cwcFile = cwcPath - ( _cwcParent + 1 ); // skip over the path separator
|
|
|
|
if ( 0 != _cwcFile )
|
|
{
|
|
_pFile = pwszPath + ( _cwcParent + 1 );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// There is a path separator at the end of the string.
|
|
//
|
|
_pFile = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Advance
|
|
//
|
|
// Synopsis: Advances the current pointer by "cwc" characters during
|
|
// comparison of split paths.
|
|
//
|
|
// Arguments: [cwc] - Number of characters to advance by.
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
inline void CSplitPath::Advance( ULONG cwc )
|
|
{
|
|
Win4Assert( cwc <= _cwcCurr );
|
|
Win4Assert( !IsDone() );
|
|
|
|
_cwcCurr -= cwc;
|
|
|
|
if ( 0 == _cwcCurr )
|
|
{
|
|
//
|
|
// We must go to the next step.
|
|
//
|
|
switch ( _step )
|
|
{
|
|
case eUseParent:
|
|
|
|
if ( 0 != _pParent )
|
|
{
|
|
_SetUsePathSep();
|
|
}
|
|
else
|
|
{
|
|
if ( 0 != _pFile )
|
|
{
|
|
_SetUseFile();
|
|
}
|
|
else
|
|
{
|
|
_SetUsePathSep();
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case eUsePathSep:
|
|
|
|
if ( 0 == _pFile )
|
|
{
|
|
_SetDone();
|
|
}
|
|
else
|
|
{
|
|
_SetUseFile();
|
|
}
|
|
|
|
break;
|
|
|
|
case eUseFile:
|
|
|
|
_SetDone();
|
|
break;
|
|
|
|
default:
|
|
Win4Assert( !"Impossible Case Condition" );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_pCurr += cwc;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetFullPathLen
|
|
//
|
|
// Synopsis: Determines the length of the fully path (in characters)
|
|
// INCLUDING the NULL terminator.
|
|
//
|
|
// History: 5-10-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
ULONG CSplitPath::GetFullPathLen() const
|
|
{
|
|
ULONG cwcTotal = 0;
|
|
|
|
if ( 0 != _cwcParent )
|
|
{
|
|
cwcTotal += (_cwcParent+1); // extra 1 is for the path separator
|
|
}
|
|
|
|
cwcTotal += GetFileNameLen();
|
|
Win4Assert( cwcTotal > 1 );
|
|
|
|
return cwcTotal;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FormFullPath
|
|
//
|
|
// Synopsis: Forms the full path and copies it to pwszPath. It will
|
|
// be NULL terminated.
|
|
//
|
|
// Arguments: [pwszPath] - OUTPUT buffer for the path
|
|
// [cwcPath] - INPUT max. length of the buffer
|
|
//
|
|
// History: 5-10-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CSplitPath::FormFullPath( WCHAR * pwszPath, ULONG cwcPath ) const
|
|
{
|
|
ULONG cwcParent;
|
|
|
|
Win4Assert( cwcPath >= GetFullPathLen() );
|
|
|
|
if ( 0 != _pParent )
|
|
{
|
|
cwcParent = _cwcParent;
|
|
RtlCopyMemory( pwszPath, _pParent, cwcParent * sizeof(WCHAR) );
|
|
//
|
|
// Append a backslash after the parent's part.
|
|
//
|
|
Win4Assert( cwcParent < cwcPath );
|
|
pwszPath[cwcParent++] = wchPathSep; // Append a backslash
|
|
pwszPath += cwcParent;
|
|
}
|
|
|
|
ULONG cwcFileName = _cwcFile;
|
|
if ( 0 != _pFile )
|
|
{
|
|
Win4Assert( 0 != _cwcFile );
|
|
RtlCopyMemory( pwszPath, _pFile, _cwcFile * sizeof(WCHAR) );
|
|
}
|
|
|
|
pwszPath[cwcFileName] = L'\0';
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FormFileName
|
|
//
|
|
// Synopsis: Fills just the "FileName" component of the path in the
|
|
// given buffer.
|
|
//
|
|
// Arguments: [pwszPath] - OUTPUT buffer - will contain the NULL
|
|
// terminated filename.
|
|
// [cwcFileName] - MAXLEN of pwszPath
|
|
//
|
|
// History: 5-10-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
inline
|
|
void CSplitPath::FormFileName( WCHAR * pwszPath, ULONG cwcFileName ) const
|
|
{
|
|
Win4Assert( cwcFileName >= GetFileNameLen() );
|
|
|
|
if ( 0 != _pFile )
|
|
{
|
|
RtlCopyMemory( pwszPath, _pFile, sizeof(WCHAR)*_cwcFile );
|
|
}
|
|
|
|
pwszPath[_cwcFile] = L'\0';
|
|
return;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _Compare
|
|
//
|
|
// Synopsis: Compars the lhs and rhs split paths.
|
|
//
|
|
// Returns: -1, 0, +1 depending on whether lhs <, =, > rhs
|
|
//
|
|
// History: 5-23-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
int CSplitPathCompare::_Compare()
|
|
{
|
|
int iComp = 0;
|
|
while ( !_IsDone() )
|
|
{
|
|
iComp = _lhs.CompareCurr( _rhs );
|
|
if ( 0 != iComp )
|
|
{
|
|
return iComp;
|
|
}
|
|
|
|
ULONG cwcMin = min ( _lhs.GetCurrLen(), _rhs.GetCurrLen() );
|
|
_lhs.Advance( cwcMin );
|
|
_rhs.Advance( cwcMin );
|
|
}
|
|
|
|
iComp = _rhs.GetStep() - _lhs.GetStep();
|
|
if ( iComp > 0 )
|
|
{
|
|
iComp = 1;
|
|
}
|
|
else if ( iComp < 0 )
|
|
{
|
|
iComp = -1;
|
|
}
|
|
|
|
return iComp;
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ComparePaths
|
|
//
|
|
// Synopsis: Compares the two paths.
|
|
//
|
|
// Returns: 0 if equal
|
|
// -1 if lhs < rhs
|
|
// +1 if lhs > rhs
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
int CSplitPathCompare::ComparePaths()
|
|
{
|
|
_lhs.InitForPathCompare();
|
|
_rhs.InitForPathCompare();
|
|
|
|
return _Compare();
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CompareNames
|
|
//
|
|
// Synopsis: Compares the "Name" component of two paths.
|
|
//
|
|
// Returns: 0 if equal
|
|
// -1 if lhs < rhs
|
|
// +1 if lhs > rhs
|
|
//
|
|
// History: 5-11-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
int CSplitPathCompare::CompareNames()
|
|
{
|
|
_lhs.InitForNameCompare();
|
|
_rhs.InitForNameCompare();
|
|
|
|
return _Compare();
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Constructor for the CStringStore
|
|
//
|
|
// History: 5-03-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CStringStore::CStringStore() : _pStrHash(0)
|
|
{
|
|
_pStrHash = new CCompressedColHashString( FALSE );
|
|
// Don't optimize for ascii
|
|
END_CONSTRUCTION( CStringStore );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: CStringStore
|
|
//
|
|
// Synopsis: Destructor for CStringStore.
|
|
//
|
|
// History: 5-03-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CStringStore::~CStringStore()
|
|
{
|
|
delete _pStrHash;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Add
|
|
//
|
|
// Synopsis: Adds the NULL terminated pwszStr to the string store.
|
|
//
|
|
// Arguments: [pwszStr] - NULL terminated string to be added.
|
|
//
|
|
// Returns: The STRINGID of the string in the store.
|
|
//
|
|
// History: 5-03-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STRINGID CStringStore::Add( const WCHAR * pwszStr )
|
|
{
|
|
|
|
ULONG strId;
|
|
GetValueResult gvr;
|
|
_pStrHash->AddData( pwszStr, strId, gvr );
|
|
Win4Assert( GVRSuccess == gvr );
|
|
|
|
return strId;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: AddCountedWStr
|
|
//
|
|
// Synopsis: Adds a "counted" string to the store.
|
|
//
|
|
// Arguments: [pwszStr] - Pointer to the string to be added.
|
|
// [cwcStr] - Number of WCHARS in the string.
|
|
//
|
|
// Returns: The ID of the string.
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STRINGID CStringStore::AddCountedWStr( const WCHAR * pwszStr, ULONG cwcStr )
|
|
{
|
|
|
|
ULONG strId;
|
|
GetValueResult gvr;
|
|
_pStrHash->AddCountedWStr( pwszStr, cwcStr, strId, gvr );
|
|
Win4Assert( GVRSuccess == gvr );
|
|
|
|
return strId;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FindCountedWStr
|
|
//
|
|
// Synopsis: Finds a "counted" string in the store.
|
|
//
|
|
// Arguments: [pwszStr] - Pointer to the string to be added.
|
|
// [cwcStr] - Number of WCHARS in the string.
|
|
//
|
|
// Returns: The ID of the string.
|
|
//
|
|
// History: 7-17-95 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STRINGID CStringStore::FindCountedWStr( const WCHAR * pwszStr, ULONG cwcStr )
|
|
{
|
|
|
|
if ( 0 != pwszStr )
|
|
return _pStrHash->FindCountedWStr( pwszStr, cwcStr );
|
|
else
|
|
return stridInvalid;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: StrLen
|
|
//
|
|
// Synopsis: Length of the String associated with strId EXCLUDING the
|
|
// terminating NULL.
|
|
//
|
|
// Arguments: [strId] - Id of the string whose length is needed.
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
ULONG CStringStore::StrLen( STRINGID strId )
|
|
{
|
|
return _pStrHash->DataLength( strId )-1;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetCountedWStr
|
|
//
|
|
// Synopsis: Gets the string identified by the "strId.
|
|
//
|
|
// Arguments: [strId] - The id of the string to lookup.
|
|
// [cwcStr] - On output, will have the count of the chars
|
|
// in the string.
|
|
//
|
|
//
|
|
// Returns: Pointer to the string - NOT NULL terminated.
|
|
//
|
|
// History: 5-03-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
const WCHAR * CStringStore::GetCountedWStr( STRINGID strId, ULONG & cwcStr )
|
|
{
|
|
return _pStrHash->GetCountedWStr( strId, cwcStr );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetString
|
|
//
|
|
// Synopsis: Returns the string identified by the strId.
|
|
//
|
|
// Arguments: [strId] - ID of the string to retrieve
|
|
// [pwszPath] - Pointer to the buffer to hold the string
|
|
// [cwcPath] - On input, the max capacity of pwszPath. On
|
|
// output, it will have the count of the chars
|
|
// in the string, excluding the terminating NULL.
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
GetValueResult
|
|
CStringStore::GetString( STRINGID strId, WCHAR * pwszPath, ULONG & cwcPath )
|
|
{
|
|
return _pStrHash->GetData( strId, pwszPath, cwcPath );
|
|
}
|
|
|
|
|
|
|
|
CPathStore::~CPathStore()
|
|
{
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FindData
|
|
//
|
|
// Synopsis: Finds the given data (pidPath/pidName) in the path store.
|
|
//
|
|
// Arguments: [pVarnt] - string to look for
|
|
// [rKey] - returns key
|
|
//
|
|
// Returns: TRUE if found, FALSE otherwise
|
|
//
|
|
// History: 7-3-95 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CPathStore::FindData(
|
|
PROPVARIANT const * const pvarnt,
|
|
ULONG & rKey )
|
|
{
|
|
Win4Assert(pvarnt->vt == VT_LPWSTR);
|
|
WCHAR * pwszData = pvarnt->pwszVal;
|
|
|
|
CSplitPath path( pwszData );
|
|
|
|
STRINGID idParent = _strStore.FindCountedWStr( path._pParent, path._cwcParent );
|
|
STRINGID idName = _strStore.FindCountedWStr( path._pFile, path._cwcFile );
|
|
|
|
CShortPath shortPath( idParent, idName );
|
|
|
|
for ( unsigned i = 0; i < _aShortPath.Count(); i++ )
|
|
{
|
|
if ( shortPath.IsSame( _aShortPath[ i ] ) )
|
|
{
|
|
rKey = i + 1; // keys are 1-based
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
} //FindData
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: AddData
|
|
//
|
|
// Synopsis: Adds the given data (pidPath/pidName) to the path store.
|
|
//
|
|
// Arguments: [pVarnt] -
|
|
// [pKey] -
|
|
// [reIndicator] -
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CPathStore::AddData( PROPVARIANT const * const pVarnt,
|
|
ULONG* pKey,
|
|
GetValueResult& reIndicator
|
|
)
|
|
{
|
|
//
|
|
// Specially handle the VT_EMPTY case
|
|
//
|
|
if (pVarnt->vt == VT_EMPTY)
|
|
{
|
|
*pKey = 0;
|
|
reIndicator = GVRSuccess;
|
|
return;
|
|
}
|
|
|
|
Win4Assert(pVarnt->vt == VT_LPWSTR);
|
|
WCHAR * pwszData = pVarnt->pwszVal;
|
|
|
|
*pKey = AddPath( pwszData );
|
|
reIndicator = GVRSuccess;
|
|
return;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetData
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: [pVarnt] - OUTPUT- Variant to hold the data.
|
|
// [PreferredType] - UNUSED
|
|
// [ulKey] - The "Key" (PathId) of the path to be
|
|
// retrieved.
|
|
// [PropId] - pidPath/pidWorkId/pidName
|
|
//
|
|
// Returns: GVRSuccess if successful.
|
|
// a GVR* failure code o/w.
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
// Notes: FreeVariant MUST be called.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
GetValueResult
|
|
CPathStore::GetData( PROPVARIANT * pVarnt,
|
|
VARTYPE PreferredType,
|
|
ULONG ulKey,
|
|
PROPID PropId )
|
|
{
|
|
if (ulKey == 0)
|
|
{
|
|
pVarnt->vt = VT_EMPTY;
|
|
return GVRNotAvailable;
|
|
}
|
|
|
|
Win4Assert( _IsValid( ulKey ) );
|
|
|
|
if ( pidWorkId == PropId )
|
|
{
|
|
pVarnt->vt = VT_I4;
|
|
pVarnt->lVal = (LONG) ulKey;
|
|
return GVRSuccess;
|
|
}
|
|
|
|
CSplitPath path( *this, ulKey );
|
|
|
|
if ( pidName == PropId )
|
|
{
|
|
ULONG cwcFileName = path.GetFileNameLen();
|
|
Win4Assert( cwcFileName > 0 );
|
|
|
|
WCHAR * pwszFileName = _GetPathBuffer( cwcFileName );
|
|
path.FormFileName( pwszFileName, cwcFileName );
|
|
|
|
pVarnt->vt = VT_LPWSTR;
|
|
pVarnt->pwszVal = pwszFileName;
|
|
|
|
return GVRSuccess;
|
|
}
|
|
else
|
|
{
|
|
Win4Assert( pidPath == PropId );
|
|
|
|
//
|
|
// Retrieve entire path name.
|
|
//
|
|
// First, compute the required size of the return buffer.
|
|
//
|
|
ULONG cwcPathLen = path.GetFullPathLen( );
|
|
WCHAR * pwszDest = _GetPathBuffer( cwcPathLen );
|
|
|
|
pVarnt->vt = VT_LPWSTR;
|
|
pVarnt->pwszVal = pwszDest;
|
|
|
|
path.FormFullPath( pwszDest, cwcPathLen );
|
|
return GVRSuccess;
|
|
}
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: FreeVariant
|
|
//
|
|
// Synopsis: Frees the variant created in the "GetData" call.
|
|
//
|
|
// Arguments: [pVarnt] - Pointer to the variant to be freed.
|
|
//
|
|
// History: 5-09-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CPathStore::FreeVariant(PROPVARIANT * pVarnt)
|
|
{
|
|
if ( pVarnt->vt != VT_EMPTY && pVarnt->vt != VT_I4 )
|
|
{
|
|
Win4Assert(pVarnt->vt == VT_LPWSTR);
|
|
_strStore.FreeVariant( pVarnt );
|
|
pVarnt->pwszVal = 0; // To prevent accidental re-use
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _AddPath
|
|
//
|
|
// Synopsis: Adds the given path to the store.
|
|
//
|
|
// Arguments: [path] -
|
|
//
|
|
// Returns: ID of the path.
|
|
//
|
|
// History: 5-23-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
PATHID CPathStore::_AddPath( CSplitPath & path )
|
|
{
|
|
|
|
STRINGID idParent = stridInvalid;
|
|
STRINGID idName = stridInvalid;
|
|
|
|
if ( 0 != path._pParent )
|
|
{
|
|
idParent = _strStore.AddCountedWStr( path._pParent, path._cwcParent );
|
|
}
|
|
|
|
if ( 0 != path._pFile )
|
|
{
|
|
idName = _strStore.AddCountedWStr( path._pFile, path._cwcFile );
|
|
}
|
|
|
|
return _AddEntry( idParent, idName );
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: AddPath
|
|
//
|
|
// Synopsis: Adds the given path to the path store.
|
|
//
|
|
// Arguments: [pwszPath] - Pointer to the path to be added.
|
|
//
|
|
// Returns: An ID for the path.
|
|
//
|
|
// History: 5-03-95 srikants Created
|
|
//
|
|
// Notes: There is NO duplicate detection for paths. A new ID is given
|
|
// everytime this method is called.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
PATHID CPathStore::AddPath( WCHAR * pwszPath )
|
|
{
|
|
Win4Assert( 0 != pwszPath );
|
|
CSplitPath path( pwszPath );
|
|
PATHID pathId = _AddPath( path );
|
|
|
|
tbDebugOut(( DEB_BOOKMARK,
|
|
"WorkId=0x%8X Path=%ws\n", pathId, pwszPath ));
|
|
|
|
return pathId;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: AddPath
|
|
//
|
|
// Synopsis: Given a source path store and an id in the source pathstore,
|
|
// this method adds the path from the source pathstore to this
|
|
// store.
|
|
//
|
|
// Arguments: [srcStore] - Reference to the source path store.
|
|
// [srcPathId] - Id in the source path store.
|
|
//
|
|
// Returns: PATHID for the path added.
|
|
//
|
|
// History: 5-23-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
PATHID CPathStore::AddPath( CPathStore & srcStore, PATHID srcPathId )
|
|
{
|
|
|
|
CSplitPath srcPath( srcStore, srcPathId );
|
|
return _AddPath( srcPath );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: PathLen
|
|
//
|
|
// Synopsis: Length of the path (INCLUDING terminating NULL) given the
|
|
// pathid.
|
|
//
|
|
// Arguments: [pathId] - Id of the path whose length is requested.
|
|
//
|
|
// Returns: Length of the path including terminating null.
|
|
//
|
|
// History: 5-03-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
ULONG CPathStore::PathLen( PATHID pathId )
|
|
{
|
|
|
|
CSplitPath path( *this, pathId );
|
|
return path.GetFullPathLen();
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetPath
|
|
//
|
|
// Synopsis: Given a pathId, it returns the path for that pathid.
|
|
//
|
|
// Arguments: [pathId] - Id of the path to be retrieved
|
|
// [vtPath] - Variant to hold the output
|
|
// [cbVarnt] - On Input, the maximum length of the variant.
|
|
// On output, the actual length of the variant.
|
|
//
|
|
// Returns: GVRSuccess if successful
|
|
// GVRNotEnoughSpace if the length of the variant is less
|
|
// than needed.
|
|
//
|
|
// History: 5-08-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
GetValueResult
|
|
CPathStore::GetPath( PATHID pathId, PROPVARIANT & vtPath, ULONG & cbVarnt )
|
|
{
|
|
CSplitPath splitPath( *this, pathId );
|
|
|
|
const ULONG cbPath = splitPath.GetFullPathLen() * sizeof(WCHAR);
|
|
const ULONG cbHeader = sizeof(PROPVARIANT);
|
|
const ULONG cbTotal = cbHeader + cbPath;
|
|
|
|
if ( cbVarnt < cbTotal )
|
|
{
|
|
cbVarnt = cbTotal;
|
|
return GVRNotEnoughSpace;
|
|
}
|
|
|
|
const ULONG cwcPath = (cbTotal-cbHeader)/sizeof(WCHAR);
|
|
|
|
WCHAR * pwszPath = (WCHAR *) ( ((BYTE*) &vtPath) + cbHeader );
|
|
splitPath.FormFullPath( pwszPath, cwcPath );
|
|
|
|
vtPath.vt = VT_LPWSTR;
|
|
vtPath.pwszVal = pwszPath;
|
|
|
|
cbVarnt = cbTotal;
|
|
return GVRSuccess;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Get
|
|
//
|
|
// Synopsis: Retrieves the path specified by the pathId into a buffer
|
|
// allocated from the dstPool.
|
|
//
|
|
// Arguments: [pathId] - Id of the path to be retrieved.
|
|
// [propId] - pidName/pidPath
|
|
// [dstPool] - Pool from which to allocate memory.
|
|
//
|
|
// Returns: Pointer to a WCHAR * containing the requested data
|
|
// (NULL Terminated).
|
|
//
|
|
// History: 5-23-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
WCHAR *
|
|
CPathStore::Get( PATHID pathId, PROPID propId, PVarAllocator & dstPool )
|
|
{
|
|
// summary catalogs can have empty paths
|
|
|
|
if ( 0 == pathId )
|
|
return 0;
|
|
|
|
CSplitPath path( *this, pathId );
|
|
|
|
WCHAR * pwszDest = 0;
|
|
|
|
if ( pidName == propId )
|
|
{
|
|
ULONG cwcFileName = path.GetFileNameLen();
|
|
ULONG cbDst = cwcFileName * sizeof(WCHAR);
|
|
Win4Assert( cwcFileName > 0 );
|
|
pwszDest = (WCHAR *) dstPool.Allocate( cbDst );
|
|
path.FormFileName( pwszDest, cwcFileName );
|
|
}
|
|
else
|
|
{
|
|
Win4Assert( pidPath == propId );
|
|
|
|
//
|
|
// Retrieve entire path name.
|
|
//
|
|
// First, compute the required size of the return buffer.
|
|
//
|
|
ULONG cwcPathLen = path.GetFullPathLen();
|
|
Win4Assert( cwcPathLen > 0 );
|
|
ULONG cbDst = cwcPathLen * sizeof(WCHAR);
|
|
pwszDest = (WCHAR *) dstPool.Allocate( cbDst );
|
|
path.FormFullPath( pwszDest, cwcPathLen );
|
|
}
|
|
|
|
return pwszDest;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: _AddEntry
|
|
//
|
|
// Synopsis: Adds an entry consisting of a ParentId and a FileId to the
|
|
// store and returns a PATHID representing this short path.
|
|
//
|
|
// Arguments: [idParent] - Id of the parent in the path
|
|
// [idFileName] - Id of the file in the path.
|
|
//
|
|
// History: 5-10-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
PATHID CPathStore::_AddEntry( STRINGID idParent, STRINGID idFileName )
|
|
{
|
|
CShortPath path( idParent, idFileName );
|
|
_aShortPath.Add( path, _aShortPath.Count() );
|
|
return _aShortPath.Count();
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Compare
|
|
//
|
|
// Synopsis: Compares two paths given their pathids.
|
|
//
|
|
// Arguments: [pathid1] -
|
|
// [pathid2] -
|
|
// [propId] - pidName/pidFile
|
|
//
|
|
// History: 5-11-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
int CPathStore::Compare( PATHID pathid1, PATHID pathid2,
|
|
PROPID propId
|
|
)
|
|
{
|
|
// summary catalogs can have empty paths
|
|
|
|
if ( 0 == pathid1 || 0 == pathid2 )
|
|
return pathid1 - pathid2;
|
|
|
|
Win4Assert( pidName == propId || pidPath == propId );
|
|
|
|
CSplitPath path1( *this, pathid1 );
|
|
CSplitPath path2( *this, pathid2 );
|
|
|
|
CSplitPathCompare comp( path1, path2 );
|
|
|
|
if ( pidName == propId )
|
|
{
|
|
return comp.CompareNames();
|
|
}
|
|
else
|
|
{
|
|
return comp.ComparePaths();
|
|
}
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Compare
|
|
//
|
|
// Synopsis: Compares a NULL terminated path with a pathid.
|
|
//
|
|
// Arguments: [pwszPath1] - NULL terminated path.
|
|
// [pathid2] - Id of the second path.
|
|
// [propId] - pidName/pidPath
|
|
//
|
|
// History: 5-11-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
int CPathStore::Compare( const WCHAR * pwszPath1, PATHID pathid2,
|
|
PROPID propId )
|
|
{
|
|
if ( 0 == pathid2 )
|
|
return 0;
|
|
|
|
Win4Assert( pidName == propId || pidPath == propId );
|
|
|
|
CSplitPath path1( pwszPath1 );
|
|
CSplitPath path2( *this, pathid2 );
|
|
|
|
CSplitPathCompare comp( path1, path2 );
|
|
|
|
if ( pidName == propId )
|
|
{
|
|
return comp.CompareNames();
|
|
}
|
|
else
|
|
{
|
|
return comp.ComparePaths();
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: Compare
|
|
//
|
|
// Synopsis: Compares a path in the variant form to a pathId.
|
|
//
|
|
// Arguments: [varnt] -
|
|
// [pathid2] -
|
|
// [propId] -
|
|
//
|
|
// History: 5-11-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
int CPathStore::Compare( PROPVARIANT &varnt, PATHID pathid2,
|
|
PROPID propId )
|
|
{
|
|
Win4Assert( pidName == propId || pidPath == propId );
|
|
|
|
Win4Assert( varnt.vt == VT_LPWSTR );
|
|
const WCHAR * pwszPath1 = varnt.pwszVal;
|
|
|
|
return Compare( pwszPath1, pathid2, propId );
|
|
}
|
|
|