[0.4.14] Sledgehammer-revert of the work towards MountMgr
authorJoachim Henze <Joachim.Henze@reactos.org>
Fri, 14 Aug 2020 14:57:10 +0000 (16:57 +0200)
committerJoachim Henze <Joachim.Henze@reactos.org>
Fri, 14 Aug 2020 14:57:10 +0000 (16:57 +0200)
to fix regression CORE-16619 "Delay during bootup due to workqueue deadlocks" (verified)
to fix regression CORE-16511 "Regression: USB drives are not mounted anymore" (verified)
to fix regression CORE-16486 "doubled drive letters for USB drives" (verified)
to fix regression "got ioctl intended for the mount manager"-logspam (verified)
and hopefully to improve on CORE-15575 (this last part still needs verification)

This reverts the following commits:
0.4.14-dev-373-g
0917815efaece8672bfcf0aa52cec6cecf692233

0.4.14-dev-296-g
324285f0b9a7726cf2c00aa49cd262f1f4f70ec0

0.4.14-dev-294-g
887200703ccd580b694929e961357b0f55f1f24d

0.4.14-dev-172-g
6889cff5b578296d956e5a4a0e9c8c0e46d328cc

0.4.14-dev-106-g
5ab1cfc553f11731d9a352f1157084cc1dfd9042

0.4.14-dev-105-g
b68104dd87b61c361c327cf44cc8845436c924ec

drivers/storage/class/cdrom/cdrom.c
drivers/storage/class/cdrom/precomp.h
drivers/storage/class/class2/class2.c
drivers/storage/class/disk/disk.c
drivers/storage/floppy/floppy/floppy.c
drivers/storage/floppy/floppy/floppy.h
drivers/storage/floppy/floppy/ioctl.c
ntoskrnl/fstub/disksup.c
ntoskrnl/guid.c
ntoskrnl/include/ntoskrnl.h

index 2794e62..554db75 100644 (file)
@@ -731,130 +731,6 @@ Return Value:
     RtlFreeUnicodeString(&unicodeString);
 }
 
-
-VOID
-NTAPI
-ReportToMountMgr(
-    IN PDEVICE_OBJECT CdDeviceObject
-    )
-
-/*++
-
-Routine Description:
-
-    This routine reports the creation of a cdrom device object to the
-    MountMgr to fake PnP.
-
-Arguments:
-
-    CdDeviceObject - Pointer to the created cdrom device.
-
-Return Value:
-
-    VOID
-
---*/
-{
-    NTSTATUS              status;
-    UNICODE_STRING        mountMgrDevice;
-    PDEVICE_OBJECT        deviceObject;
-    PFILE_OBJECT          fileObject;
-    PMOUNTMGR_TARGET_NAME mountTarget;
-    ULONG                 cdLen;
-    PDEVICE_EXTENSION     deviceExtension;
-    PIRP                  irp;
-    KEVENT                event;
-    IO_STATUS_BLOCK       ioStatus;
-
-    //
-    // First, get MountMgr DeviceObject.
-    //
-
-    RtlInitUnicodeString(&mountMgrDevice, MOUNTMGR_DEVICE_NAME);
-    status = IoGetDeviceObjectPointer(&mountMgrDevice, FILE_READ_ATTRIBUTES,
-                                      &fileObject, &deviceObject);
-
-    if (!NT_SUCCESS(status)) {
-
-        DebugPrint((1,
-                   "ReportToMountMgr: Can't get MountMgr pointers %lx\n",
-                   status));
-
-        return;
-    }
-
-    deviceExtension = CdDeviceObject->DeviceExtension;
-    cdLen = deviceExtension->DeviceName.Length;
-
-    //
-    // Allocate input buffer to report our partition device.
-    //
-
-    mountTarget = ExAllocatePool(NonPagedPool,
-                                 sizeof(MOUNTMGR_TARGET_NAME) + cdLen);
-
-    if (!mountTarget) {
-
-        DebugPrint((1,
-                   "ReportToMountMgr: Allocation of mountTarget failed\n"));
-
-        ObDereferenceObject(fileObject);
-        return;
-    }
-
-    mountTarget->DeviceNameLength = cdLen;
-    RtlCopyMemory(mountTarget->DeviceName, deviceExtension->DeviceName.Buffer, cdLen);
-
-    KeInitializeEvent(&event, NotificationEvent, FALSE);
-
-    //
-    // Build the IRP used to communicate with the MountMgr.
-    //
-
-    irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
-                                        deviceObject,
-                                        mountTarget,
-                                        sizeof(MOUNTMGR_TARGET_NAME) + cdLen,
-                                        NULL,
-                                        0,
-                                        FALSE,
-                                        &event,
-                                        &ioStatus);
-
-    if (!irp) {
-
-        DebugPrint((1,
-                    "ReportToMountMgr: Allocation of irp failed\n"));
-
-        ExFreePool(mountTarget);
-        ObDereferenceObject(fileObject);
-        return;
-    }
-
-    //
-    // Call the MountMgr.
-    //
-
-    status = IoCallDriver(deviceObject, irp);
-
-    if (status == STATUS_PENDING) {
-        KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
-        status = ioStatus.Status;
-    }
-
-    //
-    // We're done.
-    //
-
-    DPRINT1("Reported to the MountMgr: %lx\n", status);
-
-    ExFreePool(mountTarget);
-    ObDereferenceObject(fileObject);
-
-    return;
-}
-
-
 NTSTATUS
 NTAPI
 CreateCdRomDeviceObject(
@@ -1447,8 +1323,6 @@ Return Value:
 
     ExFreePool(buffer);
 
-    ReportToMountMgr(deviceObject);
-
     //
     // Start the timer now regardless of if Autorun is enabled.
     // The timer must run forever since IoStopTimer faults.
index 586ddfa..25e00ea 100644 (file)
@@ -3,7 +3,5 @@
 
 #include <ntdef.h>
 #include <ntstatus.h>
-#include <mountmgr.h>
-#include <mountdev.h>
 
 #endif /* _CDROM_PCH_ */
index 5639f07..bf67de9 100644 (file)
 #include <include/class2.h>
 #include <stdio.h>
 
+/* Part of the drive letter hack */
+#include <ntifs.h>
+#include <ketypes.h>
+
 //#define NDEBUG
 #include <debug.h>
 
@@ -131,28 +135,315 @@ DriverEntry(
     return STATUS_SUCCESS;
 }
 
+/* The following hack to assign drive letters with a non-PnP storage stack */
+
+typedef struct _CLASS_DEVICE_INFO {
+  ULONG Signature;
+  ULONG DeviceType;
+  ULONG Partitions;
+  ULONG DeviceNumber;
+  ULONG DriveNumber;
+  PDEVICE_OBJECT LowerDevice;
+} CLASS_DEVICE_INFO, *PCLASS_DEVICE_INFO;
+
+typedef struct _CLASS_DRIVER_EXTENSION {
+  ULONG PortNumber;
+  UNICODE_STRING RegistryPath;
+  CLASS_INIT_DATA InitializationData;
+} CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION;
+
+VOID
+NTAPI
+ScsiClassRemoveDriveLetter(PCLASS_DEVICE_INFO DeviceInfo)
+{
+    WCHAR Buffer1[100];
+    UNICODE_STRING DriveLetterU;
+    ULONG Index;
+
+    DriveLetterU.Buffer = Buffer1;
+    DriveLetterU.MaximumLength = sizeof(Buffer1);
+
+    /* Delete the symbolic link to PhysicalDriveX */
+    DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\\??\\PhysicalDrive%d", DeviceInfo->DriveNumber) * sizeof(WCHAR);
+    IoDeleteSymbolicLink(&DriveLetterU);
+
+    DbgPrint("HACK: Deleted symbolic link %wZ\n", &DriveLetterU);
+
+    for (Index = 0; Index < sizeof(ULONG) * 8; Index++)
+    {
+        if (DeviceInfo->Partitions & (1 << Index))
+        {
+            DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\\??\\%C:", ('C' + Index)) * sizeof(WCHAR);
+            IoDeleteSymbolicLink(&DriveLetterU);
+            DbgPrint("HACK: Deleted symbolic link %wZ\n", &DriveLetterU);
+        }
+    }
+}
+
+NTSTATUS
+NTAPI
+ScsiClassAssignDriveLetter(PCLASS_DEVICE_INFO DeviceInfo)
+{
+    WCHAR Buffer1[100];
+    WCHAR Buffer2[100];
+    UNICODE_STRING DriveLetterU, PartitionU;
+    NTSTATUS Status;
+    ULONG Index, PartitionNumber, DeviceNumber, DriveNumber;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK Iosb;
+    HANDLE PartitionHandle;
+
+    /* We assume this device does not current have a drive letter */
+
+    Index = 0;
+    DeviceNumber = 0;
+    DriveNumber = 0;
+    PartitionNumber = 1;
+    DriveLetterU.Buffer = Buffer1;
+    DriveLetterU.MaximumLength = sizeof(Buffer1);
+    PartitionU.Buffer = Buffer2;
+    PartitionU.MaximumLength = sizeof(Buffer2);
+
+    /* Determine the correct disk number */
+    do
+    {
+        /* Check that the disk exists */
+        if (DeviceInfo->DeviceType == FILE_DEVICE_DISK)
+        {
+            PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\HardDisk%d\\Partition0", DeviceNumber) * sizeof(WCHAR);
+        }
+        else if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
+        {
+            PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\CdRom%d", DeviceNumber) * sizeof(WCHAR);
+        }
+
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &PartitionU,
+                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                                   NULL,
+                                   NULL);
+        Status = ZwOpenFile(&PartitionHandle,
+                            FILE_READ_ATTRIBUTES,
+                            &ObjectAttributes,
+                            &Iosb,
+                            0,
+                            0);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Return the last one that worked */
+            DeviceNumber--;
+        }
+        else
+        {
+            ZwClose(PartitionHandle);
+            DeviceNumber++;
+        }
+    } while (Status == STATUS_SUCCESS);
+
+    /* Determine the correct drive number */
+    do
+    {
+        /* Check that the drive exists */
+        if (DeviceInfo->DeviceType == FILE_DEVICE_DISK)
+        {
+            PartitionU.Length = swprintf(PartitionU.Buffer, L"\\??\\PhysicalDrive%d", DriveNumber) * sizeof(WCHAR);
+        }
+        else if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
+        {
+            PartitionU.Length = swprintf(PartitionU.Buffer, L"\\??\\%C:", ('C' + DriveNumber)) * sizeof(WCHAR);
+        }
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &PartitionU,
+                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                                   NULL,
+                                   NULL);
+        Status = ZwOpenFile(&PartitionHandle,
+                            FILE_READ_ATTRIBUTES,
+                            &ObjectAttributes,
+                            &Iosb,
+                            0,
+                            0);
+        if (NT_SUCCESS(Status))
+        {
+            ZwClose(PartitionHandle);
+            DriveNumber++;
+        }
+    } while (Status == STATUS_SUCCESS);
+
+    if (DeviceInfo->DeviceType == FILE_DEVICE_DISK)
+    {
+        PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\Harddisk%d\\Partition0", DeviceNumber) * sizeof(WCHAR);
+        DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\\??\\PhysicalDrive%d", DriveNumber) * sizeof(WCHAR);
+    }
+    else if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
+    {
+        PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\CdRom%d", DeviceNumber) * sizeof(WCHAR);
+        DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\\??\\%C:", ('C' + DriveNumber)) * sizeof(WCHAR);
+    }
+
+    /* Create the symbolic link to PhysicalDriveX */
+    Status = IoCreateSymbolicLink(&DriveLetterU, &PartitionU);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Failed to create symbolic link */
+        DbgPrint("Failed to create symbolic link %wZ -> %wZ with %lx\n", &PartitionU, &DriveLetterU, Status);
+        return Status;
+    }
+
+    DbgPrint("HACK: Created symbolic link %wZ -> %wZ\n", &PartitionU, &DriveLetterU);
+
+    DeviceInfo->DeviceNumber = DeviceNumber;
+    DeviceInfo->DriveNumber = DriveNumber;
+
+    if (DeviceInfo->DeviceType == FILE_DEVICE_CD_ROM)
+    {
+        /* done for cdroms */
+        return STATUS_SUCCESS;
+    }
+
+    while (TRUE)
+    {
+        /* Check that the disk exists */
+        PartitionU.Length = swprintf(PartitionU.Buffer, L"\\Device\\Harddisk%d\\Partition%d", DeviceNumber, PartitionNumber) * sizeof(WCHAR);
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &PartitionU,
+                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                                   NULL,
+                                   NULL);
+        Status = ZwOpenFile(&PartitionHandle,
+                            FILE_READ_ATTRIBUTES,
+                            &ObjectAttributes,
+                            &Iosb,
+                            0,
+                            0);
+        if (!NT_SUCCESS(Status))
+            break;
+        else
+        {
+            ZwClose(PartitionHandle);
+
+            /* Assign it a drive letter */
+            do
+            {
+                DriveLetterU.Length = swprintf(DriveLetterU.Buffer, L"\\??\\%C:", ('C' + Index)) * sizeof(WCHAR);
+
+                Status = IoCreateSymbolicLink(&DriveLetterU, &PartitionU);
+
+                Index++;
+            } while (Status != STATUS_SUCCESS);
+
+            DeviceInfo->Partitions |= (1 << (Index - 1));
+
+            DbgPrint("HACK: Created symbolic link %wZ -> %wZ\n", &PartitionU, &DriveLetterU);
+            PartitionNumber++;
+        }
+    }
+
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
 ScsiClassPlugPlay(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
+    PCLASS_DEVICE_INFO DeviceInfo = DeviceObject->DeviceExtension;
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
     if (IrpSp->MinorFunction == IRP_MN_START_DEVICE)
     {
+        ASSERT(DeviceInfo->Signature == '2slc');
+        IoSkipCurrentIrpStackLocation(Irp);
+        return IoCallDriver(DeviceInfo->LowerDevice, Irp);
+    }
+    else if (IrpSp->MinorFunction == IRP_MN_REMOVE_DEVICE)
+    {
+        ASSERT(DeviceInfo->Signature == '2slc');
+        ScsiClassRemoveDriveLetter(DeviceInfo);
+
+        IoForwardIrpSynchronously(DeviceInfo->LowerDevice, Irp);
+
         Irp->IoStatus.Status = STATUS_SUCCESS;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+        IoDetachDevice(DeviceInfo->LowerDevice);
+        IoDeleteDevice(DeviceObject);
         return STATUS_SUCCESS;
     }
     else
     {
+        if (DeviceInfo->Signature == '2slc')
+        {
+            IoSkipCurrentIrpStackLocation(Irp);
+            return IoCallDriver(DeviceInfo->LowerDevice, Irp);
+        }
+
         Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_NOT_SUPPORTED;
     }
 }
 
