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.

611 lines
14 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. partition.c
  5. Abstract:
  6. Debugger extension for dumping partition structures:
  7. DRIVE_LAYOUT_INFORMATION
  8. DRIVE_LAYOUT_INFORMATION_EX
  9. PARTITION_INFORMATION
  10. PARTITION_INFORMATION_EX
  11. Author:
  12. Matthew D Hendel (math) 19-Jan-2000
  13. Revision History:
  14. --*/
  15. #include "pch.h"
  16. #include <ntdddisk.h>
  17. VOID
  18. DumpPartition(
  19. IN ULONG64 Address,
  20. IN ULONG Detail,
  21. IN ULONG Depth,
  22. IN ULONG PartitionCount
  23. )
  24. /*++
  25. Routine Description:
  26. Dump a PARTITION_INFORMATION structure.
  27. Arguments:
  28. Address - The address of the partition information structure to dump.
  29. Detail - The detail level. Currently unused.
  30. Depth - The depth to indent to.
  31. PartitionCount - The number of partitions. This is used to determine
  32. whether a particular partition ordinal is valid or not.
  33. Return Value:
  34. None.
  35. --*/
  36. {
  37. BOOL Succ;
  38. ULONG Size;
  39. ULONG64 StartingOffset;
  40. ULONG64 PartitionLength;
  41. ULONG PartitionNumber;
  42. UCHAR PartitionType;
  43. BOOLEAN BootIndicator;
  44. BOOLEAN RecognizedPartition;
  45. BOOLEAN RewritePartition;
  46. InitTypeRead(Address, nt!PARTITION_INFORMATION);
  47. StartingOffset = ReadField(StartingOffset.QuadPart);
  48. PartitionLength = ReadField(PartitionLength.QuadPart);
  49. PartitionType = (UCHAR) ReadField(PartitionType);
  50. BootIndicator = (BOOLEAN) ReadField(BootIndicator);
  51. RecognizedPartition = (BOOLEAN) ReadField(RecognizedPartition);
  52. RewritePartition = (BOOLEAN) ReadField(RewritePartition);
  53. PartitionNumber = (ULONG) ReadField(PartitionNumber);
  54. //
  55. // Sanity check the data.
  56. //
  57. if ( (BootIndicator != TRUE && BootIndicator != FALSE) ||
  58. (RecognizedPartition != TRUE && RecognizedPartition != FALSE) ||
  59. (RewritePartition != TRUE && RewritePartition != FALSE) ) {
  60. xdprintfEx (Depth, ("Invalid partition information at %p\n", Address));
  61. }
  62. if (PartitionNumber > PartitionCount) {
  63. PartitionNumber = (ULONG)-1;
  64. }
  65. xdprintfEx (Depth, ("[%-2d] %-16I64x %-16I64x %2.2x %c %c %c\n",
  66. PartitionNumber,
  67. StartingOffset,
  68. PartitionLength,
  69. PartitionType,
  70. BootIndicator ? 'x' : ' ',
  71. RecognizedPartition ? 'x' : ' ',
  72. RewritePartition ? 'x' : ' '
  73. ));
  74. }
  75. VOID
  76. DumpDriveLayout(
  77. IN ULONG64 Address,
  78. IN ULONG Detail,
  79. IN ULONG Depth
  80. )
  81. {
  82. BOOL Succ;
  83. ULONG Size;
  84. ULONG i;
  85. ULONG64 PartAddress;
  86. ULONG result;
  87. ULONG offset;
  88. ULONG PartitionCount;
  89. ULONG Signature;
  90. ULONG OffsetOfFirstPartitionInfo;
  91. ULONG SizeOfPartitionInfo;
  92. InitTypeRead(Address, nt!_DRIVE_LAYOUT_INFORMATION);
  93. PartitionCount = (ULONG) ReadField(PartitionCount);
  94. Signature = (ULONG) ReadField(Signature);
  95. xdprintfEx (Depth, ("\nDRIVE_LAYOUT %p\n", Address));
  96. //
  97. // Warn if the partition count is not a factor of 4. This is probably a
  98. // bad partition information structure, but we'll continue on anyway.
  99. //
  100. if (PartitionCount % 4 != 0) {
  101. xdprintfEx (Depth, ("WARNING: Partition count should be a factor of 4.\n"));
  102. }
  103. xdprintfEx (Depth, ("PartitionCount: %d\n", PartitionCount));
  104. xdprintfEx (Depth, ("Signature: %8.8x\n\n", Signature));
  105. xdprintfEx (Depth+1, (" ORD Offset Length Type BI RP RW\n"));
  106. xdprintfEx (Depth+1, ("------------------------------------------------------------\n"));
  107. result = GetFieldOffset("nt!_DRIVE_LAYOUT_INFORMATION",
  108. "PartitionEntry[0]",
  109. &offset);
  110. if (result) {
  111. SCSIKD_PRINT_ERROR(result);
  112. return;
  113. }
  114. OffsetOfFirstPartitionInfo = offset;
  115. result = GetFieldOffset("nt!_DRIVE_LAYOUT_INFORMATION",
  116. "PartitionEntry[1]",
  117. &offset);
  118. if (result) {
  119. SCSIKD_PRINT_ERROR(result);
  120. return;
  121. }
  122. SizeOfPartitionInfo = offset - OffsetOfFirstPartitionInfo;
  123. PartAddress = Address + OffsetOfFirstPartitionInfo;
  124. for (i = 0; i < PartitionCount; i++) {
  125. if (CheckControlC()) {
  126. return;
  127. }
  128. DumpPartition(PartAddress, Detail, Depth+1, PartitionCount);
  129. PartAddress += SizeOfPartitionInfo;
  130. }
  131. }
  132. VOID
  133. DumpPartitionEx(
  134. IN ULONG64 Address,
  135. IN ULONG Detail,
  136. IN ULONG Depth,
  137. IN ULONG PartitionCount
  138. )
  139. /*++
  140. Routine Description:
  141. Dump a PARTITION_INFORMATION_EX structure.
  142. Arguments:
  143. Address - The address of the partition information structure to dump.
  144. Detail - The detail level. Currently unused.
  145. Depth - The depth to indent to.
  146. PartitionCount - The number of partitions. This is used to determine
  147. whether a particular partition ordinal is valid or not.
  148. Return Value:
  149. None.
  150. --*/
  151. {
  152. BOOL Succ;
  153. ULONG Size;
  154. ULONG result;
  155. ULONG offset;
  156. ULONG PartitionStyle;
  157. ULONG PartitionNumber;
  158. ULONG64 StartingOffset;
  159. ULONG64 PartitionLength;
  160. BOOLEAN RewritePartition;
  161. UCHAR MbrPartitionType;
  162. BOOLEAN MbrBootIndicator;
  163. BOOLEAN MbrRecognizedPartition;
  164. ULONG64 GptAttributes;
  165. GUID GptPartitionType;
  166. GUID GptPartitionId;
  167. ULONG64 AddrOfGuid;
  168. WCHAR GptName[36+1] = {0};
  169. InitTypeRead (Address, nt!_PARTITION_INFORMATION_EX);
  170. PartitionStyle = (ULONG) ReadField(PartitionStyle);
  171. if (PartitionStyle != PARTITION_STYLE_MBR &&
  172. PartitionStyle != PARTITION_STYLE_GPT) {
  173. SCSIKD_PRINT_ERROR(0);
  174. return;
  175. }
  176. PartitionNumber = (ULONG) ReadField(PartitionNumber);
  177. StartingOffset = ReadField(StartingOffset.QuadPart);
  178. PartitionLength = ReadField(PartitionLength.QuadPart);
  179. RewritePartition = (BOOLEAN) ReadField(RewritePartition);
  180. //
  181. // We use -1 to denote an invalid partition ordinal.
  182. //
  183. if (PartitionNumber >= PartitionCount) {
  184. PartitionNumber = (ULONG)-1;
  185. }
  186. InitTypeRead (Address, nt!_PARTITION_INFORMATION_EX);
  187. if (PartitionStyle == PARTITION_STYLE_MBR) {
  188. MbrPartitionType = (UCHAR) ReadField(Mbr.PartitionType);
  189. MbrBootIndicator = (BOOLEAN) ReadField(Mbr.BootIndicator);
  190. MbrRecognizedPartition = (BOOLEAN) ReadField(Mbr.RecognizedPartition);
  191. xdprintfEx (Depth, ("[%-2d] %-16I64x %-16I64x %2.2x %c %c %c\n",
  192. PartitionNumber,
  193. StartingOffset,
  194. PartitionLength,
  195. MbrPartitionType,
  196. MbrBootIndicator ? 'x' : ' ',
  197. MbrRecognizedPartition ? 'x' : ' ',
  198. RewritePartition ? 'x' : ' '
  199. ));
  200. } else {
  201. GptAttributes = ReadField(Gpt.Attributes);
  202. result = GetFieldOffset("nt!_PARTITION_INFORMATION_EX",
  203. "Gpt.PartitionType",
  204. &offset);
  205. if (result) {
  206. SCSIKD_PRINT_ERROR(result);
  207. return;
  208. }
  209. AddrOfGuid = Address + offset;
  210. Succ = ReadMemory (
  211. AddrOfGuid,
  212. &GptPartitionType,
  213. sizeof (GUID),
  214. &Size
  215. );
  216. if (!Succ || Size != sizeof (GUID)) {
  217. SCSIKD_PRINT_ERROR(0);
  218. return;
  219. }
  220. //
  221. // PartitionId immediately follows the PartitionType. So all we have to do
  222. // is add sizeof(GUID) to the address and read PartitionId.
  223. //
  224. AddrOfGuid += sizeof(GUID);
  225. Succ = ReadMemory (
  226. AddrOfGuid,
  227. &GptPartitionId,
  228. sizeof (GUID),
  229. &Size
  230. );
  231. if (!Succ || Size != sizeof (GUID)) {
  232. SCSIKD_PRINT_ERROR(0);
  233. return;
  234. }
  235. //
  236. // Read in the Gpt.Name.
  237. //
  238. result = GetFieldOffset("nt!_PARTITION_INFORMATION_EX",
  239. "Gpt.Name",
  240. &offset);
  241. if (result) {
  242. SCSIKD_PRINT_ERROR(result);
  243. return;
  244. }
  245. Succ = ReadMemory (
  246. Address + offset,
  247. GptName,
  248. sizeof(GptName)-sizeof(WCHAR),
  249. &Size
  250. );
  251. if (!Succ || Size != sizeof (GUID)) {
  252. SCSIKD_PRINT_ERROR(0);
  253. return;
  254. }
  255. xdprintfEx (Depth, ("[%-2d] %S\n",
  256. PartitionNumber, GptName));
  257. xdprintfEx (Depth, ("OFF %-16I64x LEN %-16I64x ATTR %-16I64x R/W %c\n",
  258. StartingOffset,
  259. PartitionLength,
  260. GptAttributes,
  261. RewritePartition ? 'T' : 'F'));
  262. xdprintfEx (Depth, ("TYPE %s\n",
  263. GuidToString (&GptPartitionType)));
  264. xdprintfEx (Depth, ("ID %s\n",
  265. GuidToString (&GptPartitionId)));
  266. xdprintfEx (Depth, ("\n"));
  267. }
  268. }
  269. VOID
  270. DumpDriveLayoutEx(
  271. IN ULONG64 Address,
  272. IN ULONG Detail,
  273. IN ULONG Depth
  274. )
  275. {
  276. ULONG result;
  277. BOOL Succ;
  278. ULONG Size;
  279. ULONG i;
  280. ULONG offset;
  281. ULONG64 AddrOfDiskId;
  282. ULONG PartitionStyle;
  283. ULONG PartitionCount;
  284. ULONG MbrSignature;
  285. GUID GptDiskId;
  286. ULONG64 GptStartingUsableOffset;
  287. ULONG64 GptUsableLength;
  288. ULONG GptMaxPartitionCount;
  289. InitTypeRead(Address, nt!_DRIVE_LAYOUT_INFORMATION_EX);
  290. PartitionStyle = (ULONG)ReadField(PartitionStyle);
  291. PartitionCount = (ULONG)ReadField(PartitionCount);
  292. MbrSignature = (ULONG)ReadField(Mbr.Signature);
  293. GptStartingUsableOffset = ReadField(Gpt.StartingUsableOffset.QuadPart);
  294. GptUsableLength = ReadField(Gpt.UsableLength.QuadPart);
  295. GptMaxPartitionCount = (ULONG)ReadField(Gpt.MaxPartitionCount);
  296. result = GetFieldOffset("nt!_DRIVE_LAYOUT_INFORMATION_EX",
  297. "Gpt.DiskId",
  298. &offset);
  299. if (result) {
  300. SCSIKD_PRINT_ERROR(result);
  301. return;
  302. }
  303. AddrOfDiskId = Address + offset;
  304. Succ = ReadMemory(
  305. AddrOfDiskId,
  306. &GptDiskId,
  307. sizeof(GUID),
  308. &Size);
  309. if (!Succ || Size != sizeof(GUID)) {
  310. SCSIKD_PRINT_ERROR(result);
  311. return;
  312. }
  313. xdprintfEx (Depth, ("\nDRIVE_LAYOUT_EX %p\n", Address));
  314. if (PartitionStyle != PARTITION_STYLE_MBR &&
  315. PartitionStyle != PARTITION_STYLE_GPT) {
  316. xdprintfEx (Depth, ("ERROR: invalid partition style %d\n", PartitionStyle));
  317. return;
  318. }
  319. if (PartitionStyle == PARTITION_STYLE_MBR &&
  320. PartitionCount % 4 != 0) {
  321. xdprintfEx (Depth, ("WARNING: Partition count is not a factor of 4, (%d)\n",
  322. PartitionCount));
  323. }
  324. if (PartitionStyle == PARTITION_STYLE_MBR) {
  325. xdprintfEx (Depth, ("Signature: %8.8x\n", MbrSignature));
  326. xdprintfEx (Depth, ("PartitionCount %d\n\n", PartitionCount));
  327. xdprintfEx (Depth+1, (" ORD Offset Length Type BI RP RW\n"));
  328. xdprintfEx (Depth+1, ("------------------------------------------------------------\n"));
  329. } else {
  330. xdprintfEx (Depth, ("DiskId: %s\n", GuidToString (&GptDiskId)));
  331. xdprintfEx (Depth, ("StartingUsableOffset: %I64x\n", GptStartingUsableOffset));
  332. xdprintfEx (Depth, ("UsableLength: %I64x\n", GptUsableLength));
  333. xdprintfEx (Depth, ("MaxPartitionCount: %d\n", GptMaxPartitionCount));
  334. xdprintfEx (Depth, ("PartitionCount %d\n\n", PartitionCount));
  335. }
  336. result = GetFieldOffset("nt!_DRIVE_LAYOUT_INFORMATION_EX", "PartitionEntry[0]", &offset);
  337. if (result)
  338. {
  339. SCSIKD_PRINT_ERROR(result);
  340. return;
  341. }
  342. Address += offset;
  343. for (i = 0; i < PartitionCount; i++)
  344. {
  345. if (CheckControlC())
  346. {
  347. return;
  348. }
  349. DumpPartitionEx(Address, Detail, Depth + 1, PartitionCount);
  350. Address += sizeof(PARTITION_INFORMATION_EX);
  351. }
  352. }
  353. DECLARE_API (layout)
  354. /*++
  355. Routine Description:
  356. Dump a DRIVE_LAYOUT structure with all it's partitions.
  357. Arguments:
  358. args - A string containing the address of the DRIVE_LAYOUT structure to
  359. be dumped.
  360. Return Value:
  361. None.
  362. --*/
  363. {
  364. ULONG64 Address = 0;
  365. ULONG64 detail = 0;
  366. if (GetExpressionEx(args, &Address, &args))
  367. {
  368. GetExpressionEx(args, &detail, &args);
  369. }
  370. DumpDriveLayout (Address, (ULONG)detail, 0);
  371. return S_OK;
  372. }
  373. DECLARE_API (layoutex)
  374. /*++
  375. Routine Description:
  376. Dump a DRIVE_LAYOUT_EX structure and it's partitions.
  377. Usage:
  378. layoutex <address>
  379. Arguments:
  380. args - A string containing the address of the DRIVE_LAYOUT_EX structure
  381. to be dumped.
  382. Return Value:
  383. None.
  384. --*/
  385. {
  386. ULONG64 Address = 0;
  387. ULONG64 detail = 0;
  388. if (GetExpressionEx(args, &Address, &args))
  389. {
  390. GetExpressionEx(args, &detail, &args);
  391. }
  392. DumpDriveLayoutEx (Address, (ULONG)detail, 0);
  393. return S_OK;
  394. }
  395. DECLARE_API (part)
  396. /*++
  397. Routine Description:
  398. Dump a PARTITION_INFORMATION structure.
  399. Usage:
  400. part <address>
  401. Arguments:
  402. args - A string containing the address of the PARTITION_INFORMATION
  403. structure to be dumped.
  404. Return Value:
  405. None.
  406. --*/
  407. {
  408. ULONG64 Address = 0;
  409. ULONG64 detail = 0;
  410. if (GetExpressionEx(args, &Address, &args))
  411. {
  412. GetExpressionEx(args, &detail, &args);
  413. }
  414. DumpPartition (Address, (ULONG)detail, 0, 0);
  415. return S_OK;
  416. }
  417. DECLARE_API (partex)
  418. /*++
  419. Routine Description:
  420. Dump a PARTITION_INFORMATION_EX structure.
  421. Usage:
  422. partex <address>
  423. Arguments:
  424. args - A string containing the address of the PARTITION_INFORMATION_EX
  425. structure to be dumped.
  426. Return Value:
  427. None.
  428. --*/
  429. {
  430. ULONG64 Address = 0;
  431. ULONG64 detail = 0;
  432. if (GetExpressionEx(args, &Address, &args))
  433. {
  434. GetExpressionEx(args, &detail, &args);
  435. }
  436. DumpPartitionEx (Address, (ULONG)detail, 0, 0);
  437. return S_OK;
  438. }