|
|
// Copyright (c) 1996-1999 Microsoft Corporation
// Not currently implemented
#include "pch.cxx"
#pragma hdrstop
#include "trkwks.hxx"
#ifdef VOL_REPL
void CPersistentVolumeMap::Initialize() { InitializeCriticalSection(&_cs); _fInitializeCalled = TRUE; }
void CPersistentVolumeMap::UnInitialize() { if (IsOpen()) CloseFile(); CVolumeMap::UnInitialize(); if (_fInitializeCalled) { DeleteCriticalSection(&_cs); _fInitializeCalled = FALSE; } }
CFILETIME CPersistentVolumeMap::GetLastUpdateTime( ) { CFILETIME cft(0);
EnterCriticalSection(&_cs);
__try { if (!IsOpen()) { Load( ); }
cft = _cft; } __finally { LeaveCriticalSection(&_cs); }
return(cft); }
void CPersistentVolumeMap::CopyTo(DWORD * pcVolumes, VolumeMapEntry ** ppVolumeChanges) { EnterCriticalSection(&_cs);
__try { if (!IsOpen()) { Load( ); // BUGBUG: we may want to close this file after a period and free the map
}
CVolumeMap VolMap;
CVolumeMap::CopyTo( &VolMap ); VolMap.MoveTo( pcVolumes, ppVolumeChanges );
} __finally { LeaveCriticalSection(&_cs); }
}
BOOL CPersistentVolumeMap::FindVolume( const CVolumeId & volume, CMachineId * pmcid ) { ULONG i;
EnterCriticalSection(&_cs);
__try { if (!IsOpen()) { Load( ); // BUGBUG: we may want to close this file after a period
}
for (i=0; i < _cVolumeMapEntries; i++) { if (_pVolumeMapEntries[i].volume == volume) { *pmcid = _pVolumeMapEntries[i].machine; break; } }
} __finally { LeaveCriticalSection(&_cs); }
return( i != _cVolumeMapEntries ); }
void CPersistentVolumeMap::Merge( CVolumeMap * pOther ) { EnterCriticalSection(&_cs);
__try { if (!IsOpen()) { Load( ); }
_fMergeDirtiedMap |= CVolumeMap::Merge( pOther ); } __finally { LeaveCriticalSection(&_cs); } }
void CPersistentVolumeMap::SetLastUpdateTime( const CFILETIME & cft ) { _cft = cft; Save(); }
// format:
// DWORD Version
// DWORD cVolumeMapEntries
// CFILETIME time of last query on DC
// VolumeMapEntry[cVolumeMapEntries]
// CFILETIME time of last query on DC
void CPersistentVolumeMap::Load() { TCHAR tsz[MAX_PATH+1]; DWORD cch = ExpandEnvironmentStrings( TEXT("%systemroot%\\system32\\volumes.trk"), tsz, ELEMENTS(tsz) );
if (cch >= ELEMENTS(tsz)) { TrkLog((TRKDBG_ERROR, TEXT("CPersistentVolumeMap::Load path too long"))); TrkRaiseException(TRK_E_PATH_TOO_LONG); }
TrkAssert(!IsOpen());
RobustlyCreateFile(tsz);
// after RobustlyCreateFile has succeeded without an exception we know that
// OpenExistingFile has just returned OK (even after recreating the file.)
TrkLog((TRKDBG_VOLMAP | TRKDBG_VOLTAB_RESTORE, TEXT("CPersistentVolumeMap::Load() - _cftFirstChange = %s"), CDebugString(_cft)._tsz)); }
void CPersistentVolumeMap::Save() { TrkAssert(IsOpen());
DWORD Version = PVM_VERSION; DWORD cbWritten;
if (0 != SetFilePointer(0, NULL, FILE_BEGIN) || !WriteFile(&Version, sizeof(Version), &cbWritten) || cbWritten != sizeof(Version) || !WriteFile(&_cVolumeMapEntries, sizeof(_cVolumeMapEntries), &cbWritten) || cbWritten != sizeof(_cVolumeMapEntries) ||
// the following part of the header is read in Load()
!WriteFile(&_cft, sizeof(_cft), &cbWritten) || cbWritten != sizeof(_cft)) { TrkLog((TRKDBG_ERROR, TEXT("CPersistentVolumeMap::Save() failed"))); TrkRaiseLastError(); }
if (_fMergeDirtiedMap) { TrkLog((TRKDBG_VOLMAP | TRKDBG_VOLTAB_RESTORE, TEXT("CPersistentVolumeMap::Save() - writing map data, _cftFirstChange = %s"), CDebugString(_cft)._tsz)); if (!WriteFile(_pVolumeMapEntries, _cVolumeMapEntries * sizeof(VolumeMapEntry), &cbWritten) || cbWritten != _cVolumeMapEntries * sizeof(VolumeMapEntry)) { TrkLog((TRKDBG_ERROR, TEXT("CPersistentVolumeMap::Save() failed 2"))); TrkRaiseLastError(); } } else { TrkLog((TRKDBG_VOLMAP | TRKDBG_VOLTAB_RESTORE, TEXT("CPersistentVolumeMap::Save() - seeking past map data, _cftFirstChange = %s"), CDebugString(_cft)._tsz));
if (!SetFilePointer(_cVolumeMapEntries * sizeof(VolumeMapEntry), NULL, FILE_CURRENT)) { TrkLog((TRKDBG_ERROR, TEXT("CPersistentVolumeMap::Save() failed 3"))); TrkRaiseLastError(); } }
if (!WriteFile(&_cft, sizeof(_cft), &cbWritten) || cbWritten != sizeof(_cft) ) { TrkLog((TRKDBG_ERROR, TEXT("CPersistentVolumeMap::Save() failed 4"))); TrkRaiseLastError(); }
_fMergeDirtiedMap = FALSE; }
// BUGBUG P2: checksum, header alignment
RCF_RESULT CPersistentVolumeMap::OpenExistingFile( const TCHAR * ptszFile ) { RCF_RESULT r;
DWORD cVolumeMapEntries; DWORD Version; NTSTATUS status;
status = OpenExistingSecureFile(ptszFile); if ( NT_SUCCESS(status) ) { TrkAssert(IsOpen()); DWORD cbRead;
r = CORRUPT;
if (ReadFile(&Version, sizeof(Version), &cbRead) && cbRead == sizeof(Version) && Version == PVM_VERSION && ReadFile(&cVolumeMapEntries, sizeof(cVolumeMapEntries), &cbRead) && cbRead == sizeof(cVolumeMapEntries) && cVolumeMapEntries < 100000 && GetFileSize() == sizeof(Version) + sizeof(cVolumeMapEntries) + sizeof(CFILETIME) + cVolumeMapEntries * sizeof(VolumeMapEntry) + sizeof(CFILETIME) ) { CFILETIME cft1, cft2;
SetSize(cVolumeMapEntries);
if ( ReadFile( &cft1, sizeof(cft1), &cbRead ) && cbRead == sizeof(cft1) && (_cVolumeMapEntries == 0 || ( ReadFile(_pVolumeMapEntries, _cVolumeMapEntries * sizeof(VolumeMapEntry), &cbRead) && cbRead == _cVolumeMapEntries * sizeof(VolumeMapEntry) ) ) && ReadFile( &cft2, sizeof(cft2), &cbRead ) && cbRead == sizeof(cft2) && memcmp(&cft1, &cft2, sizeof(cft1)) == 0) { _cft = cft1; r = OK; } }
if (r != OK) { CloseFile(); } } else if (status != STATUS_OBJECT_NAME_NOT_FOUND) { TrkLog((TRKDBG_ERROR, TEXT("CPersistentVolumeMap::OpenExistingFile() failed %08x"), status)); TrkRaiseNtStatus(status); } else { r = NOT_FOUND; }
TrkLog((TRKDBG_VOLMAP | TRKDBG_VOLTAB_RESTORE, TEXT("CPersistentVolumeMap::OpenExistingFile() -> %s"), (r == NOT_FOUND ? TEXT("NOT_FOUND") : r == OK ? TEXT("OK") : r == CORRUPT ? TEXT("CORRUPT") : TEXT("unknown"))));
return (r); }
// BUGBUG P1: CPersistentVolumeMap::UnInitialize
void CPersistentVolumeMap::CreateAlwaysFile( const TCHAR * ptszFile ) { NTSTATUS status = CreateAlwaysSecureFile(ptszFile);
if( !NT_SUCCESS(status) ) TrkRaiseNtStatus( status );
CVolumeMap::SetSize(0);
_cft = CFILETIME(0); Save();
CloseFile(); } #endif
|