|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: dbcomp.cpp
//
// Contents: Hash Database Compactor
//
// History: 9-8-1998 kirtd Created
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::CHashDbCompactor, public
//
// Synopsis: Constructor
//
//----------------------------------------------------------------------------
CHashDbCompactor::CHashDbCompactor () { m_hDbLock = NULL; m_pwszDbDirectory = NULL;
m_cUniqueCatalogs = 0; m_cAllocatedUniqueCatalogs = 0; m_aUniqueCatalogs = NULL; m_iLastUniqueCatalogFoundByName = 0;
m_pwszTempKeyPath[0] = L'\0'; m_pwszTempDataPath[0] = L'\0'; }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::~CHashDbCompactor, public
//
// Synopsis: Destructor
//
//----------------------------------------------------------------------------
CHashDbCompactor::~CHashDbCompactor () { if ( m_hDbLock != NULL ) { CloseHandle( m_hDbLock ); }
if ( m_pwszTempKeyPath[ 0 ] != L'\0' ) { DeleteFileU( m_pwszTempKeyPath ); }
if ( m_pwszTempDataPath[ 0 ] != L'\0' ) { DeleteFileU( m_pwszTempDataPath ); }
delete m_pwszDbDirectory; delete m_aUniqueCatalogs; }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::Initialize, public
//
// Synopsis: initialize the compactor
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::Initialize ( IN LPCWSTR pwszDbLock, IN LPCWSTR pwszDbDirectory ) { if ( ( m_hDbLock = CreateMutexU( NULL, FALSE, pwszDbLock ) ) == NULL ) { return( FALSE ); }
m_pwszDbDirectory = new WCHAR [ wcslen( pwszDbDirectory ) + 1 ]; if ( m_pwszDbDirectory != NULL ) { wcscpy( m_pwszDbDirectory, pwszDbDirectory ); } else { SetLastError( E_OUTOFMEMORY ); return( FALSE ); }
if ( GrowUniqueCatalogs( INITIAL_UNIQUE_CATALOGS ) == FALSE ) { return( FALSE ); }
assert( m_aUniqueCatalogs != NULL ); assert( m_cAllocatedUniqueCatalogs == INITIAL_UNIQUE_CATALOGS );
if ( ( GetTempFileNameU( pwszDbDirectory, L"", 0, m_pwszTempKeyPath ) == FALSE ) || ( GetTempFileNameU( pwszDbDirectory, L"", 0, m_pwszTempDataPath ) == FALSE ) ) { return( FALSE ); }
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::LockDatabase, public
//
// Synopsis: lock the database
//
//----------------------------------------------------------------------------
VOID CHashDbCompactor::LockDatabase () { WaitForSingleObject( m_hDbLock, INFINITE ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::UnlockDatabase, public
//
// Synopsis: unlock the database
//
//----------------------------------------------------------------------------
VOID CHashDbCompactor::UnlockDatabase () { ReleaseMutex( m_hDbLock ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::MapDatabase, public
//
// Synopsis: map the database
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::MapDatabase ( IN LPCWSTR pwszDbName, OUT PCRYPT_DATA_BLOB pKey, OUT LPWSTR* ppwszKeyPath, OUT PCRYPT_DATA_BLOB pData, OUT LPWSTR* ppwszDataPath ) { BOOL fResult = TRUE; LPWSTR pwszKeyDbPath = NULL; LPWSTR pwszDataDbPath = NULL; DWORD cwDirectory = 0; DWORD cwName = 0; HANDLE hKeyFile = INVALID_HANDLE_VALUE; HANDLE hDataFile = INVALID_HANDLE_VALUE; HANDLE hMappedKeyFile = NULL; HANDLE hMappedDataFile = NULL; LPBYTE pbKey = NULL; LPBYTE pbData = NULL; DWORD cwKeyExt = 0; DWORD cwDataExt = 0; DWORD cbKeyFileSize = 0; DWORD cbDataFileSize = 0;
cwDirectory = wcslen( m_pwszDbDirectory ); cwName = wcslen( pwszDbName ); cwKeyExt = wcslen( DB_KEY_EXT ); cwDataExt = wcslen( DB_DATA_EXT );
pwszKeyDbPath = new WCHAR [ cwDirectory + cwName + cwKeyExt + 2 ]; pwszDataDbPath = new WCHAR [ cwDirectory + cwName + cwDataExt + 2 ];
if ( ( pwszKeyDbPath != NULL ) && ( pwszDataDbPath != NULL ) ) { wcscpy( pwszKeyDbPath, m_pwszDbDirectory ); wcscat( pwszKeyDbPath, L"\\" ); wcscat( pwszKeyDbPath, pwszDbName );
wcscpy( pwszDataDbPath, pwszKeyDbPath );
wcscat( pwszKeyDbPath, DB_KEY_EXT ); wcscat( pwszDataDbPath, DB_DATA_EXT ); } else { SetLastError( E_OUTOFMEMORY ); fResult = FALSE; }
if ( fResult == TRUE ) { DWORD dwErr = 0;
hKeyFile = CreateFileU( pwszKeyDbPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hKeyFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); }
hDataFile = CreateFileU( pwszDataDbPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (hDataFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); }
if ( ( hKeyFile != INVALID_HANDLE_VALUE ) && ( hDataFile != INVALID_HANDLE_VALUE ) ) { cbKeyFileSize = GetFileSize( hKeyFile, NULL ); cbDataFileSize = GetFileSize( hDataFile, NULL );
if ( cbKeyFileSize > 0 ) { hMappedKeyFile = CreateFileMapping( hKeyFile, NULL, PAGE_READONLY, 0, 0, NULL ); }
if ( cbDataFileSize > 0 ) { hMappedDataFile = CreateFileMapping( hDataFile, NULL, PAGE_READONLY, 0, 0, NULL ); } }
if ( hMappedKeyFile != NULL ) { pbKey = (LPBYTE)MapViewOfFile( hMappedKeyFile, FILE_MAP_READ, 0, 0, 0 ); }
if ( hMappedDataFile != NULL ) { pbData = (LPBYTE)MapViewOfFile( hMappedDataFile, FILE_MAP_READ, 0, 0, 0 ); }
if ( ( ( pbKey == NULL ) && ( cbKeyFileSize != 0 ) ) || ( ( pbData == NULL ) && ( cbDataFileSize != 0 ) ) ) { fResult = FALSE; } }
if ( fResult == TRUE ) { pKey->cbData = cbKeyFileSize; pKey->pbData = pbKey; *ppwszKeyPath = pwszKeyDbPath;
pData->cbData = cbDataFileSize; pData->pbData = pbData; *ppwszDataPath = pwszDataDbPath; } else { delete pwszKeyDbPath; delete pwszDataDbPath; }
if ( hKeyFile != INVALID_HANDLE_VALUE ) { CloseHandle( hKeyFile ); }
if ( hDataFile != INVALID_HANDLE_VALUE ) { CloseHandle( hDataFile ); }
if ( hMappedKeyFile != NULL ) { CloseHandle( hMappedKeyFile ); }
if ( hMappedDataFile != NULL ) { CloseHandle( hMappedDataFile ); }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::UnmapDatabase, public
//
// Synopsis: unmap the database
//
//----------------------------------------------------------------------------
VOID CHashDbCompactor::UnmapDatabase ( IN PCRYPT_DATA_BLOB pKey, IN PCRYPT_DATA_BLOB pData ) { FlushCompactionAnalysis();
if ( pKey->pbData != NULL ) { UnmapViewOfFile( pKey->pbData ); }
if ( pData->pbData != NULL ) { UnmapViewOfFile( pData->pbData ); } }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::AnalyzeDataForCompaction, public
//
// Synopsis: analyze the database data for compaction
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::AnalyzeDataForCompaction ( IN PCRYPT_DATA_BLOB pData, IN OPTIONAL LPCSTR pszUnwantedCatalog ) { BOOL fResult = TRUE; HashMastRec* pHashMastRecord; DWORD cbToNextRecord; DWORD cRecord; DWORD cCount; PUNIQUE_CATALOG pUniqueCatalog;
if ( m_cUniqueCatalogs > 0 ) { if ( FlushCompactionAnalysis() == FALSE ) { return( FALSE ); } }
pHashMastRecord = (HashMastRec *)( pData->pbData + BFILE_HEADERSIZE + sizeof( DWORD ) );
cbToNextRecord = sizeof( HashMastRec ) + sizeof( DWORD );
if ( pData->cbData < BFILE_HEADERSIZE ) { cRecord = 0; } else { cRecord = ( pData->cbData - BFILE_HEADERSIZE ) / cbToNextRecord; }
for ( cCount = 0; ( fResult == TRUE ) && ( cCount < cRecord ); cCount++ ) { if ( ( pszUnwantedCatalog == NULL ) || ( _strnicmp( pHashMastRecord->CatName, pszUnwantedCatalog, MAX_PATH ) != 0 ) ) { pUniqueCatalog = FindUniqueCatalogByName( pHashMastRecord->CatName );
if ( ( pUniqueCatalog == NULL ) && ( CatalogFileExists( pHashMastRecord->CatName, MAX_PATH ) == TRUE ) ) { fResult = AddUniqueCatalog( pHashMastRecord ); } }
pHashMastRecord = (HashMastRec *)( (LPBYTE)pHashMastRecord + cbToNextRecord ); }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::FlushCompactionAnalysis, public
//
// Synopsis: flush the last compaction analysis done
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::FlushCompactionAnalysis () { DWORD cAllocatedUniqueCatalogs; DWORD cUniqueCatalogs; PUNIQUE_CATALOG aUniqueCatalogs;
if ( m_cAllocatedUniqueCatalogs == INITIAL_UNIQUE_CATALOGS ) { m_cUniqueCatalogs = 0; m_iLastUniqueCatalogFoundByName = 0; return( TRUE ); }
aUniqueCatalogs = m_aUniqueCatalogs; cUniqueCatalogs = m_cUniqueCatalogs; cAllocatedUniqueCatalogs = m_cAllocatedUniqueCatalogs;
m_aUniqueCatalogs = NULL; m_cUniqueCatalogs = 0; m_cAllocatedUniqueCatalogs = 0;
if ( GrowUniqueCatalogs( INITIAL_UNIQUE_CATALOGS ) == FALSE ) { m_aUniqueCatalogs = aUniqueCatalogs; m_cUniqueCatalogs = cUniqueCatalogs; m_cAllocatedUniqueCatalogs = cAllocatedUniqueCatalogs;
return( FALSE ); }
delete aUniqueCatalogs;
m_iLastUniqueCatalogFoundByName = 0;
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::WriteCompactedDatabase, public
//
// Synopsis: write the compacted database
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::WriteCompactedDatabase ( IN PCRYPT_DATA_BLOB pKey, IN PCRYPT_DATA_BLOB pData, IN OPTIONAL LPCSTR pszUnwantedCatalog ) { BOOL fResult = FALSE; HANDLE hFile; HANDLE hDataFile; HANDLE hMap; DWORD cCount; DWORD cbSize; LPBYTE pbDataFile = NULL; LPBYTE pbFile = NULL; HashMastRec* pHashMastRecord; PUNIQUE_CATALOG pUniqueCatalog; LPDWORD pdw; DWORD RecordId; DWORD cKey; LPBYTE pbKey; LPBYTE pb; BFILE_HEADER* pHeader = NULL;
hDataFile = CreateFileU( m_pwszTempDataPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if ( hDataFile == INVALID_HANDLE_VALUE ) { return( FALSE ); }
cbSize = ( sizeof( DWORD ) + sizeof( HashMastRec ) ) * m_cUniqueCatalogs; cbSize += BFILE_HEADERSIZE;
if ( SetFilePointer( hDataFile, cbSize, NULL, FILE_BEGIN ) != 0xFFFFFFFF ) { fResult = SetEndOfFile( hDataFile ); }
if ( fResult == TRUE ) { if ( ( hMap = CreateFileMapping( hDataFile, NULL, PAGE_READWRITE, 0, 0, NULL ) ) != NULL ) { pbDataFile = (LPBYTE)MapViewOfFile( hMap, FILE_MAP_WRITE, 0, 0, 0 ); CloseHandle( hMap ); }
if ( pbDataFile != NULL ) { memcpy( pbDataFile, BFILE_SIG, BFILE_SIZEOFSIG );
pHeader = (BFILE_HEADER *)( pbDataFile + BFILE_SIZEOFSIG );
memset( pHeader, 0, sizeof( BFILE_HEADER ) );
pHeader->sVersion = BFILE_VERSION_1; pHeader->sIntVersion = CATDB_VERSION_1; pHeader->cbKey = KEY_SIZE; pHeader->cbData = sizeof( HashMastRec ); } else { fResult = FALSE; } }
pdw = (LPDWORD)( pbDataFile + BFILE_HEADERSIZE ); pHashMastRecord = (HashMastRec *)( (LPBYTE)pdw + sizeof( DWORD ) );
for ( cCount = 0; ( cCount < m_cUniqueCatalogs ) && ( fResult == TRUE ); cCount++ ) { RecordId = cCount + 1;
memcpy( pdw, &RecordId, sizeof( DWORD ) );
memcpy( pHashMastRecord, &m_aUniqueCatalogs[ cCount ].HashDbRecord, sizeof( HashMastRec ) );
pdw = (LPDWORD)( (LPBYTE)pdw + sizeof( HashMastRec ) + sizeof( DWORD ) );
pHashMastRecord = (HashMastRec *)( (LPBYTE)pdw + sizeof( DWORD ) ); }
if ( fResult == FALSE ) { if ( pbDataFile != NULL ) { UnmapViewOfFile( pbDataFile ); }
CloseHandle( hDataFile );
return( FALSE ); }
fResult = FALSE; pbFile = NULL;
hFile = CreateFileU( m_pwszTempKeyPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if ( hFile == INVALID_HANDLE_VALUE ) { UnmapViewOfFile( pbDataFile ); CloseHandle( hDataFile ); return( FALSE ); }
if ( SetFilePointer( hFile, pKey->cbData, NULL, FILE_BEGIN ) != 0xFFFFFFFF ) { fResult = SetEndOfFile( hFile ); }
if ( ( fResult == TRUE ) && ( pKey->cbData > 0 ) ) { if ( ( hMap = CreateFileMapping( hFile, NULL, PAGE_READWRITE, 0, 0, NULL ) ) != NULL ) { pbFile = (LPBYTE)MapViewOfFile( hMap, FILE_MAP_WRITE, 0, 0, 0 ); CloseHandle( hMap ); }
if ( pbFile == NULL ) { fResult = FALSE; } }
cKey = pKey->cbData / KEY_RECORD_SIZE; pdw = (LPDWORD)( pKey->pbData + KEY_SIZE ); pbKey = pKey->pbData; pb = pbFile; RecordId = 0;
__try { for ( cCount = 0; ( cCount < cKey ) && ( fResult == TRUE ); cCount++ ) { if ( ( *pdw + sizeof( HashMastRec ) + sizeof( DWORD ) ) <= pData->cbData ) { pHashMastRecord = (HashMastRec *)( pData->pbData + *pdw + sizeof( DWORD ) );
if ( ( pszUnwantedCatalog == NULL ) || ( _strnicmp( pHashMastRecord->CatName, pszUnwantedCatalog, MAX_PATH ) != 0 ) ) { pUniqueCatalog = FindUniqueCatalogByName( pHashMastRecord->CatName );
if ( pUniqueCatalog == NULL ) { pdw = (LPDWORD)( (LPBYTE)pdw + KEY_RECORD_SIZE ); pbKey += KEY_RECORD_SIZE; continue; }
memcpy( pb, pbKey, KEY_SIZE );
pb += KEY_SIZE;
memcpy( pb, (LPBYTE)&pUniqueCatalog->UniqueOffset, sizeof( DWORD ) );
pb += sizeof( DWORD );
RecordId += 1; } }
pdw = (LPDWORD)( (LPBYTE)pdw + KEY_RECORD_SIZE ); pbKey += KEY_RECORD_SIZE; } } __except( EXCEPTION_EXECUTE_HANDLER ) { SetLastError( GetExceptionCode() ); fResult = FALSE; }
if ( pbFile != NULL ) { UnmapViewOfFile( pbFile ); }
if ( fResult == TRUE ) { cbSize = RecordId * KEY_RECORD_SIZE;
pHeader->cbSortedEOF = cbSize; pHeader->dwLastRecNum = ( RecordId > 0 ) ? ( RecordId - 1 ) : 0; pHeader->fDirty = FALSE;
if ( SetFilePointer( hFile, cbSize, NULL, FILE_BEGIN ) != 0xFFFFFFFF ) { fResult = SetEndOfFile( hFile ); } }
UnmapViewOfFile( pbDataFile ); CloseHandle( hDataFile ); CloseHandle( hFile );
return( fResult ); }
BOOL MyMoveFileEx( LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags ) { BYTE rgbExisting[_MAX_PATH]; BYTE rgbNew[_MAX_PATH]; char * szExisting = NULL; char * szNew = NULL; BOOL bResult = FALSE;
if (FIsWinNT()) { return(MoveFileExW(lpExistingFileName, lpNewFileName, dwFlags)); }
if ((MkMBStr(rgbExisting, _MAX_PATH, lpExistingFileName, &szExisting)) && (MkMBStr(rgbNew, _MAX_PATH, lpNewFileName, &szNew))) { bResult = DeleteFile(szNew); if (bResult) { bResult = MoveFileA(szExisting, szNew); } }
FreeMBStr(rgbExisting, szExisting); FreeMBStr(rgbNew, szNew);
return (bResult); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::CommitCompactedDatabase, public
//
// Synopsis: commit the compacted database
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::CommitCompactedDatabase ( IN LPCWSTR pwszFinalKeyPath, IN LPCWSTR pwszFinalDataPath ) { DWORD dwErr = 0;
if ( MyMoveFileEx( m_pwszTempKeyPath, pwszFinalKeyPath, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH ) == FALSE ) { dwErr = GetLastError(); return( FALSE ); }
return( MyMoveFileEx( m_pwszTempDataPath, pwszFinalDataPath, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH ) ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::FreeString, public
//
// Synopsis: free allocated string
//
//----------------------------------------------------------------------------
VOID CHashDbCompactor::FreeString (IN LPWSTR pwsz) { delete pwsz; }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::GrowUniqueCatalogs, public
//
// Synopsis: grow the unique catalogs array
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::GrowUniqueCatalogs (DWORD cGrow) { BOOL fResult = FALSE; DWORD cAllocatedUniqueCatalogs; PUNIQUE_CATALOG aUniqueCatalogs;
cAllocatedUniqueCatalogs = m_cAllocatedUniqueCatalogs + cGrow; aUniqueCatalogs = new UNIQUE_CATALOG [ cAllocatedUniqueCatalogs ];
if ( aUniqueCatalogs == NULL ) { SetLastError( E_OUTOFMEMORY ); return( FALSE ); }
memset( aUniqueCatalogs, 0, sizeof( UNIQUE_CATALOG ) * cAllocatedUniqueCatalogs );
if ( m_aUniqueCatalogs != NULL ) { memcpy( aUniqueCatalogs, m_aUniqueCatalogs, m_cUniqueCatalogs * sizeof( UNIQUE_CATALOG ) );
delete m_aUniqueCatalogs; }
m_cAllocatedUniqueCatalogs = cAllocatedUniqueCatalogs; m_aUniqueCatalogs = aUniqueCatalogs;
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::FindUniqueCatalogByName, public
//
// Synopsis: find a unique catalog entry given a catalog name
//
//----------------------------------------------------------------------------
PUNIQUE_CATALOG CHashDbCompactor::FindUniqueCatalogByName (LPCSTR pszCatalogName) { DWORD cCount;
if ( ( m_iLastUniqueCatalogFoundByName < m_cUniqueCatalogs ) && ( _strnicmp( m_aUniqueCatalogs[ m_iLastUniqueCatalogFoundByName ].HashDbRecord.CatName, pszCatalogName, MAX_PATH ) == 0 ) ) { return( &m_aUniqueCatalogs[ m_iLastUniqueCatalogFoundByName ] ); }
for ( cCount = 0; cCount < m_cUniqueCatalogs; cCount++ ) { if ( _strnicmp( m_aUniqueCatalogs[ cCount ].HashDbRecord.CatName, pszCatalogName, MAX_PATH ) == 0 ) { m_iLastUniqueCatalogFoundByName = cCount; return( &m_aUniqueCatalogs[ cCount ] ); } }
return( NULL ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::AddUniqueCatalog, public
//
// Synopsis: add a unique catalog to the array
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::AddUniqueCatalog (HashMastRec* pHashMastRecord) { DWORD UniqueOffset;
if ( m_cUniqueCatalogs == m_cAllocatedUniqueCatalogs ) { if ( GrowUniqueCatalogs( GROW_UNIQUE_CATALOGS ) == FALSE ) { return( FALSE ); } }
UniqueOffset = ( m_cUniqueCatalogs * ( sizeof( HashMastRec ) + sizeof( DWORD ) ) ) + BFILE_HEADERSIZE;
m_aUniqueCatalogs[ m_cUniqueCatalogs ].HashDbRecord = *pHashMastRecord; m_aUniqueCatalogs[ m_cUniqueCatalogs ].UniqueOffset = UniqueOffset;
m_cUniqueCatalogs += 1;
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CHashDbCompactor::CatalogFileExists, public
//
// Synopsis: check if the catalog file exists in the database directory
//
//----------------------------------------------------------------------------
BOOL CHashDbCompactor::CatalogFileExists (LPCSTR pszCatalogName, DWORD cbName) { BOOL fResult = FALSE; WCHAR pwszFile[ MAX_PATH ]; WCHAR pwszPath[ MAX_PATH ]; HANDLE hFile;
if ( MultiByteToWideChar( CP_ACP, 0, pszCatalogName, cbName, pwszFile, MAX_PATH ) == 0 ) { return( FALSE ); }
if ( ( wcslen( m_pwszDbDirectory ) + wcslen( pwszFile ) + 2 ) > MAX_PATH ) { return( FALSE ); }
wcscpy( pwszPath, m_pwszDbDirectory ); wcscat( pwszPath, L"\\" ); wcscat( pwszPath, pwszFile );
if ( ( hFile = CreateFileU( pwszPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE ) { CloseHandle( hFile ); fResult = TRUE; }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: CatalogCompactHashDatabase
//
// Synopsis: API for compacting the catalog hash database
//
//----------------------------------------------------------------------------
BOOL WINAPI CatalogCompactHashDatabase ( IN LPCWSTR pwszDbLock, IN LPCWSTR pwszDbDirectory, IN LPCWSTR pwszDbName, IN OPTIONAL LPCWSTR pwszUnwantedCatalog ) { BOOL fResult; CHashDbCompactor HashDbCompactor; LPWSTR pwszKeyPath = NULL; LPWSTR pwszDataPath = NULL; CRYPT_DATA_BLOB KeyMap; CRYPT_DATA_BLOB DataMap; BOOL fDatabaseMapped = FALSE; CHAR szUnwantedCatalog[ MAX_PATH + 1 ]; LPSTR pszUnwantedCatalog = NULL;
if ( pwszUnwantedCatalog != NULL ) { pszUnwantedCatalog = szUnwantedCatalog;
if ( WideCharToMultiByte( CP_ACP, 0, pwszUnwantedCatalog, -1, pszUnwantedCatalog, MAX_PATH, NULL, NULL ) == FALSE ) { return( FALSE ); } }
fResult = HashDbCompactor.Initialize( pwszDbLock, pwszDbDirectory ); if ( fResult == FALSE ) { return( FALSE ); }
HashDbCompactor.LockDatabase();
__try { fResult = HashDbCompactor.MapDatabase( pwszDbName, &KeyMap, &pwszKeyPath, &DataMap, &pwszDataPath );
if ( fResult == TRUE ) { fDatabaseMapped = TRUE;
fResult = HashDbCompactor.AnalyzeDataForCompaction( &DataMap, pszUnwantedCatalog ); }
if ( fResult == TRUE ) { fResult = HashDbCompactor.WriteCompactedDatabase( &KeyMap, &DataMap, pszUnwantedCatalog ); }
if ( fDatabaseMapped == TRUE ) { HashDbCompactor.UnmapDatabase( &KeyMap, &DataMap ); }
if ( fResult == TRUE ) { fResult = HashDbCompactor.CommitCompactedDatabase( pwszKeyPath, pwszDataPath ); } } __except( EXCEPTION_EXECUTE_HANDLER ) { SetLastError( GetExceptionCode() ); fResult = FALSE; }
HashDbCompactor.UnlockDatabase();
if ( pwszKeyPath != NULL ) { HashDbCompactor.FreeString( pwszKeyPath ); }
if ( pwszDataPath != NULL ) { HashDbCompactor.FreeString( pwszDataPath ); }
return( fResult ); }
|