Changed drive assignment.
[reactos.git] / reactos / ntoskrnl / io / xhaldrv.c
1 /* $Id: xhaldrv.c,v 1.17 2002/03/21 19:35:58 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 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 = xHalQueryDriveLayout(&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 #if 0
404 /* Assign bootable partitions */
405 DPRINT("Assigning bootable primary partitions:\n");
406 for (i = 0; i < ConfigInfo->DiskCount; i++)
407 {
408 /* search for bootable partitions */
409 for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
410 {
411 if ((LayoutArray[i]->PartitionEntry[j].BootIndicator == TRUE) &&
412 IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType))
413 {
414 swprintf(Buffer2,
415 L"\\Device\\Harddisk%d\\Partition%d",
416 i,
417 LayoutArray[i]->PartitionEntry[j].PartitionNumber);
418 RtlInitUnicodeString(&UnicodeString2,
419 Buffer2);
420
421 DPRINT(" %wZ\n", &UnicodeString2);
422
423 /* assign it */
424 HalpAssignDrive(&UnicodeString2,
425 &DriveMap,
426 AUTO_DRIVE);
427 }
428 }
429 }
430 #endif
431
432 /* Assign bootable partition on first harddisk */
433 DPRINT("Assigning bootable primary partition on first harddisk:\n");
434 if (ConfigInfo->DiskCount > 0)
435 {
436 /* search for bootable partition */
437 for (j = 0; j < LayoutArray[0]->PartitionCount; j++)
438 {
439 if ((LayoutArray[0]->PartitionEntry[j].BootIndicator == TRUE) &&
440 IsUsablePartition(LayoutArray[0]->PartitionEntry[j].PartitionType))
441 {
442 swprintf(Buffer2,
443 L"\\Device\\Harddisk0\\Partition%d",
444 LayoutArray[0]->PartitionEntry[j].PartitionNumber);
445 RtlInitUnicodeString(&UnicodeString2,
446 Buffer2);
447
448 DPRINT(" %wZ\n", &UnicodeString2);
449
450 /* assign it */
451 HalpAssignDrive(&UnicodeString2,
452 &DriveMap,
453 AUTO_DRIVE);
454 }
455 }
456 }
457
458 #if 0
459 /* Assign non-bootable primary partitions */
460 DPRINT("Assigning non-bootable primary partitions:\n");
461 for (i = 0; i < ConfigInfo->DiskCount; i++)
462 {
463 /* search for primary (non-bootable) partitions */
464 for (j = 0; j < PARTITION_TBL_SIZE; j++)
465 {
466 if ((LayoutArray[i]->PartitionEntry[j].BootIndicator == FALSE) &&
467 IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType))
468 {
469 swprintf(Buffer2,
470 L"\\Device\\Harddisk%d\\Partition%d",
471 i,
472 LayoutArray[i]->PartitionEntry[j].PartitionNumber);
473 RtlInitUnicodeString(&UnicodeString2,
474 Buffer2);
475
476 /* assign it */
477 DPRINT(" %wZ\n",
478 &UnicodeString2);
479 HalpAssignDrive(&UnicodeString2,
480 &DriveMap,
481 AUTO_DRIVE);
482 }
483 }
484 }
485 #endif
486
487 /* Assign remaining primary partitions */
488 DPRINT("Assigning remaining primary partitions:\n");
489 for (i = 0; i < ConfigInfo->DiskCount; i++)
490 {
491 /* search for primary partitions */
492 for (j = 0; j < PARTITION_TBL_SIZE; j++)
493 {
494 if (!(i == 0 &&
495 LayoutArray[i]->PartitionEntry[j].BootIndicator == TRUE) &&
496 IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType))
497 {
498 swprintf(Buffer2,
499 L"\\Device\\Harddisk%d\\Partition%d",
500 i,
501 LayoutArray[i]->PartitionEntry[j].PartitionNumber);
502 RtlInitUnicodeString(&UnicodeString2,
503 Buffer2);
504
505 /* assign it */
506 DPRINT(" %wZ\n",
507 &UnicodeString2);
508 HalpAssignDrive(&UnicodeString2,
509 &DriveMap,
510 AUTO_DRIVE);
511 }
512 }
513 }
514
515 /* Assign extended (logical) partitions */
516 DPRINT("Assigning extended (logical) partitions:\n");
517 for (i = 0; i < ConfigInfo->DiskCount; i++)
518 {
519 /* search for extended partitions */
520 for (j = PARTITION_TBL_SIZE; j < LayoutArray[i]->PartitionCount; j++)
521 {
522 if (IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType) &&
523 (LayoutArray[i]->PartitionEntry[j].PartitionNumber != 0))
524 {
525 swprintf(Buffer2,
526 L"\\Device\\Harddisk%d\\Partition%d",
527 i,
528 LayoutArray[i]->PartitionEntry[j].PartitionNumber);
529 RtlInitUnicodeString(&UnicodeString2,
530 Buffer2);
531
532 /* assign it */
533 DPRINT(" %wZ\n",
534 &UnicodeString2);
535 HalpAssignDrive(&UnicodeString2,
536 &DriveMap,
537 AUTO_DRIVE);
538 }
539 }
540 }
541
542 /* Free layout array */
543 for (i = 0; i < ConfigInfo->DiskCount; i++)
544 {
545 if (LayoutArray[i] != NULL)
546 ExFreePool(LayoutArray[i]);
547 }
548 ExFreePool(LayoutArray);
549
550 /* Assign floppy drives */
551 DPRINT("Floppy drives: %d\n", ConfigInfo->FloppyCount);
552 for (i = 0; i < ConfigInfo->FloppyCount; i++)
553 {
554 swprintf(Buffer1,
555 L"\\Device\\Floppy%d",
556 i);
557 RtlInitUnicodeString(&UnicodeString1,
558 Buffer1);
559
560 /* assign drive letters A: or B: or first free drive letter */
561 DPRINT(" %wZ\n",
562 &UnicodeString1);
563 HalpAssignDrive(&UnicodeString1,
564 &DriveMap,
565 (i < 2) ? i : AUTO_DRIVE);
566 }
567
568 /* Assign cdrom drives */
569 DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
570 for (i = 0; i < ConfigInfo->CDRomCount; i++)
571 {
572 swprintf(Buffer1,
573 L"\\Device\\Cdrom%d",
574 i);
575 RtlInitUnicodeString(&UnicodeString1,
576 Buffer1);
577
578 /* assign first free drive letter */
579 DPRINT(" %wZ\n", &UnicodeString1);
580 HalpAssignDrive(&UnicodeString1,
581 &DriveMap,
582 AUTO_DRIVE);
583 }
584
585 /* Anything else ?? */
586
587
588 ExFreePool(Buffer2);
589 ExFreePool(Buffer1);
590 }
591
592
593 NTSTATUS FASTCALL
594 xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
595 ULONG SectorSize,
596 BOOLEAN ReturnRecognizedPartitions,
597 PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
598 {
599 KEVENT Event;
600 IO_STATUS_BLOCK StatusBlock;
601 ULARGE_INTEGER PartitionOffset;
602 ULARGE_INTEGER nextPartitionOffset;
603 ULARGE_INTEGER containerOffset;
604 PUCHAR SectorBuffer;
605 PIRP Irp;
606 NTSTATUS Status;
607 PPARTITION_TABLE PartitionTable;
608 PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
609 ULONG i;
610 ULONG Count = 0;
611 ULONG Number = 1;
612 BOOLEAN ExtendedFound = FALSE;
613
614 DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n",
615 DeviceObject,
616 SectorSize,
617 ReturnRecognizedPartitions,
618 PartitionBuffer);
619
620 *PartitionBuffer = NULL;
621
622 SectorBuffer = (PUCHAR)ExAllocatePool(PagedPool,
623 SectorSize);
624 if (SectorBuffer == NULL)
625 {
626 return STATUS_INSUFFICIENT_RESOURCES;
627 }
628
629 LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool(NonPagedPool,
630 0x1000);
631 if (LayoutBuffer == NULL)
632 {
633 ExFreePool (SectorBuffer);
634 return STATUS_INSUFFICIENT_RESOURCES;
635 }
636
637 RtlZeroMemory(LayoutBuffer,
638 0x1000);
639
640 PartitionOffset.QuadPart = 0;
641 containerOffset.QuadPart = 0;
642
643 do
644 {
645 KeInitializeEvent(&Event,
646 NotificationEvent,
647 FALSE);
648
649 DPRINT("PartitionOffset: %I64u\n", PartitionOffset.QuadPart / SectorSize);
650
651 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
652 DeviceObject,
653 SectorBuffer,
654 SectorSize,
655 (PLARGE_INTEGER)&PartitionOffset,
656 &Event,
657 &StatusBlock);
658 Status = IoCallDriver(DeviceObject,
659 Irp);
660 if (Status == STATUS_PENDING)
661 {
662 KeWaitForSingleObject(&Event,
663 Executive,
664 KernelMode,
665 FALSE,
666 NULL);
667 Status = StatusBlock.Status;
668 }
669
670 if (!NT_SUCCESS(Status))
671 {
672 DbgPrint("xHalIoReadPartitonTable failed (Status = 0x%08lx)\n",
673 Status);
674 ExFreePool(SectorBuffer);
675 ExFreePool(LayoutBuffer);
676 return Status;
677 }
678
679 PartitionTable = (PPARTITION_TABLE)(SectorBuffer+PARTITION_OFFSET);
680
681 /* check the boot sector id */
682 DPRINT("Magic %x\n", PartitionTable->Magic);
683 if (PartitionTable->Magic != PARTITION_MAGIC)
684 {
685 DbgPrint("Invalid partition table magic\n");
686 ExFreePool(SectorBuffer);
687 *PartitionBuffer = LayoutBuffer;
688 return STATUS_SUCCESS;
689 }
690
691 #ifndef NDEBUG
692 for (i = 0; i < PARTITION_TBL_SIZE; i++)
693 {
694 DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
695 i,
696 PartitionTable->Partition[i].BootFlags,
697 PartitionTable->Partition[i].PartitionType,
698 PartitionTable->Partition[i].StartingHead,
699 PartitionTable->Partition[i].StartingSector & 0x3f,
700 (((PartitionTable->Partition[i].StartingSector) & 0xc0) << 2) +
701 PartitionTable->Partition[i].StartingCylinder,
702 PartitionTable->Partition[i].EndingHead,
703 PartitionTable->Partition[i].EndingSector,
704 PartitionTable->Partition[i].EndingCylinder,
705 PartitionTable->Partition[i].StartingBlock,
706 PartitionTable->Partition[i].SectorCount);
707 }
708 #endif
709
710 if (ExtendedFound == FALSE);
711 {
712 LayoutBuffer->Signature = *((PULONG)(SectorBuffer + SIGNATURE_OFFSET));
713 }
714
715 ExtendedFound = FALSE;
716
717 for (i = 0; i < PARTITION_TBL_SIZE; i++)
718 {
719 if ((ReturnRecognizedPartitions == FALSE) ||
720 ((ReturnRecognizedPartitions == TRUE) &&
721 IsRecognizedPartition(PartitionTable->Partition[i].PartitionType)))
722 {
723 /* handle normal partition */
724 DPRINT("Partition %u: Normal Partition\n", i);
725 Count = LayoutBuffer->PartitionCount;
726 DPRINT("Logical Partition %u\n", Count);
727 if (PartitionTable->Partition[i].StartingBlock == 0)
728 {
729 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0;
730 }
731 else if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
732 {
733 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
734 (ULONGLONG)PartitionOffset.QuadPart;
735 }
736 else
737 {
738 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
739 (ULONGLONG)PartitionOffset.QuadPart +
740 ((ULONGLONG)PartitionTable->Partition[i].StartingBlock * (ULONGLONG)SectorSize);
741 }
742 LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
743 (ULONGLONG)PartitionTable->Partition[i].SectorCount * (ULONGLONG)SectorSize;
744 LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
745
746 if (IsRecognizedPartition(PartitionTable->Partition[i].PartitionType))
747 {
748 LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number;
749 Number++;
750 }
751 else
752 {
753 LayoutBuffer->PartitionEntry[Count].PartitionNumber = 0;
754 }
755
756 LayoutBuffer->PartitionEntry[Count].PartitionType =
757 PartitionTable->Partition[i].PartitionType;
758 LayoutBuffer->PartitionEntry[Count].BootIndicator =
759 (PartitionTable->Partition[i].BootFlags & 0x80)?TRUE:FALSE;
760 LayoutBuffer->PartitionEntry[Count].RecognizedPartition =
761 IsRecognizedPartition (PartitionTable->Partition[i].PartitionType);
762 LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE;
763
764 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
765 Count,
766 LayoutBuffer->PartitionEntry[Count].PartitionNumber,
767 LayoutBuffer->PartitionEntry[Count].BootIndicator,
768 LayoutBuffer->PartitionEntry[Count].PartitionType,
769 LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart,
770 LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart);
771
772 LayoutBuffer->PartitionCount++;
773 }
774
775 #if 0
776 if (IsNormalPartition(PartitionTable->Partition[i].PartitionType))
777 {
778 PartitionOffset.QuadPart = (ULONGLONG)PartitionOffset.QuadPart +
779 (((ULONGLONG)PartitionTable->Partition[i].StartingBlock +
780 (ULONGLONG)PartitionTable->Partition[i].SectorCount)* (ULONGLONG)SectorSize);
781 }
782 #endif
783
784 if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
785 {
786 ExtendedFound = TRUE;
787 if ((ULONGLONG) containerOffset.QuadPart == (ULONGLONG) 0)
788 {
789 containerOffset = PartitionOffset;
790 }
791 nextPartitionOffset.QuadPart = (ULONGLONG) containerOffset.QuadPart +
792 (ULONGLONG) PartitionTable->Partition[i].StartingBlock *
793 (ULONGLONG) SectorSize;
794 }
795 }
796 PartitionOffset = nextPartitionOffset;
797 }
798 while (ExtendedFound == TRUE);
799
800 *PartitionBuffer = LayoutBuffer;
801 ExFreePool(SectorBuffer);
802
803 return STATUS_SUCCESS;
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 */