//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1991 - 1998. // // File: Strings.hxx // // Contents: Fast (hashed) access to paths for downlevel ci. // // History: 09-Mar-92 BartoszM Created // 15-Mar-93 BartoszM Converted to memory mapped streams // 03-Jan-96 KyleP Integrate with property cache // //---------------------------------------------------------------------------- #pragma once #include #include #include #include "pershash.hxx" #include "vmap.hxx" class CiCat; class CCompositePropRecord; #define SEEN_NOT 0 #define SEEN_YES 1 #define SEEN_NEW 2 #define SEEN_IGNORE 3 #define SEEN_MASK 3 #define SEEN_BITS 2 #define SEEN_PER_BYTE 4 inline void SET_SEEN( CDynArrayInPlace * parray, WORKID wid, ULONG value ) { (*parray)[wid/SEEN_PER_BYTE] &= ~(SEEN_MASK << ((wid % SEEN_PER_BYTE) * SEEN_BITS)); (*parray)[wid/SEEN_PER_BYTE] |= value << ((wid % SEEN_PER_BYTE) * SEEN_BITS); } inline ULONG GET_SEEN( CDynArrayInPlace * parray, WORKID wid ) { return ( (*parray)[wid/SEEN_PER_BYTE] >> ((wid % SEEN_PER_BYTE) * SEEN_BITS) ) & SEEN_MASK; } enum ESeenArrayType {eScansArray, eUsnsArray}; //+------------------------------------------------------------------------- // // Class: CStrings // // Purpose: Provides for quick (hashed) lookup of strings // // History: 28-Dec-95 KyleP Created // // Notes: This class is a bit odd. In manages the hash table, but // does not control the memory used to store it. This strange // behaviour allows the hash table to be stored persistently. // //-------------------------------------------------------------------------- class CStrings : public CPersHash { public: // // Two-phase construction. // CStrings( CPropStoreManager & PropStoreMgr, CiCat & cicat ); void Abort() { _fAbort = TRUE; } virtual BOOL FastInit ( CiStorage * pStorage,ULONG version ); virtual void LongInit ( ULONG version, BOOL fDirtyShutdown ); virtual void Empty(); // // Lookup // WORKID LokFind( WCHAR const * buf ); inline WORKID LokFind( const CLowerFunnyPath & lcaseFunnyPath, BOOL fUsnVolume ); BOOL Find( WORKID wid, FILETIME & ftLastSeen ); unsigned Find( WORKID wid, XGrowable & xBuf ); unsigned Find( CCompositePropRecord & PropRec, XGrowable & xBuf ); unsigned Find( WORKID wid, CFunnyPath & funnyPath ); unsigned Find( CCompositePropRecord & PropRec, CFunnyPath & funnyPath ); unsigned Find( WORKID wid, CLowerFunnyPath & lcaseFunnyPath ); unsigned Find( CCompositePropRecord & PropRec, CLowerFunnyPath & lcaseFunnyPath ); // // Modification // WORKID LokAdd( WCHAR const * pwcPath, FILEID fileId, BOOL fUsnVolume, WORKID widParent, ULONG ulAttrib = 0, FILETIME const * pftLastWrite = 0 ); void LokDelete( WCHAR const * pwcPath, // Note: Has to be lowercase WORKID wid, BOOL fDisableDeletionCheck=FALSE, BOOL fUsnVolume = FALSE ); void LokRenameFile( const WCHAR * pwcsOldFileName, const WCHAR * pwcsNewFileName, WORKID wid, ULONG ulFileAttrib, VOLUMEID volumeId, WORKID widParent = widInvalid ); // // 'Seen' processing. // void BeginSeen( WCHAR const * pwcsRoot, CMutexSem & mutex, ESeenArrayType eType ); inline void LokEndSeen( ESeenArrayType eType ); inline void LokSetSeen ( WORKID wid, ESeenArrayType eType ); inline BOOL LokNotSeen(WORKID wid, ESeenArrayType eType); inline BOOL LokSeenNew(WORKID wid, ESeenArrayType eType); // // Virtual path changes. // BOOL AddVirtualScope( WCHAR const * vroot, WCHAR const * root, BOOL fAutomatic = FALSE, CiVRootTypeEnum eType = W3VRoot, BOOL fVRoot = FALSE, BOOL fIsIndexed = FALSE ); BOOL RemoveVirtualScope( WCHAR const * vroot, BOOL fOnlyIfAutomatic, CiVRootTypeEnum eType, BOOL fVRoot, BOOL fForceVPathFixing ); unsigned FindVirtual( WORKID wid, unsigned cSkip, XGrowable & xBuf ); unsigned FindVirtual( CCompositePropRecord & PropRec, unsigned cSkip, XGrowable & xBuf ); inline BOOL VirtualToPhysicalRoot( WCHAR const * pwcVRoot, unsigned ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot ); inline BOOL VirtualToPhysicalRoot( WCHAR const * pwcVPath, unsigned ccVPath, XGrowable & xwcsVRoot, unsigned & ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot, unsigned & iBmk ); inline BOOL VirtualToAllPhysicalRoots( WCHAR const * pwcVPath, unsigned ccVPath, XGrowable & xwcsVRoot, unsigned & ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot, ULONG & ulType, unsigned & iBmk ); inline ULONG EnumerateVRoot( XGrowable & xwcVRoot, unsigned & ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot, unsigned & iBmk ); BOOL DoesPhysicalRootExist( WCHAR const * pwcPRoot ) { return _vmap.DoesPhysicalRootExist( pwcPRoot ); } #ifdef CI_USE_JET // // To allocate a free workid // WORKID AllocWorkid( WCHAR const * pwszPath = 0 ); // virtual method of PWidGenerator #endif // CI_USE_JET private: WORKID LokParentWorkId( WCHAR const *pwcsFileName, BOOL fUsnVolume ); static unsigned HashFun ( WCHAR const * str ); void ReVirtualize(); void _Find( CCompositePropRecord & PropRec, WCHAR * buf, unsigned & cc ); // // Error recovery. // virtual BOOL ReInit( ULONG version ); virtual void HashAll(); CDynArrayInPlace _afSeenScans; // 'Seen' bytes for scans CDynArrayInPlace _afSeenUsns; // 'Seen' bytes for usns FILETIME _ftSeen; // Start of current 'seen' processing. CVMap _vmap; // Virtual/Physical path map CiCat & _cicat; // Catalog }; //+--------------------------------------------------------------------------- // // Member: CStrings::LokEndSeen, public // // Synopsis: Complete the 'seen' process. // // Arguments: [eType] -- Seen array type // // History: 11-Jan-96 KyleP Added header. // //---------------------------------------------------------------------------- inline void CStrings::LokEndSeen( ESeenArrayType eType ) { ciDebugOut(( DEB_ITRACE, "EndSeen 0x%x\n", eType )); if ( eScansArray == eType ) { _afSeenScans.Clear(); FILETIME * pft = (FILETIME *)_pStreamHash->Get(); *pft = _ftSeen; } else { _afSeenUsns.Clear(); } } //LokEndSeen //+--------------------------------------------------------------------------- // // Member: CStrings::LokSetSeen, public // // Synopsis: Mark a workid as seen. // // Arguments: [wid] -- Workid // [eType] -- Seen array type // // History: 11-Jan-96 KyleP Added header. // //---------------------------------------------------------------------------- inline void CStrings::LokSetSeen( WORKID wid, ESeenArrayType eType ) { Win4Assert( wid != widInvalid ); CDynArrayInPlace *pafSeen; if ( eType == eScansArray ) pafSeen = &_afSeenScans; else pafSeen = &_afSeenUsns; if ( 0 != pafSeen->Size() ) SET_SEEN( pafSeen, wid, SEEN_YES ); } //LokSetSeen //+--------------------------------------------------------------------------- // // Member: CStrings::LokNotSeen, public // // Arguments: [wid] -- Workid // [eType] -- Seen array type // // Returns: TRUE if [wid] has not been seen. // // History: 11-Jan-96 KyleP Added header. // //---------------------------------------------------------------------------- inline BOOL CStrings::LokNotSeen( WORKID wid, ESeenArrayType eType ) { Win4Assert( wid != widInvalid ); CDynArrayInPlace *pafSeen; if ( eType == eScansArray ) pafSeen = &_afSeenScans; else pafSeen = &_afSeenUsns; Win4Assert( 0 != pafSeen->Size() ); if ( _fAbort ) THROW( CException(STATUS_TOO_LATE) ); return GET_SEEN( pafSeen, wid ) == SEEN_NOT; } //+--------------------------------------------------------------------------- // // Member: CStrings::LokSeenNew, public // // Arguments: [wid] -- Workid // [eType] -- Seen array type // // Returns: TRUE if [wid] is new (added since beginning of seen processing) // // History: 11-Jan-96 KyleP Added header. // //---------------------------------------------------------------------------- inline BOOL CStrings::LokSeenNew(WORKID wid, ESeenArrayType eType ) { Win4Assert( wid != widInvalid ); CDynArrayInPlace *pafSeen; if ( eType == eScansArray ) pafSeen = &_afSeenScans; else pafSeen = &_afSeenUsns; Win4Assert( 0 != pafSeen->Size() ); if ( _fAbort ) THROW( CException(STATUS_TOO_LATE) ); return GET_SEEN( pafSeen, wid ) == SEEN_NEW; } inline BOOL CStrings::VirtualToPhysicalRoot( WCHAR const * pwcVRoot, unsigned ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot ) { return _vmap.VirtualToPhysicalRoot( pwcVRoot, ccVRoot, lcaseFunnyPRoot, ccPRoot ); } inline BOOL CStrings::VirtualToPhysicalRoot( WCHAR const * pwcVPath, unsigned ccVPath, XGrowable & xwcsVRoot, unsigned & ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot, unsigned & iBmk ) { return _vmap.VirtualToPhysicalRoot( pwcVPath, ccVPath, xwcsVRoot, ccVRoot, lcaseFunnyPRoot, ccPRoot, iBmk ); } inline BOOL CStrings::VirtualToAllPhysicalRoots( WCHAR const * pwcVPath, unsigned ccVPath, XGrowable & xwcsVRoot, unsigned & ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot, ULONG & ulType, unsigned & iBmk ) { return _vmap.VirtualToAllPhysicalRoots( pwcVPath, ccVPath, xwcsVRoot, ccVRoot, lcaseFunnyPRoot, ccPRoot, ulType, iBmk ); } inline ULONG CStrings::EnumerateVRoot( XGrowable & xwcVRoot, unsigned & ccVRoot, CLowerFunnyPath & lcaseFunnyPRoot, unsigned & ccPRoot, unsigned & iBmk ) { return _vmap.EnumerateRoot( xwcVRoot, ccVRoot, lcaseFunnyPRoot, ccPRoot, iBmk ); } //+------------------------------------------------------------------------- // // Member: CStrings::FindVirtual, private // // Synopsis: Given workid, find virtual path. // // Arguments: [wid] -- Workid to locate // [cSkip] -- Count of paths to skip. // [buf] -- String returned here // [cc] -- On input: size in WCHARs of [buf]. On output, // size required or 0 if string not found. // // History: 07-Feb-96 KyleP Created. // //-------------------------------------------------------------------------- inline unsigned CStrings::FindVirtual( WORKID wid, unsigned cSkip, XGrowable & xBuf ) { CCompositePropRecord PropRec( wid, _PropStoreMgr ); return FindVirtual( PropRec, cSkip, xBuf ); }