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.

428 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: VMap.hxx
  7. //
  8. // Contents: Virtual <--> physical path map.
  9. //
  10. // Classes: CVMap
  11. //
  12. // History: 05-Feb-96 KyleP Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <catalog.hxx>
  17. #include <prcstob.hxx>
  18. #include <smatch.hxx>
  19. #include <cimbmgr.hxx>
  20. const unsigned INVALID_VMAP_INDEX = 0xFFFFFFFF;
  21. //+-------------------------------------------------------------------------
  22. //
  23. // Class: CVMapDesc
  24. //
  25. // Purpose: Description of single scope mapping
  26. //
  27. // History: 05-Feb-96 KyleP Created
  28. //
  29. //--------------------------------------------------------------------------
  30. class CVMapDesc
  31. {
  32. public:
  33. inline CVMapDesc();
  34. void Init( WCHAR const * pVRoot,
  35. ULONG ccVRoot,
  36. WCHAR const * pPRoot,
  37. ULONG ccPRoot,
  38. ULONG idParent,
  39. BOOL fAutomatic,
  40. CiVRootTypeEnum eType,
  41. BOOL fIsIndexed,
  42. BOOL fNonIndexedVDir );
  43. inline unsigned PhysicalMatchLen( WCHAR const * path ) const;
  44. inline BOOL IsInPhysicalScope( WCHAR const * root, unsigned cc ) const;
  45. BOOL IsVirtualMatch( WCHAR const * pVPath, unsigned ccVPath ) const;
  46. BOOL IsPhysicalMatch( WCHAR const * pVPath, unsigned ccVPath ) const;
  47. inline ULONG Parent() const { return _idParent; }
  48. inline void SetParent( ULONG idParent ) { _idParent = idParent; }
  49. inline BOOL IsFree() { return (0 == _ccVScope); }
  50. inline void Delete() { _ccVScope = 0; }
  51. inline WCHAR const * PhysicalPath() const { return _wcPScope; }
  52. inline ULONG PhysicalLength() const { return _ccPScope; }
  53. inline WCHAR const * VirtualPath() const { return _wcVScope; }
  54. inline ULONG VirtualLength() const { return _ccVScope; }
  55. inline void SetAutomatic() { _Type |= PCatalog::AutomaticRoot; }
  56. inline void ClearAutomatic() { _Type &= ~PCatalog::AutomaticRoot; }
  57. inline BOOL IsAutomatic() const { return (_Type & PCatalog::AutomaticRoot); }
  58. inline void SetManual() { _Type |= PCatalog::ManualRoot; }
  59. inline void ClearManual() { _Type &= ~PCatalog::ManualRoot; }
  60. inline BOOL IsManual() const { return (_Type & PCatalog::ManualRoot); }
  61. inline void ClearInUse() { _Type &= ~PCatalog::UsedRoot; }
  62. inline BOOL IsInUse() const { return (_Type & PCatalog::UsedRoot); }
  63. inline BOOL IsNNTP() const { return 0 != (_Type & PCatalog::NNTPRoot); }
  64. inline BOOL IsIMAP() const { return 0 != (_Type & PCatalog::IMAPRoot); }
  65. inline BOOL IsW3() const { return !IsNNTP() && !IsIMAP(); }
  66. inline BOOL IsNonIndexedVDir() const { return 0 != (_Type & PCatalog::NonIndexedVDir); }
  67. inline void SetNonIndexedVDir() { _Type |= PCatalog::NonIndexedVDir; }
  68. inline void ClearNonIndexedVDir() { _Type &= ~PCatalog::NonIndexedVDir; }
  69. inline ULONG RootType() { return _Type; }
  70. private:
  71. ULONG _ccVScope;
  72. WCHAR _wcVScope[MAX_PATH]; // Virtual scope
  73. // IIS currently doesn't allow paths greater
  74. // than MAX_PATH. This is not a good reason for we to also not
  75. // support, but there are lot of complications right now, like
  76. // in place serialization of variable data, so currently we have the
  77. // MAX_PATH restriction of VPaths and for scopes.
  78. ULONG _ccPScope;
  79. WCHAR _wcPScope[MAX_PATH]; // Physical scope
  80. ULONG _idParent; // Link to parent (INVALID_VMAP_INDEX --> top level)
  81. ULONG _Type;
  82. };
  83. //+-------------------------------------------------------------------------
  84. //
  85. // Class: CVMap
  86. //
  87. // Purpose: Virtual/Physical path map
  88. //
  89. // History: 05-Feb-96 KyleP Created
  90. //
  91. //--------------------------------------------------------------------------
  92. class CVMap
  93. {
  94. public:
  95. CVMap();
  96. BOOL Init( PRcovStorageObj * obj );
  97. void Empty();
  98. BOOL Add( WCHAR const * vroot,
  99. WCHAR const * root,
  100. BOOL fAutomatic,
  101. ULONG & idNew,
  102. CiVRootTypeEnum eType,
  103. BOOL fVRoot,
  104. BOOL fIsIndexed );
  105. BOOL Remove( WCHAR const * vroot,
  106. BOOL fOnlyIfAutomatic,
  107. ULONG & idOld,
  108. ULONG & idNew,
  109. CiVRootTypeEnum eType,
  110. BOOL fVRoot );
  111. void MarkClean();
  112. BOOL IsClean() const { return !_fDirty; }
  113. inline BOOL IsInPhysicalScope( ULONG id, WCHAR const * root, unsigned cc );
  114. ULONG PhysicalPathToId( WCHAR const * path );
  115. BOOL VirtualToPhysicalRoot( WCHAR const * pwcVRoot,
  116. unsigned ccVRoot,
  117. CLowerFunnyPath & lcaseFunnyPRoot,
  118. unsigned & ccPRoot );
  119. BOOL VirtualToPhysicalRoot( WCHAR const * pwcVPath,
  120. unsigned ccVPath,
  121. XGrowable<WCHAR> & xwcsVRoot,
  122. unsigned & ccVRoot,
  123. CLowerFunnyPath & lcaseFunnyPRoot,
  124. unsigned & ccPRoot,
  125. unsigned & iBmk );
  126. BOOL VirtualToAllPhysicalRoots( WCHAR const * pwcVPath,
  127. unsigned ccVPath,
  128. XGrowable<WCHAR> & xwcsVRoot,
  129. unsigned & ccVRoot,
  130. CLowerFunnyPath & lcaseFunnyPRoot,
  131. unsigned & ccPRoot,
  132. ULONG & ulType,
  133. unsigned & iBmk );
  134. ULONG EnumerateRoot( XGrowable<WCHAR> & xwcVRoot,
  135. unsigned & ccVRoot,
  136. CLowerFunnyPath & lcaseFunnyPRoot,
  137. unsigned & ccPRoot,
  138. unsigned & iBmk );
  139. BOOL DoesPhysicalRootExist( WCHAR const * pwcPRoot );
  140. inline CVMapDesc const & GetDesc( ULONG id ) const;
  141. //
  142. // Path chaining.
  143. //
  144. inline ULONG Parent( ULONG id ) const;
  145. inline ULONG FindNthRemoved( ULONG id, unsigned cSkip ) const;
  146. BOOL IsNonIndexedVDir( ULONG id ) const
  147. {
  148. if ( INVALID_VMAP_INDEX == id )
  149. return FALSE;
  150. return _aMap[id].IsNonIndexedVDir();
  151. }
  152. ULONG GetExcludeParent( ULONG id ) const
  153. {
  154. Win4Assert( id < _aExcludeParent.Count() );
  155. return _aExcludeParent[ id ];
  156. }
  157. BOOL IsAnExcludeParent( ULONG id ) const
  158. {
  159. if ( INVALID_VMAP_INDEX == id )
  160. return FALSE;
  161. for ( unsigned x = 0; x < _aExcludeParent.Count(); x++ )
  162. if ( _aExcludeParent[x] == id )
  163. return TRUE;
  164. return FALSE;
  165. }
  166. private:
  167. ULONG PhysicalPathToId( WCHAR const * path, BOOL fNonIndexedVDirs );
  168. void DumpVMap();
  169. void RecomputeNonIndexedInfo();
  170. BOOL _fDirty; // TRUE if vmap went down dirty
  171. CMutexSem _mutex;
  172. CDynArrayInPlace<CVMapDesc> _aMap;
  173. CDynArrayInPlace<ULONG> _aExcludeParent;
  174. XPtr<PRcovStorageObj> _xrsoMap;
  175. };
  176. //+-------------------------------------------------------------------------
  177. //
  178. // Member: CVMapDesc::PhysicalMatchLen, private
  179. //
  180. // Synopsis: Compares input with physical path
  181. //
  182. // Arguments: [pPPath] -- Physical path.
  183. //
  184. // Returns: 0 if [pPPath] does not match physical path complete to
  185. // the end of the short of the two. On success returns
  186. // length of physical path.
  187. //
  188. // History: 07-Feb-96 KyleP Created.
  189. //
  190. //--------------------------------------------------------------------------
  191. inline unsigned CVMapDesc::PhysicalMatchLen( WCHAR const * pPPath ) const
  192. {
  193. Win4Assert( *pPPath );
  194. //
  195. // Compare strings.
  196. //
  197. unsigned i = 0;
  198. while ( *pPPath && i < _ccPScope && *pPPath == _wcPScope[i] )
  199. {
  200. i++;
  201. pPPath++;
  202. }
  203. //
  204. // Adjust for possible lack of terminating backslash.
  205. //
  206. if ( 0 == *pPPath )
  207. {
  208. if ( *(pPPath - 1) == L'\\' )
  209. return _ccPScope;
  210. else
  211. {
  212. if ( _wcPScope[i] == L'\\' )
  213. return _ccPScope;
  214. else
  215. return 0;
  216. }
  217. }
  218. else
  219. {
  220. if ( i >= _ccPScope )
  221. return _ccPScope;
  222. else
  223. return 0;
  224. }
  225. }
  226. //+-------------------------------------------------------------------------
  227. //
  228. // Member: CVMapDesc::CVMapDesc, private
  229. //
  230. // Synopsis: Constructor
  231. //
  232. // History: 07-Feb-96 KyleP Created.
  233. //
  234. //--------------------------------------------------------------------------
  235. inline CVMapDesc::CVMapDesc()
  236. : _ccVScope( 0 ),
  237. _ccPScope( 0 )
  238. {
  239. }
  240. //+-------------------------------------------------------------------------
  241. //
  242. // Member: CVMapDesc::IsInPhysicalScope, public
  243. //
  244. // Synopsis: Compares input with physical path
  245. //
  246. // Arguments: [root] -- Physical path.
  247. // [cc] -- Size, in chars, of [root]
  248. //
  249. // Returns: TRUE if [root] is within physical scope.
  250. //
  251. // History: 07-Feb-96 KyleP Created.
  252. //
  253. //--------------------------------------------------------------------------
  254. inline BOOL CVMapDesc::IsInPhysicalScope( WCHAR const * root, unsigned cc ) const
  255. {
  256. Win4Assert( root[cc-1] != L'\\' );
  257. CScopeMatch Match( _wcPScope, _ccPScope );
  258. //
  259. // Be careful not to match root of scope.
  260. //
  261. return Match.IsInScope( root, cc ) && (_ccPScope != cc + 1);
  262. }
  263. //+-------------------------------------------------------------------------
  264. //
  265. // Member: CVMap::IsInPhysicalScope, public
  266. //
  267. // Synopsis: Compares input with physical path
  268. //
  269. // Arguments: [id] -- Id of virtual/physical scope
  270. // [root] -- Physical path.
  271. // [cc] -- Size, in chars, of [root]
  272. //
  273. // Returns: TRUE if [root] is within physical scope.
  274. //
  275. // History: 07-Feb-96 KyleP Created.
  276. //
  277. //--------------------------------------------------------------------------
  278. inline BOOL CVMap::IsInPhysicalScope( ULONG id, WCHAR const * root, unsigned cc )
  279. {
  280. CLock lock(_mutex);
  281. Win4Assert( id < _aMap.Count() );
  282. return _aMap[id].IsInPhysicalScope( root, cc );
  283. }
  284. //+-------------------------------------------------------------------------
  285. //
  286. // Member: CVMap::Parent, public
  287. //
  288. // Arguments: [id] -- Id of virtual/physical scope
  289. //
  290. // Returns: Virtual/physical id of parent.
  291. //
  292. // History: 07-Feb-96 KyleP Created.
  293. //
  294. //--------------------------------------------------------------------------
  295. inline ULONG CVMap::Parent( ULONG id ) const
  296. {
  297. Win4Assert( id < _aMap.Count() );
  298. return _aMap[id].Parent();
  299. }
  300. //+-------------------------------------------------------------------------
  301. //
  302. // Member: CVMap::FindNthRemoved, public
  303. //
  304. // Synopsis: Walks up virtual root chain to the Nth link.
  305. //
  306. // Arguments: [id] -- Id of starting virtual/physical scope
  307. // [cSkip] -- Number of links to skip
  308. //
  309. // Returns: Virtual/physical id of Nth parent.
  310. //
  311. // History: 07-Feb-96 KyleP Created.
  312. //
  313. //--------------------------------------------------------------------------
  314. inline ULONG CVMap::FindNthRemoved( ULONG id, unsigned cSkip ) const
  315. {
  316. Win4Assert( id == INVALID_VMAP_INDEX || id < _aMap.Count() );
  317. while ( id != INVALID_VMAP_INDEX && !_aMap[id].IsFree() && cSkip > 0 )
  318. {
  319. id = _aMap[id].Parent();
  320. cSkip--;
  321. }
  322. if ( INVALID_VMAP_INDEX != id && _aMap[id].IsFree() )
  323. id = INVALID_VMAP_INDEX;
  324. return id;
  325. }
  326. //+-------------------------------------------------------------------------
  327. //
  328. // Member: CVMap::GetDesc, public
  329. //
  330. // Arguments: [id] -- Id of virtual/physical scope
  331. //
  332. // Returns: Scope descriptor for [id]
  333. //
  334. // History: 07-Feb-96 KyleP Created.
  335. //
  336. //--------------------------------------------------------------------------
  337. inline CVMapDesc const & CVMap::GetDesc( ULONG id ) const
  338. {
  339. Win4Assert( id < _aMap.Count() );
  340. return _aMap[id];
  341. }