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

推荐订阅源

V
Visual Studio Blog
I
InfoQ
H
Help Net Security
GbyAI
GbyAI
博客园 - 叶小钗
Recent Announcements
Recent Announcements
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
Y
Y Combinator Blog
L
LangChain Blog
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
F
Fortinet All Blogs
G
Google Developers Blog
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
博客园 - Franky
D
Docker
Jina AI
Jina AI
罗磊的独立博客

博客园 - 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. }