163 lines
4.8 KiB
C++
163 lines
4.8 KiB
C++
|
|
||
|
// 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);
|
||
|
}
|
||
|
}
|
||
|
|