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