Leaked source code of windows server 2003
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.

388 lines
9.6 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. filemap.hxx
  5. Abstract:
  6. contains class definitions for memory mapped file (MEMMAP_FILE)
  7. class objects.
  8. Author:
  9. Madan Appiah (madana) 28-April-1995
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #define NUM_BITS_IN_DWORD (sizeof(DWORD) * 8)
  15. /*++
  16. Class Description:
  17. Class that maps the URL object containter to a memory mapped file.
  18. Private Member functions:
  19. ValidateCache : this private function validate the cache when the
  20. cache is read to memory first time.
  21. Public Member functions:
  22. GetStatus : returns status of the object.
  23. AllocateEntry
  24. FreeEntry
  25. FindNextEntry : Find next entry in the URL list.
  26. GetHeapStart : returns start of the virtual memory address.
  27. --*/
  28. //
  29. // ----------------- Memory map file header -----------------------------//
  30. //
  31. #define DIR_NAME_SIZE 8
  32. struct CacheDir
  33. {
  34. DWORD nFileCount;
  35. CHAR sDirName[DIR_NAME_SIZE];
  36. };
  37. #pragma pack(16)
  38. typedef struct _MEMMAP_HEADER_SMALL
  39. {
  40. TCHAR FileSignature[MAX_SIG_SIZE];
  41. DWORD FileSize;
  42. DWORD dwHashTableOffset;
  43. DWORD NumUrlInternalEntries;
  44. DWORD NumUrlEntriesAlloced;
  45. //DWORD dwGarbage; // due to /Zp8 struct alignment
  46. LONGLONG CacheLimit;
  47. LONGLONG CacheSize;
  48. LONGLONG ExemptUsage;
  49. DWORD nDirCount;
  50. CacheDir DirArray[DEFAULT_MAX_DIRS];
  51. DWORD dwHeaderData[NUM_HEADER_DATA_DWORDS];
  52. } MEMMAP_HEADER_SMALL;
  53. #define BIT_MAP_ARRAY_SIZE (((HEADER_ENTRY_SIZE - sizeof(MEMMAP_HEADER_SMALL)))/sizeof(DWORD))
  54. typedef struct _MEMMAP_HEADER : _MEMMAP_HEADER_SMALL
  55. {
  56. DWORD AllocationBitMap[BIT_MAP_ARRAY_SIZE];
  57. } MEMMAP_HEADER, *LPMEMMAP_HEADER;
  58. #pragma pack()
  59. class MEMMAP_FILE
  60. {
  61. private:
  62. DWORD _Status;
  63. //
  64. // parameters that passed as object create.
  65. //
  66. DWORD _EntrySize;
  67. LPTSTR _FullPathName; // full path name of the cache directory.
  68. DWORD _FullPathNameLen; // full path name string length.
  69. LPTSTR _FileName; // full path name of the memory mapped file.
  70. DWORD _FileSize; // current size of the memory mapped file.
  71. HANDLE _FileHandle; // file handle of the memory mapped file.
  72. HANDLE _FileMappingHandle; // mapping object handle
  73. LPVOID _BaseAddr;
  74. LPMEMMAP_HEADER _HeaderInfo;
  75. LPBYTE _EntryArray;
  76. DWORD _NumBitMapDWords;
  77. BOOL _NewFile;
  78. BOOL ValidateCache( VOID );
  79. DWORD GrowMapFile( DWORD );
  80. DWORD GetAndSetNextFreeEntry( DWORD );
  81. BOOL CheckNextNBits(DWORD&, DWORD&, DWORD, DWORD&);
  82. BOOL SetNextNBits(DWORD, DWORD, DWORD);
  83. DWORD RemapAddress( VOID );
  84. DWORD DeleteFiles( LPTSTR Files );
  85. BOOL InitHeaderInfo( VOID );
  86. public:
  87. MEMMAP_FILE() {}
  88. ~MEMMAP_FILE( VOID );
  89. MemMapStatus Init(LPTSTR PathName, DWORD EntrySize);
  90. void CloseMapping(void);
  91. BOOL Reinitialize(void);
  92. BOOL ReAllocateEntry(LPFILEMAP_ENTRY, DWORD);
  93. LPFILEMAP_ENTRY AllocateEntry(DWORD);
  94. LPFILEMAP_ENTRY FindNextEntry (DWORD* pdwEnum, DWORD dwFilter, GROUPID GroupId, DWORD dwMatch = 0);
  95. BOOL FreeEntry(LPFILEMAP_ENTRY Entry);
  96. DWORD CheckSizeGrowAndRemapAddress(VOID);
  97. BOOL IsBadOffset (DWORD dwOffset);
  98. URL_FILEMAP_ENTRY* ValidateUrlOffset(DWORD dwOffset);
  99. BOOL IsBadGroupOffset(DWORD dwOffset);
  100. GROUP_ENTRY* ValidateGroupOffset(DWORD dwOffset, HASH_ITEM* hItem);
  101. LIST_GROUP_ENTRY* ValidateListGroupOffset(DWORD dwOffset);
  102. //
  103. // WARNING: URL_CONTAINER::CleanupAllUrls assumes
  104. // that Handle is really an offset to a HASH_ITEM*.
  105. //
  106. LPBYTE *GetHeapStart(VOID)
  107. {
  108. return( (LPBYTE *)&_BaseAddr );
  109. }
  110. LPDWORD GetPtrToHashTableOffset (VOID)
  111. {
  112. return &_HeaderInfo->dwHashTableOffset;
  113. }
  114. LPDWORD GetPtrToLeakListOffset (VOID)
  115. {
  116. return _HeaderInfo->dwHeaderData
  117. + CACHE_HEADER_DATA_ROOT_LEAK_OFFSET;
  118. }
  119. //
  120. // --------- Inline directory related funcs ------------------
  121. //
  122. DWORD GetFileCount(DWORD idx)
  123. {
  124. return _HeaderInfo->DirArray[idx].nFileCount;
  125. }
  126. VOID SetFileCount(DWORD idx, DWORD nFiles)
  127. {
  128. if (idx < DEFAULT_MAX_DIRS)
  129. _HeaderInfo->DirArray[idx].nFileCount = nFiles;
  130. else
  131. INET_ASSERT(FALSE);
  132. }
  133. VOID IncrementFileCount(DWORD idx)
  134. {
  135. if (idx < DEFAULT_MAX_DIRS)
  136. _HeaderInfo->DirArray[idx].nFileCount++;
  137. else
  138. INET_ASSERT(FALSE);
  139. }
  140. VOID DecrementFileCount(DWORD idx)
  141. {
  142. if (idx < DEFAULT_MAX_DIRS)
  143. _HeaderInfo->DirArray[idx].nFileCount--;
  144. else
  145. INET_ASSERT(FALSE);
  146. }
  147. DWORD GetDirCount()
  148. {
  149. return _HeaderInfo->nDirCount;
  150. }
  151. VOID SetDirCount(DWORD nDirCount)
  152. {
  153. _HeaderInfo->nDirCount = nDirCount;
  154. }
  155. VOID IncrementDirCount()
  156. {
  157. _HeaderInfo->nDirCount++;
  158. }
  159. VOID DecrementDirCount()
  160. {
  161. _HeaderInfo->nDirCount--;
  162. }
  163. VOID SetDirName(DWORD idx, LPSTR sDirName)
  164. {
  165. INET_ASSERT(strlen(sDirName) == DIR_NAME_SIZE);
  166. if (idx < DEFAULT_MAX_DIRS)
  167. memcpy(_HeaderInfo->DirArray[idx].sDirName,
  168. sDirName, DIR_NAME_SIZE);
  169. else
  170. INET_ASSERT(FALSE);
  171. }
  172. VOID GetDirName(DWORD idx, LPSTR szDirName)
  173. {
  174. memcpy(szDirName, _HeaderInfo->DirArray[idx].sDirName, DIR_NAME_SIZE);
  175. szDirName[DIR_NAME_SIZE] = '\0';
  176. }
  177. DWORD GetDirIndex(LPSTR szDirName)
  178. {
  179. CHAR* ptr = szDirName + strlen(_FullPathName);
  180. for (DWORD idx = 0; idx < _HeaderInfo->nDirCount; idx++)
  181. if (!strnicmp(ptr, _HeaderInfo->DirArray[idx].sDirName, DIR_NAME_SIZE))
  182. return idx;
  183. return NOT_A_CACHE_SUBDIRECTORY;
  184. }
  185. //Creates a cache directory with a given name to allow existing directories
  186. //to be copied into another cache file. Just the eight letters of the new
  187. //directory are given.
  188. BOOL CreateDirWithSecureName( LPSTR szDirName)
  189. {
  190. BOOL retVal = FALSE;
  191. CHAR szFullDirName[MAX_PATH];
  192. DWORD nNewDir;
  193. // MEMMAP_FILE::GetDirIndex requires the full directory name
  194. memcpy( szFullDirName, _FullPathName, _FullPathNameLen);
  195. lstrcpy( szFullDirName + _FullPathNameLen, szDirName);
  196. // only try to add the subdirectory if it doesn't already exist..
  197. if( GetDirIndex( szFullDirName) != NOT_A_CACHE_SUBDIRECTORY)
  198. goto exitCreateDirWithSecureName;
  199. // don't create more than DEFAULT_MAX_DIRS directories
  200. if( (nNewDir = GetDirCount()) >= DEFAULT_MAX_DIRS)
  201. goto exitCreateDirWithSecureName;
  202. IncrementDirCount();
  203. SetDirName( nNewDir, szDirName);
  204. SetFileCount( nNewDir, 0);
  205. retVal = TRUE;
  206. exitCreateDirWithSecureName:
  207. return retVal;
  208. }
  209. //
  210. // --------- General Get/Set type routines ------------------
  211. //
  212. DWORD GetStatus( VOID )
  213. {
  214. return( _Status );
  215. }
  216. DWORD IsNewFile( VOID )
  217. {
  218. return( _NewFile );
  219. }
  220. LPSTR GetFullPathName()
  221. {
  222. return _FullPathName;
  223. }
  224. DWORD GetFullPathNameLen()
  225. {
  226. return _FullPathNameLen;
  227. }
  228. LONGLONG GetCacheSize()
  229. {
  230. return _HeaderInfo->CacheSize + _FileSize;
  231. }
  232. LONGLONG GetCacheLimit()
  233. {
  234. return(_HeaderInfo->CacheLimit);
  235. }
  236. LONGLONG GetExemptUsage()
  237. {
  238. return _HeaderInfo->ExemptUsage;
  239. }
  240. VOID SetCacheLimit(LONGLONG CacheLimit)
  241. {
  242. _HeaderInfo->CacheLimit = CacheLimit;
  243. }
  244. VOID AdjustCacheSize(LONGLONG DeltaSize)
  245. {
  246. if (_HeaderInfo->CacheSize >= -DeltaSize)
  247. _HeaderInfo->CacheSize += DeltaSize;
  248. else
  249. {
  250. // INET_ASSERT (FALSE); // underflow
  251. _HeaderInfo->CacheSize = 0;
  252. }
  253. }
  254. VOID SetCacheSize(LONGLONG Delta)
  255. {
  256. INET_ASSERT((Delta>=0));
  257. _HeaderInfo->CacheSize = (Delta>=0) ? Delta : 0;
  258. }
  259. VOID AdjustExemptUsage (LONGLONG DeltaSize)
  260. {
  261. if (_HeaderInfo->ExemptUsage >= -DeltaSize)
  262. _HeaderInfo->ExemptUsage += DeltaSize;
  263. else
  264. {
  265. INET_ASSERT (FALSE); // underflow
  266. _HeaderInfo->ExemptUsage = 0;
  267. }
  268. }
  269. BOOL SetHeaderData(DWORD nIdx, DWORD dwData)
  270. {
  271. INET_ASSERT(nIdx < NUM_HEADER_DATA_DWORDS);
  272. _HeaderInfo->dwHeaderData[nIdx] = dwData;
  273. return TRUE;
  274. }
  275. BOOL GetHeaderData(DWORD nIdx, LPDWORD pdwData)
  276. {
  277. INET_ASSERT(nIdx < NUM_HEADER_DATA_DWORDS);
  278. *pdwData = _HeaderInfo->dwHeaderData[nIdx];
  279. return TRUE;
  280. }
  281. BOOL IncrementHeaderData(DWORD nIdx, LPDWORD pdwData)
  282. {
  283. INET_ASSERT(nIdx < NUM_HEADER_DATA_DWORDS);
  284. *pdwData = _HeaderInfo->dwHeaderData[nIdx];
  285. ++*pdwData;
  286. _HeaderInfo->dwHeaderData[nIdx] = *pdwData;
  287. return TRUE;
  288. }
  289. VOID ResetEntryData(LPFILEMAP_ENTRY Entry, DWORD dwResetValue, DWORD nBlocks)
  290. {
  291. for (DWORD i = 0; i < (_EntrySize * nBlocks) / sizeof(DWORD); i++)
  292. {
  293. *((DWORD*) Entry + i) = dwResetValue;
  294. }
  295. }
  296. };