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.

311 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. partiton.c
  5. Abstract:
  6. Partition scanning routines and assigning Dos Device Letters.
  7. Author:
  8. Rod Gamache (rodga) 20-Feb-1996
  9. Revision History:
  10. --*/
  11. #include "windows.h"
  12. #include "winioctl.h"
  13. #include "ntddscsi.h"
  14. #include "string.h"
  15. #include "stdio.h"
  16. #include "stdlib.h"
  17. #include "disksp.h"
  18. #include "clusdisk.h"
  19. #include "lm.h"
  20. #include "lmerr.h"
  21. #define UNICODE 1
  22. #define ENTRIES_PER_BOOTSECTOR 8
  23. BOOLEAN
  24. GetAssignedDriveLetter(
  25. ULONG Signature,
  26. LARGE_INTEGER StartingOffset,
  27. LARGE_INTEGER Length,
  28. PUCHAR DriveLetter,
  29. PULONG Partition
  30. );
  31. DWORD
  32. AssignDriveLetters(
  33. PDISK_INFO DiskInfo
  34. )
  35. /*++
  36. Routine Description:
  37. This routine scans the partitions on a specified volume and assigns device
  38. letters. If the DosDeviceLetter has already been assigned, then everything
  39. is fine. Otherwise, the 'sticky' device letter from the registry is used.
  40. An error is returned if there is a partition that does not have any
  41. registry information or no 'sticky' device letter.
  42. Arguments:
  43. DiskInfo - The disk information for this partition.
  44. Return Value:
  45. Win32 Error Status - ERROR_SUCCESS if success.
  46. --*/
  47. {
  48. DWORD status;
  49. DWORD returnLength;
  50. DWORD diskSignature;
  51. DWORD driveLayoutSize;
  52. DWORD partNumber;
  53. DWORD index;
  54. PDRIVE_LAYOUT_INFORMATION driveLayout;
  55. PPARTITION_INFORMATION partInfo;
  56. WCHAR targetPath[100];
  57. WCHAR newName[8];
  58. UCHAR driveLetter;
  59. BOOL success;
  60. DWORD partition;
  61. driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
  62. (sizeof(PARTITION_INFORMATION) * MAX_PARTITIONS);
  63. driveLayout = LocalAlloc( LMEM_FIXED, driveLayoutSize );
  64. ZeroMemory( driveLayout, driveLayoutSize );
  65. if ( !driveLayout ) {
  66. printf( "AssignDriveLetters, failed to allocate drive layout info.\n");
  67. return(ERROR_OUTOFMEMORY);
  68. }
  69. success = DeviceIoControl( DiskInfo->FileHandle,
  70. IOCTL_DISK_GET_DRIVE_LAYOUT,
  71. NULL,
  72. 0,
  73. driveLayout,
  74. driveLayoutSize,
  75. &returnLength,
  76. FALSE );
  77. if ( !success ) {
  78. printf( "AssignDriveLetters, error getting drive layout, %u.\n",
  79. status = GetLastError() );
  80. LocalFree( driveLayout );
  81. return(status);
  82. }
  83. if ( returnLength < (sizeof(DRIVE_LAYOUT_INFORMATION) +
  84. (sizeof(PARTITION_INFORMATION) *
  85. (driveLayout->PartitionCount-1))) ) {
  86. printf("Found %d partitons, need %u, return size %u.\n",
  87. driveLayout->PartitionCount, sizeof(DRIVE_LAYOUT_INFORMATION) +
  88. (sizeof(PARTITION_INFORMATION) * (driveLayout->PartitionCount - 1)), returnLength);
  89. printf("AssignDriveLetters, error getting drive layout. Zero length returned.\n");
  90. LocalFree( driveLayout );
  91. return(ERROR_INSUFFICIENT_BUFFER);
  92. }
  93. //
  94. // Process all partitions, assigning drive letters.
  95. //
  96. ZeroMemory(DiskInfo->Letters, sizeof(DiskInfo->Letters));
  97. for ( index = 0;
  98. (index < driveLayout->PartitionCount) &&
  99. (index < ENTRIES_PER_BOOTSECTOR);
  100. index++ ) {
  101. partInfo = &driveLayout->PartitionEntry[index];
  102. if ( (partInfo->PartitionType == PARTITION_ENTRY_UNUSED) ||
  103. !partInfo->RecognizedPartition ) {
  104. printf("AssignDriveLetters, unused partition found, index %u.\n", index);
  105. continue;
  106. }
  107. partNumber = partInfo->PartitionNumber;
  108. if ( partNumber > MAX_PARTITIONS ) {
  109. printf("AssignDriveLetters, bad partition number %u, index %u.\n",
  110. partNumber, index);
  111. break;
  112. }
  113. GetAssignedDriveLetter( driveLayout->Signature,
  114. partInfo->StartingOffset,
  115. partInfo->PartitionLength,
  116. &driveLetter,
  117. &partition );
  118. printf("AssignDriveLetters found letter %c, partition %u, offset %u, length %u.\n",
  119. driveLetter, partNumber, partInfo->StartingOffset, partInfo->PartitionLength);
  120. if ( driveLetter != ' ' ) {
  121. DiskInfo->Letters[partNumber] = driveLetter;
  122. swprintf( targetPath,
  123. L"\\Device\\Harddisk%d\\Partition%d",
  124. DiskInfo->PhysicalDrive,
  125. partNumber );
  126. newName[0] = (TCHAR)driveLetter;
  127. newName[1] = (TCHAR)':';
  128. newName[2] = 0;
  129. DefineDosDeviceW( DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM,
  130. newName,
  131. targetPath );
  132. }
  133. }
  134. LocalFree( driveLayout );
  135. return(ERROR_SUCCESS);
  136. } // AssignDriveLetters
  137. DWORD
  138. RemoveDriveLetters(
  139. PDISK_INFO DiskInfo
  140. )
  141. /*++
  142. Routine Description:
  143. This routine scans the partitions on a specified volume and removes device
  144. letters. If the DosDeviceLetter has already been assigned, then everything
  145. is fine. Otherwise, the 'sticky' device letter from the registry is used.
  146. An error is returned if there is a partition that does not have any
  147. registry information or no 'sticky' device letter.
  148. Arguments:
  149. DiskInfo - The disk information for this partition.
  150. Return Value:
  151. Win32 Error Status - ERROR_SUCCESS if success.
  152. --*/
  153. {
  154. DWORD status;
  155. DWORD returnLength;
  156. DWORD diskSignature;
  157. DWORD driveLayoutSize;
  158. DWORD index;
  159. PDRIVE_LAYOUT_INFORMATION driveLayout;
  160. PPARTITION_INFORMATION partInfo;
  161. TCHAR newName[8];
  162. WCHAR shareName[8];
  163. UCHAR driveLetter;
  164. BOOL success;
  165. DWORD partition;
  166. driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
  167. (sizeof(PARTITION_INFORMATION) * MAX_PARTITIONS);
  168. driveLayout = LocalAlloc( LMEM_FIXED, driveLayoutSize );
  169. if ( !driveLayout ) {
  170. printf("RemoveDriveLetters, failed to allocate drive layout info.\n");
  171. return(ERROR_OUTOFMEMORY);
  172. }
  173. success = DeviceIoControl( DiskInfo->FileHandle,
  174. IOCTL_DISK_GET_DRIVE_LAYOUT,
  175. NULL,
  176. 0,
  177. driveLayout,
  178. driveLayoutSize,
  179. &returnLength,
  180. FALSE );
  181. if ( !success ) {
  182. printf("RemoveDriveLetters, error getting partition information, %u.\n",
  183. status = GetLastError() );
  184. LocalFree( driveLayout );
  185. return(status);
  186. }
  187. if ( returnLength < (sizeof(DRIVE_LAYOUT_INFORMATION) +
  188. sizeof(PARTITION_INFORMATION)) ) {
  189. printf("RemoveDriveLetters, error getting partition information. Zero length returned.\n");
  190. LocalFree( driveLayout );
  191. return(ERROR_INSUFFICIENT_BUFFER);
  192. }
  193. //
  194. // Process all partitions, assigning drive letters.
  195. //
  196. for ( index = 0;
  197. (index < driveLayout->PartitionCount) &&
  198. (index < ENTRIES_PER_BOOTSECTOR);
  199. index++ ) {
  200. partInfo = &driveLayout->PartitionEntry[index];
  201. if ( (partInfo->PartitionType == PARTITION_ENTRY_UNUSED) ||
  202. !partInfo->RecognizedPartition ) {
  203. continue;
  204. }
  205. GetAssignedDriveLetter( driveLayout->Signature,
  206. partInfo->StartingOffset,
  207. partInfo->PartitionLength,
  208. &driveLetter,
  209. &partition );
  210. printf("Found letter %c, offset %u, length %u\n",
  211. driveLetter, partInfo->StartingOffset, partInfo->PartitionLength);
  212. if ( driveLetter != ' ' ) {
  213. newName[0] = (TCHAR)driveLetter;
  214. newName[1] = (TCHAR)':';
  215. newName[2] = (TCHAR)0;
  216. shareName[0] = (WCHAR)driveLetter;
  217. shareName[1] = (WCHAR)'$';
  218. shareName[2] = (WCHAR)0;
  219. #if 0
  220. NetShareDel( NULL,
  221. shareName,
  222. 0 );
  223. #endif
  224. success = DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM,
  225. newName,
  226. (LPCTSTR) NULL );
  227. if ( !success ) {
  228. printf("RemoveDriveLetters, error removing definition for device %c:.\n",
  229. driveLetter);
  230. }
  231. }
  232. }
  233. LocalFree( driveLayout );
  234. return(ERROR_SUCCESS);
  235. } // RemoveDriveLetters