Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

419 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1998.
  5. //
  6. // File: Strings.hxx
  7. //
  8. // Contents: Fast (hashed) access to paths for downlevel ci.
  9. //
  10. // History: 09-Mar-92 BartoszM Created
  11. // 15-Mar-93 BartoszM Converted to memory mapped streams
  12. // 03-Jan-96 KyleP Integrate with property cache
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <prpstmgr.hxx>
  17. #include <propobj.hxx>
  18. #include <smatch.hxx>
  19. #include "pershash.hxx"
  20. #include "vmap.hxx"
  21. class CiCat;
  22. class CCompositePropRecord;
  23. #define SEEN_NOT 0
  24. #define SEEN_YES 1
  25. #define SEEN_NEW 2
  26. #define SEEN_IGNORE 3
  27. #define SEEN_MASK 3
  28. #define SEEN_BITS 2
  29. #define SEEN_PER_BYTE 4
  30. inline void SET_SEEN( CDynArrayInPlace<BYTE> * parray, WORKID wid, ULONG value )
  31. {
  32. (*parray)[wid/SEEN_PER_BYTE] &= ~(SEEN_MASK << ((wid % SEEN_PER_BYTE) * SEEN_BITS));
  33. (*parray)[wid/SEEN_PER_BYTE] |= value << ((wid % SEEN_PER_BYTE) * SEEN_BITS);
  34. }
  35. inline ULONG GET_SEEN( CDynArrayInPlace<BYTE> * parray, WORKID wid )
  36. {
  37. return ( (*parray)[wid/SEEN_PER_BYTE] >> ((wid % SEEN_PER_BYTE) * SEEN_BITS) ) & SEEN_MASK;
  38. }
  39. enum ESeenArrayType {eScansArray, eUsnsArray};
  40. //+-------------------------------------------------------------------------
  41. //
  42. // Class: CStrings
  43. //
  44. // Purpose: Provides for quick (hashed) lookup of strings
  45. //
  46. // History: 28-Dec-95 KyleP Created
  47. //
  48. // Notes: This class is a bit odd. In manages the hash table, but
  49. // does not control the memory used to store it. This strange
  50. // behaviour allows the hash table to be stored persistently.
  51. //
  52. //--------------------------------------------------------------------------
  53. class CStrings : public CPersHash
  54. {
  55. public:
  56. //
  57. // Two-phase construction.
  58. //
  59. CStrings( CPropStoreManager & PropStoreMgr, CiCat & cicat );
  60. void Abort() { _fAbort = TRUE; }
  61. virtual BOOL FastInit ( CiStorage * pStorage,ULONG version );
  62. virtual void LongInit ( ULONG version, BOOL fDirtyShutdown );
  63. virtual void Empty();
  64. //
  65. // Lookup
  66. //
  67. WORKID LokFind( WCHAR const * buf );
  68. inline WORKID LokFind( const CLowerFunnyPath & lcaseFunnyPath, BOOL fUsnVolume );
  69. BOOL Find( WORKID wid, FILETIME & ftLastSeen );
  70. unsigned Find( WORKID wid, XGrowable<WCHAR> & xBuf );
  71. unsigned Find( CCompositePropRecord & PropRec, XGrowable<WCHAR> & xBuf );
  72. unsigned Find( WORKID wid, CFunnyPath & funnyPath );
  73. unsigned Find( CCompositePropRecord & PropRec, CFunnyPath & funnyPath );
  74. unsigned Find( WORKID wid, CLowerFunnyPath & lcaseFunnyPath );
  75. unsigned Find( CCompositePropRecord & PropRec, CLowerFunnyPath & lcaseFunnyPath );
  76. //
  77. // Modification
  78. //
  79. WORKID LokAdd( WCHAR const * pwcPath,
  80. FILEID fileId,
  81. BOOL fUsnVolume,
  82. WORKID widParent,
  83. ULONG ulAttrib = 0,
  84. FILETIME const * pftLastWrite = 0 );
  85. void LokDelete( WCHAR const * pwcPath, // Note: Has to be lowercase
  86. WORKID wid,
  87. BOOL fDisableDeletionCheck=FALSE,
  88. BOOL fUsnVolume = FALSE );
  89. void LokRenameFile( const WCHAR * pwcsOldFileName,
  90. const WCHAR * pwcsNewFileName,
  91. WORKID wid,
  92. ULONG ulFileAttrib,
  93. VOLUMEID volumeId,
  94. WORKID widParent = widInvalid );
  95. //
  96. // 'Seen' processing.
  97. //
  98. void BeginSeen( WCHAR const * pwcsRoot,
  99. CMutexSem & mutex,
  100. ESeenArrayType eType );
  101. inline void LokEndSeen( ESeenArrayType eType );
  102. inline void LokSetSeen ( WORKID wid, ESeenArrayType eType );
  103. inline BOOL LokNotSeen(WORKID wid, ESeenArrayType eType);
  104. inline BOOL LokSeenNew(WORKID wid, ESeenArrayType eType);
  105. //
  106. // Virtual path changes.
  107. //
  108. BOOL AddVirtualScope( WCHAR const * vroot,
  109. WCHAR const * root,
  110. BOOL fAutomatic = FALSE,
  111. CiVRootTypeEnum eType = W3VRoot,
  112. BOOL fVRoot = FALSE,
  113. BOOL fIsIndexed = FALSE );
  114. BOOL RemoveVirtualScope( WCHAR const * vroot,
  115. BOOL fOnlyIfAutomatic,
  116. CiVRootTypeEnum eType,
  117. BOOL fVRoot,
  118. BOOL fForceVPathFixing );
  119. unsigned FindVirtual( WORKID wid, unsigned cSkip, XGrowable<WCHAR> & xBuf );
  120. unsigned FindVirtual( CCompositePropRecord & PropRec, unsigned cSkip, XGrowable<WCHAR> & xBuf );
  121. inline BOOL VirtualToPhysicalRoot( WCHAR const * pwcVRoot,
  122. unsigned ccVRoot,
  123. CLowerFunnyPath & lcaseFunnyPRoot,
  124. unsigned & ccPRoot );
  125. inline BOOL VirtualToPhysicalRoot( WCHAR const * pwcVPath,
  126. unsigned ccVPath,
  127. XGrowable<WCHAR> & xwcsVRoot,
  128. unsigned & ccVRoot,
  129. CLowerFunnyPath & lcaseFunnyPRoot,
  130. unsigned & ccPRoot,
  131. unsigned & iBmk );
  132. inline BOOL VirtualToAllPhysicalRoots( WCHAR const * pwcVPath,
  133. unsigned ccVPath,
  134. XGrowable<WCHAR> & xwcsVRoot,
  135. unsigned & ccVRoot,
  136. CLowerFunnyPath & lcaseFunnyPRoot,
  137. unsigned & ccPRoot,
  138. ULONG & ulType,
  139. unsigned & iBmk );
  140. inline ULONG EnumerateVRoot( XGrowable<WCHAR> & xwcVRoot,
  141. unsigned & ccVRoot,
  142. CLowerFunnyPath & lcaseFunnyPRoot,
  143. unsigned & ccPRoot,
  144. unsigned & iBmk );
  145. BOOL DoesPhysicalRootExist( WCHAR const * pwcPRoot )
  146. {
  147. return _vmap.DoesPhysicalRootExist( pwcPRoot );
  148. }
  149. #ifdef CI_USE_JET
  150. //
  151. // To allocate a free workid
  152. //
  153. WORKID AllocWorkid( WCHAR const * pwszPath = 0 ); // virtual method of PWidGenerator
  154. #endif // CI_USE_JET
  155. private:
  156. WORKID LokParentWorkId( WCHAR const *pwcsFileName, BOOL fUsnVolume );
  157. static unsigned HashFun ( WCHAR const * str );
  158. void ReVirtualize();
  159. void _Find( CCompositePropRecord & PropRec, WCHAR * buf, unsigned & cc );
  160. //
  161. // Error recovery.
  162. //
  163. virtual BOOL ReInit( ULONG version );
  164. virtual void HashAll();
  165. CDynArrayInPlace<BYTE> _afSeenScans; // 'Seen' bytes for scans
  166. CDynArrayInPlace<BYTE> _afSeenUsns; // 'Seen' bytes for usns
  167. FILETIME _ftSeen; // Start of current 'seen' processing.
  168. CVMap _vmap; // Virtual/Physical path map
  169. CiCat & _cicat; // Catalog
  170. };
  171. //+---------------------------------------------------------------------------
  172. //
  173. // Member: CStrings::LokEndSeen, public
  174. //
  175. // Synopsis: Complete the 'seen' process.
  176. //
  177. // Arguments: [eType] -- Seen array type
  178. //
  179. // History: 11-Jan-96 KyleP Added header.
  180. //
  181. //----------------------------------------------------------------------------
  182. inline void CStrings::LokEndSeen( ESeenArrayType eType )
  183. {
  184. ciDebugOut(( DEB_ITRACE, "EndSeen 0x%x\n", eType ));
  185. if ( eScansArray == eType )
  186. {
  187. _afSeenScans.Clear();
  188. FILETIME * pft = (FILETIME *)_pStreamHash->Get();
  189. *pft = _ftSeen;
  190. }
  191. else
  192. {
  193. _afSeenUsns.Clear();
  194. }
  195. } //LokEndSeen
  196. //+---------------------------------------------------------------------------
  197. //
  198. // Member: CStrings::LokSetSeen, public
  199. //
  200. // Synopsis: Mark a workid as seen.
  201. //
  202. // Arguments: [wid] -- Workid
  203. // [eType] -- Seen array type
  204. //
  205. // History: 11-Jan-96 KyleP Added header.
  206. //
  207. //----------------------------------------------------------------------------
  208. inline void CStrings::LokSetSeen( WORKID wid, ESeenArrayType eType )
  209. {
  210. Win4Assert( wid != widInvalid );
  211. CDynArrayInPlace<BYTE> *pafSeen;
  212. if ( eType == eScansArray )
  213. pafSeen = &_afSeenScans;
  214. else
  215. pafSeen = &_afSeenUsns;
  216. if ( 0 != pafSeen->Size() )
  217. SET_SEEN( pafSeen, wid, SEEN_YES );
  218. } //LokSetSeen
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Member: CStrings::LokNotSeen, public
  222. //
  223. // Arguments: [wid] -- Workid
  224. // [eType] -- Seen array type
  225. //
  226. // Returns: TRUE if [wid] has not been seen.
  227. //
  228. // History: 11-Jan-96 KyleP Added header.
  229. //
  230. //----------------------------------------------------------------------------
  231. inline BOOL CStrings::LokNotSeen( WORKID wid, ESeenArrayType eType )
  232. {
  233. Win4Assert( wid != widInvalid );
  234. CDynArrayInPlace<BYTE> *pafSeen;
  235. if ( eType == eScansArray )
  236. pafSeen = &_afSeenScans;
  237. else
  238. pafSeen = &_afSeenUsns;
  239. Win4Assert( 0 != pafSeen->Size() );
  240. if ( _fAbort )
  241. THROW( CException(STATUS_TOO_LATE) );
  242. return GET_SEEN( pafSeen, wid ) == SEEN_NOT;
  243. }
  244. //+---------------------------------------------------------------------------
  245. //
  246. // Member: CStrings::LokSeenNew, public
  247. //
  248. // Arguments: [wid] -- Workid
  249. // [eType] -- Seen array type
  250. //
  251. // Returns: TRUE if [wid] is new (added since beginning of seen processing)
  252. //
  253. // History: 11-Jan-96 KyleP Added header.
  254. //
  255. //----------------------------------------------------------------------------
  256. inline BOOL CStrings::LokSeenNew(WORKID wid, ESeenArrayType eType )
  257. {
  258. Win4Assert( wid != widInvalid );
  259. CDynArrayInPlace<BYTE> *pafSeen;
  260. if ( eType == eScansArray )
  261. pafSeen = &_afSeenScans;
  262. else
  263. pafSeen = &_afSeenUsns;
  264. Win4Assert( 0 != pafSeen->Size() );
  265. if ( _fAbort )
  266. THROW( CException(STATUS_TOO_LATE) );
  267. return GET_SEEN( pafSeen, wid ) == SEEN_NEW;
  268. }
  269. inline BOOL CStrings::VirtualToPhysicalRoot( WCHAR const * pwcVRoot,
  270. unsigned ccVRoot,
  271. CLowerFunnyPath & lcaseFunnyPRoot,
  272. unsigned & ccPRoot )
  273. {
  274. return _vmap.VirtualToPhysicalRoot( pwcVRoot,
  275. ccVRoot,
  276. lcaseFunnyPRoot,
  277. ccPRoot );
  278. }
  279. inline BOOL CStrings::VirtualToPhysicalRoot( WCHAR const * pwcVPath,
  280. unsigned ccVPath,
  281. XGrowable<WCHAR> & xwcsVRoot,
  282. unsigned & ccVRoot,
  283. CLowerFunnyPath & lcaseFunnyPRoot,
  284. unsigned & ccPRoot,
  285. unsigned & iBmk )
  286. {
  287. return _vmap.VirtualToPhysicalRoot( pwcVPath,
  288. ccVPath,
  289. xwcsVRoot,
  290. ccVRoot,
  291. lcaseFunnyPRoot,
  292. ccPRoot,
  293. iBmk );
  294. }
  295. inline BOOL CStrings::VirtualToAllPhysicalRoots( WCHAR const * pwcVPath,
  296. unsigned ccVPath,
  297. XGrowable<WCHAR> & xwcsVRoot,
  298. unsigned & ccVRoot,
  299. CLowerFunnyPath & lcaseFunnyPRoot,
  300. unsigned & ccPRoot,
  301. ULONG & ulType,
  302. unsigned & iBmk )
  303. {
  304. return _vmap.VirtualToAllPhysicalRoots( pwcVPath,
  305. ccVPath,
  306. xwcsVRoot,
  307. ccVRoot,
  308. lcaseFunnyPRoot,
  309. ccPRoot,
  310. ulType,
  311. iBmk );
  312. }
  313. inline ULONG CStrings::EnumerateVRoot( XGrowable<WCHAR> & xwcVRoot,
  314. unsigned & ccVRoot,
  315. CLowerFunnyPath & lcaseFunnyPRoot,
  316. unsigned & ccPRoot,
  317. unsigned & iBmk )
  318. {
  319. return _vmap.EnumerateRoot( xwcVRoot,
  320. ccVRoot,
  321. lcaseFunnyPRoot,
  322. ccPRoot,
  323. iBmk );
  324. }
  325. //+-------------------------------------------------------------------------
  326. //
  327. // Member: CStrings::FindVirtual, private
  328. //
  329. // Synopsis: Given workid, find virtual path.
  330. //
  331. // Arguments: [wid] -- Workid to locate
  332. // [cSkip] -- Count of paths to skip.
  333. // [buf] -- String returned here
  334. // [cc] -- On input: size in WCHARs of [buf]. On output,
  335. // size required or 0 if string not found.
  336. //
  337. // History: 07-Feb-96 KyleP Created.
  338. //
  339. //--------------------------------------------------------------------------
  340. inline unsigned CStrings::FindVirtual( WORKID wid, unsigned cSkip, XGrowable<WCHAR> & xBuf )
  341. {
  342. CCompositePropRecord PropRec( wid, _PropStoreMgr );
  343. return FindVirtual( PropRec, cSkip, xBuf );
  344. }