[RAMDISK]
[reactos.git] / reactos / drivers / storage / class / ramdisk / ramdisk.c
index 2580352..143a6f6 100644 (file)
@@ -58,10 +58,16 @@ typedef enum _RAMDISK_DEVICE_STATE
 } RAMDISK_DEVICE_STATE;
 
 DEFINE_GUID(RamdiskBusInterface,
-                   0x5DC52DF0,
-                       0x2F8A,
-                       0x410F,
-                       0x80, 0xE4, 0x05, 0xF8, 0x10, 0xE7, 0xA8, 0x8A);
+    0x5DC52DF0,
+    0x2F8A,
+    0x410F,
+    0x80, 0xE4, 0x05, 0xF8, 0x10, 0xE7, 0xA8, 0x8A);
+
+DEFINE_GUID(RamdiskDiskInterface,
+    0x31D909F0,
+    0x2CDF,
+    0x4A20,
+    0x9E, 0xD4, 0x7D, 0x65, 0x47, 0x6C, 0xA7, 0x68);
 
 typedef struct _RAMDISK_EXTENSION
 {
@@ -399,9 +405,9 @@ RamdiskUnmapPages(IN PRAMDISK_DRIVE_EXTENSION DeviceExtension,
 NTSTATUS
 NTAPI
 RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
-                                               IN PRAMDISK_CREATE_INPUT Input,
-                                               IN BOOLEAN ValidateOnly,
-                                               OUT PRAMDISK_DRIVE_EXTENSION *NewDriveExtension)
+                        IN PRAMDISK_CREATE_INPUT Input,
+                        IN BOOLEAN ValidateOnly,
+                        OUT PRAMDISK_DRIVE_EXTENSION *NewDriveExtension)
 {
     ULONG BasePage, DiskType, Length;
     //ULONG ViewCount;
@@ -417,40 +423,40 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
     PVOID BaseAddress;
     LARGE_INTEGER CurrentOffset, CylinderSize, DiskLength;
     ULONG CylinderCount, SizeByCylinders;
-       
-       //
-       // Check if we're a boot RAM disk
-       //
-       DiskType = Input->DiskType;
-       if (DiskType >= RAMDISK_BOOT_DISK)
-       {
-               //
-               // Check if we're an ISO
-               // 
-               if (DiskType == RAMDISK_BOOT_DISK)
-               {
-                       //
-                       // NTLDR mounted us somewhere
-                       //
-                       BasePage = Input->BasePage;
-                       if (!BasePage) return STATUS_INVALID_PARAMETER;
-                       
-                       //
-                       // Sanitize disk options
-                       //
-                       Input->Options.Fixed = TRUE;
-                       Input->Options.Readonly = Input->Options.ExportAsCd |
-                                      Input->Options.Readonly;
-                       Input->Options.Hidden = FALSE;
-                       Input->Options.NoDosDevice = FALSE;
-                       Input->Options.NoDriveLetter = IsWinPEBoot ? TRUE : FALSE;
-               }
-               else
-               {
-                       //
-                       // The only other possibility is a WIM disk
-                       //
-                       if (DiskType != RAMDISK_WIM_DISK)
+
+    //
+    // Check if we're a boot RAM disk
+    //
+    DiskType = Input->DiskType;
+    if (DiskType >= RAMDISK_BOOT_DISK)
+    {
+        //
+        // Check if we're an ISO
+        // 
+        if (DiskType == RAMDISK_BOOT_DISK)
+        {
+            //
+            // NTLDR mounted us somewhere
+            //
+            BasePage = Input->BasePage;
+            if (!BasePage) return STATUS_INVALID_PARAMETER;
+            
+            //
+            // Sanitize disk options
+            //
+            Input->Options.Fixed = TRUE;
+            Input->Options.Readonly = Input->Options.ExportAsCd |
+                          Input->Options.Readonly;
+            Input->Options.Hidden = FALSE;
+            Input->Options.NoDosDevice = FALSE;
+            Input->Options.NoDriveLetter = IsWinPEBoot ? TRUE : FALSE;
+        }
+        else
+        {
+            //
+            // The only other possibility is a WIM disk
+            //
+            if (DiskType != RAMDISK_WIM_DISK)
             {
                 //
                 // Fail
@@ -458,26 +464,26 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
                 return STATUS_INVALID_PARAMETER;
             }
 
-                       //
-                       // Read the view count instead
-                       //
-                       //ViewCount = Input->ViewCount;
-                       
-                       //
-                       // Sanitize disk options
-                       //
-                       Input->Options.Hidden = FALSE;
-                       Input->Options.NoDosDevice = FALSE;
-                       Input->Options.Readonly = FALSE;
-                       Input->Options.NoDriveLetter = TRUE;
-                       Input->Options.Fixed = TRUE;
-               }
-               
-               //
-               // Are we just validating and returning to the user?
-               //
-               if (ValidateOnly) return STATUS_SUCCESS;
-        
+            //
+            // Read the view count instead
+            //
+            //ViewCount = Input->ViewCount;
+            
+            //
+            // Sanitize disk options
+            //
+            Input->Options.Hidden = FALSE;
+            Input->Options.NoDosDevice = FALSE;
+            Input->Options.Readonly = FALSE;
+            Input->Options.NoDriveLetter = TRUE;
+            Input->Options.Fixed = TRUE;
+        }
+
+        //
+        // Are we just validating and returning to the user?
+        //
+        if (ValidateOnly) return STATUS_SUCCESS;
+
         //
         // Build the GUID string
         //
@@ -490,7 +496,7 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
             Status = STATUS_INSUFFICIENT_RESOURCES;
             goto FailCreate;
         }
-        
+
         //
         // Allocate our device name
         //
@@ -533,7 +539,7 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
         // Grab the drive extension
         //
         DriveExtension = DeviceObject->DeviceExtension;
-       
+        
         //
         // Check if we need a DOS device
         //
@@ -605,9 +611,9 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
                     DriveExtension->DriveLetter = Input->DriveLetter;
                 }
             }
