Finished drive letter assignment
[reactos.git] / reactos / ntoskrnl / io / xhaldrv.c
1 /* $Id: xhaldrv.c,v 1.7 2000/08/25 15:55:02 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/xhaldrv.c
6 * PURPOSE: Hal drive routines
7 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
8 * UPDATE HISTORY:
9 * Created 19/06/2000
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/xhal.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20 /* LOCAL MACROS and TYPES ***************************************************/
21
22 #define AUTO_DRIVE ((ULONG)-1)
23
24 #define PARTITION_MAGIC 0xaa55
25 #define PART_MAGIC_OFFSET 0x01fe
26 #define PARTITION_OFFSET 0x01be
27 #define SIGNATURE_OFFSET 0x01b8
28 #define PARTITION_TBL_SIZE 4
29
30 #define IsUsablePartition(P) \
31 ((P) != PTEmpty && \
32 (P) != PTDosExtended && \
33 (P) != PTWin95ExtendedLBA)
34
35
36 typedef struct _PARTITION
37 {
38 unsigned char BootFlags;
39 unsigned char StartingHead;
40 unsigned char StartingSector;
41 unsigned char StartingCylinder;
42 unsigned char PartitionType;
43 unsigned char EndingHead;
44 unsigned char EndingSector;
45 unsigned char EndingCylinder;
46 unsigned int StartingBlock;
47 unsigned int SectorCount;
48 } PARTITION, *PPARTITION;
49
50 typedef struct _PARTITION_TABLE
51 {
52 PARTITION Partition[PARTITION_TBL_SIZE];
53 unsigned short Magic;
54 } PARTITION_TABLE, *PPARTITION_TABLE;
55
56 /* FUNCTIONS *****************************************************************/
57
58 static NTSTATUS
59 xHalpQueryDriveLayout (
60 IN PUNICODE_STRING DeviceName,
61 OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo
62 )
63 {
64 IO_STATUS_BLOCK StatusBlock;
65 DISK_GEOMETRY DiskGeometry;
66 PDEVICE_OBJECT DeviceObject = NULL;
67 PFILE_OBJECT FileObject;
68 KEVENT Event;
69 PIRP Irp;
70 NTSTATUS Status;
71
72 DPRINT ("xHalpQueryDriveLayout %wZ %p\n",
73 DeviceName,
74 LayoutInfo);
75
76 /*
77 * Get the drives sector size
78 */
79 Status = IoGetDeviceObjectPointer (DeviceName,
80 FILE_READ_DATA,
81 &FileObject,
82 &DeviceObject);
83 if (!NT_SUCCESS(Status))
84 {
85 DPRINT ("Status %x\n",Status);
86 return Status;
87 }
88
89 KeInitializeEvent (&Event,
90 NotificationEvent,
91 FALSE);
92
93 Irp = IoBuildDeviceIoControlRequest (IOCTL_DISK_GET_DRIVE_GEOMETRY,
94 DeviceObject,
95 NULL,
96 0,
97 &DiskGeometry,
98 sizeof(DISK_GEOMETRY),
99 FALSE,
100 &Event,
101 &StatusBlock);
102 if (Irp == NULL)
103 {
104 ObDereferenceObject (FileObject);
105 return STATUS_INSUFFICIENT_RESOURCES;
106 }
107
108 Status = IoCallDriver(DeviceObject, Irp);
109 if (Status == STATUS_PENDING)
110 {
111 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
112 Status = StatusBlock.Status;
113 }
114 if (!NT_SUCCESS(Status))
115 {
116 ObDereferenceObject (FileObject);
117 return Status;
118 }
119
120 DPRINT("DiskGeometry.BytesPerSector: %d\n",
121 DiskGeometry.BytesPerSector);
122
123 /* read the partition table */
124 Status = IoReadPartitionTable (DeviceObject,
125 DiskGeometry.BytesPerSector,
126 FALSE,
127 LayoutInfo);
128
129 ObDereferenceObject (FileObject);
130
131 return Status;
132 }
133
134
135 VOID
136 FASTCALL
137 xHalExamineMBR (
138 IN PDEVICE_OBJECT DeviceObject,
139 IN ULONG SectorSize,
140 IN ULONG MBRTypeIdentifier,
141 OUT PVOID * Buffer
142 )
143 {
144 KEVENT Event;
145 IO_STATUS_BLOCK StatusBlock;
146 LARGE_INTEGER Offset;
147 PUCHAR LocalBuffer;
148 PIRP Irp;
149 NTSTATUS Status;
150
151 DPRINT ("xHalExamineMBR()\n");
152 *Buffer = NULL;
153
154 if (SectorSize < 512)
155 SectorSize = 512;
156 if (SectorSize > 4096)
157 SectorSize = 4096;
158
159 LocalBuffer = (PUCHAR)ExAllocatePool (PagedPool,
160 SectorSize);
161 if (LocalBuffer == NULL)
162 return;
163
164 KeInitializeEvent (&Event,
165 NotificationEvent,
166 FALSE);
167
168 Offset.QuadPart = 0;
169
170 Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
171 DeviceObject,
172 LocalBuffer,
173 SectorSize,
174 &Offset,
175 &Event,
176 &StatusBlock);
177
178 Status = IoCallDriver (DeviceObject,
179 Irp);
180 if (Status == STATUS_PENDING)
181 {
182 KeWaitForSingleObject (&Event,
183 Executive,
184 KernelMode,
185 FALSE,
186 NULL);
187 Status = StatusBlock.Status;
188 }
189
190 if (!NT_SUCCESS(Status))
191 {
192 DPRINT ("xHalExamineMBR failed (Status = 0x%08lx)\n",
193 Status);
194 ExFreePool (LocalBuffer);
195 return;
196 }
197
198 if (LocalBuffer[0x1FE] != 0x55 || LocalBuffer[0x1FF] != 0xAA)
199 {
200 DPRINT ("xHalExamineMBR: invalid MBR signature\n");
201 ExFreePool (LocalBuffer);
202 return;
203 }
204
205 if (LocalBuffer[0x1C2] != MBRTypeIdentifier)
206 {
207 DPRINT ("xHalExamineMBR: invalid MBRTypeIdentifier\n");
208 ExFreePool (LocalBuffer);
209 return;
210 }
211
212 *Buffer = (PVOID)LocalBuffer;
213 }
214
215 static VOID
216 HalpAssignDrive (
217 IN PUNICODE_STRING PartitionName,
218 IN OUT PULONG DriveMap,
219 IN ULONG DriveNumber
220 )
221 {
222 WCHAR DriveNameBuffer[8];
223 UNICODE_STRING DriveName;
224 ULONG i;
225
226 DPRINT("HalpAssignDrive()\n");
227
228 if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 24))
229 {
230 /* force assignment */
231 if ((*DriveMap & (1 << DriveNumber)) != 0)
232 {
233 DbgPrint("Drive letter already used!\n");
234 return;
235 }
236 }
237 else
238 {
239 /* automatic assignment */
240 DriveNumber = AUTO_DRIVE;
241
242 for (i = 2; i < 24; i++)
243 {
244 if ((*DriveMap & (1 << i)) == 0)
245 {
246 DriveNumber = i;
247 break;
248 }
249 }
250
251 if (DriveNumber == AUTO_DRIVE)
252 {
253 DbgPrint("No drive letter available!\n");
254 return;
255 }
256 }
257
258 DPRINT("DriveNumber %d\n", DriveNumber);
259
260 /* set bit in drive map */
261 *DriveMap = *DriveMap | (1 << DriveNumber);
262
263 /* build drive name */
264 swprintf (DriveNameBuffer,
265 L"\\??\\%C:",
266 'A' + DriveNumber);
267 RtlInitUnicodeString (&DriveName,
268 DriveNameBuffer);
269
270 DPRINT(" %wZ ==> %wZ\n",
271 &DriveName,
272 PartitionName);
273
274 /* create symbolic link */
275 IoCreateSymbolicLink (&DriveName,
276 PartitionName);
277 }
278
279
280 VOID
281 FASTCALL
282 xHalIoAssignDriveLetters (
283 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
284 IN PSTRING NtDeviceName,
285 OUT PUCHAR NtSystemPath,
286 OUT PSTRING NtSystemPathString
287 )
288 {
289 PDRIVE_LAYOUT_INFORMATION LayoutInfo;
290 PCONFIGURATION_INFORMATION ConfigInfo;
291 OBJECT_ATTRIBUTES ObjectAttributes;
292 IO_STATUS_BLOCK StatusBlock;
293 UNICODE_STRING UnicodeString1;
294 UNICODE_STRING UnicodeString2;
295 HANDLE FileHandle;
296 PWSTR Buffer1;
297 PWSTR Buffer2;
298 ULONG i;
299 NTSTATUS Status;
300 ULONG DriveMap = 0;
301 ULONG j;
302
303 DPRINT("xHalIoAssignDriveLetters()\n");
304
305 ConfigInfo = IoGetConfigurationInformation ();
306
307 Buffer1 = (PWSTR)ExAllocatePool (PagedPool,
308 64 * sizeof(WCHAR));
309 Buffer2 = (PWSTR)ExAllocatePool (PagedPool,
310 32 * sizeof(WCHAR));
311
312 /* Create PhysicalDrive links */
313 DPRINT("Physical disk drives: %d\n", ConfigInfo->DiskCount);
314 for (i = 0; i < ConfigInfo->DiskCount; i++)
315 {
316 swprintf (Buffer1,
317 L"\\Device\\Harddisk%d\\Partition0",
318 i);
319 RtlInitUnicodeString (&UnicodeString1,
320 Buffer1);
321
322 InitializeObjectAttributes (&ObjectAttributes,
323 &UnicodeString1,
324 0,
325 NULL,
326 NULL);
327
328 Status = NtOpenFile (&FileHandle,
329 0x10001,
330 &ObjectAttributes,
331 &StatusBlock,
332 1,
333 FILE_SYNCHRONOUS_IO_NONALERT);
334 if (NT_SUCCESS(Status))
335 {
336 NtClose (FileHandle);
337
338 swprintf (Buffer2,
339 L"\\??\\PhysicalDrive%d",
340 i);
341 RtlInitUnicodeString (&UnicodeString2,
342 Buffer2);
343
344 DPRINT("Creating link: %S ==> %S\n",
345 Buffer2,
346 Buffer1);
347
348 IoCreateSymbolicLink (&UnicodeString2,
349 &UnicodeString1);
350 }
351 }
352
353 /* Assign pre-assigned (registry) partitions */
354
355 /* Assign bootable partitions */
356 DPRINT("Assigning bootable partitions:\n");
357 for (i = 0; i < ConfigInfo->DiskCount; i++)
358 {
359 swprintf (Buffer1,
360 L"\\Device\\Harddisk%d\\Partition0",
361 i);
362 RtlInitUnicodeString (&UnicodeString1,
363 Buffer1);
364
365 Status = xHalpQueryDriveLayout (&UnicodeString1,
366 &LayoutInfo);
367 if (!NT_SUCCESS(Status))
368 {
369 DbgPrint("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
370 Status);
371 continue;
372 }
373
374 DPRINT("Logical partitions: %d\n",
375 LayoutInfo->PartitionCount);
376
377 /* search for bootable partitions */
378 for (j = 0; j < LayoutInfo->PartitionCount; j++)
379 {
380 DPRINT(" %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
381 j,
382 LayoutInfo->PartitionEntry[j].PartitionNumber,
383 LayoutInfo->PartitionEntry[j].BootIndicator,
384 LayoutInfo->PartitionEntry[j].PartitionType,
385 LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
386 LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
387
388 if (LayoutInfo->PartitionEntry[j].BootIndicator)
389 {
390 swprintf (Buffer2,
391 L"\\Device\\Harddisk%d\\Partition%d",
392 i,
393 LayoutInfo->PartitionEntry[j].PartitionNumber);
394 RtlInitUnicodeString (&UnicodeString2,
395 Buffer2);
396
397 DPRINT(" %wZ\n", &UnicodeString2);
398
399 /* assign it */
400 HalpAssignDrive (&UnicodeString2,
401 &DriveMap,
402 AUTO_DRIVE);
403 }
404 }
405
406 ExFreePool (LayoutInfo);
407 }
408
409 /* Assign remaining primary partitions */
410 DPRINT("Assigning primary partitions:\n");
411 for (i = 0; i < ConfigInfo->DiskCount; i++)
412 {
413 swprintf (Buffer1,
414 L"\\Device\\Harddisk%d\\Partition0",
415 i);
416 RtlInitUnicodeString (&UnicodeString1,
417 Buffer1);
418
419 Status = xHalpQueryDriveLayout (&UnicodeString1,
420 &LayoutInfo);
421 if (!NT_SUCCESS(Status))
422 {
423 DbgPrint("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
424 Status);
425 continue;
426 }
427
428 DPRINT("Logical partitions: %d\n",
429 LayoutInfo->PartitionCount);
430
431 /* search for primary (non-bootable) partitions */
432 for (j = 0; j < PARTITION_TBL_SIZE; j++)
433 {
434 DPRINT(" %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
435 j,
436 LayoutInfo->PartitionEntry[j].PartitionNumber,
437 LayoutInfo->PartitionEntry[j].BootIndicator,
438 LayoutInfo->PartitionEntry[j].PartitionType,
439 LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
440 LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
441
442 if ((LayoutInfo->PartitionEntry[j].BootIndicator == FALSE) &&
443 IsUsablePartition(LayoutInfo->PartitionEntry[j].PartitionType))
444 {
445 swprintf (Buffer2,
446 L"\\Device\\Harddisk%d\\Partition%d",
447 i,
448 LayoutInfo->PartitionEntry[j].PartitionNumber);
449 RtlInitUnicodeString (&UnicodeString2,
450 Buffer2);
451
452 /* assign it */
453 DPRINT(" %wZ\n", &UnicodeString2);
454 HalpAssignDrive (&UnicodeString2, &DriveMap, AUTO_DRIVE);
455 }
456 }
457
458 ExFreePool (LayoutInfo);
459 }
460
461 /* Assign extended (logical) partitions */
462 DPRINT("Assigning extended (logical) partitions:\n");
463 for (i = 0; i < ConfigInfo->DiskCount; i++)
464 {
465 swprintf (Buffer1,
466 L"\\Device\\Harddisk%d\\Partition0",
467 i);
468 RtlInitUnicodeString (&UnicodeString1,
469 Buffer1);
470
471 Status = xHalpQueryDriveLayout (&UnicodeString1,
472 &LayoutInfo);
473 if (!NT_SUCCESS(Status))
474 {
475 DbgPrint("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
476 Status);
477 continue;
478 }
479
480 DPRINT("Logical partitions: %d\n",
481 LayoutInfo->PartitionCount);
482
483 /* search for extended partitions */
484 for (j = PARTITION_TBL_SIZE; j < LayoutInfo->PartitionCount; j++)
485 {
486 DPRINT(" %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
487 j,
488 LayoutInfo->PartitionEntry[j].PartitionNumber,
489 LayoutInfo->PartitionEntry[j].BootIndicator,
490 LayoutInfo->PartitionEntry[j].PartitionType,
491 LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
492 LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
493
494 if (IsUsablePartition(LayoutInfo->PartitionEntry[j].PartitionType) &&
495 (LayoutInfo->PartitionEntry[j].PartitionNumber != 0))
496 {
497 swprintf (Buffer2,
498 L"\\Device\\Harddisk%d\\Partition%d",
499 i,
500 LayoutInfo->PartitionEntry[j].PartitionNumber);
501 RtlInitUnicodeString (&UnicodeString2,
502 Buffer2);
503
504 /* assign it */
505 DPRINT(" %wZ\n", &UnicodeString2);
506 HalpAssignDrive (&UnicodeString2, &DriveMap, AUTO_DRIVE);
507 }
508 }
509
510 ExFreePool (LayoutInfo);
511 }
512
513 /* Assign floppy drives */
514 DPRINT("Floppy drives: %d\n", ConfigInfo->FloppyCount);
515 for (i = 0; i < ConfigInfo->FloppyCount; i++)
516 {
517 swprintf (Buffer1,
518 L"\\Device\\Floppy%d",
519 i);
520 RtlInitUnicodeString (&UnicodeString1,
521 Buffer1);
522
523 /* assign drive letters A: or B: or first free drive letter */
524 DPRINT(" %wZ\n", &UnicodeString1);
525 HalpAssignDrive (&UnicodeString1,
526 &DriveMap,
527 (i < 2) ? i : AUTO_DRIVE);
528 }
529
530 /* Assign cdrom drives */
531 DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
532 for (i = 0; i < ConfigInfo->CDRomCount; i++)
533 {
534 swprintf (Buffer1,
535 L"\\Device\\Cdrom%d",
536 i);
537 RtlInitUnicodeString (&UnicodeString1,
538 Buffer1);
539
540 /* assign first free drive letter */
541 DPRINT(" %wZ\n", &UnicodeString1);
542 HalpAssignDrive (&UnicodeString1,
543 &DriveMap,
544 AUTO_DRIVE);
545 }
546
547 /* Anything else ?? */
548
549
550 ExFreePool (Buffer2);
551 ExFreePool (Buffer1);
552 }
553
554
555 NTSTATUS
556 FASTCALL
557 xHalIoReadPartitionTable (
558 PDEVICE_OBJECT DeviceObject,
559 ULONG SectorSize,
560 BOOLEAN ReturnRecognizedPartitions,
561 PDRIVE_LAYOUT_INFORMATION * PartitionBuffer
562 )
563 {
564 KEVENT Event;
565 IO_STATUS_BLOCK StatusBlock;
566 ULARGE_INTEGER Offset;
567 PUCHAR SectorBuffer;
568 PIRP Irp;
569 NTSTATUS Status;
570 PPARTITION_TABLE PartitionTable;
571 PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
572 ULONG i;
573 ULONG Count = 0;
574 ULONG Number = 1;
575 BOOLEAN ExtendedFound = FALSE;
576
577 DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n",
578 DeviceObject,
579 SectorSize,
580 ReturnRecognizedPartitions,
581 PartitionBuffer);
582
583 *PartitionBuffer = NULL;
584
585 SectorBuffer = (PUCHAR)ExAllocatePool (PagedPool,
586 SectorSize);
587 if (SectorBuffer == NULL)
588 {
589 return STATUS_INSUFFICIENT_RESOURCES;
590 }
591
592 LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool (NonPagedPool,
593 0x1000);
594 if (LayoutBuffer == NULL)
595 {
596 ExFreePool (SectorBuffer);
597 return STATUS_INSUFFICIENT_RESOURCES;
598 }
599
600 RtlZeroMemory (LayoutBuffer, 0x1000);
601
602 Offset.QuadPart = 0;
603
604 do
605 {
606 KeInitializeEvent (&Event,
607 NotificationEvent,
608 FALSE);
609
610 Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
611 DeviceObject,
612 SectorBuffer,
613 SectorSize,
614 (PLARGE_INTEGER)&Offset,
615 &Event,
616 &StatusBlock);
617
618 Status = IoCallDriver (DeviceObject,
619 Irp);
620 if (Status == STATUS_PENDING)
621 {
622 KeWaitForSingleObject (&Event,
623 Executive,
624 KernelMode,
625 FALSE,
626 NULL);
627 Status = StatusBlock.Status;
628 }
629
630 if (!NT_SUCCESS(Status))
631 {
632 DPRINT1("xHalIoReadPartitonTable failed (Status = 0x%08lx)\n",
633 Status);
634 ExFreePool (SectorBuffer);
635 ExFreePool (LayoutBuffer);
636 return Status;
637 }
638
639 PartitionTable = (PPARTITION_TABLE)(SectorBuffer+PARTITION_OFFSET);
640
641 /* check the boot sector id */
642 DPRINT("Magic %x\n", PartitionTable->Magic);
643 if (PartitionTable->Magic != PARTITION_MAGIC)
644 {
645 DPRINT1("Invalid partition table magic\n");
646 ExFreePool (SectorBuffer);
647 // ExFreePool (LayoutBuffer);
648 // return STATUS_UNSUCCESSFUL;
649
650 *PartitionBuffer = LayoutBuffer;
651 return STATUS_SUCCESS;
652 }
653
654 #ifndef NDEBUG
655 for (i = 0; i < PARTITION_TBL_SIZE; i++)
656 {
657 DPRINT(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
658 i,
659 PartitionTable->Partition[i].BootFlags,
660 PartitionTable->Partition[i].PartitionType,
661 PartitionTable->Partition[i].StartingHead,
662 PartitionTable->Partition[i].StartingSector,
663 PartitionTable->Partition[i].StartingCylinder,
664 PartitionTable->Partition[i].EndingHead,
665 PartitionTable->Partition[i].EndingSector,
666 PartitionTable->Partition[i].EndingCylinder,
667 PartitionTable->Partition[i].StartingBlock,
668 PartitionTable->Partition[i].SectorCount);
669 }
670 #endif
671
672 if (ExtendedFound == FALSE);
673 {
674 LayoutBuffer->Signature = *((PULONG)(SectorBuffer + SIGNATURE_OFFSET));
675 }
676
677 ExtendedFound = FALSE;
678 for (i = 0; i < PARTITION_TBL_SIZE; i++)
679 {
680 /* handle normal partition */
681 DPRINT("Partition %u: Normal Partition\n", i);
682 Count = LayoutBuffer->PartitionCount;
683 DPRINT("Logical Partition %u\n", Count);
684
685 if (PartitionTable->Partition[i].StartingBlock)
686 {
687 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
688 (ULONGLONG)Offset.QuadPart +
689 ((ULONGLONG)PartitionTable->Partition[i].StartingBlock * (ULONGLONG)SectorSize);
690 }
691 else
692 {
693 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0;
694 }
695 LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
696 (ULONGLONG)PartitionTable->Partition[i].SectorCount * (ULONGLONG)SectorSize;
697 LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
698
699 if (IsUsablePartition(PartitionTable->Partition[i].PartitionType))
700 {
701 LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number;
702 Number++;
703 }
704 else
705 {
706 LayoutBuffer->PartitionEntry[Count].PartitionNumber = 0;
707 }
708
709 LayoutBuffer->PartitionEntry[Count].PartitionType =
710 PartitionTable->Partition[i].PartitionType;
711 LayoutBuffer->PartitionEntry[Count].BootIndicator =
712 (PartitionTable->Partition[i].BootFlags & 0x80)?TRUE:FALSE;
713 LayoutBuffer->PartitionEntry[Count].RecognizedPartition =
714 IsRecognizedPartition (PartitionTable->Partition[i].PartitionType);
715 LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE;
716
717 DPRINT(" Offset: 0x%I64x", Offset.QuadPart);
718
719 if (IsUsablePartition(PartitionTable->Partition[i].PartitionType))
720 {
721 Offset.QuadPart = (ULONGLONG)Offset.QuadPart +
722 (((ULONGLONG)PartitionTable->Partition[i].StartingBlock + (ULONGLONG)PartitionTable->Partition[i].SectorCount)* (ULONGLONG)SectorSize);
723 }
724
725 if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
726 {
727 ExtendedFound = TRUE;
728 }
729
730 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
731 Count,
732 LayoutBuffer->PartitionEntry[Count].PartitionNumber,
733 LayoutBuffer->PartitionEntry[Count].BootIndicator,
734 LayoutBuffer->PartitionEntry[Count].PartitionType,
735 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart,
736 LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart);
737
738 LayoutBuffer->PartitionCount++;
739 }
740 }
741 while (ExtendedFound == TRUE);
742
743 *PartitionBuffer = LayoutBuffer;
744 ExFreePool (SectorBuffer);
745
746 return STATUS_SUCCESS;
747 }
748
749 /* EOF */