const
STATUS_SUCCESS = NTSTATUS($00000000);
STATUS_INVALID_PARAMETER = NTSTATUS($C000000D);
STATUS_INFO_LENGTH_MISMATCH = NTSTATUS($C0000004);
type
NTSTATUS = ULONG;
HANDLE =
Winapi.Windows.THandle;
PWSTR =
Winapi.Windows.LPWSTR;
PUNICODE_STRING = ^UNICODE_STRING;
_UNICODE_STRING =
record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PWSTR;
end;
UNICODE_STRING = _UNICODE_STRING;
PCUNICODE_STRING = ^UNICODE_STRING;
TUnicodeString = UNICODE_STRING;
PUnicodeString = PUNICODE_STRING;
function GetFilePathFromHandle(hFile: THandle):
String;
function DeviceNameToFilePath(FileName:
String):
String;
var
Buffer:
array[0..MAX_PATH - 1]
of Char;
BufferSize: DWord;
LogicalDrives:
array of Char;
I: Integer;
DeviceName:
String;
begin
Result := FileName;
BufferSize := GetLogicalDriveStrings(MAX_PATH, @Buffer[0]);
if (BufferSize = 0)
then Exit;
SetLength(LogicalDrives, (BufferSize - 2 * SizeOf(Char))
div 3);
for I := Low(LogicalDrives)
to High(LogicalDrives)
do
begin
LogicalDrives[I] := Buffer[I * 4];
end;
for I := Low(LogicalDrives)
to High(LogicalDrives)
do
begin
BufferSize := QueryDosDevice(PChar(LogicalDrives[I] + '
:'),
@Buffer[0], MAX_PATH);
if (BufferSize > 0)
then
begin
DeviceName := AnsiLowerCase(PWideChar(@Buffer[0]));
if (AnsiLowerCase(Copy(FileName, 1, Length(DeviceName))) =
DeviceName)
then
begin
Result := LogicalDrives[I] + '
:' + Copy(FileName,
Length(DeviceName) + 1, Length(FileName));
Exit;
end;
end;
end;
end;
const
ObjectNameInformation = 1;
var
NtQueryObject:
function(ObjectHandle:
HANDLE;
ObjectInformationClass: ULONG; ObjectInformation: PVOID;
ObjectInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS;
stdcall;
var
ObjectInformation: PUNICODE_STRING;
ReturnLength: ULONG;
Status: NTSTATUS;
begin
Result := '
';
@NtQueryObject := GetProcAddress(LoadLibrary('
ntdll.dll'), '
NtQueryObject');
if not Assigned(@NtQueryObject)
then Exit;
Status := NtQueryObject(hFile, ObjectNameInformation,
nil, 0, @ReturnLength);
if (Status <> STATUS_INFO_LENGTH_MISMATCH)
then Exit;
GetMem(ObjectInformation, ReturnLength);
try
Status := NtQueryObject(hFile, ObjectNameInformation, ObjectInformation,
ReturnLength, @ReturnLength);
if (Status = STATUS_SUCCESS)
then
begin
Result := ObjectInformation.Buffer;
Result := DeviceNameToFilePath(Result);
end;
finally
FreeMem(ObjectInformation);
end;
end;