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