Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

359 lines
7.9 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <msg.h>
  4. HANDLE OutputFile;
  5. BOOL IsConsoleOutput;
  6. void
  7. DisplayIt(
  8. IN PWSTR Message
  9. )
  10. {
  11. DWORD bytes, len;
  12. PSTR message;
  13. if (IsConsoleOutput) {
  14. WriteConsole(OutputFile, Message, wcslen(Message),
  15. &bytes, NULL);
  16. } else {
  17. len = wcslen(Message);
  18. message = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
  19. if (!message) {
  20. return;
  21. }
  22. CharToOem(Message, message);
  23. WriteFile(OutputFile, message, strlen(message), &bytes, NULL);
  24. LocalFree(message);
  25. }
  26. }
  27. void
  28. PrintMessage(
  29. DWORD messageID,
  30. ...
  31. )
  32. {
  33. unsigned short messagebuffer[4096];
  34. va_list ap;
  35. va_start(ap, messageID);
  36. FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, NULL, messageID, 0,
  37. messagebuffer, 4095, &ap);
  38. DisplayIt(messagebuffer);
  39. va_end(ap);
  40. } // PrintMessage
  41. void
  42. PrintTargetForName(
  43. IN PWSTR VolumeName
  44. )
  45. {
  46. BOOL b;
  47. DWORD len;
  48. WCHAR messageBuffer[MAX_PATH];
  49. PWSTR volumePaths, p;
  50. PrintMessage(MOUNTVOL_VOLUME_NAME, VolumeName);
  51. b = GetVolumePathNamesForVolumeName(VolumeName, NULL, 0, &len);
  52. if (!b && GetLastError() != ERROR_MORE_DATA) {
  53. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
  54. messageBuffer, MAX_PATH, NULL);
  55. DisplayIt(messageBuffer);
  56. return;
  57. }
  58. volumePaths = LocalAlloc(0, len*sizeof(WCHAR));
  59. if (!volumePaths) {
  60. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  61. ERROR_NOT_ENOUGH_MEMORY, 0, messageBuffer, MAX_PATH,
  62. NULL);
  63. DisplayIt(messageBuffer);
  64. return;
  65. }
  66. b = GetVolumePathNamesForVolumeName(VolumeName, volumePaths, len, NULL);
  67. if (!b) {
  68. LocalFree(volumePaths);
  69. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
  70. messageBuffer, MAX_PATH, NULL);
  71. DisplayIt(messageBuffer);
  72. return;
  73. }
  74. if (!volumePaths[0]) {
  75. PrintMessage(MOUNTVOL_NO_MOUNT_POINTS);
  76. LocalFree(volumePaths);
  77. return;
  78. }
  79. p = volumePaths;
  80. for (;;) {
  81. PrintMessage(MOUNTVOL_MOUNT_POINT, p);
  82. while (*p++);
  83. if (!*p) {
  84. break;
  85. }
  86. }
  87. LocalFree(volumePaths);
  88. PrintMessage(MOUNTVOL_NEWLINE);
  89. }
  90. BOOL
  91. GetSystemPartitionFromRegistry(
  92. IN OUT PWCHAR SystemPartition
  93. )
  94. {
  95. LONG r;
  96. HKEY key;
  97. DWORD bytes;
  98. r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_QUERY_VALUE,
  99. &key);
  100. if (r) {
  101. SetLastError(r);
  102. return FALSE;
  103. }
  104. bytes = MAX_PATH*sizeof(WCHAR);
  105. r = RegQueryValueEx(key, L"SystemPartition", NULL, NULL,
  106. (LPBYTE) SystemPartition, &bytes);
  107. RegCloseKey(key);
  108. if (r) {
  109. SetLastError(r);
  110. return FALSE;
  111. }
  112. return TRUE;
  113. }
  114. void
  115. PrintMappedESP(
  116. )
  117. {
  118. WCHAR systemPartition[MAX_PATH];
  119. UCHAR c;
  120. WCHAR dosDevice[10], dosTarget[MAX_PATH];
  121. if (!GetSystemPartitionFromRegistry(systemPartition)) {
  122. return;
  123. }
  124. dosDevice[1] = ':';
  125. dosDevice[2] = 0;
  126. for (c = 'A'; c <= 'Z'; c++) {
  127. dosDevice[0] = c;
  128. if (!QueryDosDevice(dosDevice, dosTarget, MAX_PATH)) {
  129. continue;
  130. }
  131. if (lstrcmp(dosTarget, systemPartition)) {
  132. continue;
  133. }
  134. dosDevice[2] = '\\';
  135. dosDevice[3] = 0;
  136. PrintMessage(MOUNTVOL_EFI, dosDevice);
  137. break;
  138. }
  139. }
  140. void
  141. PrintVolumeList(
  142. )
  143. {
  144. HANDLE h;
  145. WCHAR volumeName[MAX_PATH];
  146. WCHAR messageBuffer[MAX_PATH];
  147. BOOL b;
  148. h = FindFirstVolume(volumeName, MAX_PATH);
  149. if (h == INVALID_HANDLE_VALUE) {
  150. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
  151. 0, messageBuffer, MAX_PATH, NULL);
  152. DisplayIt(messageBuffer);
  153. return;
  154. }
  155. for (;;) {
  156. PrintTargetForName(volumeName);
  157. b = FindNextVolume(h, volumeName, MAX_PATH);
  158. if (!b) {
  159. break;
  160. }
  161. }
  162. FindVolumeClose(h);
  163. #if defined(_M_IA64)
  164. PrintMappedESP();
  165. #endif
  166. }
  167. BOOL
  168. SetSystemPartitionDriveLetter(
  169. IN PWCHAR DirName
  170. )
  171. /*++
  172. Routine Description:
  173. This routine will set the given drive letter to the system partition.
  174. Arguments:
  175. DirName - Supplies the drive letter directory name.
  176. Return Value:
  177. BOOL
  178. --*/
  179. {
  180. WCHAR systemPartition[MAX_PATH];
  181. if (!GetSystemPartitionFromRegistry(systemPartition)) {
  182. return FALSE;
  183. }
  184. DirName[wcslen(DirName) - 1] = 0;
  185. if (!DefineDosDevice(DDD_RAW_TARGET_PATH, DirName, systemPartition)) {
  186. return FALSE;
  187. }
  188. return TRUE;
  189. }
  190. int __cdecl
  191. main(
  192. int argc,
  193. char** argv
  194. )
  195. {
  196. DWORD mode;
  197. WCHAR dirName[MAX_PATH];
  198. WCHAR volumeName[MAX_PATH];
  199. DWORD dirLen, volumeLen;
  200. BOOLEAN deletePoint, listPoint, systemPartition;
  201. BOOL b;
  202. WCHAR messageBuffer[MAX_PATH];
  203. SetErrorMode(SEM_FAILCRITICALERRORS);
  204. OutputFile = GetStdHandle(STD_OUTPUT_HANDLE);
  205. IsConsoleOutput = GetConsoleMode(OutputFile, &mode);
  206. if (argc != 3) {
  207. PrintMessage(MOUNTVOL_USAGE1);
  208. #if defined(_M_IA64)
  209. PrintMessage(MOUNTVOL_USAGE1_IA64);
  210. #endif
  211. PrintMessage(MOUNTVOL_USAGE2);
  212. #if defined(_M_IA64)
  213. PrintMessage(MOUNTVOL_USAGE2_IA64);
  214. #endif
  215. PrintMessage(MOUNTVOL_START_OF_LIST);
  216. PrintVolumeList();
  217. return 0;
  218. }
  219. SetErrorMode(SEM_FAILCRITICALERRORS);
  220. swprintf(dirName, L"%hs", argv[1]);
  221. swprintf(volumeName, L"%hs", argv[2]);
  222. dirLen = wcslen(dirName);
  223. volumeLen = wcslen(volumeName);
  224. if (argv[2][0] == '/' && argv[2][1] != 0 && argv[2][2] == 0) {
  225. if (argv[2][1] == 'd' || argv[2][1] == 'D') {
  226. deletePoint = TRUE;
  227. listPoint = FALSE;
  228. systemPartition = FALSE;
  229. } else if (argv[2][1] == 'l' || argv[2][1] == 'L') {
  230. deletePoint = FALSE;
  231. listPoint = TRUE;
  232. systemPartition = FALSE;
  233. } else if (argv[2][1] == 's' || argv[2][1] == 'S') {
  234. deletePoint = FALSE;
  235. listPoint = FALSE;
  236. systemPartition = TRUE;
  237. } else {
  238. deletePoint = FALSE;
  239. listPoint = FALSE;
  240. systemPartition = FALSE;
  241. }
  242. } else {
  243. deletePoint = FALSE;
  244. listPoint = FALSE;
  245. systemPartition = FALSE;
  246. }
  247. if (dirName[dirLen - 1] != '\\') {
  248. wcscat(dirName, L"\\");
  249. dirLen++;
  250. }
  251. if (volumeName[volumeLen - 1] != '\\') {
  252. wcscat(volumeName, L"\\");
  253. volumeLen++;
  254. }
  255. if (deletePoint) {
  256. b = DeleteVolumeMountPoint(dirName);
  257. if (!b && GetLastError() == ERROR_INVALID_PARAMETER) {
  258. dirName[dirLen - 1] = 0;
  259. b = DefineDosDevice(DDD_REMOVE_DEFINITION, dirName, NULL);
  260. }
  261. } else if (listPoint) {
  262. b = GetVolumeNameForVolumeMountPoint(dirName, volumeName, MAX_PATH);
  263. if (b) {
  264. PrintMessage(MOUNTVOL_VOLUME_NAME, volumeName);
  265. }
  266. } else if (systemPartition) {
  267. b = SetSystemPartitionDriveLetter(dirName);
  268. } else {
  269. if (dirName[1] == ':' && dirName[2] == '\\' && !dirName[3]) {
  270. dirName[2] = 0;
  271. b = QueryDosDevice(dirName, messageBuffer, MAX_PATH);
  272. if (b) {
  273. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
  274. ERROR_DIR_NOT_EMPTY, 0, messageBuffer, MAX_PATH,
  275. NULL);
  276. DisplayIt(messageBuffer);
  277. return 1;
  278. }
  279. dirName[2] = '\\';
  280. }
  281. b = SetVolumeMountPoint(dirName, volumeName);
  282. }
  283. if (!b) {
  284. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
  285. messageBuffer, MAX_PATH, NULL);
  286. DisplayIt(messageBuffer);
  287. return 1;
  288. }
  289. return 0;
  290. }