Changed drive assignment.
[reactos.git] / reactos / ntoskrnl / io / xhaldrv.c
index 9fa2eaa..f2b3410 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: xhaldrv.c,v 1.3 2000/08/21 00:14:04 ekohl Exp $
+/* $Id: xhaldrv.c,v 1.17 2002/03/21 19:35:58 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -9,17 +9,6 @@
  *                  Created 19/06/2000
  */
 
-/*
- * TODO:
- *  - Check/fix 'StartingOffset' and 'PartitionLength' in
- *    xHalIoReadPartitionTable().
- *  - Fix 'ReturnRecognizesPartitions' in xHalIoReadPartitionTable().
- *  - Read disk signature in xHalIoReadPartitionTable().
- *  - Build correct system path from nt device name or arc name.
- *    For example: \Device\Harddisk0\Partition1\reactos ==> C:\reactos
- *    Or: multi(0)disk(0)rdisk(0)partition(1)\reactos ==> C:\reactos
- */
-
 /* INCLUDES *****************************************************************/
 
 #include <ddk/ntddk.h>
 #define  PARTITION_MAGIC    0xaa55
 #define  PART_MAGIC_OFFSET  0x01fe
 #define  PARTITION_OFFSET   0x01be
+#define  SIGNATURE_OFFSET   0x01b8
 #define  PARTITION_TBL_SIZE 4
 
-/*
-#define  PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \
-    (scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2)))
-#define  PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \
-    (s) = (lba) % (scnt) + 1,  \
-    (lba) /= (scnt), \
-    (h) = (lba) % (hcnt), \
-    (lba) /= (heads), \
-    (c) = (lba) & 0xff, \
-    (s) |= ((lba) >> 2) & 0xc0)
-*/
 
 #define IsUsablePartition(P)  \
-    ((P) != PTEmpty && \
-     (P) != PTDosExtended && \
-     (P) != PTWin95ExtendedLBA)
+    ((P) == PTDOS3xPrimary  || \
+     (P) == PTOLDDOS16Bit   || \
+     (P) == PTDos5xPrimary  || \
+     (P) == PTWin95FAT32    || \
+     (P) == PTWin95FAT32LBA || \
+     (P) == PTWin95FAT16LBA)
 
 
 typedef struct _PARTITION
@@ -77,515 +59,548 @@ typedef struct _PARTITION_TABLE
 
 /* FUNCTIONS *****************************************************************/
 
-static NTSTATUS
-xHalpQueryDriveLayout (
-       IN      PUNICODE_STRING DeviceName,
-       OUT     PDRIVE_LAYOUT_INFORMATION *LayoutInfo
-       )
+NTSTATUS
+xHalQueryDriveLayout(IN PUNICODE_STRING DeviceName,
+                    OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo)
 {
-       IO_STATUS_BLOCK StatusBlock;
-       DISK_GEOMETRY DiskGeometry;
-       PDEVICE_OBJECT DeviceObject = NULL;
-       PFILE_OBJECT FileObject;
-       KEVENT Event;
-       PIRP Irp;
-       NTSTATUS Status;
-
-       DPRINT ("xHalpQueryDriveLayout %wZ %p\n",
-               DeviceName,
-               LayoutInfo);
-
-       /*
-        * Get the drives sector size
-        */
-       Status = IoGetDeviceObjectPointer (DeviceName,
-                                          FILE_READ_DATA,
-                                          &FileObject,
-                                          &DeviceObject);
-       if (!NT_SUCCESS(Status))
-       {
-               DPRINT ("Status %x\n",Status);
-               return Status;
-       }
-
-       KeInitializeEvent (&Event,
-                          NotificationEvent,
-                          FALSE);
-
-       Irp = IoBuildDeviceIoControlRequest (IOCTL_DISK_GET_DRIVE_GEOMETRY,
-                                            DeviceObject,
-                                            NULL,
-                                            0,
-                                            &DiskGeometry,
-                                            sizeof(DISK_GEOMETRY),
-                                            FALSE,
-                                            &Event,
-                                            &StatusBlock);
-       if (Irp == NULL)
-       {
-               ObDereferenceObject (FileObject);
-               return STATUS_INSUFFICIENT_RESOURCES;
-       }
-
-       Status = IoCallDriver(DeviceObject, Irp);
-       if (Status == STATUS_PENDING)
-       {
-               KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-               Status = StatusBlock.Status;
-       }
-       if (!NT_SUCCESS(Status))
-       {
-               ObDereferenceObject (FileObject);
-               return Status;
-       }
+   IO_STATUS_BLOCK StatusBlock;
+   DISK_GEOMETRY DiskGeometry;
+   PDEVICE_OBJECT DeviceObject = NULL;
+   PFILE_OBJECT FileObject;
+   KEVENT Event;
+   PIRP Irp;
+   NTSTATUS Status;
 
-       DPRINT("DiskGeometry.BytesPerSector: %d\n",
-              DiskGeometry.BytesPerSector);
+   DPRINT("xHalpQueryDriveLayout %wZ %p\n",
+         DeviceName,
+         LayoutInfo);
 
-       /* read the partition table */
-       Status = IoReadPartitionTable (DeviceObject,
-                                      DiskGeometry.BytesPerSector,
-                                      FALSE,
-                                      LayoutInfo);
+   /* Get the drives sector size */
+   Status = IoGetDeviceObjectPointer(DeviceName,
+                                    FILE_READ_DATA,
+                                    &FileObject,
+                                    &DeviceObject);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT("Status %x\n",Status);
+       return Status;
+     }
 
-       ObDereferenceObject (FileObject);
+   KeInitializeEvent(&Event,
+                    NotificationEvent,
+                    FALSE);
+
+   Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
+                                      DeviceObject,
+                                      NULL,
+                                      0,
+                                      &DiskGeometry,
+                                      sizeof(DISK_GEOMETRY),
+                                      FALSE,
+                                      &Event,
+                                      &StatusBlock);
+   if (Irp == NULL)
+     {
+       ObDereferenceObject(FileObject);
+       return STATUS_INSUFFICIENT_RESOURCES;
+     }
 
