Hello guys
I need to retrieve object informatino, such as File/Process/Registry etc from a handle. Is there any way from the api to do that? without causing a big performance penalty. thanks
Object info from handle (Iconic help :))
-
- Posts: 46
- Joined: Fri Apr 28, 2006 1:17 pm
There are several ways to optimize the query for a large amount of handles.
The following sample code retrieves the object type name for a single handle:
The following sample code retrieves the object type name for a single handle:
Code: Select all
{$ALIGN ON}
{$MINENUMSIZE 4}
type
TNtStatus = LongInt;
type
PNtUnicodeString = ^TNtUnicodeString;
TNtUnicodeString = record
Length : Word;
MaximumLength: Word;
Buffer : PWideChar;
end;
type
TObjectInformationClass = (
ObjectBasicInformation, // 0
ObjectNameInformation, // 1
ObjectTypeInformation, // 2
ObjectTypesInformation, // 3
ObjectHandleFlagInformation, // 4
ObjectSessionInformation, // 5
MaxObjectInfoClass // 6
);
type
PObjectBasicInformation = ^TObjectBasicInformation;
TObjectBasicInformation = record
Attributes : ULONG;
GrantedAccess : ACCESS_MASK;
HandleCount : ULONG;
PointerCount : ULONG;
PagedPoolCharge : ULONG;
NonPagedPoolCharge : ULONG;
Reserved : array [0..2] of ULONG;
NameInfoSize : ULONG;
TypeInfoSize : ULONG;
SecurityDescriptorSize: ULONG;
CreationTime : LARGE_INTEGER;
end;
type
PObjectNameInformation = ^TObjectNameInformation;
TObjectNameInformation = record
Name: TNtUnicodeString;
end;
type
PObjectTypeInformation = ^TObjectTypeInformation;
TObjectTypeInformation = record
TypeName : TNtUnicodeString;
TotalNumberOfObjects : ULONG;
TotalNumberOfHandles : ULONG;
TotalPagedPoolUsage : ULONG;
TotalNonPagedPoolUsage : ULONG;
TotalNamePoolUsage : ULONG;
TotalHandleTableUsage : ULONG;
HighWaterNumberOfObjects : ULONG;
HighWaterNumberOfHandles : ULONG;
HighWaterPagedPoolUsage : ULONG;
HighWaterNonPagedPoolUsage: ULONG;
HighWaterNamePoolUsage : ULONG;
HighWaterHandleTableUsage : ULONG;
InvalidAttributes : ULONG;
GenericMapping : TGenericMapping;
ValidAccessMask : ULONG;
SecurityRequired : Boolean;
MaintainHandleCount : Boolean;
PoolType : ULONG;
DefaultPagedPoolCharge : ULONG;
DefaultNonPagedPoolCharge : ULONG;
end;
type
TObjectTypesInformation = record
NumberOfTypes: ULONG;
// AlignUp(Pointer)
{ TypeInformation: TObjectTypeInformation; }
{ TypeInformation.TypeName.Buffer: array [TypeName.MaximumLength] of Byte; }
//...
end;
type
PObjectHandleFlagInformation = ^TObjectHandleFlagInformation;
TObjectHandleFlagInformation = record
Inherit : Boolean; // HANDLE_FLAG_INHERIT
ProtectFromClose: Boolean; // HANDLE_FLAG_PROTECT_FROM_CLOSE
end;
type
PObjectSessionInformation = ^TObjectSessionInformation;
TObjectSessionInformation = record
SessionId: ULONG;
end;
const
NtDllLib = 'ntdll.dll';
function NtQueryObject(Handle: THandle;
ObjectInformationClass: TObjectInformationClass; ObjectInformation: Pointer;
ObjectInformationLength: ULONG; ReturnLength: PULONG): TNtStatus; stdcall;
external NtDllLib;
function RtlNtStatusToDosError(Status: TNtStatus): ULONG; stdcall;
external NtDllLib;
////////////////////////////////////////////////////////////////////////////////
function GetObjectTypeNameByHandle(AHandle: THandle): WideString;
const
InfoLength = SizeOf(TObjectTypeInformation) + High(Word) * SizeOf(WideChar);
var
TypeInfo: PObjectTypeInformation;
ErrCode: DWORD;
Status: TNtStatus;
begin
Result := '';
TypeInfo := VirtualAlloc(nil, InfoLength, MEM_COMMIT, PAGE_READWRITE);
if Assigned(TypeInfo) then
try
Status := NtQueryObject(AHandle, ObjectTypeInformation, TypeInfo,
InfoLength, nil);
if Status >= 0 then
begin
SetLength(Result, TypeInfo.TypeName.Length div SizeOf(WideChar));
if Length(Result) > 0 then
Move(TypeInfo.TypeName.Buffer[0], Result[1],
Length(Result) * SizeOf(WideChar));
end;
SetLastError(RtlNtStatusToDosError(Status));
finally
ErrCode := GetLastError();
VirtualFree(TypeInfo, 0, MEM_RELEASE);
SetLastError(ErrCode);
end;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TForm1.FormCreate(ASender: TObject);
var
Process: THandle;
begin
if DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
GetCurrentProcess(), @Process, 0, False, 0) then
try
MessageBoxW(Handle, PWideChar(GetObjectTypeNameByHandle(Process)),
'Process', MB_ICONINFORMATION);
finally
CloseHandle(Process);
end;
end;
-
- Posts: 46
- Joined: Fri Apr 28, 2006 1:17 pm
If you want to determine the object types of many handles, you might call NtQuerySystemInformation(SystemHandleInformation) or NtQuerySystemInformation(SystemExtendedHandleInformation) and use the ObjectTypeIndex to cache the results (note: do not assume that this index is the same as in NtQueryObject(ObjectTypesInformation) - e.g. depending on the Windows version the index for the File object type is currently off by one or two).
Note: NtQuerySystemInformation(SystemHandleInformation) isn’t correctly emulated on WOW64.
Note: NtQuerySystemInformation(SystemHandleInformation) isn’t correctly emulated on WOW64.