Leaked source code of windows server 2003
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.

226 lines
6.0 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. typedef LONG NTSTATUS;
  4. #include <ntdskreg.h>
  5. #include <ntddft.h>
  6. UCHAR
  7. QueryDriveLetter(
  8. IN ULONG Signature,
  9. IN LONGLONG Offset
  10. )
  11. {
  12. PDRIVE_LAYOUT_INFORMATION layout;
  13. UCHAR c;
  14. TCHAR name[80];
  15. TCHAR result[80];
  16. TCHAR num[10];
  17. DWORD i, j;
  18. HANDLE h;
  19. BOOL b;
  20. DWORD bytes;
  21. PARTITION_INFORMATION partInfo;
  22. DWORD em;
  23. layout = MALLOC(4096);
  24. if (!layout) {
  25. return 0;
  26. }
  27. em = SetErrorMode(0);
  28. SetErrorMode( em | SEM_FAILCRITICALERRORS );
  29. for (c = 'C'; c <= 'Z'; c++) {
  30. name[0] = (TCHAR)c;
  31. name[1] = (TCHAR)':';
  32. name[2] = (TCHAR)'\0';
  33. if (QueryDosDevice(name, result, ARRAYSIZE(result)) < 17) {
  34. continue;
  35. }
  36. j = 0;
  37. for (i = 16; result[i] && j < ARRAYSIZE(num); i++) {
  38. if (result[i] == (TCHAR)'\\') {
  39. break;
  40. }
  41. num[j++] = result[i];
  42. }
  43. if(j == ARRAYSIZE(num)){
  44. continue;// or return 0;
  45. }
  46. num[j] = (TCHAR)'\0';
  47. wsprintf(name, TEXT("\\\\.\\PhysicalDrive%s"), num);
  48. h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  49. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  50. INVALID_HANDLE_VALUE);
  51. if (h == INVALID_HANDLE_VALUE) {
  52. continue;
  53. }
  54. b = DeviceIoControl(h, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, layout,
  55. 4096, &bytes, NULL);
  56. CloseHandle(h);
  57. if (!b) {
  58. continue;
  59. }
  60. if (layout->Signature != Signature) {
  61. continue;
  62. }
  63. wsprintf(name, TEXT("\\\\.\\%c:"), c);
  64. h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  65. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  66. INVALID_HANDLE_VALUE);
  67. if (h == INVALID_HANDLE_VALUE) {
  68. continue;
  69. }
  70. b = DeviceIoControl(h, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
  71. &partInfo, sizeof(partInfo), &bytes, NULL);
  72. CloseHandle(h);
  73. if (!b) {
  74. continue;
  75. }
  76. if (partInfo.StartingOffset.QuadPart == Offset) {
  77. break;
  78. }
  79. }
  80. FREE(layout);
  81. SetErrorMode( em );
  82. return (c <= 'Z') ? c : 0;
  83. }
  84. VOID
  85. ForceStickyDriveLetters(
  86. )
  87. {
  88. LONG error;
  89. HKEY key;
  90. TCHAR name[10];
  91. UCHAR driveLetter;
  92. UINT driveType;
  93. TCHAR targetPath[MAX_PATH];
  94. DWORD type;
  95. DWORD size;
  96. PBYTE registryValue;
  97. PDISK_CONFIG_HEADER header;
  98. PDISK_REGISTRY diskRegistry;
  99. PDISK_DESCRIPTION diskDescription;
  100. ULONG i, j;
  101. PDISK_PARTITION diskPartition;
  102. DWORD d;
  103. error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\DISK"), 0,
  104. KEY_QUERY_VALUE | KEY_SET_VALUE, &key);
  105. if (error != ERROR_SUCCESS) {
  106. #ifdef _X86_
  107. if (IsNEC98() && Upgrade){
  108. error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  109. TEXT("SYSTEM\\DISK"),
  110. 0,
  111. NULL,
  112. REG_OPTION_NON_VOLATILE,
  113. KEY_QUERY_VALUE | KEY_SET_VALUE,
  114. NULL,
  115. &key,
  116. &d
  117. );
  118. if (error != ERROR_SUCCESS) {
  119. return;
  120. }
  121. }else{
  122. return;
  123. }
  124. #else
  125. return;
  126. #endif
  127. }
  128. name[1] = (TCHAR)':';
  129. name[2] = (TCHAR)'\\';
  130. name[3] = (TCHAR)'\0';
  131. for (driveLetter = 'C'; driveLetter <= 'Z'; driveLetter++) {
  132. name[0] = (TCHAR)driveLetter;
  133. name[2] = (TCHAR)'\\';
  134. driveType = GetDriveType(name);
  135. if (driveType != DRIVE_REMOVABLE && driveType != DRIVE_CDROM) {
  136. continue;
  137. }
  138. name[2] = (TCHAR)'\0';
  139. if (!QueryDosDevice(name, targetPath, MAX_PATH)) {
  140. continue;
  141. }
  142. RegSetValueEx(key, targetPath, 0, REG_SZ, (PBYTE)name, 3*sizeof(TCHAR));
  143. }
  144. error = RegQueryValueEx(key, TEXT("Information"), NULL, &type, NULL,
  145. &size);
  146. if (error != ERROR_SUCCESS) {
  147. RegCloseKey(key);
  148. return;
  149. }
  150. registryValue = MALLOC(size);
  151. if (!registryValue) {
  152. RegCloseKey(key);
  153. return;
  154. }
  155. error = RegQueryValueEx(key, TEXT("Information"), NULL, &type,
  156. registryValue, &size);
  157. if (error != ERROR_SUCCESS) {
  158. FREE(registryValue);
  159. RegCloseKey(key);
  160. return;
  161. }
  162. header = (PDISK_CONFIG_HEADER) registryValue;
  163. diskRegistry = (PDISK_REGISTRY) ((PCHAR) header +
  164. header->DiskInformationOffset);
  165. diskDescription = &diskRegistry->Disks[0];
  166. for (i = 0; i < diskRegistry->NumberOfDisks; i++) {
  167. for (j = 0; j < diskDescription->NumberOfPartitions; j++) {
  168. diskPartition = &diskDescription->Partitions[j];
  169. if (diskPartition->AssignDriveLetter &&
  170. !diskPartition->DriveLetter) {
  171. driveLetter = QueryDriveLetter(diskDescription->Signature,
  172. diskPartition->StartingOffset.QuadPart);
  173. if (driveLetter) {
  174. diskPartition->DriveLetter = driveLetter;
  175. }
  176. }
  177. }
  178. diskDescription = (PDISK_DESCRIPTION) &diskDescription->
  179. Partitions[diskDescription->NumberOfPartitions];
  180. }
  181. RegSetValueEx(key, TEXT("Information"), 0, type, registryValue, size);
  182. FREE(registryValue);
  183. RegCloseKey(key);
  184. }