+   Status = IoCallDriver(DeviceObject,
+                        Irp);
+   if (Status == STATUS_PENDING)
+     {
+       KeWaitForSingleObject(&Event,
+                             Executive,
+                             KernelMode,
+                             FALSE,
+                             NULL);
+       Status = StatusBlock.Status;
+     }
+   if (!NT_SUCCESS(Status))
+     {
+       ObDereferenceObject(FileObject);
        return Status;
+     }
+
+   DPRINT("DiskGeometry.BytesPerSector: %d\n",
+         DiskGeometry.BytesPerSector);
+
+   /* read the partition table */
+   Status = IoReadPartitionTable(DeviceObject,
+                                DiskGeometry.BytesPerSector,
+                                FALSE,
+                                LayoutInfo);
+
+   ObDereferenceObject(FileObject);
+
+   return Status;
 }
 
 
-VOID
-FASTCALL
-xHalExamineMBR (
-       IN      PDEVICE_OBJECT  DeviceObject,
-       IN      ULONG           SectorSize,
-       IN      ULONG           MBRTypeIdentifier,
-       OUT     PVOID           * Buffer
-       )
+VOID FASTCALL
+xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject,
+              IN ULONG SectorSize,
+              IN ULONG MBRTypeIdentifier,
+              OUT PVOID *Buffer)
 {
-       KEVENT Event;
-       IO_STATUS_BLOCK StatusBlock;
-       LARGE_INTEGER Offset;
-       PUCHAR LocalBuffer;
-       PIRP Irp;
-       NTSTATUS Status;
-
-       DPRINT ("xHalExamineMBR()\n");
-       *Buffer = NULL;
-
-       if (SectorSize < 512)
-               SectorSize = 512;
-       if (SectorSize > 4096)
-               SectorSize = 4096;
-
-       LocalBuffer = (PUCHAR)ExAllocatePool (PagedPool,
-                                             SectorSize);
-       if (LocalBuffer == NULL)
-               return;
-
-       KeInitializeEvent (&Event,
-                          NotificationEvent,
-                          FALSE);
-
-       Offset.QuadPart = 0;
-
-       Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
-                                           DeviceObject,
-                                           LocalBuffer,
-                                           SectorSize,
-                                           &Offset,
-                                           &Event,
-                                           &StatusBlock);
-
-       Status = IoCallDriver (DeviceObject,
-                              Irp);
-       if (Status == STATUS_PENDING)
-       {
-               KeWaitForSingleObject (&Event,
-                                      Executive,
-                                      KernelMode,
-                                      FALSE,
-                                      NULL);
-               Status = StatusBlock.Status;
-       }
+   KEVENT Event;
+   IO_STATUS_BLOCK StatusBlock;
+   LARGE_INTEGER Offset;
+   PUCHAR LocalBuffer;
+   PIRP Irp;
+   NTSTATUS Status;
 
-       if (!NT_SUCCESS(Status))
-       {
-               DPRINT ("xHalExamineMBR failed (Status = 0x%08lx)\n",
-                       Status);
-               ExFreePool (LocalBuffer);
-               return;
-       }
-
-       if (LocalBuffer[0x1FE] != 0x55 || LocalBuffer[0x1FF] != 0xAA)
-       {
-               DPRINT ("xHalExamineMBR: invalid MBR signature\n");
-               ExFreePool (LocalBuffer);
-               return;
-       }
-
-       if (LocalBuffer[0x1C2] != MBRTypeIdentifier)
-       {
-               DPRINT ("xHalExamineMBR: invalid MBRTypeIdentifier\n");
-               ExFreePool (LocalBuffer);
-               return;
-       }
-
-       *Buffer = (PVOID)LocalBuffer;
+   DPRINT("xHalExamineMBR()\n");
+   *Buffer = NULL;
+
+   if (SectorSize < 512)
+     SectorSize = 512;
+   if (SectorSize > 4096)
+     SectorSize = 4096;
+
+   LocalBuffer = (PUCHAR)ExAllocatePool(PagedPool,
+                                       SectorSize);
+   if (LocalBuffer == NULL)
+     return;
+
+   KeInitializeEvent(&Event,
+                    NotificationEvent,
+                    FALSE);
+
+   Offset.QuadPart = 0;
+
+   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+                                     DeviceObject,
+                                     LocalBuffer,
+                                     SectorSize,
+                                     &Offset,
+                                     &Event,
+                                     &StatusBlock);
+
+   Status = IoCallDriver(DeviceObject,
+                        Irp);
+   if (Status == STATUS_PENDING)
+     {
+       KeWaitForSingleObject(&Event,
+                             Executive,
+                             KernelMode,
+                             FALSE,
+                             NULL);
+       Status = StatusBlock.Status;
+     }
+
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT("xHalExamineMBR failed (Status = 0x%08lx)\n",
+              Status);
+       ExFreePool(LocalBuffer);
+       return;
+     }
+
+   if (LocalBuffer[0x1FE] != 0x55 || LocalBuffer[0x1FF] != 0xAA)
+     {
+       DPRINT("xHalExamineMBR: invalid MBR signature\n");
+       ExFreePool(LocalBuffer);
+       return;
+     }
+
+   if (LocalBuffer[0x1C2] != MBRTypeIdentifier)
+     {
+       DPRINT("xHalExamineMBR: invalid MBRTypeIdentifier\n");
+       ExFreePool(LocalBuffer);
+       return;
+     }
+
+   *Buffer = (PVOID)LocalBuffer;
 }
 
+
 static VOID
