句柄在Windows系统中有很重要的作用,窗口、文件、线程……都会产生一个句柄来告诉操作系统如何对对象进行操纵。那么一旦句柄拿到,那么就可以拿到更多信息。
BOOL GetFileNameFromHandleW(HANDLE hFile, LPWSTR lpFilePath) {
const int ObjectNameInformation = 1; // enum OBJECT_INFORMATION_CLASS;
typedef LONG(CALLBACK* ZWQUERYOBJECT)(
HANDLE ObjectHandle,
ULONG ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength
);
lpFilePath[0] = 0x00;
HMODULE hNtDLL = LoadLibraryW(L"ntdll.dll");
if (hNtDLL == 0x00)
{
return FALSE;
}
ZWQUERYOBJECT ZwQueryObject = (ZWQUERYOBJECT)GetProcAddress(hNtDLL, "ZwQueryObject");
if (ZwQueryObject == 0x00)
{
return FALSE;
}
WCHAR szPathInfo[MAX_PATH + 4];
WCHAR szDrive[MAX_PATH];
WCHAR *lpDrive = szDrive;
ULONG dwResult;
int iPathLen;
if (ZwQueryObject(hFile, ObjectNameInformation, szPathInfo, sizeof(szPathInfo) - 1, &dwResult) != 0)
{
return FALSE;
}
// if the file on net drive
const PWCHAR szNetDevice = L"//Device//LanmanRedirector";
if (!wcsnicmp(szPathInfo + 4, szNetDevice, lstrlenW(szNetDevice)))
{
lstrcpyW(lpFilePath, L"//");
lstrcatW(lpFilePath, szPathInfo + 4 + lstrlenW(szNetDevice));
return TRUE;
}
if (GetLogicalDriveStringsW(MAX_PATH - 1, szDrive) >= MAX_PATH)
{
return FALSE;
}
while ((iPathLen = lstrlenW(lpDrive)) != 0)
{
WCHAR szDevName[MAX_PATH];
lpDrive[iPathLen - 1] = 0x00;
int iDevLen = (int)QueryDosDeviceW(lpDrive, szDevName, MAX_PATH);
if (iDevLen && iDevLen < MAX_PATH)
{
iDevLen = lstrlenW(szDevName);
if (!wcsnicmp(szPathInfo + 4, szDevName, iDevLen))
{
lstrcpyW(lpFilePath, lpDrive);
lstrcatW(lpFilePath, szPathInfo + 4 + iDevLen);
break;
}
}
lpDrive += iPathLen + 1;
}
return TRUE;
}