// Copyright (c) 1996-1999 Microsoft Corporation //+------------------------------------------------------------------------- // // Microsoft Windows // // File: objidenm.cxx // // Contents: CObjId enumeration from a volume // // Classes: CObjIdEnumerator // // History: 18-Nov-96 BillMo Created. // 09-Jun-97 WeiruC Modified. Skip volume id entries in // NTFS object id table. // // Notes: // // Codework: // //-------------------------------------------------------------------------- #include "pch.cxx" #pragma hdrstop #include "trklib.hxx" //+---------------------------------------------------------------------------- // // CObjIdEnumerator::Initialize // // Prepare to enumerate the object IDs on a volume. This opens a handle // to the object ID index directory. // //+---------------------------------------------------------------------------- BOOL CObjIdEnumerator::Initialize(const TCHAR *ptszVolumeDeviceName) { TCHAR tszDirPath[MAX_PATH]; _tcscpy( tszDirPath, ptszVolumeDeviceName); _tcscat( tszDirPath, TEXT("\\$Extend\\$ObjId:$O:$INDEX_ALLOCATION") ); _hDir = CreateFile( tszDirPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | SECURITY_IMPERSONATION, NULL ); return( INVALID_HANDLE_VALUE != _hDir ); } //+---------------------------------------------------------------------------- // // CObjIdEnumerator::UnInitialize // // Close the handle to the object ID index directory. // //+---------------------------------------------------------------------------- void CObjIdEnumerator::UnInitialize() { if( INVALID_HANDLE_VALUE != _hDir ) CloseHandle(_hDir); _hDir = INVALID_HANDLE_VALUE; } //+---------------------------------------------------------------------------- // // CObjIdEnumerator::Find // // This private method is used by the public FindFirst and FindNext // methods. This method queries the object ID index directory // for a set of entries and puts the result into _ObjIdInfo. It then // takes the first real entry and puts it into the caller-provided parameters // (the object ID and birth ID). To start enumerating from the top of the // index, fRestart is set by the caller. // //+---------------------------------------------------------------------------- BOOL CObjIdEnumerator::Find( CObjId * pobjid, CDomainRelativeObjId * pdroidBirth, BOOL fRestart ) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; BOOL fObjFound = FALSE; // Loop until we find a real entry. do { // Query the object ID index for a set of entries. Status = NtQueryDirectoryFile( _hDir, NULL, // Event NULL, // ApcRoutine NULL, // ApcContext &IoStatusBlock, _ObjIdInfo, sizeof(_ObjIdInfo), FileObjectIdInformation, FALSE, // ReturnSingleEntry NULL, // FileName fRestart != 0); // RestartScan if(NT_SUCCESS(Status) && IoStatusBlock.Information != 0) { fRestart = FALSE; // Update the count of entries and the cursor into the entries. _cbObjIdInfo = (ULONG)IoStatusBlock.Information; _pObjIdInfo = _ObjIdInfo; TrkAssert( _cbObjIdInfo % sizeof(*_pObjIdInfo) == 0 ); TrkAssert( _cbObjIdInfo <= sizeof(_ObjIdInfo) ); // In the NTFS's ObjectID table is a record which represents // not the file object id but the volume id. We skip this record. while( _pObjIdInfo < &_ObjIdInfo[_cbObjIdInfo / sizeof(_ObjIdInfo[0])] && (_pObjIdInfo->FileReference & FILEREF_MASK) == FILEREF_VOL ) { _pObjIdInfo++; } // If we haven't exhausted the objects in the buffer, take the next // one and return it to the caller. if(_pObjIdInfo < &_ObjIdInfo[_cbObjIdInfo / sizeof(_ObjIdInfo[0])]) { UnloadFileObjectIdInfo( *_pObjIdInfo, pobjid, pdroidBirth ); _pObjIdInfo ++; fObjFound = TRUE; break; } } else { break; } } while(TRUE); if(TRUE == fObjFound) { return(TRUE); } else { _cbObjIdInfo = 0; return(FALSE); } }