-HalpAssignDrive (
-       PUNICODE_STRING PartitionName,
-       PULONG DriveMap,
-       ULONG DriveNumber
-       )
+HalpAssignDrive(IN PUNICODE_STRING PartitionName,
+               IN OUT PULONG DriveMap,
+               IN ULONG DriveNumber)
 {
-       WCHAR DriveNameBuffer[8];
-       UNICODE_STRING DriveName;
-       ULONG i;
-
-       DPRINT("HalpAssignDrive()\n");
-
-       if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 24))
-       {
-               /* force assignment */
-               if ((*DriveMap & (1 << DriveNumber)) != 0)
-               {
-                       DbgPrint("Drive letter already used!\n");
-                       return;
-               }
-       }
-       else
-       {
-               /* automatic assignment */
-               DriveNumber = AUTO_DRIVE;
-
-               for (i = 2; i < 24; i++)
-               {
-                       if ((*DriveMap & (1 << i)) == 0)
-                       {
-                               DriveNumber = i;
-                               break;
-                       }
-               }
-
-               if (DriveNumber == AUTO_DRIVE)
-               {
-                       DbgPrint("No drive letter available!\n");
-                       return;
-               }
-       }
-
-       DPRINT("DriveNumber %d\n", DriveNumber);
-
-       /* set bit in drive map */
-       *DriveMap = *DriveMap | (1 << DriveNumber);
-
-       /* build drive name */
-       swprintf (DriveNameBuffer,
-                 L"\\??\\%C:",
-                 'A' + DriveNumber);
-       RtlInitUnicodeString (&DriveName,
-                             DriveNameBuffer);
-
-       DPRINT1("  %wZ ==> %wZ\n",
-               &DriveName,
-               PartitionName);
-
-       /* create symbolic link */
-       IoCreateSymbolicLink (&DriveName,
-                             PartitionName);
+   WCHAR DriveNameBuffer[8];
+   UNICODE_STRING DriveName;
+   ULONG i;
+
+   DPRINT("HalpAssignDrive()\n");
+
+   if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 24))
+     {
+       /* force assignment */
+       if ((*DriveMap & (1 << DriveNumber)) != 0)
+         {
+            DbgPrint("Drive letter already used!\n");
+            return;
+         }
+     }
+   else
+     {
+       /* automatic assignment */
+       DriveNumber = AUTO_DRIVE;
+
+       for (i = 2; i < 24; i++)
+         {
+            if ((*DriveMap & (1 << i)) == 0)
+              {
+                 DriveNumber = i;
+                 break;
+              }
+         }
+
+       if (DriveNumber == AUTO_DRIVE)
+         {
+            DbgPrint("No drive letter available!\n");
+            return;
+         }
+     }
+
+   DPRINT("DriveNumber %d\n", DriveNumber);
+
+   /* set bit in drive map */
+   *DriveMap = *DriveMap | (1 << DriveNumber);
+
+   /* build drive name */
+   swprintf(DriveNameBuffer,
+           L"\\??\\%C:",
+           'A' + DriveNumber);
+   RtlInitUnicodeString(&DriveName,
+                       DriveNameBuffer);
+
+   DPRINT("  %wZ ==> %wZ\n",
+         &DriveName,
+         PartitionName);
+
+   /* create symbolic link */
+   IoCreateSymbolicLink(&DriveName,
+                       PartitionName);
 }
 
 
