文档章节

从文件句柄获得全路径

rise-worlds
 rise-worlds
发布于 2016/06/20 13:39
字数 374
阅读 1
收藏 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

没有更多内容

加载失败,请刷新页面

加载更多

JS 打印控制

JS 打印控制 var PrintStartString = "<!--打印开始标示符-->";//设置打印开始区域var PrintEndString = "<!--打印结束标示符-->";//设置打印结束区域var HtmlText = window.do......

DrChenXX
20分钟前
5
0
LevelDB:使用介绍

LevelDB 提供的接口其实很简单,下面举例进行简单说明。 安装 git clone https://github.com/google/leveldb cd leveldb mkdir -p build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. ......

slagga
25分钟前
5
0
《JavaScript正则表达式迷你书》读书笔记

正则基础 常见简写形式 字符组 具体含义 记忆方式 \d 表示 [0-9]。表示是一位数字。 其英文是 digit(数字) \D 表示 [^0-9]。表示除数字外的任意字符。 \w 表示 [0-9a-zA-Z_]。表示数字、大小...

muzi131313
30分钟前
4
0
Git的反悔操作

概述 这次主要来讲讲Git的反悔操作,自己平时在写代码的过程中经常会出现想要弃用所有的改动或回滚到上一次commit的情况。Git上的反悔操作有reset、rebase、revert等,每个操作各有区别和对应...

duduYZ
30分钟前
2
0
实现双向绑定Proxy比defineproperty优劣如何?

前言 双向绑定其实已经是一个老掉牙的问题了,只要涉及到MVVM框架就不得不谈的知识点,但它毕竟是Vue的三要素之一. Vue三要素 响应式: 例如如何监听数据变化,其中的实现方法就是我们提到的双向...

寻找海蓝
42分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部