//+--------------------------------------------------------------------------- // // Microsoft Windows NT Security // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: dbcomp.cpp // // Contents: Hash Database Compactor // // History: 9-8-1998 kirtd Created // //---------------------------------------------------------------------------- #include //+--------------------------------------------------------------------------- // // 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 ); }