-            
+    
         }
-        
+
         //
         // Setup the device object flags
         //
@@ -620,17 +626,17 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
         *NewDriveExtension = DriveExtension;
         DriveExtension->Type = RamdiskDrive;
         DiskLength = Input->DiskLength;
-               ExInitializeFastMutex(&DriveExtension->DiskListLock);
-           IoInitializeRemoveLock(&DriveExtension->RemoveLock,
-                               'dmaR',
-                               0,
-                               1);
+        ExInitializeFastMutex(&DriveExtension->DiskListLock);
+        IoInitializeRemoveLock(&DriveExtension->RemoveLock,
+                              'dmaR',
+                              1,
+                              0);
         DriveExtension->DriveDeviceName = DeviceName;
         DriveExtension->SymbolicLinkName = SymbolicLinkName;
         DriveExtension->GuidString = GuidString;
         DriveExtension->DiskGuid = Input->DiskGuid;
-           DriveExtension->PhysicalDeviceObject = DeviceObject;
-           DriveExtension->DeviceObject = RamdiskBusFdo;
+        DriveExtension->PhysicalDeviceObject = DeviceObject;
+        DriveExtension->DeviceObject = RamdiskBusFdo;
         DriveExtension->AttachedDevice = RamdiskBusFdo;
         DriveExtension->DiskType = Input->DiskType;
         DriveExtension->DiskOptions = Input->Options;
@@ -780,104 +786,104 @@ NTSTATUS
 NTAPI
 RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject,
                      IN PIRP Irp,
