从文件句柄获得全路径 (二)

来源:互联网 发布:淘宝店合作合同 编辑:程序博客网 时间:2024/05/23 16:53
 

从文件句柄获得全路径这个问题,似乎是个“老大难”问题。
很久以前我就在水木清华见到过。最近又不断有人提到。
其实问题并不难,只是解决办法有点绕,不是调用一个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 HANDLEObjectHandle,
  11.     IN ULONGObjectInformationClass,
  12.     OUT PVOIDObjectInformation,
  13.     IN ULONGObjectInformationLength,
  14.     OUT PULONGReturnLength OPTIONAL
  15.     );
  16.  
  17. BOOL GetPathByHandle(HANDLEhFile, LPWSTRlpBuf, DWORDnBuf)
  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. }
原创粉丝点击