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.

554 lines
9.9 KiB

  1. #ifndef _FILECACHE_HXX_
  2. #define _FILECACHE_HXX_
  3. #include "datetime.hxx"
  4. #include "usercache.hxx"
  5. //
  6. // When accessing file cache, file cache user describes the user trying to
  7. // access the file (it is either a token or token/sid)
  8. //
  9. class FILE_CACHE_USER
  10. {
  11. public:
  12. FILE_CACHE_USER()
  13. : _hToken( NULL ),
  14. _pSid( NULL )
  15. {
  16. }
  17. HANDLE _hToken;
  18. PSID _pSid;
  19. };
  20. //
  21. // Users of the file cache can associate (1) object with a cache entry which
  22. // will get cleaned up (by calling the Cleanup() method) when the object
  23. // is flushed
  24. //
  25. class ASSOCIATED_FILE_OBJECT
  26. {
  27. public:
  28. virtual
  29. VOID
  30. Cleanup(
  31. VOID
  32. ) = 0;
  33. };
  34. class W3_FILE_INFO_KEY : public CACHE_KEY
  35. {
  36. public:
  37. W3_FILE_INFO_KEY()
  38. : _strFileKey( _achFileKey, sizeof( _achFileKey ) ),
  39. _pszFileKey( NULL ),
  40. _cchFileKey( 0 )
  41. {
  42. }
  43. virtual ~W3_FILE_INFO_KEY()
  44. {
  45. }
  46. WCHAR *
  47. QueryHintKey(
  48. VOID
  49. )
  50. {
  51. return _pszFileKey;
  52. }
  53. HRESULT
  54. CreateCacheKey(
  55. WCHAR * pszFileKey,
  56. DWORD cchFileKey,
  57. BOOL fCopy
  58. );
  59. DWORD
  60. QueryKeyHash(
  61. VOID
  62. ) const
  63. {
  64. return HashString( _pszFileKey );
  65. }
  66. BOOL
  67. QueryIsEqual(
  68. const CACHE_KEY * pCacheCompareKey
  69. ) const
  70. {
  71. W3_FILE_INFO_KEY * pFileKey = (W3_FILE_INFO_KEY*) pCacheCompareKey;
  72. return _cchFileKey == pFileKey->_cchFileKey &&
  73. !wcscmp( _pszFileKey, pFileKey->_pszFileKey );
  74. }
  75. WCHAR _achFileKey[ 64 ];
  76. STRU _strFileKey;
  77. WCHAR * _pszFileKey;
  78. DWORD _cchFileKey;
  79. };
  80. // The maximum length of an ETag is 16 chars for the last modified time plus
  81. // one char for the colon plus 2 chars for the quotes plus 8 chars for the
  82. // system change notification number plus two for the optional prefix W/ and
  83. // one for the trailing NULL, for a total of 30 chars.
  84. #define MAX_ETAG_BUFFER_LENGTH 30
  85. //
  86. // Embedded security descriptor used for cache hits
  87. //
  88. #define SECURITY_DESC_DEFAULT_SIZE 256
  89. //
  90. // File cache entry object
  91. //
  92. #define W3_FILE_INFO_SIGNATURE ((DWORD)'IF3W')
  93. #define W3_FILE_INFO_SIGNATURE_FREE ((DWORD)'if3w')
  94. class W3_FILE_INFO : public CACHE_ENTRY
  95. {
  96. public:
  97. W3_FILE_INFO( OBJECT_CACHE * pObjectCache )
  98. : CACHE_ENTRY( pObjectCache ),
  99. _hFile( INVALID_HANDLE_VALUE ),
  100. _pFileBuffer( NULL ),
  101. _dwFileAttributes( 0 ),
  102. _nFileSizeLow( 0 ),
  103. _nFileSizeHigh( 0 ),
  104. _bufSecDesc( _abSecDesc, sizeof( _abSecDesc ) ),
  105. _cchETag( 0 ),
  106. _pAssociatedObject( NULL ),
  107. _pLastSid( NULL )
  108. {
  109. _dwSignature = W3_FILE_INFO_SIGNATURE;
  110. }
  111. virtual ~W3_FILE_INFO(
  112. VOID
  113. );
  114. VOID *
  115. operator new(
  116. size_t size
  117. )
  118. {
  119. DBG_ASSERT( size == sizeof( W3_FILE_INFO ) );
  120. DBG_ASSERT( sm_pachW3FileInfo != NULL );
  121. return sm_pachW3FileInfo->Alloc();
  122. }
  123. VOID
  124. operator delete(
  125. VOID * pW3FileInfo
  126. )
  127. {
  128. DBG_ASSERT( pW3FileInfo != NULL );
  129. DBG_ASSERT( sm_pachW3FileInfo != NULL );
  130. DBG_REQUIRE( sm_pachW3FileInfo->Free( pW3FileInfo ) );
  131. }
  132. CACHE_KEY *
  133. QueryCacheKey(
  134. VOID
  135. ) const
  136. {
  137. return (CACHE_KEY*) &_cacheKey;
  138. }
  139. BOOL
  140. QueryIsOkToFlushDirmon(
  141. WCHAR * pszPath,
  142. DWORD cchPath
  143. );
  144. BOOL
  145. CheckSignature(
  146. VOID
  147. ) const
  148. {
  149. return _dwSignature == W3_FILE_INFO_SIGNATURE;
  150. }
  151. HRESULT
  152. GetFileHandle(
  153. HANDLE * phHandle
  154. );
  155. PBYTE
  156. QueryFileBuffer(
  157. VOID
  158. ) const
  159. {
  160. return _pFileBuffer;
  161. }
  162. VOID
  163. QuerySize(
  164. LARGE_INTEGER * pliSize
  165. ) const
  166. {
  167. DBG_ASSERT( pliSize != NULL );
  168. pliSize->LowPart = _nFileSizeLow;
  169. pliSize->HighPart = _nFileSizeHigh;
  170. }
  171. WCHAR *
  172. QueryPhysicalPath(
  173. VOID
  174. )
  175. {
  176. return _cacheKey._pszFileKey;
  177. }
  178. DWORD
  179. QueryAttributes(
  180. VOID
  181. ) const
  182. {
  183. return _dwFileAttributes;
  184. }
  185. PSECURITY_DESCRIPTOR
  186. QuerySecDesc(
  187. VOID
  188. );
  189. PSID
  190. QueryLastSid(
  191. VOID
  192. )
  193. {
  194. return _pLastSid;
  195. }
  196. VOID
  197. QueryLastWriteTime(
  198. FILETIME * pFileTime
  199. ) const
  200. {
  201. DBG_ASSERT( pFileTime != NULL );
  202. memcpy( pFileTime,
  203. &_CastratedLastWriteTime,
  204. sizeof( *pFileTime ) );
  205. }
  206. CHAR *
  207. QueryLastModifiedString(
  208. VOID
  209. )
  210. {
  211. return _achLastModified;
  212. }
  213. BOOL
  214. QueryIsWeakETag(
  215. VOID
  216. ) const
  217. {
  218. return _achETag[ 0 ] == 'W' && _achETag[ 1 ] == '/';
  219. }
  220. HANDLE
  221. QueryFileHandle(
  222. VOID
  223. )
  224. {
  225. return _hFile;
  226. }
  227. CHAR *
  228. QueryETag(
  229. VOID
  230. )
  231. {
  232. return _achETag;
  233. }
  234. DWORD
  235. QueryETagSize(
  236. VOID
  237. ) const
  238. {
  239. return _cchETag;
  240. }
  241. dllexp
  242. BOOL
  243. SetAssociatedObject(
  244. ASSOCIATED_FILE_OBJECT * pObject
  245. );
  246. ASSOCIATED_FILE_OBJECT *
  247. QueryAssociatedObject(
  248. VOID
  249. )
  250. {
  251. return _pAssociatedObject;
  252. }
  253. HRESULT
  254. OpenFile(
  255. STRU & strFileName,
  256. FILE_CACHE_USER * pOpeningUser
  257. );
  258. HRESULT
  259. DoAccessCheck(
  260. FILE_CACHE_USER * pOpeningUser
  261. );
  262. BOOL
  263. IsCacheable(
  264. VOID
  265. ) const;
  266. HRESULT
  267. MakeCacheable(
  268. FILE_CACHE_USER * pOpeningUser
  269. );
  270. static
  271. HRESULT
  272. Initialize(
  273. VOID
  274. );
  275. static
  276. VOID
  277. Terminate(
  278. VOID
  279. );
  280. private:
  281. HRESULT
  282. ReadSecurityDescriptor(
  283. VOID
  284. );
  285. HRESULT
  286. GenerateETag(
  287. VOID
  288. );
  289. HRESULT
  290. GenerateLastModifiedTimeString(
  291. VOID
  292. );
  293. DWORD _dwSignature;
  294. W3_FILE_INFO_KEY _cacheKey;
  295. //
  296. // File info data
  297. //
  298. HANDLE _hFile;
  299. PBYTE _pFileBuffer;
  300. FILETIME _ftLastWriteTime;
  301. FILETIME _CastratedLastWriteTime;
  302. DWORD _dwFileAttributes;
  303. ULONG _nFileSizeLow;
  304. ULONG _nFileSizeHigh;
  305. //
  306. // Security descriptor stuff
  307. //
  308. BYTE _abSecDesc[ SECURITY_DESC_DEFAULT_SIZE ];
  309. BUFFER _bufSecDesc;
  310. //
  311. // ETag
  312. //
  313. CHAR _achETag[ MAX_ETAG_BUFFER_LENGTH ];
  314. DWORD _cchETag;
  315. //
  316. // Last modified time
  317. //
  318. CHAR _achLastModified[ GMT_STRING_SIZE ];
  319. //
  320. // Last SID to access the file
  321. //
  322. BYTE _abLastSid[ 64 ];
  323. PSID _pLastSid;
  324. //
  325. // Associated object (only one is allowed)
  326. //
  327. ASSOCIATED_FILE_OBJECT* _pAssociatedObject;
  328. //
  329. // Lookaside
  330. //
  331. static ALLOC_CACHE_HANDLER * sm_pachW3FileInfo;
  332. };
  333. //
  334. // The file cache itself
  335. //
  336. #define DEFAULT_FILE_SIZE_THRESHOLD (256*1024)
  337. #define DEFAULT_W3_FILE_INFO_CACHE_TTL (30)
  338. #define DEFAULT_W3_FILE_INFO_CACHE_ACTIVITY (10)
  339. class W3_FILE_INFO_CACHE : public OBJECT_CACHE
  340. {
  341. public:
  342. W3_FILE_INFO_CACHE();
  343. virtual ~W3_FILE_INFO_CACHE();
  344. dllexp
  345. HRESULT
  346. GetFileInfo(
  347. STRU & strFileName,
  348. DIRMON_CONFIG * pDirmonConfig,
  349. FILE_CACHE_USER * pOpeningUser,
  350. BOOL fDoCache,
  351. W3_FILE_INFO ** ppFileInfo
  352. );
  353. WCHAR *
  354. QueryName(
  355. VOID
  356. ) const
  357. {
  358. return L"W3_FILE_INFO_CACHE";
  359. }
  360. HRESULT
  361. ReadFileIntoMemoryCache(
  362. HANDLE hFile,
  363. DWORD cbFile,
  364. VOID ** ppvFileBuffer
  365. );
  366. HRESULT
  367. ReleaseFromMemoryCache(
  368. VOID * pFileBuffer,
  369. DWORD cbFileBuffer
  370. );
  371. VOID
  372. DoDirmonInvalidationSpecific(
  373. WCHAR * pszPath
  374. );
  375. ULONGLONG
  376. QueryFileSizeThreshold(
  377. VOID
  378. ) const
  379. {
  380. return _cbFileSizeThreshold;
  381. }
  382. BOOL
  383. QueryCacheEnabled(
  384. VOID
  385. ) const
  386. {
  387. return _fEnableCache;
  388. }
  389. BOOL
  390. QueryElementLimitExceeded(
  391. VOID
  392. )
  393. {
  394. return _cMaxFileEntries && _cMaxFileEntries <= PerfQueryCurrentEntryCount();
  395. }
  396. ULONGLONG
  397. PerfQueryCurrentMemCacheSize(
  398. VOID
  399. ) const
  400. {
  401. return _cbMemCacheCurrentSize;
  402. }
  403. ULONGLONG
  404. PerfQueryMaxMemCacheSize(
  405. VOID
  406. ) const
  407. {
  408. return _cbMaxMemCacheSize;
  409. }
  410. HRESULT
  411. Initialize(
  412. VOID
  413. );
  414. VOID
  415. Terminate(
  416. VOID
  417. );
  418. dllexp
  419. static
  420. W3_FILE_INFO_CACHE *
  421. GetFileCache(
  422. VOID
  423. );
  424. private:
  425. HRESULT
  426. InitializeMemoryCache(
  427. VOID
  428. );
  429. VOID
  430. TerminateMemoryCache(
  431. VOID
  432. );
  433. static
  434. VOID
  435. MemoryCacheAdjustor(
  436. PVOID pFileCache,
  437. BOOLEAN TimerOrWaitFired
  438. );
  439. ULONGLONG _cbFileSizeThreshold;
  440. ULONGLONG _cbMemoryCacheSize;
  441. DWORD _cMaxFileEntries;
  442. BOOL _fEnableCache;
  443. //
  444. // Memcache stuff
  445. //
  446. CRITICAL_SECTION _csMemCache;
  447. ULONGLONG _cbMemCacheLimit;
  448. ULONGLONG _cbMemCacheCurrentSize;
  449. ULONGLONG _cbMaxMemCacheSize;
  450. HANDLE _hMemCacheHeap;
  451. HANDLE _hTimer;
  452. };
  453. #endif