-                                        IN BOOLEAN ValidateOnly)
+                     IN BOOLEAN ValidateOnly)
 {
-       PRAMDISK_CREATE_INPUT Input;
-       ULONG Length;
-       PRAMDISK_BUS_EXTENSION DeviceExtension;
+    PRAMDISK_CREATE_INPUT Input;
+    ULONG Length;
+    PRAMDISK_BUS_EXTENSION DeviceExtension;
     PRAMDISK_DRIVE_EXTENSION DriveExtension; 
-       ULONG DiskType;
-       PWCHAR FileNameStart, FileNameEnd;
-       NTSTATUS Status;
-       PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
-       
-       //
-       // Get the device extension and our input data
-       //
-       DeviceExtension = DeviceObject->DeviceExtension;
-       Length = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
-       Input = (PRAMDISK_CREATE_INPUT)Irp->AssociatedIrp.SystemBuffer;
-       
-       //
-       // Validate input parameters
-       //
-       if ((Length < sizeof(RAMDISK_CREATE_INPUT)) ||
-               (Input->Version != sizeof(RAMDISK_CREATE_INPUT)))
-       {
-               //
-               // Invalid input
-               //
-               return STATUS_INVALID_PARAMETER;
-       }
-       
-       //
-       // Validate the disk type
-       //
-       DiskType = Input->DiskType;
-       if (DiskType == RAMDISK_WIM_DISK) return STATUS_INVALID_PARAMETER;
-       
-       //
-       // Look at the disk type
-       //
-       if (DiskType == RAMDISK_BOOT_DISK)
-       {
-               //
-               // We only allow this as an early-init boot
-               //
-               if (!KeLoaderBlock) return STATUS_INVALID_PARAMETER;
-               
-               //
-               // Save command-line flags
-               //
-               if (ExportBootDiskAsCd) Input->Options.ExportAsCd = TRUE;
-               if (IsWinPEBoot) Input->Options.NoDriveLetter = TRUE;
-       }
-    
-       //
-       // Validate the disk type
-       //
-       if ((Input->Options.ExportAsCd) && (DiskType != RAMDISK_BOOT_DISK))
-       {
-               //
-               // If the type isn't CDFS, it has to at least be raw CD
-               //
-               if (DiskType != RAMDISK_MEMORY_MAPPED_DISK) return STATUS_INVALID_PARAMETER;
-       }
-       
-       //
-       // Check if this is an actual file
-       //
-       if (DiskType <= RAMDISK_MEMORY_MAPPED_DISK)
-       {
-               //
-               // Validate the file name
-               //
-               FileNameStart = (PWCHAR)((ULONG_PTR)Input + Length);
-               FileNameEnd = Input->FileName + 1;
-               while ((FileNameEnd < FileNameStart) && *(FileNameEnd)) FileNameEnd++;
-               if (FileNameEnd == FileNameStart) return STATUS_INVALID_PARAMETER;
-       }
-    
-       //
-       // Create the actual device
-       //
-       Status = RamdiskCreateDiskDevice(DeviceExtension,
-                                                                        Input, 
-                                                                        ValidateOnly,
-                                                                        &DriveExtension);
-       if (NT_SUCCESS(Status))
-       {
-               //
-               // Invalidate and set success
-               //
-               IoInvalidateDeviceRelations(DeviceExtension->PhysicalDeviceObject, 0);
-               Irp->IoStatus.Information = STATUS_SUCCESS;
-       }
-       
-       //
-       // We're done
-       //
-       return Status;
+    ULONG DiskType;
+    PWCHAR FileNameStart, FileNameEnd;
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    
+    //
+    // Get the device extension and our input data
+    //
+    DeviceExtension = DeviceObject->DeviceExtension;
+    Length = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
+    Input = (PRAMDISK_CREATE_INPUT)Irp->AssociatedIrp.SystemBuffer;
+    
+    //
+    // Validate input parameters
+    //
+    if ((Length < sizeof(RAMDISK_CREATE_INPUT)) ||
+       (Input->Version != sizeof(RAMDISK_CREATE_INPUT)))
+    {
+       //
+       // Invalid input
+       //
+       return STATUS_INVALID_PARAMETER;
+    }
+    
+    //
+    // Validate the disk type
+    //
+    DiskType = Input->DiskType;
+    if (DiskType == RAMDISK_WIM_DISK) return STATUS_INVALID_PARAMETER;
+    
+    //
+    // Look at the disk type
+    //
+    if (DiskType == RAMDISK_BOOT_DISK)
+    {
+       //
+       // We only allow this as an early-init boot
+       //
+       if (!KeLoaderBlock) return STATUS_INVALID_PARAMETER;
+       
+       //
+       // Save command-line flags
+       //
+       if (ExportBootDiskAsCd) Input->Options.ExportAsCd = TRUE;
+       if (IsWinPEBoot) Input->Options.NoDriveLetter = TRUE;
+    }
+    
+    //
+    // Validate the disk type
+    //
+    if ((Input->Options.ExportAsCd) && (DiskType != RAMDISK_BOOT_DISK))
+    {
+       //
+       // If the type isn't CDFS, it has to at least be raw CD
+       //
+       if (DiskType != RAMDISK_MEMORY_MAPPED_DISK) return STATUS_INVALID_PARAMETER;
+    }
+    
+    //
+    // Check if this is an actual file
+    //
+    if (DiskType <= RAMDISK_MEMORY_MAPPED_DISK)
+    {
+       //
+       // Validate the file name
+       //
+       FileNameStart = (PWCHAR)((ULONG_PTR)Input + Length);
+       FileNameEnd = Input->FileName + 1;
+       while ((FileNameEnd < FileNameStart) && *(FileNameEnd)) FileNameEnd++;
+       if (FileNameEnd == FileNameStart) return STATUS_INVALID_PARAMETER;
+    }
+    
+    //
+    // Create the actual device
+    //
+    Status = RamdiskCreateDiskDevice(DeviceExtension,
+                                     Input, 
+                                     ValidateOnly,
+                                     &DriveExtension);
+    if (NT_SUCCESS(Status))
+    {
+       //
+       // Invalidate and set success
+       //
+       IoInvalidateDeviceRelations(DeviceExtension->PhysicalDeviceObject, 0);
+       Irp->IoStatus.Information = STATUS_SUCCESS;
+    }
+    
+    //
+    // We're done
+    //
+    return Status;
 }
 
 NTSTATUS