+NTSTATUS
+NTAPI
+ScsiClassAddDevice(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+    PCLASS_DRIVER_EXTENSION DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+    PCLASS_DEVICE_INFO DeviceInfo;
+    PDEVICE_OBJECT DeviceObject;
+    NTSTATUS Status;
+
+    if (DriverExtension->InitializationData.ClassFindDevices(DriverObject, &DriverExtension->RegistryPath, &DriverExtension->InitializationData,
+                                                             PhysicalDeviceObject, DriverExtension->PortNumber))
+    {
+        /* Create a device object */
+        Status = IoCreateDevice(DriverObject,
+                                sizeof(CLASS_DEVICE_INFO),
+                                NULL,
+                                DriverExtension->InitializationData.DeviceType,
+                                0,
+                                FALSE,
+                                &DeviceObject);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+
+        DeviceInfo = DeviceObject->DeviceExtension;
+        RtlZeroMemory(DeviceInfo, sizeof(CLASS_DEVICE_INFO));
+        DeviceInfo->Signature = '2slc';
+
+        /* Attach it to the PDO */
+        DeviceInfo->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
+        DeviceInfo->DeviceType = DriverExtension->InitializationData.DeviceType;
+
+        /* Check that the kernel has already assigned drive letters */
+        if (KeLoaderBlock == NULL)
+        {
+            /* Assign a drive letter */
+            ScsiClassAssignDriveLetter(DeviceInfo);
+        }
+        else
+        {
+            /* The kernel will handle it */
+        }
+
+        /* Move to the next port number */
+        DriverExtension->PortNumber++;
+    }
+    else
+    {
+        /* Failed to find device */
+        DbgPrint("FAILED TO FIND DEVICE!\n");
+    }
+
+    return STATUS_SUCCESS;
+}
+/* ---- End hack ---- */
+
 
 \f
 ULONG
@@ -186,14 +477,15 @@ Return Value:
 
 
     PDRIVER_OBJECT  DriverObject = Argument1;
-    ULONG           portNumber = 0;
     PDEVICE_OBJECT  portDeviceObject;
     NTSTATUS        status;
     STRING          deviceNameString;
     UNICODE_STRING  unicodeDeviceName;
     PFILE_OBJECT    fileObject;
     CCHAR           deviceNameBuffer[256];
-    BOOLEAN         deviceFound = FALSE;
+    /* BOOLEAN         deviceFound = FALSE; See note at the end */
+    PCLASS_DRIVER_EXTENSION DriverExtension;
+    PUNICODE_STRING RegistryPath = Argument2;
 
     DebugPrint((3,"\n\nSCSI Class Driver\n"));
 
@@ -224,6 +516,27 @@ Return Value:
         return (ULONG) STATUS_REVISION_MISMATCH;
     }
 
+    status = IoAllocateDriverObjectExtension(DriverObject,
+                                             DriverObject,
+                                             sizeof(CLASS_DRIVER_EXTENSION),
+                                             (PVOID *)&DriverExtension);
+    if (!NT_SUCCESS(status))
+        return status;
+
+    RtlCopyMemory(&DriverExtension->InitializationData, InitializationData, sizeof(CLASS_INIT_DATA));
+    DriverExtension->PortNumber = 0;
+
+    DriverExtension->RegistryPath.Buffer = ExAllocatePool(PagedPool, RegistryPath->MaximumLength);
+    if (!DriverExtension->RegistryPath.Buffer)
+        return STATUS_NO_MEMORY;
+
+    DriverExtension->RegistryPath.Length = RegistryPath->Length;
+    DriverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;
+
+    RtlCopyMemory(DriverExtension->RegistryPath.Buffer,
+                  RegistryPath->Buffer,
+                  RegistryPath->Length);
+
     //
     // Update driver object with entry points.
     //
@@ -237,6 +550,7 @@ Return Value:
     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScsiClassDeviceControlDispatch;
     DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ScsiClassShutdownFlush;
     DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ScsiClassShutdownFlush;
+    DriverObject->DriverExtension->AddDevice = ScsiClassAddDevice;
 
     if (InitializationData->ClassStartIo) {
         DriverObject->DriverStartIo = InitializationData->ClassStartIo;
@@ -248,7 +562,7 @@ Return Value:
 
     do {
 
-        sprintf(deviceNameBuffer, "\\Device\\ScsiPort%lu", portNumber);
+        sprintf(deviceNameBuffer, "\\Device\\ScsiPort%lu", DriverExtension->PortNumber);
 
         DebugPrint((2, "ScsiClassInitialize: Open Port %s\n", deviceNameBuffer));
 
@@ -274,9 +588,9 @@ Return Value:
             //
 
             if (InitializationData->ClassFindDevices(DriverObject, Argument2, InitializationData,
-                                                     portDeviceObject, portNumber)) {
+                                                     portDeviceObject, DriverExtension->PortNumber)) {
 
-                deviceFound = TRUE;
+                /* deviceFound = TRUE; See note at the end */
             }
         }
 
@@ -284,11 +598,12 @@ Return Value:
         // Check next SCSI adapter.
         //
 
-        portNumber++;
+        DriverExtension->PortNumber++;
 
     } while(NT_SUCCESS(status));
 
-    return deviceFound ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;
+    /* We don't want to fail init just because we don't have devices right now */
+    return STATUS_SUCCESS; /*deviceFound ? STATUS_SUCCESS : STATUS_NO_SUCH_DEVICE;*/
 }
 
 \f
index 535de1f..580c899 100644 (file)
@@ -1068,129 +1068,6 @@ CreateDiskDeviceObjectsExit:
 } // end CreateDiskDeviceObjects()
 
 \f
