惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
雷峰网
雷峰网
量子位
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
The Cloudflare Blog
博客园 - Franky
罗磊的独立博客
宝玉的分享
宝玉的分享
博客园_首页
腾讯CDC
The GitHub Blog
The GitHub Blog
D
DataBreaches.Net
IT之家
IT之家
D
Docker
Microsoft Security Blog
Microsoft Security Blog
博客园 - 司徒正美
V
V2EX
月光博客
月光博客
N
Netflix TechBlog - Medium
爱范儿
爱范儿
I
InfoQ
P
Proofpoint News Feed

博客园 - suiyingjie

vs2010 将.mc编译为.rc文件 列出系统支持的区域设置 MySQL判断索引是否存在的存储过程 如何用windbg分析64位机上32位程序的dump文件 libcurl发送邮件C++类 (转) libcurl教程(转) VC 宏与预处理使用方法总结(转) 解决VS2010升级SP1后出现的warning C4005问题 nafxcw.lib与LIBCMT.lib在vs2008,VS2010中链接冲突解决方案 使用JAVASCRIPT去360DOC复制限制 如何自动获取网络变化通知(转) 用户中心 - 博客园 使用Symchk.exe 下载符号 A Crash Course on the Depths of Win32 Structured Exception Handling Ip安全策略批处理脚本 c++资源之不完全导引 (转) 突破局域网中对用户上网的限制(转) [转载]HTML七种加密解密 - suiyingjie - 博客园 挂马代码大全 - suiyingjie - 博客园
[转载] 从文件句柄获得全路径
suiyingjie · 2008-03-13 · via 博客园 - suiyingjie

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

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

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

  1. #include <windows></windows>
  2. #include <ntsecapi></ntsecapi>
  3.  
  4. #pragma comment (lib,"ntdll.lib") // Copy From DDK
  5.  
  6. NTSYSAPI
  7. NTSTATUS
  8. NTAPI
  9. ZwQueryObject(
  10. IN HANDLE ObjectHandle,
  11. IN ULONG ObjectInformationClass,
  12. OUT PVOID ObjectInformation,
  13. IN ULONG ObjectInformationLength,
  14. OUT PULONG ReturnLength OPTIONAL
  15. );
  16.  
  17. BOOL GetPathByHandle(HANDLE hFile, LPWSTR lpBuf, DWORD nBuf)
  18. {
  19. ULONG m, n;
  20. WCHAR lpPath[MAX_PATH+4];
  21. WCHAR lpDrive[MAX_PATH];
  22. WCHAR lpDevName[MAX_PATH];
  23. if (ZwQueryObject(hFile, 1, lpPath, MAX_PATH+4, &amp;m) &gt;= 0 &amp;&amp;
  24. (m = GetLogicalDriveStringsW(MAX_PATH, lpDrive)) &amp;&amp; m &lt; MAX_PATH)
  25. {
  26. WCHAR *p = lpDrive;
  27. while (m = wcslen(p))
  28. {
  29. p[m-1] = L'\0';
  30. n = QueryDosDeviceW(p, lpDevName, MAX_PATH);
  31. if (n &amp;&amp; n &lt; MAX_PATH)
  32. {
  33. n = wcslen(lpDevName);
  34. if (!wcsnicmp(lpPath+4, lpDevName, n))
  35. {
  36. wcsncpy(lpBuf, p, nBuf);
  37. if (nBuf &gt; 2) wcsncpy(lpBuf+2, lpPath+4+n, nBuf-2);
  38. return TRUE;
  39. }
  40. }
  41. p += m + 1;
  42. }
  43. }
  44. return FALSE;
  45. }
  46.  
  47. void main()
  48. {
  49. WCHAR buf[MAX_PATH];
  50. HANDLE hFile = createFile("C:\\boot.ini", 0, 0, 0, OPEN_EXISTING, 0, 0);
  51. if (hFile != INVALID_HANDLE_VALUE)
  52. {
  53. GetPathByHandle(hFile, buf, MAX_PATH);
  54. printf("%ws\n", buf);
  55. CloseHandle(hFile);
  56. }
  57. else
  58. {
  59. printf("createFile Failed: %d\n", GetLastError());
  60. }
  61. }