文档章节

从文件句柄获得全路径

rise-worlds
 rise-worlds
发布于 2016/06/20 13:39
字数 374
阅读 3
收藏 0

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

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

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

  1. #include <windows.h>
  2. #include <ntsecapi.h>
  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, &m) >= 0 &&
  24.         (m = GetLogicalDriveStringsW(MAX_PATH, lpDrive)) && m < 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 && n < MAX_PATH)
  32.             {
  33.                 n = wcslen(lpDevName);
  34.                 if (!wcsnicmp(lpPath+4, lpDevName, n))
  35.                 {
  36.                     wcsncpy(lpBuf, p, nBuf);
  37.                     if (nBuf > 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 = cr&#101;ateFile("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("cr&#101;ateFile Failed: %d\n", GetLastError());
  60.     }
  61. }

本文转载自:http://www.cnblogs.com/flying_bat/archive/2008/03/29/1128625.html

rise-worlds

rise-worlds

粉丝 3
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
CTreeCtrl 控件使用总结

一 基础操作 1 插入节点 1)插入根节点 //插入根节点HTREEITEM hRoot;CString str=L"ROOT"hRoot=nTreeCtrl.InsertItem(str); //相当于hRoot=nTreeCtrl.InsertItem(str,TVIROOT,TVILAST); 2)......

shuilan0066
2018/05/06
0
0
MFC获取程序安装目录

描述: 对office做插件 使用DLL注入方式 目的: 获取DLL文件的真实路径 使用方法: GetCurrentDirectory() GetModuleFileName() 区别: GetCurrentDirectory()获取的是程序安装的目录 如:c:wind...

Norman_li
2014/03/09
0
0
jungleliu0923/myconf

myconf是一个可以方便读取key-value配置的C/C++库。 1 规则如下 1)、配置为 key : value 格式 2)、可以支持读取int(正负数), unsigend int, char *, 支持默认缺省值。 3)、string如果有特殊字...

jungleliu0923
2013/12/17
0
0
C#调用C++代码

C++代码定义 typedef struct stPlay { HWND wndPlay;//播放窗口句柄 bool bAudio;//是否播放音频,现在只能播放一路音频 PlayType type;//播放类型 //only for net play. TransmissionType ...

技术小胖子
2017/11/08
0
0
conf 配置文件解析库--myconf

myconf是一个可以方便读取key-value配置的C/C++库。 1 规则如下 1)、配置为 key : value 格式 2)、可以支持读取int(正负数), unsigend int, char *, 支持默认缺省值。 3)、string如果有特殊字...

jungleliu0923
2013/12/16
2K
0

没有更多内容

加载失败,请刷新页面

加载更多

Java常见异常处理

异常是Java程序中经常遇到的问题,一个异常就是一个Bug,就要花很多时间来定位异常。 Java异常 (1)Throwable是Java异常的顶级类,所有的异常都继承于这个类。 (2)Error,Exception是异常...

daxiongdi
13分钟前
1
0
Validator 常用注解

说明 Validator主要是校验用户提交的数据的合理性的,比如是否为空了,密码长度是否大于6位,是否是纯数字的,等等。那么在spring boot怎么使用这么强大的校验框架呢。 常用 [@null](https:...

五彩的颜色
22分钟前
1
0
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。

#1 先把入栈顺序的第一数据入栈, #2 if 入栈的数据==等于出栈的数据,就循环一次看是否新建的栈的数据是否出栈 #3 返回新建的栈是否为空,就是要的结果 public class Solution { public boo...

winkwink
28分钟前
1
0
《JAVA核心知识》学习笔记 (19. 数据库)

19.1.1. 存储引擎 19.1.1.1. 概念 数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、 更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧...

Shingfi
34分钟前
4
0
三分钟手操自己的yum源

本文章原创首发公众号:编程三分钟 上次就想手操yum源了,考虑到有的朋友没接触过,直接写成了yum源的科普,活活憋了我一个星期,现在我们快快开始。 什么情况下我们需要搭建一个仓库呢? 记...

编程三分钟
38分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部