-VOID
-NTAPI
-ReportToMountMgr(
-    IN PDEVICE_OBJECT DiskDeviceObject
-    )
-
-/*++
-
-Routine Description:
-
-    This routine reports the creation of a disk device object to the
-    MountMgr to fake PnP.
-
-Arguments:
-
-    DiskDeviceObject - Pointer to the created disk device.
-
-Return Value:
-
-    VOID
-
---*/
-{
-    NTSTATUS              status;
-    UNICODE_STRING        mountMgrDevice;
-    PDEVICE_OBJECT        deviceObject;
-    PFILE_OBJECT          fileObject;
-    PMOUNTMGR_TARGET_NAME mountTarget;
-    ULONG                 diskLen;
-    PDEVICE_EXTENSION     deviceExtension;
-    PIRP                  irp;
-    KEVENT                event;
-    IO_STATUS_BLOCK       ioStatus;
-
-    //
-    // First, get MountMgr DeviceObject.
-    //
-
-    RtlInitUnicodeString(&mountMgrDevice, MOUNTMGR_DEVICE_NAME);
-    status = IoGetDeviceObjectPointer(&mountMgrDevice, FILE_READ_ATTRIBUTES,
-                                      &fileObject, &deviceObject);
-
-    if (!NT_SUCCESS(status)) {
-
-        DebugPrint((1,
-                   "ReportToMountMgr: Can't get MountMgr pointers %lx\n",
-                   status));
-
-        return;
-    }
-
-    deviceExtension = DiskDeviceObject->DeviceExtension;
-    diskLen = deviceExtension->DeviceName.Length;
-
-    //
-    // Allocate input buffer to report our partition device.
-    //
-
-    mountTarget = ExAllocatePool(NonPagedPool,
-                                 sizeof(MOUNTMGR_TARGET_NAME) + diskLen);
-
-    if (!mountTarget) {
-
-        DebugPrint((1,
-                   "ReportToMountMgr: Allocation of mountTarget failed\n"));
-
-        ObDereferenceObject(fileObject);
-        return;
-    }
-
-    mountTarget->DeviceNameLength = diskLen;
-    RtlCopyMemory(mountTarget->DeviceName, deviceExtension->DeviceName.Buffer, diskLen);
-
-    KeInitializeEvent(&event, NotificationEvent, FALSE);
-
-    //
-    // Build the IRP used to communicate with the MountMgr.
-    //
-
-    irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
-                                        deviceObject,
-                                        mountTarget,
-                                        sizeof(MOUNTMGR_TARGET_NAME) + diskLen,
-                                        NULL,
-                                        0,
-                                        FALSE,
-                                        &event,
-                                        &ioStatus);
-
-    if (!irp) {
-
-        DebugPrint((1,
-                    "ReportToMountMgr: Allocation of irp failed\n"));
-
-        ExFreePool(mountTarget);
-        ObDereferenceObject(fileObject);
-        return;
-    }
-
-    //
-    // Call the MountMgr.
-    //
-
-    status = IoCallDriver(deviceObject, irp);
-
-    if (status == STATUS_PENDING) {
-        KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
-        status = ioStatus.Status;
-    }
-
-    //
-    // We're done.
-    //
-
-    DPRINT1("Reported to the MountMgr: %lx\n", status);
-
-    ExFreePool(mountTarget);
-    ObDereferenceObject(fileObject);
-
-    return;
-}
-
-\f
 NTSTATUS
 NTAPI
 CreatePartitionDeviceObjects(
@@ -1583,14 +1460,6 @@ CreatePartitionDeviceObjects(
             deviceExtension->DeviceObject = deviceObject;
             deviceExtension->DeviceFlags |= physicalDeviceExtension->DeviceFlags;
 
-            //
-            // Now we're done, report to the MountMgr.
-            // This is a HACK required to have the driver
-            // handle the associated DosDevices.
-            //
-
-            ReportToMountMgr(deviceObject);
-
         } // end for (partitionNumber) ...
 
         //
index b67c609..4234b0f 100644 (file)
@@ -406,6 +406,9 @@ Unload(PDRIVER_OBJECT DriverObject)
             {
                 UNICODE_STRING Link;
 
+                RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
+                IoDeleteSymbolicLink(&Link);
+
                 RtlInitUnicodeString(&Link, gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
                 IoDeassignArcName(&Link);
 
@@ -808,98 +811,6 @@ InitController(PCONTROLLER_INFO ControllerInfo)
 }
 
 
-static VOID NTAPI
-ReportToMountMgr(UCHAR ControlerId, UCHAR DriveId)
-/*
- * FUNCTION: Called to report a new controler to the MountMgr
- * ARGUMENTS:
- *     ControlerId: ID of the controler
- *     DriveId: ID of the device for the controler
- * RETURNS:
- *     Nothing
- * NOTES:
- *     - This is a hack to allow MountMgr handling our devices
- */
-{
-    NTSTATUS              Status;
-    UNICODE_STRING        MountMgrDevice;
-    PDEVICE_OBJECT        DeviceObject;
-    PFILE_OBJECT          FileObject;
-    PMOUNTMGR_TARGET_NAME MountTarget;
-    ULONG                 DeviceLen;
-    PIRP                  Irp;
-    KEVENT                Event;
-    IO_STATUS_BLOCK       IoStatus;
-
-    /* First, get MountMgr DeviceObject */
-    RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
-    Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
-                                      &FileObject, &DeviceObject);
-
-    if(!NT_SUCCESS(Status))
-    {
-        WARN_(FLOPPY, "ReportToMountMgr: Can't get MountMgr pointers %lx\n", Status);
-        return;
-    }
-
-    DeviceLen = wcslen(&gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer[0]) * sizeof(WCHAR);
-
-    /* Allocate input buffer to report our floppy device */
-    MountTarget = ExAllocatePool(NonPagedPool,
-                                 sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen);
-
-    if(!MountTarget)
-    {
-        WARN_(FLOPPY, "ReportToMountMgr: Allocation of mountTarget failed\n");
-        ObDereferenceObject(FileObject);
-        return;
-    }
-
-    MountTarget->DeviceNameLength = DeviceLen;
-    RtlCopyMemory(MountTarget->DeviceName,
-                  gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer,
-                  DeviceLen);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    /* Build the IRP used to communicate with the MountMgr */
-    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
-                                        DeviceObject,
-                                        MountTarget,
-                                        sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen,
-                                        NULL,
-                                        0,
-                                        FALSE,
-                                        &Event,
-                                        &IoStatus);
-
-    if(!Irp)
-    {
-        WARN_(FLOPPY, "ReportToMountMgr: Allocation of irp failed\n");
-        ExFreePool(MountTarget);
-        ObDereferenceObject(FileObject);
-        return;
-    }
-
-    /* Call the MountMgr */
-    Status = IoCallDriver(DeviceObject, Irp);
-
-    if (Status == STATUS_PENDING) {
-        KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
-        Status = IoStatus.Status;
-    }
-
-    /* We're done */
-
-    INFO_(FLOPPY, "Reported to the MountMgr: %lx\n", Status);
-
-    ExFreePool(MountTarget);
-    ObDereferenceObject(FileObject);
-
-    return;
-}
-
-
 static BOOLEAN NTAPI
 AddControllers(PDRIVER_OBJECT DriverObject)
 /*
@@ -1001,7 +912,9 @@ AddControllers(PDRIVER_OBJECT DriverObject)
         /* 3: per-drive setup */
         for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
         {
+            WCHAR DeviceNameBuf[MAX_DEVICE_NAME];
             UNICODE_STRING DeviceName;
+            UNICODE_STRING LinkName;
             UNICODE_STRING ArcPath;
             UCHAR DriveNumber;
 
@@ -1023,8 +936,9 @@ AddControllers(PDRIVER_OBJECT DriverObject)
 
             DriveNumber = (UCHAR)(i*4 + j); /* loss of precision is OK; there are only 16 of 'em */
 
-            swprintf(gControllerInfo[i].DriveInfo[j].DeviceNameBuffer, L"\\Device\\Floppy%d", DriveNumber);
-            RtlInitUnicodeString(&DeviceName, gControllerInfo[i].DriveInfo[j].DeviceNameBuffer);
+            RtlZeroMemory(&DeviceNameBuf, MAX_DEVICE_NAME * sizeof(WCHAR));
+            swprintf(DeviceNameBuf, L"\\Device\\Floppy%d", DriveNumber);
+            RtlInitUnicodeString(&DeviceName, DeviceNameBuf);
 
             if(IoCreateDevice(DriverObject, sizeof(PVOID), &DeviceName,
                               FILE_DEVICE_DISK, FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE, FALSE,
@@ -1035,9 +949,7 @@ AddControllers(PDRIVER_OBJECT DriverObject)
                 continue; /* continue on to next drive */
             }
 
-            INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n",
-                          gControllerInfo[i].DriveInfo[j].DeviceNameBuffer,
-                          gControllerInfo[i].DriveInfo[j].DeviceObject);
+            INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n", DeviceNameBuf, gControllerInfo[i].DriveInfo[j].DeviceObject);
 
             /* 3b.5: Create an ARC path in case we're booting from this drive */
             swprintf(gControllerInfo[i].DriveInfo[j].ArcPathBuffer,
@@ -1049,30 +961,38 @@ AddControllers(PDRIVER_OBJECT DriverObject)
             /* 3c: Set flags up */
             gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO;
 
-            /* 3d: Increase global floppy drives count */
+            /* 3d: Create a symlink */
+            swprintf(gControllerInfo[i].DriveInfo[j].SymLinkBuffer, L"\\DosDevices\\%c:", DriveNumber + 'A');
+            RtlInitUnicodeString(&LinkName, gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
+            if(IoCreateSymbolicLink(&LinkName, &DeviceName) != STATUS_SUCCESS)
+            {
+                WARN_(FLOPPY, "AddControllers: Unable to create a symlink for drive %d\n", DriveNumber);
+                IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
+                IoDeassignArcName(&ArcPath);
+                continue; /* continue to next drive */
+            }
+
+            /* 3e: Increase global floppy drives count */
             IoGetConfigurationInformation()->FloppyCount++;
 
-            /* 3e: Set up the DPC */
+            /* 3f: Set up the DPC */
             IoInitializeDpcRequest(gControllerInfo[i].DriveInfo[j].DeviceObject, (PIO_DPC_ROUTINE)DpcForIsr);
 
-            /* 3f: Point the device extension at our DriveInfo struct */
+            /* 3g: Point the device extension at our DriveInfo struct */
             gControllerInfo[i].DriveInfo[j].DeviceObject->DeviceExtension = &gControllerInfo[i].DriveInfo[j];
 
-            /* 3g: neat comic strip */
+            /* 3h: neat comic strip */
 
-            /* 3h: set the initial media type to unknown */
+            /* 3i: set the initial media type to unknown */
             memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0, sizeof(DISK_GEOMETRY));
             gControllerInfo[i].DriveInfo[j].DiskGeometry.MediaType = Unknown;
 
-            /* 3i: Now that we're done, set the Initialized flag so we know to free this in Unload */
+            /* 3j: Now that we're done, set the Initialized flag so we know to free this in Unload */
             gControllerInfo[i].DriveInfo[j].Initialized = TRUE;
 
-            /* 3j: Clear the DO_DEVICE_INITIALIZING flag */
+            /* 3k: Clear the DO_DEVICE_INITIALIZING flag */
             gControllerInfo[i].DriveInfo[j].DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 
-            /* 3k: Report to the MountMgr */
-            ReportToMountMgr(i, j);
-
             /* 3l: Attempt to get drive info - if a floppy is already present */
             StartMotor(&gControllerInfo[i].DriveInfo[j]);
             RWDetermineMediaType(&gControllerInfo[i].DriveInfo[j], TRUE);
index 3dfd7c6..cd0301c 100644 (file)
@@ -48,8 +48,8 @@ typedef struct _DRIVE_INFO
     CM_FLOPPY_DEVICE_DATA    FloppyDeviceData;
     DISK_GEOMETRY            DiskGeometry;
     UCHAR                    BytesPerSectorCode;
+    WCHAR                    SymLinkBuffer[MAX_DEVICE_NAME];
     WCHAR                    ArcPathBuffer[MAX_ARC_PATH_LEN];
-    WCHAR                    DeviceNameBuffer[MAX_DEVICE_NAME];
     ULONG                    DiskChangeCount;
     BOOLEAN                  Initialized;
 } DRIVE_INFO, *PDRIVE_INFO;
index e6073a9..74a3517 100644 (file)
@@ -75,7 +75,6 @@ DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
     ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode;
     BOOLEAN DiskChanged;
     PMOUNTDEV_NAME Name;
-    PMOUNTDEV_UNIQUE_ID UniqueId;
 
     TRACE_(FLOPPY, "DeviceIoctl called\n");
     Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -257,54 +256,27 @@ DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
         Irp->IoStatus.Information = 0;
         break;
 
-    case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
-        if(OutputLength < sizeof(MOUNTDEV_UNIQUE_ID))
-        {
-            Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
-            Irp->IoStatus.Information = 0;
-            break;
-        }
-
-        UniqueId = Irp->AssociatedIrp.SystemBuffer;
-        UniqueId->UniqueIdLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) * sizeof(WCHAR);
-
-        if(OutputLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueId->UniqueIdLength)
-        {
-            Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
-            Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
-            break;
-        }
-
-        RtlCopyMemory(UniqueId->UniqueId, &DriveInfo->DeviceNameBuffer[0],
-                      UniqueId->UniqueIdLength);
-
-        Irp->IoStatus.Status = STATUS_SUCCESS;
-        Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueId->UniqueIdLength;
-        break;
-
     case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
-        if(OutputLength < sizeof(MOUNTDEV_NAME))
-        {
+        if (OutputLength < sizeof(MOUNTDEV_NAME)) {
             Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
-            Irp->IoStatus.Information = 0;
+            Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
             break;
         }
 
         Name = Irp->AssociatedIrp.SystemBuffer;
-        Name->NameLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) * sizeof(WCHAR);
+        Name->NameLength = wcslen(&DriveInfo->SymLinkBuffer[0]) * sizeof(WCHAR);
 
-        if(OutputLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + Name->NameLength)
-        {
+        if (OutputLength < sizeof(USHORT) + Name->NameLength) {
             Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
             Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
             break;
         }
 
-        RtlCopyMemory(Name->Name, &DriveInfo->DeviceNameBuffer[0],
+        RtlCopyMemory(Name->Name, &DriveInfo->SymLinkBuffer[0],
                       Name->NameLength);
 
         Irp->IoStatus.Status = STATUS_SUCCESS;
-        Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + Name->NameLength;
+        Irp->IoStatus.Information = sizeof(USHORT) + Name->NameLength;
         break;
 
     default:
index 3198481..dfdbf0c 100644 (file)
@@ -6,7 +6,6 @@
 * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
 *                  Eric Kohl
 *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
-*                  Pierre Schweitzer
 */
 
 /* INCLUDES ******************************************************************/
@@ -16,6 +15,9 @@
 #include <debug.h>
 #include <internal/hal.h>
 
+/* DEPRECATED FUNCTIONS ******************************************************/
+
+#if 1
 const WCHAR DiskMountString[] = L"\\DosDevices\\%C:";
 
 #define AUTO_DRIVE         MAXULONG
@@ -41,1346 +43,905 @@ typedef enum _DISK_MANAGER
     EZ_Drive
 } DISK_MANAGER;
 
-typedef enum _PARTITION_TYPE
-{
-    BootablePartition,
-    PrimaryPartition,
-    LogicalPartition,
-    FtPartition,
-    UnknownPartition,
-    DataPartition
-} PARTITION_TYPE, *PPARTITION_TYPE;
-
-NTSTATUS
-FASTCALL
-HalpQueryDriveLayout(IN PUNICODE_STRING DeviceName,
-                     OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo)
+static BOOLEAN
+HalpAssignDrive(IN PUNICODE_STRING PartitionName,
+                IN ULONG DriveNumber,
+                IN UCHAR DriveType,
+                IN ULONG Signature,
+                IN LARGE_INTEGER StartingOffset,
+                IN HANDLE hKey,
+                IN PUNICODE_STRING BootDevice,
+                OUT PUCHAR NtSystemPath)
 {
-    IO_STATUS_BLOCK StatusBlock;
-    PDEVICE_OBJECT DeviceObject = NULL;
-    PFILE_OBJECT FileObject;
-    KEVENT Event;
-    PIRP Irp;
+    WCHAR DriveNameBuffer[16];
+    UNICODE_STRING DriveName;
+    ULONG i;
     NTSTATUS Status;
-    ULONG BufferSize;
-    PDRIVE_LAYOUT_INFORMATION Buffer;
-    PAGED_CODE();
-
-    /* Get device pointers */
-    Status = IoGetDeviceObjectPointer(DeviceName,
-                                      FILE_READ_ATTRIBUTES,
-                                      &FileObject,
-                                      &DeviceObject);
-    if (!NT_SUCCESS(Status))
-    {
-        return Status;
-    }
+    REG_DISK_MOUNT_INFO DiskMountInfo;
 
-    /* Get attached device object */
-    DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
-    ObDereferenceObject(FileObject);
+    DPRINT("HalpAssignDrive()\n");
 
-    /* Do not handle removable media */
-    if (BooleanFlagOn(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA))
+    if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 26))
     {
-        ObDereferenceObject(DeviceObject);
-        return STATUS_NO_MEDIA;
+        /* Force assignment */
+        KeAcquireGuardedMutex(&ObpDeviceMapLock);
+        if ((ObSystemDeviceMap->DriveMap & (1 << DriveNumber)) != 0)
+        {
+            DbgPrint("Drive letter already used!\n");
+            KeReleaseGuardedMutex(&ObpDeviceMapLock);
+            return FALSE;
+        }
+        KeReleaseGuardedMutex(&ObpDeviceMapLock);
     }
-
-    /* We'll loop until our buffer is big enough */
-    Buffer = NULL;
-    BufferSize = 0x1000;
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    do
+    else
     {
-        /* If we already had a buffer, it means it's not big
-         * enough, so free and multiply size by two
-         */
-        if (Buffer != NULL)
+        /* Automatic assignment */
+        DriveNumber = AUTO_DRIVE;
+        KeAcquireGuardedMutex(&ObpDeviceMapLock);
+        for (i = 2; i < 26; i++)
         {
-            ExFreePoolWithTag(Buffer, TAG_FSTUB);
-            BufferSize *= 2;
+            if ((ObSystemDeviceMap->DriveMap & (1 << i)) == 0)
+            {
+                DriveNumber = i;
+                break;
+            }
         }
+        KeReleaseGuardedMutex(&ObpDeviceMapLock);
 
-        /* Allocate buffer for output buffer */
-        Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, TAG_FSTUB);
-        if (Buffer == NULL)
+        if (DriveNumber == AUTO_DRIVE)
         {
-            Status = STATUS_NO_MEMORY;
-            break;
+            DbgPrint("No drive letter available!\n");
+            return FALSE;
         }
+    }
 
-        /* Build the IRP to query drive layout */
-        Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_LAYOUT,
-                                            DeviceObject,
-                                            NULL,
-                                            0,
-                                            Buffer,
-                                            BufferSize,
-                                            FALSE,
-                                            &Event,
-                                            &StatusBlock);
-        if (Irp == NULL)
-        {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            break;
-        }
+    DPRINT("DriveNumber %lu\n", DriveNumber);
 
