windows-nt/Source/XPSP1/NT/com/svcdlls/trksvcs/common/objidenm.cxx
2020-09-26 16:20:57 +08:00

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);
}
}