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