-        /* Call the driver and wait if appropriate */
-        Status = IoCallDriver(DeviceObject, Irp);
-        if (Status == STATUS_PENDING)
+    /* Build drive name */
+    swprintf(DriveNameBuffer,
+        L"\\??\\%C:",
+        'A' + DriveNumber);
+    RtlInitUnicodeString(&DriveName,
+        DriveNameBuffer);
+
+    DPRINT("  %wZ ==> %wZ\n",
+        &DriveName,
+        PartitionName);
+
+    /* Create symbolic link */
+    Status = IoCreateSymbolicLink(&DriveName,
+        PartitionName);
+
+    if (hKey &&
+        DriveType == DOSDEVICE_DRIVE_FIXED &&
+        Signature)
+    {
+        DiskMountInfo.Signature = Signature;
+        DiskMountInfo.StartingOffset = StartingOffset;
+        swprintf(DriveNameBuffer, DiskMountString, L'A' + DriveNumber);
+        RtlInitUnicodeString(&DriveName, DriveNameBuffer);
+
+        Status = ZwSetValueKey(hKey,
+            &DriveName,
+            0,
+            REG_BINARY,
+            &DiskMountInfo,
+            sizeof(DiskMountInfo));
+        if (!NT_SUCCESS(Status))
         {
-            KeWaitForSingleObject(&Event,
-                                  Executive,
-                                  KernelMode,
-                                  FALSE,
-                                  NULL);
-            Status = StatusBlock.Status;
+            DPRINT1("ZwCreateValueKey failed for %wZ, status=%x\n", &DriveName, Status);
         }
-        /* If buffer is too small, keep looping */
-    } while (Status == STATUS_BUFFER_TOO_SMALL);
+    }
 
-    /* We're done with the device */
-    ObDereferenceObject(DeviceObject);
+    /* Check if this is a boot partition */
+    if (RtlCompareUnicodeString(PartitionName, BootDevice, FALSE) == 0)
+    {
+        /* Set NtSystemPath to that partition's disk letter */
+        *NtSystemPath = (UCHAR)('A' + DriveNumber);
+    }
 
-    /* If querying worked, then return the buffer to the caller */
-    if (NT_SUCCESS(Status))
+    return TRUE;
+}
+
+ULONG
+xHalpGetRDiskCount(VOID)
+{
+    NTSTATUS Status;
+    UNICODE_STRING ArcName;
+    PWCHAR ArcNameBuffer;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE DirectoryHandle;
+    POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
+    ULONG Skip;
+    ULONG ResultLength;
+    ULONG CurrentRDisk;
+    ULONG RDiskCount;
+    BOOLEAN First = TRUE;
+    ULONG Count;
+
+    DirectoryInfo = ExAllocatePoolWithTag(PagedPool, 2 * PAGE_SIZE, TAG_FILE_SYSTEM);
+    if (DirectoryInfo == NULL)
     {
-        ASSERT(Buffer != NULL);
-        *LayoutInfo = Buffer;
+        return 0;
     }
-    /* Else, release the buffer if still allocated and fail */
-    else
+
+    RtlInitUnicodeString(&ArcName, L"\\ArcName");
+    InitializeObjectAttributes(&ObjectAttributes,
+        &ArcName,
+        0,
+        NULL,
+        NULL);
+
+    Status = ZwOpenDirectoryObject (&DirectoryHandle,
+        DIRECTORY_ALL_ACCESS,
+        &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
     {
-        if (Buffer != NULL)
+        DPRINT1("ZwOpenDirectoryObject for %wZ failed, status=%lx\n", &ArcName, Status);
+        ExFreePoolWithTag(DirectoryInfo, TAG_FILE_SYSTEM);
+        return 0;
+    }
+
+    RDiskCount = 0;
+    Skip = 0;
+    while (NT_SUCCESS(Status))
+    {
+        Status = ZwQueryDirectoryObject (DirectoryHandle,
+            DirectoryInfo,
+            2 * PAGE_SIZE,
+            FALSE,
+            First,
+            &Skip,
+            &ResultLength);
+        First = FALSE;
+        if (NT_SUCCESS(Status))
         {
-            ExFreePoolWithTag(Buffer, TAG_FSTUB);
+            Count = 0;
+            while (DirectoryInfo[Count].Name.Buffer)
+            {
+                DPRINT("Count %x\n", Count);
+                DirectoryInfo[Count].Name.Buffer[DirectoryInfo[Count].Name.Length / sizeof(WCHAR)] = 0;
+                ArcNameBuffer = DirectoryInfo[Count].Name.Buffer;
+                if (DirectoryInfo[Count].Name.Length >= sizeof(L"multi(0)disk(0)rdisk(0)") - sizeof(WCHAR) &&
+                    !_wcsnicmp(ArcNameBuffer, L"multi(0)disk(0)rdisk(", (sizeof(L"multi(0)disk(0)rdisk(") - sizeof(WCHAR)) / sizeof(WCHAR)))
+                {
+                    DPRINT("%S\n", ArcNameBuffer);
+                    ArcNameBuffer += (sizeof(L"multi(0)disk(0)rdisk(") - sizeof(WCHAR)) / sizeof(WCHAR);
+                    CurrentRDisk = 0;
+                    while (iswdigit(*ArcNameBuffer))
+                    {
+                        CurrentRDisk = CurrentRDisk * 10 + *ArcNameBuffer - L'0';
+                        ArcNameBuffer++;
+                    }
+                    if (!_wcsicmp(ArcNameBuffer, L")") &&
+                        CurrentRDisk >= RDiskCount)
+                    {
+                        RDiskCount = CurrentRDisk + 1;
+                    }
+                }
+                Count++;
+            }
         }
     }
 
-    return Status;
+    ZwClose(DirectoryHandle);
+
+    ExFreePoolWithTag(DirectoryInfo, TAG_FILE_SYSTEM);
+    return RDiskCount;
 }
 
 NTSTATUS
-HalpQueryPartitionType(IN PUNICODE_STRING DeviceName,
-                       IN PDRIVE_LAYOUT_INFORMATION LayoutInfo,
-                       OUT PPARTITION_TYPE PartitionType)
+xHalpGetDiskNumberFromRDisk(ULONG RDisk, PULONG DiskNumber)
 {
-    USHORT i;
-    PIRP Irp;
-    KEVENT Event;
+    WCHAR NameBuffer[80];
+    UNICODE_STRING ArcName;
+    UNICODE_STRING LinkName;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE LinkHandle;
     NTSTATUS Status;
-    PFILE_OBJECT FileObject;
-    PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PARTITION_INFORMATION_EX PartitionInfo;
 
-    PAGED_CODE();
+    swprintf(NameBuffer,
+        L"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
+        RDisk);
+
+    RtlInitUnicodeString(&ArcName, NameBuffer);
+    InitializeObjectAttributes(&ObjectAttributes,
+        &ArcName,
+        0,
+        NULL,
+        NULL);
+    Status = ZwOpenSymbolicLinkObject(&LinkHandle,
+        SYMBOLIC_LINK_ALL_ACCESS,
+        &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("ZwOpenSymbolicLinkObject failed for %wZ, status=%lx\n", &ArcName, Status);
+        return Status;
+    }
 
-    /* Get device pointers */
-    Status = IoGetDeviceObjectPointer(DeviceName,
-                                      FILE_READ_ATTRIBUTES,
-                                      &FileObject,
-                                      &DeviceObject);
+    LinkName.Buffer = NameBuffer;
+    LinkName.Length = 0;
+    LinkName.MaximumLength = sizeof(NameBuffer);
+    Status = ZwQuerySymbolicLinkObject(LinkHandle,
+        &LinkName,
+        NULL);
+    ZwClose(LinkHandle);
     if (!NT_SUCCESS(Status))
     {
+        DPRINT1("ZwQuerySymbolicLinkObject failed, status=%lx\n", Status);
         return Status;
     }
+    if (LinkName.Length < sizeof(L"\\Device\\Harddisk0\\Partition0") - sizeof(WCHAR) ||
+        LinkName.Length >= sizeof(NameBuffer))
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
 
-    /* Get attached device object */
-    DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
-    ObDereferenceObject(FileObject);
+    NameBuffer[LinkName.Length / sizeof(WCHAR)] = 0;
+    if (_wcsnicmp(NameBuffer, L"\\Device\\Harddisk", (sizeof(L"\\Device\\Harddisk") - sizeof(WCHAR)) / sizeof(WCHAR)))
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+    LinkName.Buffer += (sizeof(L"\\Device\\Harddisk") - sizeof(WCHAR)) / sizeof(WCHAR);
+
+    if (!iswdigit(*LinkName.Buffer))
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+    *DiskNumber = 0;
+    while (iswdigit(*LinkName.Buffer))
+    {
+        *DiskNumber = *DiskNumber * 10 + *LinkName.Buffer - L'0';
+        LinkName.Buffer++;
+    }
+    if (_wcsicmp(LinkName.Buffer, L"\\Partition0"))
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+FASTCALL
+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);
 
-    /* Assume logical partition for removable devices */
-    if (BooleanFlagOn(DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA))
+    /* Get the drives sector size */
+    Status = IoGetDeviceObjectPointer(DeviceName,
+        FILE_READ_ATTRIBUTES,
+        &FileObject,
+        &DeviceObject);
+    if (!NT_SUCCESS(Status))
     {
-        ObDereferenceObject(DeviceObject);
-        *PartitionType = LogicalPartition;
-        return STATUS_SUCCESS;
+        DPRINT("Status %x\n", Status);
+        return(Status);
     }
 
-    /* For the others, query partition info */
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO_EX,
-                                        DeviceObject,
-                                        NULL,
-                                        0,
-                                        &PartitionInfo,
-                                        sizeof(PartitionInfo),
-                                        FALSE,
-                                        &Event,
-                                        &IoStatusBlock);
+    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(DeviceObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
+        ObDereferenceObject(FileObject);
+        return(STATUS_INSUFFICIENT_RESOURCES);
     }
 
-    Status = IoCallDriver(DeviceObject, Irp);
+    Status = IoCallDriver(DeviceObject,
+        Irp);
     if (Status == STATUS_PENDING)
     {
         KeWaitForSingleObject(&Event,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
-        Status = IoStatusBlock.Status;
+            Executive,
+            KernelMode,
+            FALSE,
+            NULL);
+        Status = StatusBlock.Status;
     }
-
-    /* We're done with the device */
-    ObDereferenceObject(DeviceObject);
-
-    /* If we failed querying partition info, try to return something
-     * if caller didn't provide a precise layout, assume logical
-     * partition and fake success. Otherwise, just fail.
-     */
     if (!NT_SUCCESS(Status))
     {
-        if (LayoutInfo == NULL)
+        if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
         {
-            *PartitionType = LogicalPartition;
-            return STATUS_SUCCESS;
+            DiskGeometry.BytesPerSector = 512;
+        }
+        else
+        {
+            ObDereferenceObject(FileObject);
+            return(Status);
         }
-
-        return Status;
     }
 
-    /* First, handle non MBR style (easy cases) */
-    if (PartitionInfo.PartitionStyle != PARTITION_STYLE_MBR)
+    DPRINT("DiskGeometry.BytesPerSector: %lu\n",
+        DiskGeometry.BytesPerSector);
+
+    if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
     {
-        /* If not GPT, we don't know what it is */
-        if (PartitionInfo.PartitionStyle != PARTITION_STYLE_GPT)
+        PDRIVE_LAYOUT_INFORMATION Buffer;
+
+        /* Allocate a partition list for a single entry. */
+        Buffer = ExAllocatePoolWithTag(NonPagedPool,
+            sizeof(DRIVE_LAYOUT_INFORMATION), TAG_FILE_SYSTEM);
+        if (Buffer != NULL)
         {
-            *PartitionType = UnknownPartition;
-            return STATUS_SUCCESS;
-        }
+            RtlZeroMemory(Buffer,
+                sizeof(DRIVE_LAYOUT_INFORMATION));
+            Buffer->PartitionCount = 1;
+            *LayoutInfo = Buffer;
 
-        /* Check whether that's data partition */
-        if (RtlCompareMemory(&PartitionInfo.Gpt.PartitionType,
-                             &PARTITION_BASIC_DATA_GUID,
-                             sizeof(GUID)) == sizeof(GUID))
+            Status = STATUS_SUCCESS;
+        }
+        else
         {
-            *PartitionType = DataPartition;
-            return STATUS_SUCCESS;
+            Status = STATUS_UNSUCCESSFUL;
         }
-
-        /* Otherwise, we don't know */
-        *PartitionType = UnknownPartition;
-        return STATUS_SUCCESS;
     }