@@ -1734,7 +1740,7 @@ RamdiskQueryDeviceRelations(IN DEVICE_RELATION_TYPE Type,
     //
     // Anything but bus relations, we don't handle
     //
-    if (Type) goto PassToNext;
+    if (Type != BusRelations) goto PassToNext;
     
     //
     // Acquire the disk list lock
@@ -2022,6 +2028,270 @@ RamdiskRemoveBusDevice(IN PDEVICE_OBJECT DeviceObject,
     return Status;
 }
 
+NTSTATUS
+NTAPI
+RamdiskQueryId(IN PRAMDISK_DRIVE_EXTENSION DriveExtension,
+               IN PIRP Irp)
+{
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStackLocation;
+    PWSTR OutputString = NULL;
+    ULONG StringLength;
+
+    Status = STATUS_SUCCESS;
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+    //
+    // Get what is being queried
+    //
+    switch (IoStackLocation->Parameters.QueryId.IdType)
+    {
+        case BusQueryDeviceID:
+
+            //
+            // Allocate a buffer long enough to receive Ramdisk\RamDisk in any case
+            // In case we don't have RAMDISK_REGISTRY_DISK, we then need two more
+            // chars to store Ramdisk\RamVolume instead
+            //
+            StringLength = 4 * (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK) + sizeof(L"Ramdisk\\RamDisk");
+            OutputString = ExAllocatePoolWithTag(PagedPool, StringLength, 'dmaR');
+            if (OutputString == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            wcsncpy(OutputString, L"Ramdisk\\", StringLength / sizeof(WCHAR));
+            if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
+            {
+                wcsncat(OutputString, L"RamVolume", StringLength / sizeof(WCHAR));
+            }
+            else
+            {
+                wcsncat(OutputString, L"RamDisk", StringLength / sizeof(WCHAR));
+            }
+
+            break;
+
+        case BusQueryHardwareIDs:
+
+            //
+            // Allocate a buffer long enough to receive Ramdisk\RamDisk in any case
+            // In case we don't have RAMDISK_REGISTRY_DISK, we then need two more
+            // chars to store Ramdisk\RamVolume instead
+            // We also need an extra char, because it is required that the string
+            // is null-terminated twice
+            //
+            StringLength = 4 * (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK) +
+                           sizeof(UNICODE_NULL) + sizeof(L"Ramdisk\\RamDisk");
+            OutputString = ExAllocatePoolWithTag(PagedPool, StringLength, 'dmaR');
+            if (OutputString == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            wcsncpy(OutputString, L"Ramdisk\\", StringLength / sizeof(WCHAR));
+            if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
+            {
+                wcsncat(OutputString, L"RamVolume", StringLength / sizeof(WCHAR));
+            }
+            else
+            {
+                wcsncat(OutputString, L"RamDisk", StringLength / sizeof(WCHAR));
+            }
+            OutputString[(StringLength / sizeof(WCHAR)) - 1] = UNICODE_NULL;
+
+            break;
+
+        case BusQueryCompatibleIDs:
+
+            if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
+            {
+                Status = STATUS_INVALID_DEVICE_REQUEST;
+                break;
+            }
+
+            StringLength = sizeof(L"GenDisk");
+            OutputString = ExAllocatePoolWithTag(PagedPool, StringLength, 'dmaR');
+            if (OutputString == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            wcsncpy(OutputString, L"GenDisk", StringLength / sizeof(WCHAR));
+            OutputString[(StringLength / sizeof(WCHAR)) - 1] = UNICODE_NULL;
+
+            break;
+
+        case BusQueryInstanceID:
+
+            OutputString = ExAllocatePoolWithTag(PagedPool, DriveExtension->GuidString.MaximumLength, 'dmaR');
+            if (OutputString == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            wcsncpy(OutputString, DriveExtension->GuidString.Buffer, DriveExtension->GuidString.MaximumLength / sizeof(WCHAR));
+
+            break;
+
+        case BusQueryDeviceSerialNumber:
+            
+            //
+            // Nothing to do
+            //
+
+            break;
+    }
+
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = (ULONG_PTR)OutputString;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RamdiskQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,
+                         IN PIRP Irp)
+{
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStackLocation;
+    PDEVICE_CAPABILITIES DeviceCapabilities;
+    PRAMDISK_DRIVE_EXTENSION DriveExtension;
+
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    DeviceCapabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities;
+    DriveExtension = DeviceObject->DeviceExtension;
+
+    //
+    // Validate our input buffer
+    //
+    if (DeviceCapabilities->Version != 1 || DeviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES))
+    {
+        Status = STATUS_UNSUCCESSFUL;
+    }
+    else
+    {
+        //
+        // And set everything we know about our capabilities
+        //
+        DeviceCapabilities->Removable = MarkRamdisksAsRemovable;
+        DeviceCapabilities->UniqueID = TRUE;
+        DeviceCapabilities->SilentInstall = TRUE;
+        DeviceCapabilities->RawDeviceOK = TRUE;
+        DeviceCapabilities->SurpriseRemovalOK = (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK);
+        DeviceCapabilities->NoDisplayInUI = TRUE;
+        Status = STATUS_SUCCESS;
+    }
+
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RamdiskQueryDeviceText(IN PRAMDISK_DRIVE_EXTENSION DriveExtension,
+                       IN PIRP Irp)
+{
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStackLocation;
+    DEVICE_TEXT_TYPE DeviceTextType;
+    PWSTR OutputString = NULL;
+
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    DeviceTextType = IoStackLocation->Parameters.QueryDeviceText.DeviceTextType;
+    Status = STATUS_SUCCESS;
+
+    //
+    // Just copy our constants, according to the input
+    //
+    switch (DeviceTextType)
+    {
+        case DeviceTextDescription:
+
+            OutputString = ExAllocatePoolWithTag(PagedPool, sizeof(L"RamDisk"), 'dmaR');
+            if (OutputString == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            wcsncpy(OutputString, L"RamDisk", sizeof(L"RamDisk") / sizeof(WCHAR));
+
+            break;
+
+        case DeviceTextLocationInformation:
+
+            OutputString = ExAllocatePoolWithTag(PagedPool, sizeof(L"RamDisk\\0"), 'dmaR');
+            if (OutputString == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            wcsncpy(OutputString, L"RamDisk\\0", sizeof(L"RamDisk\\0") / sizeof(WCHAR));
+
+            break;
+    }
+
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = (ULONG_PTR)OutputString;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RamdiskQueryBusInformation(IN PDEVICE_OBJECT DeviceObject,
+                           IN PIRP Irp)
+{
+    PPNP_BUS_INFORMATION PnpBusInfo;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    //
+    // Allocate output memory
+    //
+    PnpBusInfo = ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION), 'dmaR');
+    if (PnpBusInfo == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+    else
+    {
+        //
+        // Copy our bus GUID and set our legacy type
+        //
+        RtlCopyMemory(&PnpBusInfo->BusTypeGuid, &GUID_BUS_TYPE_RAMDISK, sizeof(GUID));
+        PnpBusInfo->LegacyBusType = PNPBus;
+        PnpBusInfo->BusNumber = 0;
+    }
+
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = (ULONG_PTR)PnpBusInfo;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+RamdiskIoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
+                           IN PIRP Irp,
+                           IN PVOID Context)
+
+{
+    //
+    // Just set the event to unlock caller
+    //
+    KeSetEvent((PKEVENT)Context, 0, FALSE);
+
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
 NTSTATUS
 NTAPI
 RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
@@ -2031,7 +2301,8 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
     PRAMDISK_BUS_EXTENSION DeviceExtension;
     NTSTATUS Status;
     UCHAR Minor;
-    
+    KEVENT Event;
+
     //
     // Get the device extension and stack location
     //
@@ -2080,8 +2351,112 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
     switch (Minor)
     {
         case IRP_MN_START_DEVICE:
-            
-            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
+
+            if (DeviceExtension->Type == RamdiskDrive)
+            {
+                ULONG ResultLength;
+                DEVICE_INSTALL_STATE InstallState;
+                PRAMDISK_DRIVE_EXTENSION DriveExtension = (PRAMDISK_DRIVE_EXTENSION)DeviceExtension;
+
+                //
+                // If we already have a drive name, free it
+                //
+                if (DriveExtension->DriveDeviceName.Buffer)
+                {
+                    ExFreePool(DriveExtension->DriveDeviceName.Buffer);
+                }
+
+                //
+                // Register our device interface
+                //
+                if (DriveExtension->DiskType != RAMDISK_REGISTRY_DISK)
+                {
+                    Status = IoRegisterDeviceInterface(DeviceObject,
+                                                       &GUID_DEVINTERFACE_VOLUME,
+                                                       NULL,
+                                                       &DriveExtension->DriveDeviceName);
+                }
+                else
+                {
+                    Status = IoRegisterDeviceInterface(DeviceObject,
+                                                       &RamdiskDiskInterface,
+                                                       NULL,
+                                                       &DriveExtension->DriveDeviceName);
+                }
+
+                //
+                // If we were asked not to assign a drive letter or
+                // if getting a name failed, just return saying
+                // we're now started
+                //
+                if (DriveExtension->DiskOptions.NoDriveLetter ||
+                    DriveExtension->DriveDeviceName.Buffer == NULL)
+                {
+                    DriveExtension->State = RamdiskStateStarted;
+                    Irp->IoStatus.Status = Status;
+                    break;
+                }
+
+                //
+                // Now get our installation state
+                //
+                Status = IoGetDeviceProperty(DeviceObject, DevicePropertyInstallState,
+                                             sizeof(InstallState), &InstallState, &ResultLength);
+                //
+                // If querying the information failed, assume success
+                //
+                if (!NT_SUCCESS(Status))
+                {
+                    InstallState = InstallStateInstalled;
+                }
+
+                //
+                // If we were properly installed, then, enable the interface
+                //
+                if (InstallState == InstallStateInstalled)
+                {
+                    Status = IoSetDeviceInterfaceState(&DriveExtension->DriveDeviceName, TRUE);
+                }
+
+                //
+                // We're fine & up
+                //
+                DriveExtension->State = RamdiskStateStarted;
+                Irp->IoStatus.Status = Status;
+                break;
+            }
+
+            //
+            // Prepare next stack to pass it down
+            //
+            IoCopyCurrentIrpStackLocationToNext(Irp);
+
+            //
+            // Initialize our notification event & our completion routine
+            //
+            KeInitializeEvent(&Event, NotificationEvent, FALSE);
+            IoSetCompletionRoutine(Irp, RamdiskIoCompletionRoutine, &Event, TRUE, TRUE, TRUE);
+
+            //
+            // Call lower driver
+            //
+            Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
+            if (Status == STATUS_PENDING)
+            {
+                KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+                Status = Irp->IoStatus.Status;
+            }
+
+            //
+            // If it succeed to start, then, enable ourselve and we're up!
+            //
+            if (NT_SUCCESS(Status))
+            {
+                Status = IoSetDeviceInterfaceState(&DeviceExtension->DriveDeviceName, TRUE);
+                DeviceExtension->State = RamdiskStateStarted;
+            }
+
+            Irp->IoStatus.Status = Status;
             break;
             
         case IRP_MN_QUERY_STOP_DEVICE:
@@ -2150,7 +2525,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
+                Status = RamdiskQueryId((PRAMDISK_DRIVE_EXTENSION)DeviceExtension, Irp);
             }
             break;
             
@@ -2161,7 +2536,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
+                Status = RamdiskQueryBusInformation(DeviceObject, Irp);
             }
             break;
             
@@ -2177,7 +2552,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
+                Status = RamdiskQueryDeviceText((PRAMDISK_DRIVE_EXTENSION)DeviceExtension, Irp);
             }
             break;
             
@@ -2200,7 +2575,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
+                Status = RamdiskQueryCapabilities(DeviceObject, Irp);
             }
             break;
             
@@ -2477,115 +2852,115 @@ NTAPI
 RamdiskAddDevice(IN PDRIVER_OBJECT DriverObject, 
                  IN PDEVICE_OBJECT PhysicalDeviceObject)
 {
-       PRAMDISK_BUS_EXTENSION DeviceExtension;
-       PDEVICE_OBJECT AttachedDevice;
-       NTSTATUS Status; 
-       UNICODE_STRING DeviceName;
-       PDEVICE_OBJECT DeviceObject;
-       
-       //
-       // Only create the bus FDO once
-       //
-       if (RamdiskBusFdo) return STATUS_DEVICE_ALREADY_ATTACHED;
-       
-       //
-       // Create the bus FDO
-       //
-       RtlInitUnicodeString(&DeviceName, L"\\Device\\Ramdisk");
-       Status = IoCreateDevice(DriverObject,
-                                                   sizeof(RAMDISK_BUS_EXTENSION),
-                                                       &DeviceName,
-                                                       FILE_DEVICE_BUS_EXTENDER,
-                                                       FILE_DEVICE_SECURE_OPEN,
-                                                       0,
-                                                       &DeviceObject);
-       if (NT_SUCCESS(Status))
-       {
-               //
-               // Initialize the bus FDO extension
-               //
-           DeviceExtension = DeviceObject->DeviceExtension;
-           RtlZeroMemory(DeviceObject->DeviceExtension,
+    PRAMDISK_BUS_EXTENSION DeviceExtension;
+    PDEVICE_OBJECT AttachedDevice;
+    NTSTATUS Status; 
+    UNICODE_STRING DeviceName;
+    PDEVICE_OBJECT DeviceObject;
+    
+    //
+    // Only create the bus FDO once
+    //
+    if (RamdiskBusFdo) return STATUS_DEVICE_ALREADY_ATTACHED;
+    
+    //
+    // Create the bus FDO
+    //
+    RtlInitUnicodeString(&DeviceName, L"\\Device\\Ramdisk");
+    Status = IoCreateDevice(DriverObject,
+                            sizeof(RAMDISK_BUS_EXTENSION),
+                            &DeviceName,
+                            FILE_DEVICE_BUS_EXTENDER,
+                            FILE_DEVICE_SECURE_OPEN,
+                            0,
+                            &DeviceObject);
+    if (NT_SUCCESS(Status))
+    {
+       //
+       // Initialize the bus FDO extension
+       //
+        DeviceExtension = DeviceObject->DeviceExtension;
+        RtlZeroMemory(DeviceObject->DeviceExtension,
                       sizeof(RAMDISK_BUS_EXTENSION));
-
-               //
-               // Set bus FDO flags
-               //
-           DeviceObject->Flags |= DO_POWER_PAGABLE | DO_DIRECT_IO;
-
-               //
-               // Setup the bus FDO extension
-               //
-           DeviceExtension->Type = RamdiskBus;
-               ExInitializeFastMutex(&DeviceExtension->DiskListLock);
-           IoInitializeRemoveLock(&DeviceExtension->RemoveLock,
+    
+       //
+       // Set bus FDO flags
+       //
+        DeviceObject->Flags |= DO_POWER_PAGABLE | DO_DIRECT_IO;
+    
+       //
+       // Setup the bus FDO extension
+       //
+        DeviceExtension->Type = RamdiskBus;
+       ExInitializeFastMutex(&DeviceExtension->DiskListLock);
+        IoInitializeRemoveLock(&DeviceExtension->RemoveLock,
                                'dmaR',
-                               0,
-                               1);
-               InitializeListHead(&DeviceExtension->DiskList);
-           DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
-           DeviceExtension->DeviceObject = DeviceObject;
-
-               //
-               // Register the RAM disk device interface
-               //
-           Status = IoRegisterDeviceInterface(PhysicalDeviceObject,
-                                                                                  &RamdiskBusInterface,
-                                                                                  NULL,
-                                                                                  &DeviceExtension->BusDeviceName);
-           if (!NT_SUCCESS(Status))
-           {
-                       //
-                       // Fail
-                       //
-                       IoDeleteDevice(DeviceObject);
-                       return Status;
-           }
-
-               //
-               // Attach us to the device stack
-               //
-           AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject,
-                                                                                                        PhysicalDeviceObject);
-           DeviceExtension->AttachedDevice = AttachedDevice;
-           if (!AttachedDevice)
-           {
-                       //
-                       // Fail
-                       //
-                       IoSetDeviceInterfaceState(&DeviceExtension->BusDeviceName, 0);
-                       RtlFreeUnicodeString(&DeviceExtension->BusDeviceName);
-                       IoDeleteDevice(DeviceObject);
-                       return STATUS_NO_SUCH_DEVICE;
-           }
-
-               //
-               // Bus FDO is initialized
-               //
-           RamdiskBusFdo = DeviceObject;
-
-               //
-               // Loop for loader block
-               //
-           if (KeLoaderBlock)
-           {
-                       //
-                       // Are we being booted from setup? Not yet supported
-                       //
-                       //ASSERT(!KeLoaderBlock->SetupLdrBlock);
-           }
-
-               //
-               // All done
-               //
-           DeviceObject->Flags &= DO_DEVICE_INITIALIZING;
-           Status = STATUS_SUCCESS;
-       }
-
-       //
-       // Return status
-       //
-       return Status;
+                               1,
+                               0);
+       InitializeListHead(&DeviceExtension->DiskList);
+        DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
+        DeviceExtension->DeviceObject = DeviceObject;
+    
+       //
+       // Register the RAM disk device interface
+       //
+        Status = IoRegisterDeviceInterface(PhysicalDeviceObject,
+                                           &RamdiskBusInterface,
+                                           NULL,
+                                           &DeviceExtension->BusDeviceName);
+        if (!NT_SUCCESS(Status))
+        {
+            //
+            // Fail
+            //
+            IoDeleteDevice(DeviceObject);
+            return Status;
+        }
+    
+       //
+       // Attach us to the device stack
+       //
+        AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject,
+                                                     PhysicalDeviceObject);
+        DeviceExtension->AttachedDevice = AttachedDevice;
+        if (!AttachedDevice)
+        {
+           //
+           // Fail
+           //
+           IoSetDeviceInterfaceState(&DeviceExtension->BusDeviceName, 0);
+           RtlFreeUnicodeString(&DeviceExtension->BusDeviceName);
+           IoDeleteDevice(DeviceObject);
+           return STATUS_NO_SUCH_DEVICE;
+        }
+    
+       //
+       // Bus FDO is initialized
+       //
+        RamdiskBusFdo = DeviceObject;
+    
+       //
+       // Loop for loader block
+       //
+        if (KeLoaderBlock)
+        {
+           //
+           // Are we being booted from setup? Not yet supported
+           //
+           //ASSERT(!KeLoaderBlock->SetupLdrBlock);
+        }
+    
+       //
+       // All done
+       //
+        DeviceObject->Flags &= DO_DEVICE_INITIALIZING;
+        Status = STATUS_SUCCESS;
+    }
+    
+    //
+    // Return status
+    //
+    return Status;
 }
 
 NTSTATUS