-VOID
-FASTCALL
-xHalIoAssignDriveLetters (
-       IN      PLOADER_PARAMETER_BLOCK LoaderBlock,
-       IN      PSTRING                 NtDeviceName,
-       OUT     PUCHAR                  NtSystemPath,
-       OUT     PSTRING                 NtSystemPathString
-       )
+VOID FASTCALL
+xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                        IN PSTRING NtDeviceName,
+                        OUT PUCHAR NtSystemPath,
+                        OUT PSTRING NtSystemPathString)
 {
-       PDRIVE_LAYOUT_INFORMATION LayoutInfo;   // ebp-4
-       PCONFIGURATION_INFORMATION ConfigInfo;
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       IO_STATUS_BLOCK StatusBlock;
-       UNICODE_STRING UnicodeString1;
-       UNICODE_STRING UnicodeString2;
-       HANDLE FileHandle;
-       PWSTR Buffer1;
-       PWSTR Buffer2;
-       ULONG i;
-       NTSTATUS Status;
-       ULONG DriveMap = 0;
-       ULONG j;
-
-       DPRINT("xHalIoAssignDriveLetters()\n");
-
-       ConfigInfo = IoGetConfigurationInformation ();
-
-       Buffer1 = (PWSTR)ExAllocatePool (PagedPool,
-                                        64 * sizeof(WCHAR));
-       Buffer2 = (PWSTR)ExAllocatePool (PagedPool,
-                                        32 * sizeof(WCHAR));
-
-       /* Create PhysicalDrive links */
-       DPRINT("Physical disk drives: %d\n", ConfigInfo->DiskCount);
-       for (i = 0; i < ConfigInfo->DiskCount; i++)
-       {
-               swprintf (Buffer1,
-                         L"\\Device\\Harddisk%d\\Partition0",
-                         i);
-               RtlInitUnicodeString (&UnicodeString1,
-                                     Buffer1);
-
-               InitializeObjectAttributes (&ObjectAttributes,
-                                           &UnicodeString1,
-                                           0,
-                                           NULL,
-                                           NULL);
-
-               Status = NtOpenFile (&FileHandle,
-                                    0x10001,
-                                    &ObjectAttributes,
-                                    &StatusBlock,
-                                    1,
-                                    FILE_SYNCHRONOUS_IO_NONALERT);
-               if (NT_SUCCESS(Status))
-               {
-                       NtClose (FileHandle);
-
-                       swprintf (Buffer2,
-                                 L"\\??\\PhysicalDrive%d",
-                                 i);
-                       RtlInitUnicodeString (&UnicodeString2,
-                                             Buffer2);
-
-                       DPRINT1("Creating link: %S ==> %S\n",
-                               Buffer2,
-                               Buffer1);
-
-                       IoCreateSymbolicLink (&UnicodeString2,
-                                             &UnicodeString1);
-               }
-       }
-
-       /* Assign pre-assigned (registry) partitions */
-
-       /* Assign bootable partitions */
-       DPRINT("Assigning bootable partitions:\n");
-       for (i = 0; i < ConfigInfo->DiskCount; i++)
-       {
-               swprintf (Buffer1,
-                         L"\\Device\\Harddisk%d\\Partition0",
-                         i);
-               RtlInitUnicodeString (&UnicodeString1,
-                                     Buffer1);
-
-               Status = xHalpQueryDriveLayout (&UnicodeString1,
-                                               &LayoutInfo);
-               if (!NT_SUCCESS(Status))
-               {
-                       DPRINT1("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
-                               Status);
-                       continue;
-               }
-
-               DPRINT("Logical partitions: %d\n",
-                      LayoutInfo->PartitionCount);
-
-               /* search for bootable partitions */
-               for (j = 0; j < LayoutInfo->PartitionCount; j++)
-               {
-                       DPRINT("  %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
-                              j,
-                              LayoutInfo->PartitionEntry[j].PartitionNumber,
-                              LayoutInfo->PartitionEntry[j].BootIndicator,
-                              LayoutInfo->PartitionEntry[j].PartitionType,
-                              LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
-                              LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
-
-                       if (LayoutInfo->PartitionEntry[j].BootIndicator)
-                       {
-                               swprintf (Buffer2,
-                                         L"\\Device\\Harddisk%d\\Partition%d",
-                                         i,
-                                         LayoutInfo->PartitionEntry[j].PartitionNumber);
-                               RtlInitUnicodeString (&UnicodeString2,
-                                                     Buffer2);
-
-                               DPRINT("  %wZ\n", &UnicodeString2);
-
-                               /* assign it */
-                               HalpAssignDrive (&UnicodeString2,
-                                                &DriveMap,
-                                                AUTO_DRIVE);
-                       }
-               }
-
-               ExFreePool (LayoutInfo);
-       }
-
-       /* Assign remaining primary partitions */
-       DPRINT("Assigning primary partitions:\n");
-       for (i = 0; i < ConfigInfo->DiskCount; i++)
-       {
-               swprintf (Buffer1,
-                         L"\\Device\\Harddisk%d\\Partition0",
-                         i);
-               RtlInitUnicodeString (&UnicodeString1,
-                                     Buffer1);
-
-               Status = xHalpQueryDriveLayout (&UnicodeString1,
-                                               &LayoutInfo);
-               if (!NT_SUCCESS(Status))
-               {
-                       DPRINT1("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
-                               Status);
-                       continue;
-               }
-
-               DPRINT("Logical partitions: %d\n",
-                      LayoutInfo->PartitionCount);
-
-               /* search for primary (non-bootable) partitions */
-               for (j = 0; j < PARTITION_TBL_SIZE; j++)
-               {
-                       DPRINT("  %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
-                              j,
-                              LayoutInfo->PartitionEntry[j].PartitionNumber,
-                              LayoutInfo->PartitionEntry[j].BootIndicator,
-                              LayoutInfo->PartitionEntry[j].PartitionType,
-                              LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
-                              LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
-
-                       if ((LayoutInfo->PartitionEntry[j].BootIndicator == FALSE) &&
-                           IsUsablePartition(LayoutInfo->PartitionEntry[j].PartitionType))
-                       {
-                               swprintf (Buffer2,
-                                         L"\\Device\\Harddisk%d\\Partition%d",
-                                         i,
-                                         LayoutInfo->PartitionEntry[j].PartitionNumber);
-                               RtlInitUnicodeString (&UnicodeString2,
-                                                     Buffer2);
-
-                               /* assign it */
-                               DPRINT("  %wZ\n", &UnicodeString2);
-                               HalpAssignDrive (&UnicodeString2, &DriveMap, AUTO_DRIVE);
-                       }
-               }
-
-               ExFreePool (LayoutInfo);
-       }
-
-       /* Assign extended (logical) partitions */
-       DPRINT("Assigning extended (logical) partitions:\n");
-       for (i = 0; i < ConfigInfo->DiskCount; i++)
-       {
-               swprintf (Buffer1,
-                         L"\\Device\\Harddisk%d\\Partition0",
-                         i);
-               RtlInitUnicodeString (&UnicodeString1,
-                                     Buffer1);
-
-               Status = xHalpQueryDriveLayout (&UnicodeString1,
-                                               &LayoutInfo);
-               if (!NT_SUCCESS(Status))
-               {
-                       DPRINT1("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
-                               Status);
-                       continue;
-               }
-
-               DPRINT("Logical partitions: %d\n",
-                      LayoutInfo->PartitionCount);
-
-               /* search for extended partitions */
-               for (j = PARTITION_TBL_SIZE; j < LayoutInfo->PartitionCount; j++)
-               {
-                       DPRINT("  %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
-                              j,
-                              LayoutInfo->PartitionEntry[j].PartitionNumber,
-                              LayoutInfo->PartitionEntry[j].BootIndicator,
-                              LayoutInfo->PartitionEntry[j].PartitionType,
-                              LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
-                              LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
-
-                       if (IsUsablePartition(LayoutInfo->PartitionEntry[j].PartitionType) &&
-                           (LayoutInfo->PartitionEntry[j].PartitionNumber != 0))
-                       {
-                               swprintf (Buffer2,
-                                         L"\\Device\\Harddisk%d\\Partition%d",
-                                         i,
-                                         LayoutInfo->PartitionEntry[j].PartitionNumber);
-                               RtlInitUnicodeString (&UnicodeString2,
-                                                     Buffer2);
-
-                               /* assign it */
-                               DPRINT("  %wZ\n", &UnicodeString2);
-                               HalpAssignDrive (&UnicodeString2, &DriveMap, AUTO_DRIVE);
-                       }
-               }
-
-               ExFreePool (LayoutInfo);
-       }
-
-       /* Assign floppy drives */
-       DPRINT("Floppy drives: %d\n", ConfigInfo->FloppyCount);
-       for (i = 0; i < ConfigInfo->FloppyCount; i++)
-       {
-               swprintf (Buffer1,
-                         L"\\Device\\Floppy%d",
-                         i);
-               RtlInitUnicodeString (&UnicodeString1,
-                                     Buffer1);
-
-               /* assign drive letters A: or B: or first free drive letter */
-               DPRINT("  %wZ\n", &UnicodeString1);
-               HalpAssignDrive (&UnicodeString1,
-                                &DriveMap,
-                                (i < 2) ? i : AUTO_DRIVE);
-       }
-
-       /* Assign cdrom drives */
-       DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
-       for (i = 0; i < ConfigInfo->CDRomCount; i++)
-       {
-               swprintf (Buffer1,
-                         L"\\Device\\Cdrom%d",
-                         i);
-               RtlInitUnicodeString (&UnicodeString1,
-                                     Buffer1);
-
-               /* assign first free drive letter */
-               DPRINT("  %wZ\n", &UnicodeString1);
-               HalpAssignDrive (&UnicodeString1,
-                                &DriveMap,
-                                AUTO_DRIVE);
-       }
-
-       /* Anything else ?? */
-
-
-       ExFreePool (Buffer2);
-       ExFreePool (Buffer1);
+   PDRIVE_LAYOUT_INFORMATION *LayoutArray;
+   PCONFIGURATION_INFORMATION ConfigInfo;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   IO_STATUS_BLOCK StatusBlock;
+   UNICODE_STRING UnicodeString1;
+   UNICODE_STRING UnicodeString2;
+   HANDLE FileHandle;
+   PWSTR Buffer1;
+   PWSTR Buffer2;
+   ULONG i;
+   NTSTATUS Status;
+   ULONG DriveMap = 0;
+   ULONG j;
+
+   DPRINT("xHalIoAssignDriveLetters()\n");
+
+   ConfigInfo = IoGetConfigurationInformation ();
+
+   Buffer1 = (PWSTR)ExAllocatePool(PagedPool,
+                                  64 * sizeof(WCHAR));
+   Buffer2 = (PWSTR)ExAllocatePool(PagedPool,
+                                  32 * sizeof(WCHAR));
+
+   /* Create PhysicalDrive links */
+   DPRINT("Physical disk drives: %d\n", ConfigInfo->DiskCount);
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       swprintf(Buffer1,
+                L"\\Device\\Harddisk%d\\Partition0",
+                i);
+       RtlInitUnicodeString(&UnicodeString1,
+                            Buffer1);
+
+       InitializeObjectAttributes(&ObjectAttributes,
+                                  &UnicodeString1,
+                                  0,
+                                  NULL,
+                                  NULL);
+
+       Status = NtOpenFile(&FileHandle,
+                           0x10001,
+                           &ObjectAttributes,
+                           &StatusBlock,
+                           1,
+                           FILE_SYNCHRONOUS_IO_NONALERT);
+       if (NT_SUCCESS(Status))
+         {
+            NtClose(FileHandle);
+
+            swprintf(Buffer2,
+                     L"\\??\\PhysicalDrive%d",
+                     i);
+            RtlInitUnicodeString(&UnicodeString2,
+                                 Buffer2);
+
+            DPRINT("Creating link: %S ==> %S\n",
+                   Buffer2,
+                   Buffer1);
+
+            IoCreateSymbolicLink(&UnicodeString2,
+                                 &UnicodeString1);
+         }
+     }
+
+   /* Initialize layout array */
+   LayoutArray = ExAllocatePool(NonPagedPool,
+                               ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
+   RtlZeroMemory(LayoutArray,
+                ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       swprintf(Buffer1,
+                L"\\Device\\Harddisk%d\\Partition0",
+                i);
+       RtlInitUnicodeString(&UnicodeString1,
+                            Buffer1);
+
+       Status = xHalQueryDriveLayout(&UnicodeString1,
+                                     &LayoutArray[i]);
+       if (!NT_SUCCESS(Status))
+         {
+            DbgPrint("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
+                     Status);
+            LayoutArray[i] = NULL;
+            continue;
+         }
+     }
+
+#ifndef NDEBUG
+   /* Dump layout array */
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       DPRINT("Harddisk %d:\n",
+              i);
+
+       if (LayoutArray[i] == NULL)
+         continue;
+
+       DPRINT("Logical partitions: %d\n",
+              LayoutArray[i]->PartitionCount);
+
+       for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
+         {
+            DPRINT("  %d: nr:%x boot:%x type:%x startblock:%I64u count:%I64u\n",
+                   j,
+                   LayoutArray[i]->PartitionEntry[j].PartitionNumber,
+                   LayoutArray[i]->PartitionEntry[j].BootIndicator,
+                   LayoutArray[i]->PartitionEntry[j].PartitionType,
+                   LayoutArray[i]->PartitionEntry[j].StartingOffset.QuadPart,
+                   LayoutArray[i]->PartitionEntry[j].PartitionLength.QuadPart);
+         }
+     }
+#endif
+
+   /* Assign pre-assigned (registry) partitions */
+
+#if 0
+   /* Assign bootable partitions */
+   DPRINT("Assigning bootable primary partitions:\n");
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       /* search for bootable partitions */
+       for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
+         {
+            if ((LayoutArray[i]->PartitionEntry[j].BootIndicator == TRUE) &&
+                IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType))
+              {
+                 swprintf(Buffer2,
+                          L"\\Device\\Harddisk%d\\Partition%d",
+                          i,
+                          LayoutArray[i]->PartitionEntry[j].PartitionNumber);
+                 RtlInitUnicodeString(&UnicodeString2,
+                                      Buffer2);
+
+                 DPRINT("  %wZ\n", &UnicodeString2);
+
+                 /* assign it */
+                 HalpAssignDrive(&UnicodeString2,
+                                 &DriveMap,
+                                 AUTO_DRIVE);
+              }
+         }
+     }
+#endif
+
+   /* Assign bootable partition on first harddisk */
+   DPRINT("Assigning bootable primary partition on first harddisk:\n");
+   if (ConfigInfo->DiskCount > 0)
+     {
+       /* search for bootable partition */
+       for (j = 0; j < LayoutArray[0]->PartitionCount; j++)
+         {
+            if ((LayoutArray[0]->PartitionEntry[j].BootIndicator == TRUE) &&
+                IsUsablePartition(LayoutArray[0]->PartitionEntry[j].PartitionType))
+              {
+                 swprintf(Buffer2,
+                          L"\\Device\\Harddisk0\\Partition%d",
+                          LayoutArray[0]->PartitionEntry[j].PartitionNumber);
+                 RtlInitUnicodeString(&UnicodeString2,
+                                      Buffer2);
+
+                 DPRINT("  %wZ\n", &UnicodeString2);
+
+                 /* assign it */
+                 HalpAssignDrive(&UnicodeString2,
+                                 &DriveMap,
+                                 AUTO_DRIVE);
+              }
+         }
+     }
+
+#if 0
+   /* Assign non-bootable primary partitions */
+   DPRINT("Assigning non-bootable primary partitions:\n");
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       /* search for primary (non-bootable) partitions */
+       for (j = 0; j < PARTITION_TBL_SIZE; j++)
+         {
+            if ((LayoutArray[i]->PartitionEntry[j].BootIndicator == FALSE) &&
+                IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType))
+              {
+                 swprintf(Buffer2,
+                          L"\\Device\\Harddisk%d\\Partition%d",
+                          i,
+                          LayoutArray[i]->PartitionEntry[j].PartitionNumber);
+                 RtlInitUnicodeString(&UnicodeString2,
+                                      Buffer2);
+
+                 /* assign it */
+                 DPRINT("  %wZ\n",
+                        &UnicodeString2);
+                 HalpAssignDrive(&UnicodeString2,
+                                 &DriveMap,
+                                 AUTO_DRIVE);
+              }
+         }
+     }
+#endif
+
+   /* Assign remaining  primary partitions */
+   DPRINT("Assigning remaining primary partitions:\n");
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       /* search for primary partitions */
+       for (j = 0; j < PARTITION_TBL_SIZE; j++)
+         {
+            if (!(i == 0 &&
+                  LayoutArray[i]->PartitionEntry[j].BootIndicator == TRUE) &&
+                IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType))
+              {
+                 swprintf(Buffer2,
+                          L"\\Device\\Harddisk%d\\Partition%d",
+                          i,
+                          LayoutArray[i]->PartitionEntry[j].PartitionNumber);
+                 RtlInitUnicodeString(&UnicodeString2,
+                                      Buffer2);
+
+                 /* assign it */
+                 DPRINT("  %wZ\n",
+                        &UnicodeString2);
+                 HalpAssignDrive(&UnicodeString2,
+                                 &DriveMap,
+                                 AUTO_DRIVE);
+              }
+         }
+     }
+
+   /* Assign extended (logical) partitions */
+   DPRINT("Assigning extended (logical) partitions:\n");
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       /* search for extended partitions */
+       for (j = PARTITION_TBL_SIZE; j < LayoutArray[i]->PartitionCount; j++)
+         {
+            if (IsUsablePartition(LayoutArray[i]->PartitionEntry[j].PartitionType) &&
+                (LayoutArray[i]->PartitionEntry[j].PartitionNumber != 0))
+              {
+                 swprintf(Buffer2,
+                          L"\\Device\\Harddisk%d\\Partition%d",
+                          i,
+                          LayoutArray[i]->PartitionEntry[j].PartitionNumber);
+                 RtlInitUnicodeString(&UnicodeString2,
+                                      Buffer2);
+
+                 /* assign it */
+                 DPRINT("  %wZ\n",
+                        &UnicodeString2);
+                 HalpAssignDrive(&UnicodeString2,
+                                 &DriveMap,
+                                 AUTO_DRIVE);
+              }
+         }
+     }
+
+   /* Free layout array */
+   for (i = 0; i < ConfigInfo->DiskCount; i++)
+     {
+       if (LayoutArray[i] != NULL)
+         ExFreePool(LayoutArray[i]);
+     }
+   ExFreePool(LayoutArray);
+
+   /* Assign floppy drives */
+   DPRINT("Floppy drives: %d\n", ConfigInfo->FloppyCount);
+   for (i = 0; i < ConfigInfo->FloppyCount; i++)
+     {
+       swprintf(Buffer1,
+                L"\\Device\\Floppy%d",
+                i);
+       RtlInitUnicodeString(&UnicodeString1,
+                            Buffer1);
+
+       /* assign drive letters A: or B: or first free drive letter */
+       DPRINT("  %wZ\n",
+              &UnicodeString1);
+       HalpAssignDrive(&UnicodeString1,
+                       &DriveMap,
+                       (i < 2) ? i : AUTO_DRIVE);
+     }
+
+   /* Assign cdrom drives */
+   DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
+   for (i = 0; i < ConfigInfo->CDRomCount; i++)
+     {
+       swprintf(Buffer1,
+                L"\\Device\\Cdrom%d",
+                i);
+       RtlInitUnicodeString(&UnicodeString1,
+                            Buffer1);
+
+       /* assign first free drive letter */
+       DPRINT("  %wZ\n", &UnicodeString1);
+       HalpAssignDrive(&UnicodeString1,
+                       &DriveMap,
+                       AUTO_DRIVE);
+     }
+
+   /* Anything else ?? */
+
+
+   ExFreePool(Buffer2);
+   ExFreePool(Buffer1);
 }
 
 