+    else
+    {
+        /* Read the partition table */
+        Status = IoReadPartitionTable(DeviceObject,
+            DiskGeometry.BytesPerSector,
+            TRUE,
+            LayoutInfo);
+    }
+
+    ObDereferenceObject(FileObject);
+
+    return(Status);
+}
+
+VOID
+FASTCALL
+xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                         IN PSTRING NtDeviceName,
+                         OUT PUCHAR NtSystemPath,
+                         OUT PSTRING NtSystemPathString)
+{
+    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, j, k;
+    ULONG DiskNumber;
+    ULONG RDisk;
+    NTSTATUS Status;
+    HANDLE hKey;
+    ULONG Length;
+    PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
+    PREG_DISK_MOUNT_INFO DiskMountInfo;
+    ULONG RDiskCount;
+    UNICODE_STRING BootDevice;
+
+    Status = RtlAnsiStringToUnicodeString(&BootDevice,
+                                          NtDeviceName,
+                                          TRUE);
+
+    DPRINT("xHalIoAssignDriveLetters()\n");
+
+    ConfigInfo = IoGetConfigurationInformation();
+
+    RDiskCount = xHalpGetRDiskCount();
 
-    /* If we don't recognize partition type, return unknown */
-    if (!IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
+    DPRINT("RDiskCount %lu\n", RDiskCount);
+
+    Buffer1 = ExAllocatePoolWithTag(PagedPool,
+        64 * sizeof(WCHAR),
+        TAG_FILE_SYSTEM);
+    if (!Buffer1) return;
+
+    Buffer2 = ExAllocatePoolWithTag(PagedPool,
+        32 * sizeof(WCHAR),
+        TAG_FILE_SYSTEM);
+    if (!Buffer2)
     {
-        *PartitionType = UnknownPartition;
-        return STATUS_SUCCESS;
+        ExFreePoolWithTag(Buffer1, TAG_FILE_SYSTEM);
+        return;
     }
 
-    /* Check if that's a FT volume */
-    if (IsFTPartition(PartitionInfo.Mbr.PartitionType))
+    PartialInformation = ExAllocatePoolWithTag(PagedPool,
+        sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(REG_DISK_MOUNT_INFO),
+        TAG_FILE_SYSTEM);
+    if (!PartialInformation)
     {
-        *PartitionType = FtPartition;
-        return STATUS_SUCCESS;
+        ExFreePoolWithTag(Buffer2, TAG_FILE_SYSTEM);
+        ExFreePoolWithTag(Buffer1, TAG_FILE_SYSTEM);
+        return;
     }
 
-    /* If the caller didn't provide the complete layout, just return */
-    if (LayoutInfo == NULL)
+    DiskMountInfo = (PREG_DISK_MOUNT_INFO) PartialInformation->Data;
+
+    /* Create or open the 'MountedDevices' key */
+    RtlInitUnicodeString(&UnicodeString1, L"\\Registry\\Machine\\SYSTEM\\MountedDevices");
+    InitializeObjectAttributes(&ObjectAttributes,
+        &UnicodeString1,
+        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+        NULL,
+        NULL);
+    Status = ZwCreateKey(&hKey,
+        KEY_ALL_ACCESS,
+        &ObjectAttributes,
+        0,
+        NULL,
+        REG_OPTION_NON_VOLATILE,
+        NULL);
+    if (!NT_SUCCESS(Status))
     {
-        *PartitionType = LogicalPartition;
-        return STATUS_SUCCESS;
+        hKey = NULL;
+        DPRINT("ZwCreateKey failed for %wZ, status=%x\n", &UnicodeString1, Status);
     }
 
-    /* Now, evaluate the partition to the 4 in the input layout */
-    for (i = 0; i < 4; ++i)
+    /* Create PhysicalDrive links */
+    DPRINT("Physical disk drives: %lu\n", ConfigInfo->DiskCount);
+    for (i = 0; i < ConfigInfo->DiskCount; i++)
     {
-        /* If we find a partition matching */
-        if (LayoutInfo->PartitionEntry[i].StartingOffset.QuadPart == PartitionInfo.StartingOffset.QuadPart)
+        swprintf(Buffer1, L"\\Device\\Harddisk%lu\\Partition0", i);
+        RtlInitUnicodeString(&UnicodeString1, Buffer1);
+
+        InitializeObjectAttributes(&ObjectAttributes,
+            &UnicodeString1,
+            0,
+            NULL,
+            NULL);
+
+        Status = ZwOpenFile(&FileHandle,
+            FILE_READ_DATA | SYNCHRONIZE,
+            &ObjectAttributes,
+            &StatusBlock,
+            FILE_SHARE_READ,
+            FILE_SYNCHRONOUS_IO_NONALERT);
+        if (NT_SUCCESS(Status))
         {
-            /* Return boot if boot flag is set */
-            if (PartitionInfo.Mbr.BootIndicator)
-            {
-                *PartitionType = BootablePartition;
-            }
-            /* Primary otherwise */
-            else
-            {
-                *PartitionType = PrimaryPartition;
-            }
+            ZwClose(FileHandle);
 
-            return STATUS_SUCCESS;
-        }
-    }
+            swprintf(Buffer2, L"\\??\\PhysicalDrive%lu", i);
+            RtlInitUnicodeString(&UnicodeString2, Buffer2);
 
-    /* Otherwise, assume logical */
-    *PartitionType = LogicalPartition;
-    return STATUS_SUCCESS;
-}
+            DPRINT("Creating link: %S ==> %S\n",
+                Buffer2,
+                Buffer1);
 
-PULONG
-IopComputeHarddiskDerangements(IN ULONG DiskCount)
-{
-    PIRP Irp;
-    KEVENT Event;
-    ULONG i, j, k;
-    PULONG Devices;
-    NTSTATUS Status;
-    WCHAR Buffer[100];
-    UNICODE_STRING ArcName;
-    PFILE_OBJECT FileObject;
-    PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK IoStatusBlock;
-    STORAGE_DEVICE_NUMBER DeviceNumber;
+            IoCreateSymbolicLink(&UnicodeString2,
+                &UnicodeString1);
+        }
+    }
 
-    /* No disks, nothing to do */
-    if (DiskCount == 0)
+    /* Initialize layout array */
+    if (ConfigInfo->DiskCount == 0)
+        goto end_assign_disks;
+    LayoutArray = ExAllocatePoolWithTag(NonPagedPool,
+        ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION), TAG_FILE_SYSTEM);
+    if (!LayoutArray)
     {
-        return NULL;
+        ExFreePoolWithTag(PartialInformation, TAG_FILE_SYSTEM);
+        ExFreePoolWithTag(Buffer2, TAG_FILE_SYSTEM);
+        ExFreePoolWithTag(Buffer1, TAG_FILE_SYSTEM);
+        if (hKey) ObCloseHandle(hKey, KernelMode);
+        return;
     }
 
-    /* Allocate a buffer big enough to hold all the disks */
-    Devices = ExAllocatePoolWithTag(PagedPool | POOL_COLD_ALLOCATION,
-                                    sizeof(ULONG) * DiskCount,
-                                    TAG_FSTUB);
-    if (Devices == NULL)
+    RtlZeroMemory(LayoutArray,
+        ConfigInfo->DiskCount * sizeof(PDRIVE_LAYOUT_INFORMATION));
+    for (i = 0; i < ConfigInfo->DiskCount; i++)
     {
-        return NULL;
+        swprintf(Buffer1, L"\\Device\\Harddisk%lu\\Partition0", i);
+        RtlInitUnicodeString(&UnicodeString1, Buffer1);
+
+        Status = xHalQueryDriveLayout(&UnicodeString1, &LayoutArray[i]);
+        if (!NT_SUCCESS(Status))
+        {
+            DbgPrint("xHalQueryDriveLayout() failed (Status = 0x%lx)\n",
+                Status);
+            LayoutArray[i] = NULL;
+            continue;
+        }
+        /* We don't use the RewritePartition value while mounting the disks.
+        * We use this value for marking pre-assigned (registry) partitions.
+        */
+        for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
+        {
+            LayoutArray[i]->PartitionEntry[j].RewritePartition = FALSE;
+        }
     }
 
