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