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.

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