-NTSTATUS
-FASTCALL
-xHalIoReadPartitionTable (
-       PDEVICE_OBJECT                  DeviceObject,
-       ULONG                           SectorSize,
-       BOOLEAN                         ReturnRecognizedPartitions,
-       PDRIVE_LAYOUT_INFORMATION       * PartitionBuffer
-       )
+NTSTATUS FASTCALL
+xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
+                        ULONG SectorSize,
+                        BOOLEAN ReturnRecognizedPartitions,
+                        PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
 {
    KEVENT Event;
    IO_STATUS_BLOCK StatusBlock;
-   LARGE_INTEGER Offset;
+   ULARGE_INTEGER PartitionOffset;
+   ULARGE_INTEGER  nextPartitionOffset;
+   ULARGE_INTEGER  containerOffset;
    PUCHAR SectorBuffer;
    PIRP Irp;
    NTSTATUS Status;
@@ -604,57 +619,60 @@ xHalIoReadPartitionTable (
 
    *PartitionBuffer = NULL;
 
-   SectorBuffer = (PUCHAR)ExAllocatePool (PagedPool,
-                                          SectorSize);
+   SectorBuffer = (PUCHAR)ExAllocatePool(PagedPool,
+                                        SectorSize);
    if (SectorBuffer == NULL)
      {
        return STATUS_INSUFFICIENT_RESOURCES;
      }
 
-   LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool (PagedPool,
-                                                             0x1000);
+   LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool(NonPagedPool,
+                                                           0x1000);
    if (LayoutBuffer == NULL)
      {
        ExFreePool (SectorBuffer);
        return STATUS_INSUFFICIENT_RESOURCES;
      }
 
-   RtlZeroMemory (LayoutBuffer, 0x1000);
+   RtlZeroMemory(LayoutBuffer,
+                0x1000);
 
-   Offset.QuadPart = 0;
+   PartitionOffset.QuadPart = 0;
+   containerOffset.QuadPart = 0;
 
    do
      {
-       KeInitializeEvent (&Event,
-                          NotificationEvent,
-                          FALSE);
-
-       Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
-                                           DeviceObject,
-                                           SectorBuffer,
-                                           SectorSize,
-                                           &Offset,
-                                           &Event,
-                                           &StatusBlock);
-
-       Status = IoCallDriver (DeviceObject,
-                              Irp);
+       KeInitializeEvent(&Event,
+                         NotificationEvent,
+                         FALSE);
+
+       DPRINT("PartitionOffset: %I64u\n", PartitionOffset.QuadPart / SectorSize);
+
+       Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+                                          DeviceObject,
+                                          SectorBuffer,
+                                          SectorSize,
+                                          (PLARGE_INTEGER)&PartitionOffset,
+                                          &Event,
+                                          &StatusBlock);
+       Status = IoCallDriver(DeviceObject,
+                             Irp);
        if (Status == STATUS_PENDING)
-       {
-               KeWaitForSingleObject (&Event,
-                                      Executive,
-                                      KernelMode,
-                                      FALSE,
-                                      NULL);
-               Status = StatusBlock.Status;
-       }
+         {
+            KeWaitForSingleObject(&Event,
+                                  Executive,
+                                  KernelMode,
+                                  FALSE,
+                                  NULL);
+            Status = StatusBlock.Status;
+         }
 
        if (!NT_SUCCESS(Status))
          {
-            DPRINT("xHalIoReadPartitonTable failed (Status = 0x%08lx)\n",
+            DbgPrint("xHalIoReadPartitonTable failed (Status = 0x%08lx)\n",
                    Status);
-            ExFreePool (SectorBuffer);
-            ExFreePool (LayoutBuffer);
+            ExFreePool(SectorBuffer);
+            ExFreePool(LayoutBuffer);
             return Status;
          }
 
@@ -664,84 +682,145 @@ xHalIoReadPartitionTable (
        DPRINT("Magic %x\n", PartitionTable->Magic);
        if (PartitionTable->Magic != PARTITION_MAGIC)
          {
-            DPRINT("Invalid partition table magic\n");
-            ExFreePool (SectorBuffer);
-            ExFreePool (LayoutBuffer);
-            return STATUS_UNSUCCESSFUL;
+            DbgPrint("Invalid partition table magic\n");
+            ExFreePool(SectorBuffer);
+            *PartitionBuffer = LayoutBuffer;
+            return STATUS_SUCCESS;
          }
 
 #ifndef NDEBUG
        for (i = 0; i < PARTITION_TBL_SIZE; i++)
-       {
-               DPRINT("  %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n", 
-                      i,
-                      PartitionTable->Partition[i].BootFlags,
-                      PartitionTable->Partition[i].PartitionType,
-                      PartitionTable->Partition[i].StartingHead,
-                      PartitionTable->Partition[i].StartingSector,
-                      PartitionTable->Partition[i].StartingCylinder,
-                      PartitionTable->Partition[i].EndingHead,
-                      PartitionTable->Partition[i].EndingSector,
-                      PartitionTable->Partition[i].EndingCylinder,
-                      PartitionTable->Partition[i].StartingBlock,
-                      PartitionTable->Partition[i].SectorCount);
-       }
+         {
+            DPRINT1("  %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n", 
+                   i,
+                   PartitionTable->Partition[i].BootFlags,
+                   PartitionTable->Partition[i].PartitionType,
+                   PartitionTable->Partition[i].StartingHead,
+                   PartitionTable->Partition[i].StartingSector & 0x3f,
+                   (((PartitionTable->Partition[i].StartingSector) & 0xc0) << 2) +
+          PartitionTable->Partition[i].StartingCylinder,
+                   PartitionTable->Partition[i].EndingHead,
+                   PartitionTable->Partition[i].EndingSector,
+                   PartitionTable->Partition[i].EndingCylinder,
+                   PartitionTable->Partition[i].StartingBlock,
+                   PartitionTable->Partition[i].SectorCount);
+         }
 #endif
 
-       /* FIXME: Set the correct value */
        if (ExtendedFound == FALSE);
          {
-            LayoutBuffer->Signature = 0xdeadbeef;
+            LayoutBuffer->Signature = *((PULONG)(SectorBuffer + SIGNATURE_OFFSET));
          }
 
        ExtendedFound = FALSE;
+
        for (i = 0; i < PARTITION_TBL_SIZE; i++)
          {
-            /* handle normal partition */
-            DPRINT("Partition %u: Normal Partition\n", i);
-            Count = LayoutBuffer->PartitionCount;
-            DPRINT("Logical Partition %u\n", Count);
-
-            LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
-               PartitionTable->Partition[i].StartingBlock * SectorSize;
-            LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
-               PartitionTable->Partition[i].SectorCount * SectorSize;
-            LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
-
-            if (IsUsablePartition(PartitionTable->Partition[i].PartitionType))
+            if ((ReturnRecognizedPartitions == FALSE) ||
+                ((ReturnRecognizedPartitions == TRUE) &&
+                 IsRecognizedPartition(PartitionTable->Partition[i].PartitionType)))
               {
-                 LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number;
-                 Number++;
+                 /* handle normal partition */
+                 DPRINT("Partition %u: Normal Partition\n", i);
+                 Count = LayoutBuffer->PartitionCount;
+                 DPRINT("Logical Partition %u\n", Count);
+                 if (PartitionTable->Partition[i].StartingBlock == 0)
+                   {
+                      LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0;
+                   }
+                 else if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
+                   {
+                      LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
+                       (ULONGLONG)PartitionOffset.QuadPart;
+                   }
+                 else
+                   {
+                      LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
+                       (ULONGLONG)PartitionOffset.QuadPart +
+                       ((ULONGLONG)PartitionTable->Partition[i].StartingBlock * (ULONGLONG)SectorSize);
+                   }
+                 LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
+                       (ULONGLONG)PartitionTable->Partition[i].SectorCount * (ULONGLONG)SectorSize;
+                 LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
+
+                 if (IsRecognizedPartition(PartitionTable->Partition[i].PartitionType))
+                   {
+                      LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number;
+                      Number++;
+                   }
+                 else
+                   {
+                      LayoutBuffer->PartitionEntry[Count].PartitionNumber = 0;
+                   }
+
+                 LayoutBuffer->PartitionEntry[Count].PartitionType =
+                       PartitionTable->Partition[i].PartitionType;
+                 LayoutBuffer->PartitionEntry[Count].BootIndicator =
+                       (PartitionTable->Partition[i].BootFlags & 0x80)?TRUE:FALSE;
+                 LayoutBuffer->PartitionEntry[Count].RecognizedPartition =
+                       IsRecognizedPartition (PartitionTable->Partition[i].PartitionType);
+                 LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE;
+
+                 DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
+                        Count,
+                        LayoutBuffer->PartitionEntry[Count].PartitionNumber,
+                        LayoutBuffer->PartitionEntry[Count].BootIndicator,
+                        LayoutBuffer->PartitionEntry[Count].PartitionType,
+                        LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart,
+                        LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart);
+
+                 LayoutBuffer->PartitionCount++;
               }
-            else
+
+#if 0
+            if (IsNormalPartition(PartitionTable->Partition[i].PartitionType))
               {
-                 LayoutBuffer->PartitionEntry[Count].PartitionNumber = 0;
+                 PartitionOffset.QuadPart = (ULONGLONG)PartitionOffset.QuadPart +
+                    (((ULONGLONG)PartitionTable->Partition[i].StartingBlock +
+                      (ULONGLONG)PartitionTable->Partition[i].SectorCount)* (ULONGLONG)SectorSize);
               }
-
-            LayoutBuffer->PartitionEntry[Count].PartitionType =
-               PartitionTable->Partition[i].PartitionType;
-            LayoutBuffer->PartitionEntry[Count].BootIndicator =
-               (PartitionTable->Partition[i].BootFlags & 0x80)?TRUE:FALSE;
-            LayoutBuffer->PartitionEntry[Count].RecognizedPartition =
-               IsRecognizedPartition (PartitionTable->Partition[i].PartitionType);
-            LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE;
+#endif
 
             if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
               {
-                 Offset.QuadPart +=
-                    (PartitionTable->Partition[i].StartingBlock * SectorSize);
                  ExtendedFound = TRUE;
+                  if ((ULONGLONG) containerOffset.QuadPart == (ULONGLONG) 0)
+                  {
+                    containerOffset = PartitionOffset;
+                  }
+                 nextPartitionOffset.QuadPart = (ULONGLONG) containerOffset.QuadPart +
+                    (ULONGLONG) PartitionTable->Partition[i].StartingBlock * 
+                     (ULONGLONG) SectorSize;
               }
-
-            LayoutBuffer->PartitionCount++;
          }
+         PartitionOffset = nextPartitionOffset;
      }
    while (ExtendedFound == TRUE);
 
    *PartitionBuffer = LayoutBuffer;
-   ExFreePool (SectorBuffer);
+   ExFreePool(SectorBuffer);
 
    return STATUS_SUCCESS;
 }
 
+NTSTATUS FASTCALL
+xHalIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
+                             IN ULONG SectorSize,
+                             IN ULONG PartitionNumber,
+                             IN ULONG PartitionType)
+{
+   return STATUS_NOT_IMPLEMENTED;
+}
+
+
+NTSTATUS FASTCALL
+xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
+                         IN ULONG SectorSize,
+                         IN ULONG SectorsPerTrack,
+                         IN ULONG NumberOfHeads,
+                         IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
+{
+   return STATUS_NOT_IMPLEMENTED;
+}
+
 /* EOF */