Nii, kuna jõulud tulekul otsustasin oma koodiarhiividest hakata parimaid koodilõike avalikustama. Mõned on undocumented tüüpi, aga just need on parimad ja tihti väga vajalikud.
Antud APIga(NtQueryObject) saate näiteks objekti “handle” järgi teada tema nime või handle järgi teada, mis objektiga tegemist.
Defineerime siis API
function NtQueryObject(AObjectHandle:THandle; AObjectInformationClass:Cardinal;AObjectInformation:Pointer;
AObjectInformationLength:Cardinal;
AReturnLength:PCardinal):dword;stdcall; external ‘ntdll.dll’;
…
type
PUnicodeString=^TUnicodeString;
TUnicodeString=packed record
Length : Word;
MaximumLength:Word;
Buffer:PWideChar;
end;
type
PObjectNameInformation=^TObjectNameInformation;
TObjectNameInformation=packed record
Name:TUnicodeString;
end;
function ing_getObjectNameByHandle(const fhandle:THandle;
const getnamebyhnd: boolean = true):String;
const
STATUS_INFO_LENGTH_MISMATCH: NTSTATUS = $C0000004;
ObjectNameInformation=1;
ObjectTypeInformation=2;
const
statusArr : Array[boolean] of Byte = (ObjectTypeInformation,
ObjectNameInformation);
var
LPObjectInfo:PObjectNameInformation;
status : dword;
resBuffer,LRet: Integer;
begin
result:=”;
try
LRet:=1024;
getmem(LPObjectInfo,LRet);
fillchar(LPObjectInfo^,LRet,0);
status:=NtQueryObject(fHandle,statusArr[getnamebyhnd],LPObjectInfo,LRet,nil);
while (status=STATUS_INFO_LENGTH_MISMATCH) and (LRet<$9000) {et puhver lõhki ei läheks} do
begin
LRet:=1024+LRet;
Reallocmem(LPObjectInfo,LRet);
fillchar(LPObjectInfo^,LRet,0);
status:=NtQueryObject(fHandle,statusArr[getnamebyhnd],LPObjectInfo,LRet,nil);
end;
if LPObjectInfo.Name.Length>0 then
begin
resBuffer:=(LPObjectInfo.Name.Length div 2)+1;
setlength(result,resBuffer);
WideCharToMultiByte(CP_ACP,0,@LPObjectInfo.Name.Buffer[0],
LPObjectInfo.Name.Length,PChar(result),resBuffer,Nil,Nil);
end else
result:=”;
{
try
RtlUnicodeStringToAnsiString(@LAnsiString,@LPObjectInfo^.Name,True);
Result:=LAnsiString.Buffer;
finally
RtlFreeAnsiString(@LAnsiString);
end;
}
finally
freemem(LPObjectInfo,LRet);
end;
end;
Lihtne näide: teeme tempkataloogi ühe faili ning tema “file handle” järgi küsime nime.
function getWindowsTempDir_:String;
var
bSize : DWord;
begin
setlength(result,MAX_PATH);
bsize:=GetTempPath(bsize,pchar(result));
if bsize=0 then
begin
result:=”;
raiselastoserror;
end;
setlength(result,bsize);
end;
var minutest: TFileStream;
begin
minutest:=TFileStream.create(getWindowsTempDir_+’\'+’test.tmp’,fmCreate or fmOpenWrite );
showmessage(ing_getObjectNameByHandle(minutest.handle));
minutest.free;
end;