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

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
filemap.hxx
Abstract:
contains class definitions for memory mapped file (MEMMAP_FILE)
class objects.
Author:
Madan Appiah (madana) 28-April-1995
Environment:
User Mode - Win32
Revision History:
--*/
#define NUM_BITS_IN_DWORD (sizeof(DWORD) * 8)
/*++
Class Description:
Class that maps the URL object containter to a memory mapped file.
Private Member functions:
ValidateCache : this private function validate the cache when the
cache is read to memory first time.
Public Member functions:
GetStatus : returns status of the object.
AllocateEntry
FreeEntry
FindNextEntry : Find next entry in the URL list.
GetHeapStart : returns start of the virtual memory address.
--*/
//
// ----------------- Memory map file header -----------------------------//
//
#define DIR_NAME_SIZE 8
struct CacheDir
{
DWORD nFileCount;
CHAR sDirName[DIR_NAME_SIZE];
};
#pragma pack(16)
typedef struct _MEMMAP_HEADER_SMALL
{
TCHAR FileSignature[MAX_SIG_SIZE];
DWORD FileSize;
DWORD dwHashTableOffset;
DWORD NumUrlInternalEntries;
DWORD NumUrlEntriesAlloced;
//DWORD dwGarbage; // due to /Zp8 struct alignment
LONGLONG CacheLimit;
LONGLONG CacheSize;
LONGLONG ExemptUsage;
DWORD nDirCount;
CacheDir DirArray[DEFAULT_MAX_DIRS];
DWORD dwHeaderData[NUM_HEADER_DATA_DWORDS];
} MEMMAP_HEADER_SMALL;
#define BIT_MAP_ARRAY_SIZE (((HEADER_ENTRY_SIZE - sizeof(MEMMAP_HEADER_SMALL)))/sizeof(DWORD))
typedef struct _MEMMAP_HEADER : _MEMMAP_HEADER_SMALL
{
DWORD AllocationBitMap[BIT_MAP_ARRAY_SIZE];
} MEMMAP_HEADER, *LPMEMMAP_HEADER;
#pragma pack()
class MEMMAP_FILE
{
private:
DWORD _Status;
//
// parameters that passed as object create.
//
DWORD _EntrySize;
LPTSTR _FullPathName; // full path name of the cache directory.
DWORD _FullPathNameLen; // full path name string length.
LPTSTR _FileName; // full path name of the memory mapped file.
DWORD _FileSize; // current size of the memory mapped file.
HANDLE _FileHandle; // file handle of the memory mapped file.
HANDLE _FileMappingHandle; // mapping object handle
LPVOID _BaseAddr;
LPMEMMAP_HEADER _HeaderInfo;
LPBYTE _EntryArray;
DWORD _NumBitMapDWords;
BOOL _NewFile;
BOOL ValidateCache( VOID );
DWORD GrowMapFile( DWORD );
DWORD GetAndSetNextFreeEntry( DWORD );
BOOL CheckNextNBits(DWORD&, DWORD&, DWORD, DWORD&);
BOOL SetNextNBits(DWORD, DWORD, DWORD);
DWORD RemapAddress( VOID );
DWORD DeleteFiles( LPTSTR Files );
BOOL InitHeaderInfo( VOID );
public:
MEMMAP_FILE() {}
~MEMMAP_FILE( VOID );
MemMapStatus Init(LPTSTR PathName, DWORD EntrySize);
void CloseMapping(void);
BOOL Reinitialize(void);
BOOL ReAllocateEntry(LPFILEMAP_ENTRY, DWORD);
LPFILEMAP_ENTRY AllocateEntry(DWORD);
LPFILEMAP_ENTRY FindNextEntry (DWORD* pdwEnum, DWORD dwFilter, GROUPID GroupId, DWORD dwMatch = 0);
BOOL FreeEntry(LPFILEMAP_ENTRY Entry);
DWORD CheckSizeGrowAndRemapAddress(VOID);
BOOL IsBadOffset (DWORD dwOffset);
URL_FILEMAP_ENTRY* ValidateUrlOffset(DWORD dwOffset);
BOOL IsBadGroupOffset(DWORD dwOffset);
GROUP_ENTRY* ValidateGroupOffset(DWORD dwOffset, HASH_ITEM* hItem);
LIST_GROUP_ENTRY* ValidateListGroupOffset(DWORD dwOffset);
//
// WARNING: URL_CONTAINER::CleanupAllUrls assumes
// that Handle is really an offset to a HASH_ITEM*.
//
LPBYTE *GetHeapStart(VOID)
{
return( (LPBYTE *)&_BaseAddr );
}
LPDWORD GetPtrToHashTableOffset (VOID)
{
return &_HeaderInfo->dwHashTableOffset;
}
LPDWORD GetPtrToLeakListOffset (VOID)
{
return _HeaderInfo->dwHeaderData
+ CACHE_HEADER_DATA_ROOT_LEAK_OFFSET;
}
//
// --------- Inline directory related funcs ------------------
//
DWORD GetFileCount(DWORD idx)
{
return _HeaderInfo->DirArray[idx].nFileCount;
}
VOID SetFileCount(DWORD idx, DWORD nFiles)
{
if (idx < DEFAULT_MAX_DIRS)
_HeaderInfo->DirArray[idx].nFileCount = nFiles;
else
INET_ASSERT(FALSE);
}
VOID IncrementFileCount(DWORD idx)
{
if (idx < DEFAULT_MAX_DIRS)
_HeaderInfo->DirArray[idx].nFileCount++;
else
INET_ASSERT(FALSE);
}
VOID DecrementFileCount(DWORD idx)
{
if (idx < DEFAULT_MAX_DIRS)
_HeaderInfo->DirArray[idx].nFileCount--;
else
INET_ASSERT(FALSE);
}
DWORD GetDirCount()
{
return _HeaderInfo->nDirCount;
}
VOID SetDirCount(DWORD nDirCount)
{
_HeaderInfo->nDirCount = nDirCount;
}
VOID IncrementDirCount()
{
_HeaderInfo->nDirCount++;
}
VOID DecrementDirCount()
{
_HeaderInfo->nDirCount--;
}
VOID SetDirName(DWORD idx, LPSTR sDirName)
{
INET_ASSERT(strlen(sDirName) == DIR_NAME_SIZE);
if (idx < DEFAULT_MAX_DIRS)
memcpy(_HeaderInfo->DirArray[idx].sDirName,
sDirName, DIR_NAME_SIZE);
else
INET_ASSERT(FALSE);
}
VOID GetDirName(DWORD idx, LPSTR szDirName)
{
memcpy(szDirName, _HeaderInfo->DirArray[idx].sDirName, DIR_NAME_SIZE);
szDirName[DIR_NAME_SIZE] = '\0';
}
DWORD GetDirIndex(LPSTR szDirName)
{
CHAR* ptr = szDirName + strlen(_FullPathName);
for (DWORD idx = 0; idx < _HeaderInfo->nDirCount; idx++)
if (!strnicmp(ptr, _HeaderInfo->DirArray[idx].sDirName, DIR_NAME_SIZE))
return idx;
return NOT_A_CACHE_SUBDIRECTORY;
}
//Creates a cache directory with a given name to allow existing directories
//to be copied into another cache file. Just the eight letters of the new
//directory are given.
BOOL CreateDirWithSecureName( LPSTR szDirName)
{
BOOL retVal = FALSE;
CHAR szFullDirName[MAX_PATH];
DWORD nNewDir;
// MEMMAP_FILE::GetDirIndex requires the full directory name
memcpy( szFullDirName, _FullPathName, _FullPathNameLen);
lstrcpy( szFullDirName + _FullPathNameLen, szDirName);
// only try to add the subdirectory if it doesn't already exist..
if( GetDirIndex( szFullDirName) != NOT_A_CACHE_SUBDIRECTORY)
goto exitCreateDirWithSecureName;
// don't create more than DEFAULT_MAX_DIRS directories
if( (nNewDir = GetDirCount()) >= DEFAULT_MAX_DIRS)
goto exitCreateDirWithSecureName;
IncrementDirCount();
SetDirName( nNewDir, szDirName);
SetFileCount( nNewDir, 0);
retVal = TRUE;
exitCreateDirWithSecureName:
return retVal;
}
//
// --------- General Get/Set type routines ------------------
//
DWORD GetStatus( VOID )
{
return( _Status );
}
DWORD IsNewFile( VOID )
{
return( _NewFile );
}
LPSTR GetFullPathName()
{
return _FullPathName;
}
DWORD GetFullPathNameLen()
{
return _FullPathNameLen;
}
LONGLONG GetCacheSize()
{
return _HeaderInfo->CacheSize + _FileSize;
}
LONGLONG GetCacheLimit()
{
return(_HeaderInfo->CacheLimit);
}
LONGLONG GetExemptUsage()
{
return _HeaderInfo->ExemptUsage;
}
VOID SetCacheLimit(LONGLONG CacheLimit)
{
_HeaderInfo->CacheLimit = CacheLimit;
}
VOID AdjustCacheSize(LONGLONG DeltaSize)
{
if (_HeaderInfo->CacheSize >= -DeltaSize)
_HeaderInfo->CacheSize += DeltaSize;
else
{
// INET_ASSERT (FALSE); // underflow
_HeaderInfo->CacheSize = 0;
}
}
VOID SetCacheSize(LONGLONG Delta)
{
INET_ASSERT((Delta>=0));
_HeaderInfo->CacheSize = (Delta>=0) ? Delta : 0;
}
VOID AdjustExemptUsage (LONGLONG DeltaSize)
{
if (_HeaderInfo->ExemptUsage >= -DeltaSize)
_HeaderInfo->ExemptUsage += DeltaSize;
else
{
INET_ASSERT (FALSE); // underflow
_HeaderInfo->ExemptUsage = 0;
}
}
BOOL SetHeaderData(DWORD nIdx, DWORD dwData)
{
INET_ASSERT(nIdx < NUM_HEADER_DATA_DWORDS);
_HeaderInfo->dwHeaderData[nIdx] = dwData;
return TRUE;
}
BOOL GetHeaderData(DWORD nIdx, LPDWORD pdwData)
{
INET_ASSERT(nIdx < NUM_HEADER_DATA_DWORDS);
*pdwData = _HeaderInfo->dwHeaderData[nIdx];
return TRUE;
}
BOOL IncrementHeaderData(DWORD nIdx, LPDWORD pdwData)
{
INET_ASSERT(nIdx < NUM_HEADER_DATA_DWORDS);
*pdwData = _HeaderInfo->dwHeaderData[nIdx];
++*pdwData;
_HeaderInfo->dwHeaderData[nIdx] = *pdwData;
return TRUE;
}
VOID ResetEntryData(LPFILEMAP_ENTRY Entry, DWORD dwResetValue, DWORD nBlocks)
{
for (DWORD i = 0; i < (_EntrySize * nBlocks) / sizeof(DWORD); i++)
{
*((DWORD*) Entry + i) = dwResetValue;
}
}
};