-    /* Now, we'll query all the disks */
-    for (i = 0; i < DiskCount; ++i)
+#ifndef NDEBUG
+    /* Dump layout array */
+    for (i = 0; i < ConfigInfo->DiskCount; i++)
     {
-        /* Using their ARC name */
-        swprintf(Buffer, L"\\ArcName\\multi(0)disk(0)rdisk(%d)", i);
-        RtlInitUnicodeString(&ArcName, Buffer);
-        /* Get the attached DeviceObject */
-        if (NT_SUCCESS(IoGetDeviceObjectPointer(&ArcName, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject)))
+        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++)
         {
-            DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
-            ObDereferenceObject(FileObject);
+            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
 
-            /* And query it for device number */
-            KeInitializeEvent(&Event, NotificationEvent, FALSE);
-            Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER,
-                                                DeviceObject,
-                                                NULL,
-                                                0,
-                                                &DeviceNumber,
-                                                sizeof(DeviceNumber),
-                                                FALSE,
-                                                &Event,
-                                                &IoStatusBlock);
-            if (Irp != NULL)
+    /* Assign pre-assigned (registry) partitions */
+    if (hKey)
+    {
+        for (k = 2; k < 26; k++)
+        {
+            swprintf(Buffer1, DiskMountString, L'A' + k);
+            RtlInitUnicodeString(&UnicodeString1, Buffer1);
+            Status = ZwQueryValueKey(hKey,
+                &UnicodeString1,
+                KeyValuePartialInformation,
+                PartialInformation,
+                sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(REG_DISK_MOUNT_INFO),
+                &Length);
+            if (NT_SUCCESS(Status) &&
+                PartialInformation->Type == REG_BINARY &&
+                PartialInformation->DataLength == sizeof(REG_DISK_MOUNT_INFO))
             {
-                Status = IoCallDriver(DeviceObject, Irp);
-                if (Status == STATUS_PENDING)
+                DPRINT("%wZ => %08x:%08x%08x\n", &UnicodeString1, DiskMountInfo->Signature,
+                    DiskMountInfo->StartingOffset.u.HighPart, DiskMountInfo->StartingOffset.u.LowPart);
                 {
-                    KeWaitForSingleObject(&Event,
-                                          Executive,
-                                          KernelMode,
-                                          FALSE,
-                                          NULL);
-                    Status = IoStatusBlock.Status;
+                    BOOLEAN Found = FALSE;
+                    for (i = 0; i < ConfigInfo->DiskCount; i++)
+                    {
+                        DPRINT("%x\n", LayoutArray[i]->Signature);
+                        if (LayoutArray[i] &&
+                            LayoutArray[i]->Signature &&
+                            LayoutArray[i]->Signature == DiskMountInfo->Signature)
+                        {
+                            for (j = 0; j < LayoutArray[i]->PartitionCount; j++)
+                            {
+                                if (LayoutArray[i]->PartitionEntry[j].StartingOffset.QuadPart == DiskMountInfo->StartingOffset.QuadPart)
+                                {
+                                    if (IsRecognizedPartition(LayoutArray[i]->PartitionEntry[j].PartitionType) &&
+                                        LayoutArray[i]->PartitionEntry[j].RewritePartition == FALSE)
+                                    {
+                                        swprintf(Buffer2,
+                                                 L"\\Device\\Harddisk%lu\\Partition%lu",
+                                                 i,
+                                                 LayoutArray[i]->PartitionEntry[j].PartitionNumber);
+                                        RtlInitUnicodeString(&UnicodeString2, Buffer2);
+
+                                        /* Assign drive */
+                                        DPRINT("  %wZ\n", &UnicodeString2);
+                                        Found = HalpAssignDrive(&UnicodeString2,
+                                            k,
+                                            DOSDEVICE_DRIVE_FIXED,
+                                            DiskMountInfo->Signature,
+                                            DiskMountInfo->StartingOffset,
+                                            NULL,
+                                            &BootDevice,
+                                            NtSystemPath);
+                                        /* Mark the partition as assigned */
+                                        LayoutArray[i]->PartitionEntry[j].RewritePartition = TRUE;
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if (Found == FALSE)
+                    {
+                        /* We didn't find a partition for this entry, remove them. */
+                        Status = ZwDeleteValueKey(hKey, &UnicodeString1);
+                    }
                 }
+            }
+        }
+    }
 
-                ObDereferenceObject(DeviceObject);
-
-                /* In case of a success remember device number */
-                if (NT_SUCCESS(Status))
+    /* Assign bootable partition on first harddisk */
+    DPRINT("Assigning bootable primary partition on first harddisk:\n");
+    if (RDiskCount > 0)
+    {
+        Status = xHalpGetDiskNumberFromRDisk(0, &DiskNumber);
+        if (NT_SUCCESS(Status) &&
+            DiskNumber < ConfigInfo->DiskCount &&
+            LayoutArray[DiskNumber])
+        {
+            /* Search for bootable partition */
+            for (j = 0; j < NUM_PARTITION_TABLE_ENTRIES && j < LayoutArray[DiskNumber]->PartitionCount; j++)
+            {
+                if ((LayoutArray[DiskNumber]->PartitionEntry[j].BootIndicator != FALSE) &&
+                    IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType))
                 {
-                    Devices[i] = DeviceNumber.DeviceNumber;
-                    /* Move on, not to fall into our default case */
-                    continue;
+                    if (LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE)
+                    {
+                        swprintf(Buffer2,
+                                 L"\\Device\\Harddisk%lu\\Partition%lu",
+                                 DiskNumber,
+                                 LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
+                        RtlInitUnicodeString(&UnicodeString2, Buffer2);
+
+                        /* Assign drive */
+                        DPRINT("  %wZ\n", &UnicodeString2);
+                        HalpAssignDrive(&UnicodeString2,
+                            AUTO_DRIVE,
+                            DOSDEVICE_DRIVE_FIXED,
+                            LayoutArray[DiskNumber]->Signature,
+                            LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
+                            hKey,
+                            &BootDevice,
+                            NtSystemPath);
+                        /* Mark the partition as assigned */
+                        LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
+                    }
+                    break;
                 }
             }
-            else
-            {
-                ObDereferenceObject(DeviceObject);
-            }
-
-            /* Default case, for failures, set -1 */
-            Devices[i] = -1;
         }
     }
 
-    /* Now, we'll check all device numbers */
-    for (i = 0; i < DiskCount; ++i)
+    /* Assign remaining primary partitions */
+    DPRINT("Assigning remaining primary partitions:\n");
+    for (RDisk = 0; RDisk < RDiskCount; RDisk++)
     {
-        /* First of all, check if we're at the right place */
-        for (j = 0; j < DiskCount; ++j)
+        Status = xHalpGetDiskNumberFromRDisk(RDisk, &DiskNumber);
+        if (NT_SUCCESS(Status) &&
+            DiskNumber < ConfigInfo->DiskCount &&
+            LayoutArray[DiskNumber])
         {
-            if (Devices[j] == i)
+            /* Search for primary partitions */
+            for (j = 0; (j < NUM_PARTITION_TABLE_ENTRIES) && (j < LayoutArray[DiskNumber]->PartitionCount); j++)
             {
-                break;
+                if (LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
+                    IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType))
+                {
+                    swprintf(Buffer2,
+                             L"\\Device\\Harddisk%lu\\Partition%lu",
+                             DiskNumber,
+                             LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
+                    RtlInitUnicodeString(&UnicodeString2, Buffer2);
+
+                    /* Assign drive */
+                    DPRINT("  %wZ\n",
+                        &UnicodeString2);
+                    HalpAssignDrive(&UnicodeString2,
+                        AUTO_DRIVE,
+                        DOSDEVICE_DRIVE_FIXED,
+                        LayoutArray[DiskNumber]->Signature,
+                        LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
+                        hKey,
+                        &BootDevice,
+                        NtSystemPath);
+                    /* Mark the partition as assigned */
+                    LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
+                }
             }
         }
+    }
 
-        /* If not, perform the change */
-        if (j >= DiskCount)
+    /* Assign extended (logical) partitions */
+    DPRINT("Assigning extended (logical) partitions:\n");
+    for (RDisk = 0; RDisk < RDiskCount; RDisk++)
+    {
+        Status = xHalpGetDiskNumberFromRDisk(RDisk, &DiskNumber);
+        if (NT_SUCCESS(Status) &&
+            DiskNumber < ConfigInfo->DiskCount &&
+            LayoutArray[DiskNumber])
         {
-            k = 0;
-            while (Devices[k] != -1)
+            /* Search for extended partitions */
+            for (j = NUM_PARTITION_TABLE_ENTRIES; j < LayoutArray[DiskNumber]->PartitionCount; j++)
             {
-                if (++k >= DiskCount)
+                if (IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType) &&
+                    LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
+                    LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber != 0)
                 {
-                    break;
+                    swprintf(Buffer2,
+                             L"\\Device\\Harddisk%lu\\Partition%lu",
+                             DiskNumber,
+                             LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
+                    RtlInitUnicodeString(&UnicodeString2, Buffer2);
+
+                    /* Assign drive */
+                    DPRINT("  %wZ\n",
+                        &UnicodeString2);
+                    HalpAssignDrive(&UnicodeString2,
+                        AUTO_DRIVE,
+                        DOSDEVICE_DRIVE_FIXED,
+                        LayoutArray[DiskNumber]->Signature,
+                        LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
+                        hKey,
+                        &BootDevice,
+                        NtSystemPath);
+                    /* Mark the partition as assigned */
+                    LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
                 }
             }
+        }
+    }
 
-            if (k < DiskCount)
+    /* Assign remaining primary partitions without an arc-name */
+    DPRINT("Assigning remaining primary partitions:\n");
+    for (DiskNumber = 0; DiskNumber < ConfigInfo->DiskCount; DiskNumber++)
+    {
+        if (LayoutArray[DiskNumber])
+        {
+            /* Search for primary partitions */
+            for (j = 0; (j < NUM_PARTITION_TABLE_ENTRIES) && (j < LayoutArray[DiskNumber]->PartitionCount); j++)
             {
-                Devices[k] = i;
+                if (LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
+                    IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType))
+                {
+                    swprintf(Buffer2,
+                             L"\\Device\\Harddisk%lu\\Partition%lu",
+                             DiskNumber,
+                             LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
+                    RtlInitUnicodeString(&UnicodeString2, Buffer2);
+
+                    /* Assign drive */
+                    DPRINT("  %wZ\n",
+                        &UnicodeString2);
+                    HalpAssignDrive(&UnicodeString2,
+                        AUTO_DRIVE,
+                        DOSDEVICE_DRIVE_FIXED,
+                        LayoutArray[DiskNumber]->Signature,
+                        LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
+                        hKey,
+                        &BootDevice,
+                        NtSystemPath);
+                    /* Mark the partition as assigned */
+                    LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
+                }
             }
         }
     }
 
-    /* Return our device derangement map */
-    return Devices;
-}
-
-NTSTATUS
-HalpNextMountLetter(IN PUNICODE_STRING DeviceName,
-                    OUT PUCHAR DriveLetter)
-{
-    PIRP Irp;
-    KEVENT Event;
-    NTSTATUS Status;
-    UNICODE_STRING MountMgr;
-    PFILE_OBJECT FileObject;
-    PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PMOUNTMGR_DRIVE_LETTER_TARGET Target;
-    MOUNTMGR_DRIVE_LETTER_INFORMATION LetterInfo;
-
-    /* To get next mount letter, we need the MountMgr */
-    RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
-    Status = IoGetDeviceObjectPointer(&MountMgr,
-                                      FILE_READ_ATTRIBUTES,
-                                      &FileObject,
-                                      &DeviceObject);
-    if (!NT_SUCCESS(Status))
-    {
-        return Status;
-    }
-
-    /* Allocate our input buffer */
-    Target = ExAllocatePoolWithTag(PagedPool,
-                                   DeviceName->Length + FIELD_OFFSET(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName),
-                                   TAG_FSTUB);
-    if (Target == NULL)
-    {
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* And fill it with the device hat needs a drive letter */
-    Target->DeviceNameLength = DeviceName->Length;
-    RtlCopyMemory(&Target->DeviceName[0], DeviceName->Buffer, DeviceName->Length);
-
-    /* Call the mount manager */
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER,
-                                        DeviceObject,
-                                        Target,
-                                        DeviceName->Length + FIELD_OFFSET(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName),
-                                        &LetterInfo,
-                                        sizeof(LetterInfo),
-                                        FALSE,
-                                        &Event,
-                                        &IoStatusBlock);
-    if (Irp == NULL)
-    {
-        ExFreePoolWithTag(Target, TAG_FSTUB);
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    Status = IoCallDriver(DeviceObject, Irp);
-    if (Status == STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&Event,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
-        Status = IoStatusBlock.Status;
-    }
-
-    ExFreePoolWithTag(Target, TAG_FSTUB);
-    ObDereferenceObject(FileObject);
-
-    DPRINT("Done: %d %c\n", LetterInfo.DriveLetterWasAssigned,
-                            LetterInfo.CurrentDriveLetter);
-
-    /* Return the drive letter the MountMgr potentially assigned */
-    *DriveLetter = LetterInfo.CurrentDriveLetter;
-
-    /* Also return the success */
-    return Status;
-}
-
-NTSTATUS
-HalpSetMountLetter(IN PUNICODE_STRING DeviceName,
-                   UCHAR DriveLetter)
-{
-    PIRP Irp;
-    KEVENT Event;
-    NTSTATUS Status;
-    WCHAR Buffer[30];
-    ULONG InputBufferLength;
-    PFILE_OBJECT FileObject;
-    PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK IoStatusBlock;
-    UNICODE_STRING DosDevice, MountMgr;
-    PMOUNTMGR_CREATE_POINT_INPUT InputBuffer;
-
-    /* Setup the DosDevice name */
-    swprintf(Buffer, L"\\DosDevices\\%c:", DriveLetter);
-    RtlInitUnicodeString(&DosDevice, Buffer);
-
-    /* Allocate the input buffer for the MountMgr */
-    InputBufferLength = DosDevice.Length + DeviceName->Length + sizeof(MOUNTMGR_CREATE_POINT_INPUT);
-    InputBuffer = ExAllocatePoolWithTag(PagedPool, InputBufferLength, TAG_FSTUB);
-    if (InputBuffer == NULL)
-    {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* Fill the input buffer */
-    InputBuffer->SymbolicLinkNameOffset = sizeof(MOUNTMGR_CREATE_POINT_INPUT);
-    InputBuffer->SymbolicLinkNameLength = DosDevice.Length;
-    InputBuffer->DeviceNameOffset = DosDevice.Length + sizeof(MOUNTMGR_CREATE_POINT_INPUT);
-    InputBuffer->DeviceNameLength = DeviceName->Length;
-    RtlCopyMemory(&InputBuffer[1], DosDevice.Buffer, DosDevice.Length);
-    RtlCopyMemory((PVOID)((ULONG_PTR)InputBuffer + InputBuffer->DeviceNameOffset),
-                  DeviceName->Buffer,
-                  DeviceName->Length);
-
-    /* Get the MountMgr device pointer, to send the IOCTL */
-    RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
-    Status = IoGetDeviceObjectPointer(&MountMgr,
-                                      FILE_READ_ATTRIBUTES,
-                                      &FileObject,
-                                      &DeviceObject);
-    if (!NT_SUCCESS(Status))
+    /* Assign extended (logical) partitions without an arc-name */
+    DPRINT("Assigning extended (logical) partitions:\n");
+    for (DiskNumber = 0; DiskNumber < ConfigInfo->DiskCount; DiskNumber++)
     {
-        ExFreePoolWithTag(InputBuffer, TAG_FSTUB);
-        return Status;
-    }
-
-    /* Call the MountMgr */
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_CREATE_POINT,
-                                        DeviceObject,
-                                        InputBuffer,
-                                        InputBufferLength,
-                                        NULL,
-                                        0,
-                                        FALSE,
-                                        &Event,
-                                        &IoStatusBlock);
-    if (Irp == NULL)
-    {
-        ObDereferenceObject(FileObject);
-        ExFreePoolWithTag(InputBuffer, TAG_FSTUB);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    Status = IoCallDriver(DeviceObject, Irp);
-    if (Status == STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&Event,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
-        Status = IoStatusBlock.Status;
-    }
-
-    ObDereferenceObject(FileObject);
-    ExFreePoolWithTag(InputBuffer, TAG_FSTUB);
-
-    /* Return the MountMgr status */
-    return Status;
-}
-
-UCHAR
-HalpNextDriveLetter(IN PUNICODE_STRING DeviceName,
-                    IN PSTRING NtDeviceName,
-                    OUT PUCHAR NtSystemPath,
-                    BOOLEAN IsRemovable)
-{
-    UCHAR i;
-    WCHAR Buffer[40];
-    UCHAR DriveLetter;
-    UNICODE_STRING FloppyString, CdString, NtDeviceNameU, DosDevice;
-
-    /* Quick path, ask directly the mount manager to assign the next
-     * free drive letter
-     */
-    if (NT_SUCCESS(HalpNextMountLetter(DeviceName, &DriveLetter)))
-    {
-        return DriveLetter;
-    }
-
-    /* We'll allow MountMgr to fail only for non vital path */
-    if (NtDeviceName == NULL || NtSystemPath == NULL)
-    {
-        return -1;
-    }
-
-    /* And for removable devices */
-    if (!IsRemovable)
-    {
-        return 0;
-    }
-
-    /* Removable might be floppy or cdrom */
-    RtlInitUnicodeString(&FloppyString, L"\\Device\\Floppy");
-    RtlInitUnicodeString(&CdString, L"\\Device\\CdRom");
-
-    /* If floppy, start at A */
-    if (RtlPrefixUnicodeString(&FloppyString, DeviceName, TRUE))
-    {
-        DriveLetter = 'A';
-    }
-    /* If CD start C */
-    else if (RtlPrefixUnicodeString(&CdString, DeviceName, TRUE))
-    {
-        DriveLetter = 'D';
-    }
-    /* For the rest start at C */
-    else
-    {
-        DriveLetter = 'C';
-    }
-
-    /* Now, try to assign a drive letter manually with the MountMgr */
-    for (i = DriveLetter; i <= 'Z'; ++i)
-    {
-        if (NT_SUCCESS(HalpSetMountLetter(DeviceName, i)))
+        if (LayoutArray[DiskNumber])
         {
-            /* If it worked, if we were managing system path, update manually */
-            if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&NtDeviceNameU, NtDeviceName, TRUE)))
+            /* Search for extended partitions */
+            for (j = NUM_PARTITION_TABLE_ENTRIES; j < LayoutArray[DiskNumber]->PartitionCount; j++)
             {
-                if (RtlEqualUnicodeString(&NtDeviceNameU, DeviceName, TRUE))
+                if (IsRecognizedPartition(LayoutArray[DiskNumber]->PartitionEntry[j].PartitionType) &&
+                    LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition == FALSE &&
+                    LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber != 0)
                 {
-                    *NtSystemPath = i;
+                    swprintf(Buffer2,
+                             L"\\Device\\Harddisk%lu\\Partition%lu",
+                             DiskNumber,
+                             LayoutArray[DiskNumber]->PartitionEntry[j].PartitionNumber);
+                    RtlInitUnicodeString(&UnicodeString2, Buffer2);
+
+                    /* Assign drive */
+                    DPRINT("  %wZ\n",
+                        &UnicodeString2);
+                    HalpAssignDrive(&UnicodeString2,
+                        AUTO_DRIVE,
+                        DOSDEVICE_DRIVE_FIXED,
+                        LayoutArray[DiskNumber]->Signature,
+                        LayoutArray[DiskNumber]->PartitionEntry[j].StartingOffset,
+                        hKey,
+                        &BootDevice,
+                        NtSystemPath);
+                    /* Mark the partition as assigned */
+                    LayoutArray[DiskNumber]->PartitionEntry[j].RewritePartition = TRUE;
                 }
-
-                RtlFreeUnicodeString(&NtDeviceNameU);
             }
-
-            return i;
         }
     }
 
-    /* Last fall back, we're not on a PnP device... */
-    for (i = DriveLetter; i <= 'Z'; ++i)
+    /* Assign removable disk drives */
+    DPRINT("Assigning removable disk drives:\n");
+    for (i = 0; i < ConfigInfo->DiskCount; i++)
     {
-        /* We'll link manually, without MountMgr knowing anything about the device */
-        swprintf(Buffer, L"\\DosDevices\\%c:", i);
-        RtlInitUnicodeString(&DosDevice, Buffer);
-
-        /* If linking worked, then the letter was free ;-) */
-        if (NT_SUCCESS(IoCreateSymbolicLink(&DosDevice, DeviceName)))
+        if (LayoutArray[i])
         {
-            /* If it worked, if we were managing system path, update manually */
-            if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&NtDeviceNameU, NtDeviceName, TRUE)))
+            /* Search for virtual partitions */
+            if (LayoutArray[i]->PartitionCount == 1 &&
+                LayoutArray[i]->PartitionEntry[0].PartitionType == 0)
             {
-                if (RtlEqualUnicodeString(&NtDeviceNameU, DeviceName, TRUE))
-                {
-                    *NtSystemPath = i;
-                }
-
-                RtlFreeUnicodeString(&NtDeviceNameU);
+                swprintf(Buffer2, L"\\Device\\Harddisk%lu\\Partition1", i);
+                RtlInitUnicodeString(&UnicodeString2, Buffer2);
+
+                /* Assign drive */
+                DPRINT("  %wZ\n",
+                    &UnicodeString2);
+                HalpAssignDrive(&UnicodeString2,
+                    AUTO_DRIVE,
+                    DOSDEVICE_DRIVE_REMOVABLE,
+                    0,
+                    RtlConvertLongToLargeInteger(0),
+                    hKey,
+                    &BootDevice,
+                    NtSystemPath);
             }
-
-            return i;
         }
     }
 
-    /* We're done, nothing happened */
-    return 0;
-}
-
-BOOLEAN
-HalpIsOldStyleFloppy(PUNICODE_STRING DeviceName)
-{
-    PIRP Irp;
-    KEVENT Event;
-    NTSTATUS Status;
-    MOUNTDEV_NAME DevName;
-    PFILE_OBJECT FileObject;
-    PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PAGED_CODE();
-
-    /* Get the attached device object to our device */
-    if (!NT_SUCCESS(IoGetDeviceObjectPointer(DeviceName,
-                                             FILE_READ_ATTRIBUTES,
-                                             &FileObject,
-                                             &DeviceObject)))
-    {
-        return FALSE;
-    }
-
-    DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
-    ObDereferenceObject(FileObject);
-
-    /* Query its device name (ie, check floppy.sys implements MountMgr interface) */
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
-                                        DeviceObject,
-                                        NULL,
-                                        0,
-                                        &DevName,
-                                        sizeof(DevName),
-                                        FALSE,
-                                        &Event,
-                                        &IoStatusBlock);
-    if (Irp == NULL)
-    {
-        ObDereferenceObject(DeviceObject);
-        return FALSE;
-    }
-
-    Status = IoCallDriver(DeviceObject, Irp);
-    if (Status == STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&Event,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
-        Status = IoStatusBlock.Status;
-    }
-
-    /* If status is not STATUS_BUFFER_OVERFLOW, it means
-     * it's pre-mountmgr driver, aka "Old style".
-     */
-    ObDereferenceObject(DeviceObject);
-    return (Status != STATUS_BUFFER_OVERFLOW);
-}
-
-NTSTATUS
-HalpDeleteMountLetter(UCHAR DriveLetter)
-{
-    PIRP Irp;
-    KEVENT Event;
-    NTSTATUS Status;
-    WCHAR Buffer[30];
-    ULONG InputBufferLength;
-    PFILE_OBJECT FileObject;
-    PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PMOUNTMGR_MOUNT_POINT InputBuffer;
-    UNICODE_STRING DosDevice, MountMgr;
-    PMOUNTMGR_MOUNT_POINTS OutputBuffer;
-
-    /* Setup the device name of the letter to delete */
-    swprintf(Buffer, L"\\DosDevices\\%c:", DriveLetter);
-    RtlInitUnicodeString(&DosDevice, Buffer);
-
-    /* Allocate the input buffer for MountMgr */
-    InputBufferLength = DosDevice.Length + sizeof(MOUNTMGR_MOUNT_POINT);
-    InputBuffer = ExAllocatePoolWithTag(PagedPool, InputBufferLength, TAG_FSTUB);
-    if (InputBuffer == NULL)
-    {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* Fill it in */
-    RtlZeroMemory(InputBuffer, InputBufferLength);
-    InputBuffer->SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
-    InputBuffer->SymbolicLinkNameLength = DosDevice.Length;
-    RtlCopyMemory(&InputBuffer[1], DosDevice.Buffer, DosDevice.Length);
-
-    /* Allocate big enough output buffer (we don't care about the output) */
-    OutputBuffer = ExAllocatePoolWithTag(PagedPool, 0x1000, TAG_FSTUB);
-    if (OutputBuffer == NULL)
-    {
-        ExFreePoolWithTag(InputBuffer, TAG_FSTUB);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* Get the device pointer to the MountMgr */
-    RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
-    Status = IoGetDeviceObjectPointer(&MountMgr,
-                                      FILE_READ_ATTRIBUTES,
-                                      &FileObject,
-                                      &DeviceObject);
-    if (!NT_SUCCESS(Status))
-    {
-        ExFreePoolWithTag(OutputBuffer, TAG_FSTUB);
-        ExFreePoolWithTag(InputBuffer, TAG_FSTUB);
-        return Status;
-    }
-
-    /* Call the mount manager to delete the drive letter */
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_DELETE_POINTS,
-                                        DeviceObject,
-                                        InputBuffer,
-                                        InputBufferLength,
-                                        OutputBuffer,
-                                        0x1000,
-                                        FALSE,
-                                        &Event,
-                                        &IoStatusBlock);
-    if (Irp == NULL)
+    /* Free layout array */
+    for (i = 0; i < ConfigInfo->DiskCount; i++)
     {
-        ObDereferenceObject(FileObject);
-        ExFreePoolWithTag(OutputBuffer, TAG_FSTUB);
-        ExFreePoolWithTag(InputBuffer, TAG_FSTUB);
-        return STATUS_INSUFFICIENT_RESOURCES;
+        if (LayoutArray[i] != NULL)
+            ExFreePoolWithTag(LayoutArray[i], TAG_FILE_SYSTEM);
     }
+    ExFreePoolWithTag(LayoutArray, TAG_FILE_SYSTEM);
+end_assign_disks:
 
-    Status = IoCallDriver(DeviceObject, Irp);
-    if (Status == STATUS_PENDING)
+    /* Assign floppy drives */
+    DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
+    for (i = 0; i < ConfigInfo->FloppyCount; i++)
     {
-        KeWaitForSingleObject(&Event,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
-        Status = IoStatusBlock.Status;
-    }
-
-    ObDereferenceObject(FileObject);
-    ExFreePoolWithTag(OutputBuffer, TAG_FSTUB);
-    ExFreePoolWithTag(InputBuffer, TAG_FSTUB);
-
-    return Status;
-}
-
-VOID
-HalpEnableAutomaticDriveLetterAssignment(VOID)
-{
-    PIRP Irp;
-    KEVENT Event;
-    NTSTATUS Status;
-    UNICODE_STRING MountMgr;
-    PFILE_OBJECT FileObject;
-    PDEVICE_OBJECT DeviceObject;
-    IO_STATUS_BLOCK IoStatusBlock;
+        swprintf(Buffer1, L"\\Device\\Floppy%lu", i);
+        RtlInitUnicodeString(&UnicodeString1, Buffer1);
 
-    /* Get the device pointer to the MountMgr */
-    RtlInitUnicodeString(&MountMgr, L"\\Device\\MountPointManager");
-    Status = IoGetDeviceObjectPointer(&MountMgr,
-                                      FILE_READ_ATTRIBUTES,
-                                      &FileObject,
-                                      &DeviceObject);
-    if (!NT_SUCCESS(Status))
-    {
-        return;
+        /* Assign drive letters A: or B: or first free drive letter */
+        DPRINT("  %wZ\n",
+            &UnicodeString1);
+        HalpAssignDrive(&UnicodeString1,
+            (i < 2) ? i : AUTO_DRIVE,
+            DOSDEVICE_DRIVE_REMOVABLE,
+            0,
+            RtlConvertLongToLargeInteger(0),
+            hKey,
+            &BootDevice,
+            NtSystemPath);
     }
 
-    /* Just send an IOCTL to enable the feature */
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS,
-                                        DeviceObject,
-                                        NULL,
-                                        0,
-                                        NULL,
-                                        0,
-                                        FALSE,
-                                        &Event,
-                                        &IoStatusBlock);
-    if (Irp == NULL)
+    /* Assign cdrom drives */
+    DPRINT("CD-Rom drives: %lu\n", ConfigInfo->CdRomCount);
+    for (i = 0; i < ConfigInfo->CdRomCount; i++)
     {
-        return;
-    }
+        swprintf(Buffer1, L"\\Device\\CdRom%lu", i);
+        RtlInitUnicodeString(&UnicodeString1, Buffer1);
 
-    Status = IoCallDriver(DeviceObject, Irp);
-    if (Status == STATUS_PENDING)
-    {
-        KeWaitForSingleObject(&Event,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
-        Status = IoStatusBlock.Status;
+        /* Assign first free drive letter */
+        DPRINT("  %wZ\n", &UnicodeString1);
+        HalpAssignDrive(&UnicodeString1,
+            AUTO_DRIVE,
+            DOSDEVICE_DRIVE_CDROM,
+            0,
+            RtlConvertLongToLargeInteger(0),
+            hKey,
+            &BootDevice,
+            NtSystemPath);
     }
 
-    ObDereferenceObject(FileObject);
+    /* Anything else to do? */
 
-    return;
+    ExFreePoolWithTag(PartialInformation, TAG_FILE_SYSTEM);
+    ExFreePoolWithTag(Buffer2, TAG_FILE_SYSTEM);
+    ExFreePoolWithTag(Buffer1, TAG_FILE_SYSTEM);
+    if (hKey) ObCloseHandle(hKey, KernelMode);
 }
 
-VOID
-FASTCALL
-xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
-                         IN PSTRING NtDeviceName,
-                         OUT PUCHAR NtSystemPath,
-                         OUT PSTRING NtSystemPathString)
-{
-    USHORT i;
-    PULONG Devices;
-    NTSTATUS Status;
-    WCHAR Buffer[50];
-    HANDLE FileHandle;
-    UCHAR DriveLetter;
-    BOOLEAN SystemFound;
-    IO_STATUS_BLOCK StatusBlock;
-    PARTITION_TYPE PartitionType;
-    ANSI_STRING StringA1, StringA2;
-    PSTR Buffer1, Buffer2, LoadOptions;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    PDRIVE_LAYOUT_INFORMATION LayoutInfo;
-    PCONFIGURATION_INFORMATION ConfigInfo;
-    UNICODE_STRING StringU1, StringU2, StringU3;
-    ULONG Increment, DiskCount, RealDiskCount, HarddiskCount, PartitionCount, SystemPartition;
-
-    PAGED_CODE();
-
-    /* Get our disk count */
-    ConfigInfo = IoGetConfigurationInformation();
-    DiskCount = ConfigInfo->DiskCount;
-    RealDiskCount = 0;
-
-    /* Allocate two generic string buffers we'll use and reuser later on */
-    Buffer1 = ExAllocatePoolWithTag(NonPagedPool, 128, TAG_FSTUB);
-    Buffer2 = ExAllocatePoolWithTag(NonPagedPool, 64, TAG_FSTUB);
-    if (Buffer1 == NULL || Buffer2 == NULL)
-    {
-        KeBugCheck(ASSIGN_DRIVE_LETTERS_FAILED);
-    }
-
-    /* In case of a remote boot, setup system path */
-    if (IoRemoteBootClient)
-    {
-        PSTR Last, Saved;
-
-        /* Find last \ */
-        Last = strrchr(LoaderBlock->NtBootPathName, '\\');
-        Saved = NULL;
-        /* Misformed name, fail */
-        if (Last == NULL)
-        {
-            KeBugCheck(ASSIGN_DRIVE_LETTERS_FAILED);
-        }
-
-        /* In case the name was terminated by a \... */
-        if (Last[1] == ANSI_NULL)
-        {
-            /* Erase it, save position and find the previous \ */
-            *Last = ANSI_NULL;
-            Saved = Last;
-            Last = strrchr(LoaderBlock->NtBootPathName, '\\');
-            *Saved = '\\';
-        }
-
-        /* Misformed name, fail */
-        if (Last == NULL)
-        {
-            KeBugCheck(ASSIGN_DRIVE_LETTERS_FAILED);
-        }
-
-        /* For a remote boot, assign X drive letter */
-        NtSystemPath[0] = 'X';
-        NtSystemPath[1] = ':';
-        /* And copy the end of the boot path */
-        strcpy((PSTR)&NtSystemPath[2], Last);
-
-        /* If we had to remove the trailing \, remove it here too */
-        if (Saved != NULL)
-        {
-            NtSystemPath[strlen((PSTR)NtSystemPath) - 1] = ANSI_NULL;
-        }
-
-        /* Setup output string */
-        RtlInitString(NtSystemPathString, (PSTR)NtSystemPath);
-    }
-
-    /* For each of our disks, create the physical device DOS device */
-    Increment = 0;
-    if (DiskCount != 0)
-    {
-        for (i = 0; i < DiskCount; ++i)
-        {
-            /* Setup the origin name */
-            sprintf(Buffer1, "\\Device\\Harddisk%d\\Partition%d", i, 0);
-            RtlInitAnsiString(&StringA1, Buffer1);
-            if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&StringU1, &StringA1, TRUE)))
-            {
-                /* We cannot fail */
-                KeBugCheck(ASSIGN_DRIVE_LETTERS_FAILED);
-            }
-
-            /* Open the device */
-            InitializeObjectAttributes(&ObjectAttributes,
-                                       &StringU1,
-                                       OBJ_CASE_INSENSITIVE,
-                                       NULL,
-                                       NULL);
-            Status = ZwOpenFile(&FileHandle,
-                                SYNCHRONIZE | FILE_READ_DATA,
-                                &ObjectAttributes,
-                                &StatusBlock,
-                                FILE_SHARE_READ,
-                                FILE_SYNCHRONOUS_IO_NONALERT);
-            if (NT_SUCCESS(Status))
-            {
-                /* If we managed, create the link */
-                sprintf(Buffer2, "\\DosDevices\\PhysicalDrive%d", i);
-                RtlInitAnsiString(&StringA2, Buffer2);
-                Status = RtlAnsiStringToUnicodeString(&StringU2, &StringA2, TRUE);
-                if (NT_SUCCESS(Status))
-                {
-                    IoCreateSymbolicLink(&StringU2, &StringU1);
-                    RtlFreeUnicodeString(&StringU2);
-                }
-
-                ZwClose(FileHandle);
-
-                RealDiskCount = i + 1;
-            }
-
-            RtlFreeUnicodeString(&StringU1);
-
-            if (!NT_SUCCESS(Status))
-            {
-                if (Increment < 50)
-                {
-                    ++Increment;
-                    ++DiskCount;
-                }
-            }
-        }
-    }
-
-    /* We done for our buffers */
-    ExFreePoolWithTag(Buffer1, TAG_FSTUB);
-    ExFreePoolWithTag(Buffer2, TAG_FSTUB);
-
-    /* Upcase our load options, if any */
-    if (LoaderBlock->LoadOptions != NULL)
-    {
-        LoadOptions = _strupr(LoaderBlock->LoadOptions);
-    }
-    else
-    {
-        LoadOptions = NULL;
-    }
-
-    /* If we boot with /MININT (system hive as volatile) option, assign X letter to boot device */
-    if (LoadOptions != NULL &&
-        strstr(LoadOptions, "MININT") != 0 &&
-        NT_SUCCESS(RtlAnsiStringToUnicodeString(&StringU1, NtDeviceName, TRUE)))
-    {
-        if (NT_SUCCESS(HalpSetMountLetter(&StringU1, 'X')))
-        {
-            *NtSystemPath = 'X';
-        }
-
-        RtlFreeUnicodeString(&StringU1);
-    }
-
-    /* Compute our disks derangements */
-    DiskCount -= Increment;
-    if (RealDiskCount > DiskCount)
-    {
-        DiskCount = RealDiskCount;
-    }
-    Devices = IopComputeHarddiskDerangements(DiskCount);
-
-    /* Now, start browsing all our disks for assigning drive letters
-     * Here, we'll only handle boot partition and primary partitions
-     */
-    HarddiskCount = 0;
-    for (i = 0; i < DiskCount; ++i)
-    {
-        /* Get device ID according to derangements map */
-        if (Devices != NULL)
-        {
-            HarddiskCount = Devices[i];
-        }
-
-        /* Query disk layout */
-        swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", HarddiskCount);
-        RtlInitUnicodeString(&StringU1, Buffer);
-        if (!NT_SUCCESS(HalpQueryDriveLayout(&StringU1, &LayoutInfo)))
-        {
-            LayoutInfo = NULL;
-        }
-
-        /* Assume we didn't find system */
-        SystemFound = FALSE;
-        swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, 1);
-        RtlInitUnicodeString(&StringU1, Buffer);
-        /* Query partition info for our disk */
-        if (!NT_SUCCESS(HalpQueryPartitionType(&StringU1, LayoutInfo, &PartitionType)))
-        {
-            /* It failed, retry for all the partitions */
-            for (PartitionCount = 1; ; ++PartitionCount)
-            {
-                swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
-                RtlInitUnicodeString(&StringU1, Buffer);
-                if (!NT_SUCCESS(HalpQueryPartitionType(&StringU1, LayoutInfo, &PartitionType)))
-                {
-                    break;
-                }
-
-                /* We found a primary partition, assign a drive letter */
-                if (PartitionType == PrimaryPartition)
-                {
-                    HalpNextDriveLetter(&StringU1, NtDeviceName, NtSystemPath, 0);
-                    break;
-                }
-            }
-        }
-        else
-        {
-            /* All right */
-            for (PartitionCount = 2; ; ++PartitionCount)
-            {
-                /* If our partition is bootable (MBR) or data (GPT), that's system partition */
-                if (PartitionType == BootablePartition || PartitionType == DataPartition)
-                {
-                    SystemFound = TRUE;
-
-                    /* Assign a drive letter and stop here if MBR */
-                    HalpNextDriveLetter(&StringU1, NtDeviceName, NtSystemPath, 0);
-                    if (PartitionType == BootablePartition)
-                    {
-                        break;
-                    }
-                }
-
-                /* Keep looping on all the partitions */
-                swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
-                RtlInitUnicodeString(&StringU1, Buffer);
-                if (!NT_SUCCESS(HalpQueryPartitionType(&StringU1, LayoutInfo, &PartitionType)))
-                {
-                    /* Mount every primary partition if we didn't find system */
-                    if (!SystemFound)
-                    {
-                        for (PartitionCount = 1; ; ++PartitionCount)
-                        {
-                            swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
-                            RtlInitUnicodeString(&StringU1, Buffer);
-                            if (!NT_SUCCESS(HalpQueryPartitionType(&StringU1, LayoutInfo, &PartitionType)))
-                            {
-                                break;
-                            }
-
-                            if (PartitionType == PrimaryPartition)
-                            {
-                                HalpNextDriveLetter(&StringU1, NtDeviceName, NtSystemPath, 0);
-                                break;
-                            }
-                        }
-                    }
-
-                    break;
-                }
-            }
-        }
-
-        /* Free layout, we'll reallocate it for next device */
-        if (LayoutInfo != NULL)
-        {
-            ExFreePoolWithTag(LayoutInfo, TAG_FSTUB);
-        }
-
-        HarddiskCount = i + 1;
-    }
-
-    /* Now, assign logical partitions */
-    for (i = 0; i < DiskCount; ++i)
-    {
-        /* Get device ID according to derangements map */
-        if (Devices != NULL)
-        {
-            HarddiskCount = Devices[i];
-        }
-        else
-        {
-            HarddiskCount = i;
-        }
-
-        /* Query device layout */
-        swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", HarddiskCount);
-        RtlInitUnicodeString(&StringU1, Buffer);
-        if (!NT_SUCCESS(HalpQueryDriveLayout(&StringU1, &LayoutInfo)))
-        {
-            LayoutInfo = NULL;
-        }
-
-        /* And assign drive letter to logical partitions */
-        for (PartitionCount = 1; ; ++PartitionCount)
-        {
-            swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
-            RtlInitUnicodeString(&StringU1, Buffer);
-            if (!NT_SUCCESS(HalpQueryPartitionType(&StringU1, LayoutInfo, &PartitionType)))
-            {
-                break;
-            }
-
-            if (PartitionType == LogicalPartition)
-            {
-                HalpNextDriveLetter(&StringU1, NtDeviceName, NtSystemPath, 0);
-            }
-        }
-
-        /* Free layout, we'll reallocate it for next device */
-        if (LayoutInfo != NULL)
-        {
-            ExFreePoolWithTag(LayoutInfo, 0);
-        }
-    }
-
-    /* Now, assign drive letters to everything else */
-    for (i = 0; i < DiskCount; ++i)
-    {
-        /* Get device ID according to derangements map */
-        if (Devices != NULL)
-        {
-            HarddiskCount = Devices[i];
-        }
-        else
-        {
-            HarddiskCount = i;
-        }
-
-        /* Query device layout */
-        swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition0", HarddiskCount);
-        RtlInitUnicodeString(&StringU1, Buffer);
-        if (!NT_SUCCESS(HalpQueryDriveLayout(&StringU1, &LayoutInfo)))
-        {
-            LayoutInfo = NULL;
-        }
-
-        /* Save system partition if any */
-        SystemPartition = 0;
-        for (PartitionCount = 1; ; ++PartitionCount)
-        {
-            swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
-            RtlInitUnicodeString(&StringU1, Buffer);
-            if (!NT_SUCCESS(HalpQueryPartitionType(&StringU1, LayoutInfo, &PartitionType)))
-            {
-                break;
-            }
-
-            if ((PartitionType == BootablePartition || PartitionType == PrimaryPartition) && (SystemPartition == 0))
-            {
-                SystemPartition = PartitionCount;
-            }
-        }
-
-        /* And assign drive letter to anything but system partition */
-        for (PartitionCount = 1; ; ++PartitionCount)
-        {
-            if (PartitionCount != SystemPartition)
-            {
-                swprintf(Buffer, L"\\Device\\Harddisk%d\\Partition%d", HarddiskCount, PartitionCount);
-                RtlInitUnicodeString(&StringU1, Buffer);
-                if (!NT_SUCCESS(HalpQueryPartitionType(&StringU1, LayoutInfo, &PartitionType)))
-                {
-                    if (LayoutInfo != NULL)
-                    {
-                        ExFreePoolWithTag(LayoutInfo, 0);
-                    }
-
-                    break;
-                }
-
-                if (PartitionType == PrimaryPartition || PartitionType == FtPartition)
-                {
-                    HalpNextDriveLetter(&StringU1, NtDeviceName, NtSystemPath, 0);
-                }
-            }
-        }
-    }
-
-    /* We're done with disks, if we have a device map, free it */
-    if (Devices != NULL)
-    {
-        ExFreePoolWithTag(Devices, TAG_FSTUB);
-    }
-
-    /* Now, assign drive letter to floppy drives */
-    for (i = 0; i < ConfigInfo->FloppyCount; ++i)
-    {
-        swprintf(Buffer, L"\\Device\\Floppy%d", i);
-        RtlInitUnicodeString(&StringU1, Buffer);
-        if (HalpIsOldStyleFloppy(&StringU1))
-        {
-            HalpNextDriveLetter(&StringU1, NtDeviceName, NtSystemPath, TRUE);
-        }
-    }
-
-    /* And CD drives */
-    for (i = 0; i < ConfigInfo->CdRomCount; ++i)
-    {
-        swprintf(Buffer, L"\\Device\\CdRom%d", i);
-        RtlInitUnicodeString(&StringU1, Buffer);
-        HalpNextDriveLetter(&StringU1, NtDeviceName, NtSystemPath, TRUE);
-    }
-
-    /* If not remote boot, handle NtDeviceName */
-    if (!IoRemoteBootClient && NT_SUCCESS(RtlAnsiStringToUnicodeString(&StringU1, NtDeviceName, TRUE)))
-    {
-        /* Assign it a drive letter */
-        DriveLetter = HalpNextDriveLetter(&StringU1, NULL, NULL, TRUE);
-        if (DriveLetter != 0)
-        {
-            if (DriveLetter != 0xFF)
-            {
-                *NtSystemPath = DriveLetter;
-            }
-        }
-        /* If it fails through mount manager, retry manually */
-        else
-        {
-            RtlInitUnicodeString(&StringU2, L"\\Device\\Floppy");
-            RtlInitUnicodeString(&StringU3, L"\\Device\\CdRom");
-
-            if (RtlPrefixUnicodeString(&StringU2, &StringU1, TRUE))
-            {
-                DriveLetter = 'A';
-            }
-            else if (RtlPrefixUnicodeString(&StringU3, &StringU1, TRUE))
-            {
-                DriveLetter = 'D';
-            }
-            else
-            {
-                DriveLetter = 'C';
-            }
-
-            /* Try any drive letter */
-            while (HalpSetMountLetter(&StringU1, DriveLetter) != STATUS_SUCCESS)
-            {
-                ++DriveLetter;
-
-                if (DriveLetter > 'Z')
-                {
-                    break;
-                }
-            }
-
-            /* If we're beyond Z (ie, no slot left) */
-            if (DriveLetter > 'Z')
-            {
-                /* Delete Z, and reuse it for system */
-                HalpDeleteMountLetter('Z');
-                HalpSetMountLetter(&StringU1, 'Z');
-                *NtSystemPath = 'Z';
-            }
-            else
-            {
-                /* Return matching drive letter */
-                *NtSystemPath = DriveLetter;
-            }
-        }
-
-        RtlFreeUnicodeString(&StringU1);
-    }
-
-    /* Enable auto assignement for mountmgr */
-    HalpEnableAutomaticDriveLetterAssignment();
-}
+#endif
 
 /* PRIVATE FUNCTIONS *********************************************************/
 
index 4e21994..31cc462 100644 (file)
@@ -4,6 +4,5 @@
 #include <initguid.h>
 #include <batclass.h>
 #include <poclass.h>
-#include <diskguid.h>
 
 /* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
index c03dc5d..384a4e0 100644 (file)
@@ -33,7 +33,6 @@
 #include <ntdef.h>
 #include <ntifs.h>
 #include <wdmguid.h>
-#include <diskguid.h>
 #include <arc/arc.h>
 #include <mountmgr.h>
 #undef NTHALAPI