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