经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Windows » 查看文章
NT路径,DOS路径和Device路径互相转换
来源:cnblogs  作者:Anow  时间:2018/12/3 9:58:08  对本文有异议

项目中遇到的比较奇葩的问题,从网上找到一份源码,https://blog.csdn.net/qq125096885/article/details/70766206

稍微整理了下,VS可以直接编译

  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <iostream>
  4.  
  5.  
  6. #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
  7.  
  8. #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
  9.  
  10. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
  11.  
  12. #define STATUS_NAME_TOO_LONG ((NTSTATUS)0xC0000106L)
  13.  
  14. //删除指针
  15. #define SafeDeletePoint(pData) { if(pData){delete pData;pData=NULL;} }
  16.  
  17. //删除数组
  18. #define SafeDeleteArraySize(pData) { if(pData){delete []pData;pData=NULL;} }
  19. typedef struct _UNICODE_STRING {
  20. USHORT Length;
  21. USHORT MaximumLength;
  22. PWCH Buffer;
  23. } UNICODE_STRING;
  24. typedef UNICODE_STRING *PUNICODE_STRING;
  25. typedef struct _RTL_BUFFER {
  26. PWCHAR Buffer;
  27. PWCHAR StaticBuffer;
  28. SIZE_T Size;
  29. SIZE_T StaticSize;
  30. SIZE_T ReservedForAllocatedSize; // for future doubling
  31. PVOID ReservedForIMalloc; // for future pluggable growth
  32. } RTL_BUFFER, *PRTL_BUFFER;
  33. typedef struct _RTL_UNICODE_STRING_BUFFER {
  34. UNICODE_STRING String;
  35. RTL_BUFFER ByteBuffer;
  36. WCHAR MinimumStaticBufferForTerminalNul[sizeof(WCHAR)];
  37. } RTL_UNICODE_STRING_BUFFER, *PRTL_UNICODE_STRING_BUFFER;
  38. //DOS路径转换NT路径 C:\\WINDOWS\\system32\\drivers -- \\??\\C:\\WINDOWS\\system32\\drivers
  39. NTSTATUS DosPathToNtPath(wchar_t* pDosPath, PUNICODE_STRING pNtPath)
  40. {
  41. //定义变量
  42. NTSTATUS Status = STATUS_UNSUCCESSFUL;
  43. typedef BOOLEAN(__stdcall *fnRtlDosPathNameToNtPathName_U)(PCWSTR DosFileName, PUNICODE_STRING NtFileName, PWSTR *FilePart, PVOID Reserved);
  44. static fnRtlDosPathNameToNtPathName_U RtlDosPathNameToNtPathName_U = (fnRtlDosPathNameToNtPathName_U)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlDosPathNameToNtPathName_U");
  45. //参数效验
  46. if (IsBadReadPtr(pDosPath, 1) != 0)return NULL;
  47. if (RtlDosPathNameToNtPathName_U == NULL)return NULL;
  48. if (RtlDosPathNameToNtPathName_U(pDosPath, pNtPath, NULL, NULL))
  49. {
  50. Status = STATUS_SUCCESS;
  51. }
  52. return Status;
  53. }
  54. //NT路径转换DOS路径 \\??\\C:\\WINDOWS\\system32\\drivers -- C:\\WINDOWS\\system32\\drivers
  55. NTSTATUS NtPathToDosPath(PUNICODE_STRING pNtPath, wchar_t* pszDosPath)
  56. {
  57. //定义变量
  58. NTSTATUS Status = STATUS_UNSUCCESSFUL;
  59. RTL_UNICODE_STRING_BUFFER DosPath = { 0 };
  60. wchar_t* ByteDosPathBuffer = NULL;
  61. wchar_t* ByteNtPathBuffer = NULL;
  62. typedef NTSTATUS(__stdcall *fnRtlNtPathNameToDosPathName)(ULONG Flags, PRTL_UNICODE_STRING_BUFFER Path, PULONG Disposition, PWSTR* FilePart);
  63. static fnRtlNtPathNameToDosPathName RtlNtPathNameToDosPathName = (fnRtlNtPathNameToDosPathName)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlNtPathNameToDosPathName");
  64. //参数效验
  65. if (IsBadReadPtr(pNtPath, 1) != 0)return Status;
  66. if (IsBadWritePtr(pszDosPath, 1) != 0)return Status;
  67. if (RtlNtPathNameToDosPathName == NULL)return Status;
  68. ByteDosPathBuffer = (wchar_t*)new char[pNtPath->Length + sizeof(wchar_t)];
  69. ByteNtPathBuffer = (wchar_t*)new char[pNtPath->Length + sizeof(wchar_t)];
  70. if (ByteDosPathBuffer == NULL || ByteNtPathBuffer == NULL) return Status;
  71. RtlZeroMemory(ByteDosPathBuffer, pNtPath->Length + sizeof(wchar_t));
  72. RtlZeroMemory(ByteNtPathBuffer, pNtPath->Length + sizeof(wchar_t));
  73. RtlCopyMemory(ByteDosPathBuffer, pNtPath->Buffer, pNtPath->Length);
  74. RtlCopyMemory(ByteNtPathBuffer, pNtPath->Buffer, pNtPath->Length);
  75. DosPath.ByteBuffer.Buffer = ByteDosPathBuffer;
  76. DosPath.ByteBuffer.StaticBuffer = ByteNtPathBuffer;
  77. DosPath.String.Buffer = pNtPath->Buffer;
  78. DosPath.String.Length = pNtPath->Length;
  79. DosPath.String.MaximumLength = pNtPath->Length;
  80. DosPath.ByteBuffer.Size = pNtPath->Length;
  81. DosPath.ByteBuffer.StaticSize = pNtPath->Length;
  82. Status = RtlNtPathNameToDosPathName(0, &DosPath, NULL, NULL);
  83. if (NT_SUCCESS(Status))
  84. {
  85. if (_wcsnicmp(pNtPath->Buffer, ByteDosPathBuffer, pNtPath->Length) == 0)
  86. {
  87. Status = STATUS_UNSUCCESSFUL;
  88. }
  89. else
  90. {
  91. RtlCopyMemory(pszDosPath, ByteDosPathBuffer, wcslen(ByteDosPathBuffer) * sizeof(wchar_t));
  92. }
  93. }
  94. else
  95. {
  96. //wprintf(L"GetLastError=%i\n", pRtlNtStatusToDosError(Status));
  97. Status = STATUS_UNSUCCESSFUL;
  98. }
  99. SafeDeleteArraySize(ByteDosPathBuffer);
  100. SafeDeleteArraySize(ByteNtPathBuffer);
  101. return Status;
  102. }
  103. //\\Device\\HarddiskVolume1\x86.sys c:\x86.sys
  104. BOOL DeviceDosPathToNtPath(wchar_t* pszDosPath, wchar_t* pszNtPath)
  105. {
  106. static TCHAR szDriveStr[MAX_PATH] = { 0 };
  107. static TCHAR szDevName[MAX_PATH] = { 0 };
  108. TCHAR szDrive[3];
  109. INT cchDevName;
  110. INT i;
  111. //检查参数
  112. if (IsBadReadPtr(pszDosPath, 1) != 0)return FALSE;
  113. if (IsBadWritePtr(pszNtPath, 1) != 0)return FALSE;
  114. //获取本地磁盘字符串
  115. ZeroMemory(szDriveStr, ARRAYSIZE(szDriveStr));
  116. ZeroMemory(szDevName, ARRAYSIZE(szDevName));
  117. if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
  118. {
  119. for (i = 0; szDriveStr[i]; i += 4)
  120. {
  121. if (!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\")))
  122. continue;
  123. szDrive[0] = szDriveStr[i];
  124. szDrive[1] = szDriveStr[i + 1];
  125. szDrive[2] = '\0';
  126. if (!QueryDosDevice(szDrive, szDevName, MAX_PATH))//查询 Dos 设备名
  127. return FALSE;
  128. cchDevName = lstrlen(szDevName);
  129. if (_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0)//命中
  130. {
  131. lstrcpy(pszNtPath, szDrive);//复制驱动器
  132. lstrcat(pszNtPath, pszDosPath + cchDevName);//复制路径
  133.  
  134. return TRUE;
  135. }
  136. }
  137. }
  138. lstrcpy(pszNtPath, pszDosPath);
  139. return FALSE;
  140. }
  141. NTSTATUS RtlInitUnicodeString(OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString)
  142. {
  143. #define ARGUMENT_PRESENT(ArgumentPointer) (\
  144. (CHAR *)((ULONG_PTR)(ArgumentPointer)) != (CHAR *)(NULL) )
  145. SIZE_T Length;
  146. DestinationString->Length = 0;
  147. DestinationString->MaximumLength = 0;
  148. DestinationString->Buffer = (PWSTR)SourceString;
  149. if (ARGUMENT_PRESENT(SourceString))
  150. {
  151. Length = wcslen(SourceString);
  152. // We are actually limited to 32765 characters since we want to store a meaningful
  153. // MaximumLength also.
  154. if (Length > (UNICODE_STRING_MAX_CHARS - 1)) {
  155. return STATUS_NAME_TOO_LONG;
  156. }
  157. Length *= sizeof(WCHAR);
  158. DestinationString->Length = (USHORT)Length;
  159. DestinationString->MaximumLength = (USHORT)(Length + sizeof(WCHAR));
  160. }
  161. return STATUS_SUCCESS;
  162. }
  163. int main()
  164. {
  165. NTSTATUS status;
  166. wchar_t szWindowsDirectory[MAX_PATH] = { 0 };
  167. wchar_t DosPathBuffer[MAX_PATH] = { 0 };
  168. wchar_t szNtPath[MAX_PATH] = { 0 };
  169. UNICODE_STRING strBuff = { 0 };
  170. std::wstring dosPath = L"C:\\WINDOWS\\system32\\drivers";
  171. std::wstring devicePath = L"\\Device\\HarddiskVolume4\\123.txt";
  172. PUNICODE_STRING pNtPath = new UNICODE_STRING;
  173. GetWindowsDirectory(szWindowsDirectory, ARRAYSIZE(szWindowsDirectory));
  174. status = DosPathToNtPath((wchar_t*)dosPath.c_str(), pNtPath);
  175. if (NT_SUCCESS(status))
  176. {
  177. status = NtPathToDosPath(pNtPath, DosPathBuffer);
  178. SafeDeletePoint(pNtPath);
  179. }
  180. DeviceDosPathToNtPath((wchar_t*)devicePath.c_str(), szNtPath);
  181. RtlInitUnicodeString(&strBuff, szNtPath);
  182. getchar();
  183. return 0;
  184. system("pause");
  185. return 0;
  186. }

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号