您的位置:首页 > 其它

从文件句柄获得全路径

2016-06-20 00:00 351 查看
从文件句柄获得全路径这个问题,似乎是个“老大难”问题。
很久以前我就在水木清华见到过。最近又不断有人提到。
其实问题并不难,只是解决办法有点绕,不是调用一个API就能解决的。

问题的关键在于,形如”X:”的Dos设备名都是符号链接(SymblicLink),而文件打开后文件对象中保存的是逻辑卷设备名(如”\Device\HarddiskVolumeX”)。前者可以转换成后者,而后者却不能简单地转换成前者。以至于从句柄得到的路径总是“缺少”盘符这一部分。实际上,把所有的”X:”都变成设备名去匹配路径就可以了。

下面是演示代码,很简单,所以就不加注释啦 ^_^

#include <windows.h>

#include <ntsecapi.h>

#pragma comment (lib,"ntdll.lib") // Copy From DDK

NTSYSAPI

NTSTATUS

NTAPI

ZwQueryObject(

IN HANDLE ObjectHandle,

IN ULONG ObjectInformationClass,

OUT PVOID ObjectInformation,

IN ULONG ObjectInformationLength,

OUT PULONG ReturnLength OPTIONAL

);

BOOL GetPathByHandle(HANDLE hFile, LPWSTR lpBuf, DWORD nBuf)

{

ULONG m, n;

WCHAR lpPath[MAX_PATH+4];

WCHAR lpDrive[MAX_PATH];

WCHAR lpDevName[MAX_PATH];

if (ZwQueryObject(hFile, 1, lpPath, MAX_PATH+4, &m) >= 0 &&

(m = GetLogicalDriveStringsW(MAX_PATH, lpDrive)) && m < MAX_PATH)

{

WCHAR *p = lpDrive;

while (m = wcslen(p))

{

p[m-1] = L'\0';

n = QueryDosDeviceW(p, lpDevName, MAX_PATH);

if (n && n < MAX_PATH)

{

n = wcslen(lpDevName);

if (!wcsnicmp(lpPath+4, lpDevName, n))

{

wcsncpy(lpBuf, p, nBuf);

if (nBuf > 2) wcsncpy(lpBuf+2, lpPath+4+n, nBuf-2);

return TRUE;

}

}

p += m + 1;

}

}

return FALSE;

}

void main()

{

WCHAR buf[MAX_PATH];

HANDLE hFile = createFile("C:\\boot.ini", 0, 0, 0, OPEN_EXISTING, 0, 0);

if (hFile != INVALID_HANDLE_VALUE)

{

GetPathByHandle(hFile, buf, MAX_PATH);

printf("%ws\n", buf);

CloseHandle(hFile);

}

else

{

printf("createFile Failed: %d\n", GetLastError());

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: