Precision: r58138 was part 2a/3 of my changes.
[reactos.git] / reactos / drivers / storage / class / ramdisk / ramdisk.c
index 6a353bc..7b70972 100644 (file)
@@ -403,7 +403,8 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
                                                IN BOOLEAN ValidateOnly,
                                                OUT PRAMDISK_DRIVE_EXTENSION *NewDriveExtension)
 {
-       ULONG BasePage, ViewCount, DiskType, Length;
+    ULONG BasePage, DiskType, Length;
+    //ULONG ViewCount;
     NTSTATUS Status;
     PDEVICE_OBJECT DeviceObject;
     PRAMDISK_DRIVE_EXTENSION DriveExtension;
@@ -456,11 +457,11 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
                 //
                 return STATUS_INVALID_PARAMETER;
             }
-                       
+
                        //
                        // Read the view count instead
                        //
-                       ViewCount = Input->ViewCount;
+                       //ViewCount = Input->ViewCount;
                        
                        //
                        // Sanitize disk options
@@ -771,8 +772,7 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
     }
     
 FailCreate:
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_SUCCESS;
 }
 
@@ -880,6 +880,131 @@ RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject,
        return Status;
 }
 
+NTSTATUS
+NTAPI
+RamdiskGetPartitionInfo(IN PIRP Irp,
+                        IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
+{
+    NTSTATUS Status;
+    PPARTITION_INFORMATION PartitionInfo;
+    PVOID BaseAddress;
+    LARGE_INTEGER Zero = {{0, 0}};
+    ULONG Length;
+    PIO_STACK_LOCATION IoStackLocation;
+    
+    //
+    // Validate the length
+    //
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    if (IoStackLocation->Parameters.DeviceIoControl.
+        OutputBufferLength < sizeof(PARTITION_INFORMATION))
+    {
+        //
+        // Invalid length
+        //
+        Status = STATUS_BUFFER_TOO_SMALL;
+        Irp->IoStatus.Status = Status;
+        Irp->IoStatus.Information = 0;
+        return Status;
+    }
+    
+    //
+    // Map the partition table
+    //
+    BaseAddress = RamdiskMapPages(DeviceExtension, Zero, PAGE_SIZE, &Length);
+    if (!BaseAddress)
+    {
+        //
+        // No memory
+        //
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        Irp->IoStatus.Status = Status;
+        Irp->IoStatus.Information = 0;
+        return Status;
+    }
+    
+    //
+    // Fill out the information
+    //
+    PartitionInfo = Irp->AssociatedIrp.SystemBuffer;
+    PartitionInfo->StartingOffset.QuadPart = DeviceExtension->BytesPerSector;
+    PartitionInfo->PartitionLength.QuadPart = DeviceExtension->BytesPerSector *
+                                              DeviceExtension->SectorsPerTrack *
+                                              DeviceExtension->NumberOfHeads *
+                                              DeviceExtension->Cylinders;
+    PartitionInfo->HiddenSectors = DeviceExtension->HiddenSectors;
+    PartitionInfo->PartitionNumber = 0;
+    PartitionInfo->PartitionType = *((PCHAR)BaseAddress + 450);
+    PartitionInfo->BootIndicator = (DeviceExtension->DiskType ==
+                                    RAMDISK_BOOT_DISK) ? TRUE: FALSE;
+    PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartitionInfo->
+                                                               PartitionType);
+    PartitionInfo->RewritePartition = FALSE;
+
+    //
+    // Unmap the partition table
+    //
+    RamdiskUnmapPages(DeviceExtension, BaseAddress, Zero, Length);
+    
+    //
+    // Done
+    //
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+RamdiskSetPartitionInfo(IN PIRP Irp,
+                        IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
+{
+    ULONG BytesRead;
+    NTSTATUS Status;
+    PVOID BaseAddress;
+    PIO_STACK_LOCATION Stack;
+    LARGE_INTEGER Zero = {{0, 0}};
+    PPARTITION_INFORMATION PartitionInfo;
+
+    //
+    // First validate input
+    //
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+    if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PARTITION_INFORMATION))
+    {
+        Status = STATUS_INVALID_PARAMETER;
+        goto SetAndQuit;
+    }
+
+    //
+    // Map to get MBR
+    //
+    BaseAddress = RamdiskMapPages(DeviceExtension, Zero, PAGE_SIZE, &BytesRead);
+    if (BaseAddress == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto SetAndQuit;
+    }
+
+    //
+    // Set the new partition type
+    // On partition 0, field system indicator
+    //
+    PartitionInfo = (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+    *((PCHAR)BaseAddress + 450) = PartitionInfo->PartitionType;
+
+    //
+    // And unmap
+    //
+    RamdiskUnmapPages(DeviceExtension, BaseAddress, Zero, BytesRead);
+    Status = STATUS_SUCCESS;
+
+SetAndQuit:
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = 0;
+    return Status;
+}
+
 VOID
 NTAPI
 RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
@@ -934,31 +1059,23 @@ RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
                         break;
                         
                     case IOCTL_DISK_SET_PARTITION_INFO:
-                        
-                        DPRINT1("Set partition info request\n");
-                        UNIMPLEMENTED;
-                        while (TRUE);
+
+                        Status = RamdiskSetPartitionInfo(Irp, (PRAMDISK_DRIVE_EXTENSION)DeviceExtension);
                         break;
-                        
+
                     case IOCTL_DISK_GET_DRIVE_LAYOUT:
                         
-                        DPRINT1("Get drive layout request\n");
-                        UNIMPLEMENTED;
-                        while (TRUE);
+                        UNIMPLEMENTED_DBGBREAK("Get drive layout request\n");
                         break;
                         
                     case IOCTL_DISK_GET_PARTITION_INFO:
-                        
-                        DPRINT1("Get partitinon info request\n");
-                        UNIMPLEMENTED;
-                        while (TRUE);
+
+                        Status = RamdiskGetPartitionInfo(Irp, (PRAMDISK_DRIVE_EXTENSION)DeviceExtension);
                         break;
-                        
+
                     default:
                         
-                        DPRINT1("Invalid request\n");
-                        UNIMPLEMENTED;
-                        while (TRUE);
+                        UNIMPLEMENTED_DBGBREAK("Invalid request\n");
                         break;
                 }
                 
@@ -973,9 +1090,7 @@ RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
             case IRP_MJ_READ:
             case IRP_MJ_WRITE:
                 
-                DPRINT1("Read/Write request\n");
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("Read/Write request\n");
                 break;
                 
             //
@@ -983,9 +1098,7 @@ RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
             //
             case IRP_MJ_INTERNAL_DEVICE_CONTROL:
 
-                DPRINT1("SCSI request\n");
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("SCSI request\n");
                 break;
                 
             //
@@ -993,9 +1106,7 @@ RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
             //
             case IRP_MJ_FLUSH_BUFFERS:
                 
-                DPRINT1("Flush request\n");
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("Flush request\n");
                 break;
 
             //
@@ -1003,9 +1114,7 @@ RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
             //
             default:
                 
-                DPRINT1("Invalid request: %lx\n", IoStackLocation->MajorFunction);
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("Invalid request: %lx\n", IoStackLocation->MajorFunction);
                 break;
         }
         
@@ -1194,80 +1303,6 @@ DoCopy:
     }
 }
 
-NTSTATUS
-NTAPI
-RamdiskGetPartitionInfo(IN PIRP Irp,
-                        IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
-{
-    NTSTATUS Status;
-    PPARTITION_INFORMATION PartitionInfo;
-    PVOID BaseAddress;
-    LARGE_INTEGER Zero = {{0, 0}};
-    ULONG Length;
-    PIO_STACK_LOCATION IoStackLocation;
-    
-    //
-    // Validate the length
-    //
-    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
-    if (IoStackLocation->Parameters.DeviceIoControl.
-        OutputBufferLength < sizeof(PARTITION_INFORMATION))
-    {
-        //
-        // Invalid length
-        //
-        Status = STATUS_BUFFER_TOO_SMALL;
-        Irp->IoStatus.Status = Status;
-        Irp->IoStatus.Information = 0;
-        return Status;
-    }
-    
-    //
-    // Map the partition table
-    //
-    BaseAddress = RamdiskMapPages(DeviceExtension, Zero, PAGE_SIZE, &Length);
-    if (!BaseAddress)
-    {
-        //
-        // No memory
-        //
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        Irp->IoStatus.Status = Status;
-        Irp->IoStatus.Information = 0;
-        return Status;
-    }
-    
-    //
-    // Fill out the information
-    //
-    PartitionInfo = Irp->AssociatedIrp.SystemBuffer;
-    PartitionInfo->StartingOffset.QuadPart = DeviceExtension->BytesPerSector;
-    PartitionInfo->PartitionLength.QuadPart = DeviceExtension->BytesPerSector *
-                                              DeviceExtension->SectorsPerTrack *
-                                              DeviceExtension->NumberOfHeads *
-                                              DeviceExtension->Cylinders;
-    PartitionInfo->HiddenSectors = DeviceExtension->HiddenSectors;
-    PartitionInfo->PartitionNumber = 0;
-    PartitionInfo->PartitionType = PARTITION_FAT32; //*((PCHAR)BaseAddress + 450);
-    PartitionInfo->BootIndicator = (DeviceExtension->DiskType ==
-                                    RAMDISK_BOOT_DISK) ? TRUE: FALSE;
-    PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartitionInfo->
-                                                               PartitionType);
-    PartitionInfo->RewritePartition = FALSE;
-
-    //
-    // Unmap the partition table
-    //
-    RamdiskUnmapPages(DeviceExtension, BaseAddress, Zero, Length);
-    
-    //
-    // Done
-    //
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-    Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
-    return STATUS_SUCCESS;
-}
-
 NTSTATUS
 NTAPI
 RamdiskOpenClose(IN PDEVICE_OBJECT DeviceObject,
@@ -1288,11 +1323,11 @@ RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject,
                  IN PIRP Irp)
 {
     PRAMDISK_DRIVE_EXTENSION DeviceExtension;
-    ULONG Length;
-    LARGE_INTEGER ByteOffset;
+    //ULONG Length;
+    //LARGE_INTEGER ByteOffset;
     PIO_STACK_LOCATION IoStackLocation;
     NTSTATUS Status, ReturnStatus;
-    
+
     //
     // Get the device extension and make sure this isn't a bus
     //
@@ -1310,8 +1345,8 @@ RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject,
     // Capture parameters
     //
     IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
-    Length = IoStackLocation->Parameters.Read.Length;
-    ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
+    //Length = IoStackLocation->Parameters.Read.Length;
+    //ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
     
     //
     // FIXME: Validate offset
@@ -1433,8 +1468,7 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                 //
                 // We don't handle anything else yet
                 //
-                ASSERT(FALSE);
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
         }
     }
     else
@@ -1449,8 +1483,7 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
             case IOCTL_STORAGE_CHECK_VERIFY2:
             case IOCTL_CDROM_CHECK_VERIFY:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
 
             case IOCTL_STORAGE_GET_MEDIA_TYPES:
@@ -1571,8 +1604,7 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                 
             case IOCTL_DISK_SET_PARTITION_INFO:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                Status = RamdiskSetPartitionInfo(Irp, DriveExtension);
                 break;
                 
             case IOCTL_DISK_GET_PARTITION_INFO:
@@ -1616,68 +1648,57 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                 
             case IOCTL_DISK_GET_DRIVE_LAYOUT:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_DISK_GET_LENGTH_INFO:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_DISK_IS_WRITABLE:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_SCSI_MINIPORT:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_STORAGE_QUERY_PROPERTY:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_MOUNTDEV_QUERY_STABLE_GUID:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_VOLUME_SET_GPT_ATTRIBUTES:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_VOLUME_GET_GPT_ATTRIBUTES:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             case IOCTL_VOLUME_OFFLINE:
                 
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
                 break;
                 
             default:
@@ -1745,8 +1766,7 @@ RamdiskQueryDeviceRelations(IN DEVICE_RELATION_TYPE Type,
         //
         // FIXME: TODO
         //
-        UNIMPLEMENTED;
-        while (TRUE);
+        UNIMPLEMENTED_DBGBREAK();
     }
     
     //
@@ -1927,6 +1947,119 @@ PassToNext:
     return IoCallDriver(DeviceExtension->AttachedDevice, Irp);  
 }
 
+NTSTATUS
+NTAPI
+RamdiskDeleteDiskDevice(IN PDEVICE_OBJECT DeviceObject,
+                        IN PIRP Irp)
+{
+    UNIMPLEMENTED_DBGBREAK();
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+RamdiskRemoveBusDevice(IN PDEVICE_OBJECT DeviceObject,
+                       IN PIRP Irp)
+{
+    NTSTATUS Status;
+    PLIST_ENTRY ListHead, NextEntry;
+    PRAMDISK_BUS_EXTENSION DeviceExtension;
+    PRAMDISK_DRIVE_EXTENSION DriveExtension;
+
+    DeviceExtension = DeviceObject->DeviceExtension;
+
+    //
+    // Acquire disks list lock
+    //
+    KeEnterCriticalRegion();
+    ExAcquireFastMutex(&DeviceExtension->DiskListLock);
+
+    //
+    // Loop over drives
+    //
+    ListHead = &DeviceExtension->DiskList;
+    NextEntry = ListHead->Flink;
+    while (NextEntry != ListHead)
+    {
+        DriveExtension = CONTAINING_RECORD(NextEntry,
+                                           RAMDISK_DRIVE_EXTENSION,
+                                           DiskList);
+
+        //
+        // Delete the disk
+        //
+        IoAcquireRemoveLock(&DriveExtension->RemoveLock, NULL);
+        RamdiskDeleteDiskDevice(DriveExtension->PhysicalDeviceObject, NULL);
+
+        //
+        // RamdiskDeleteDiskDevice releases list lock, so reacquire it
+        //
+        KeEnterCriticalRegion();
+        ExAcquireFastMutex(&DeviceExtension->DiskListLock);
+    }
+
+    //
+    // Release disks list lock
+    //
+    ExReleaseFastMutex(&DeviceExtension->DiskListLock);
+    KeLeaveCriticalRegion();
+
+    //
+    // Prepare to pass to the lower driver
+    //
+    IoSkipCurrentIrpStackLocation(Irp);
+    //
+    // Here everything went fine
+    //
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+    //
+    // Call lower driver
+    //
+    Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
+
+    //
+    // Update state
+    //
+    DeviceExtension->State = RamdiskStateBusRemoved;
+
+    //
+    // Release the lock, and ensure that everyone
+    // has finished its job before we continue
+    // The lock has been acquired by the dispatcher
+    //
+    IoReleaseRemoveLockAndWait(&DeviceExtension->RemoveLock, Irp);
+
+    //
+    // If there's a drive name
+    //
+    if (DeviceExtension->DriveDeviceName.Buffer)
+    {
+        //
+        // Inform it's going to be disabled
+        // and free the drive name
+        //
+        IoSetDeviceInterfaceState(&DeviceExtension->DriveDeviceName, FALSE);
+        RtlFreeUnicodeString(&DeviceExtension->DriveDeviceName);
+    }
+
+    //
+    // Part from the stack, detach from lower device
+    //
+    IoDetachDevice(DeviceExtension->AttachedDevice);
+
+    //
+    // Finally, delete device
+    //
+    RamdiskBusFdo = NULL;
+    IoDeleteDevice(DeviceObject);
+
+    //
+    // Return status from lower driver
+    //
+    return Status;
+}
+
 NTSTATUS
 NTAPI
 RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
@@ -1952,7 +2085,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
         //
         // Only remove-device and query-id are allowed
         //
-        if ((Minor != IRP_MN_REMOVE_DEVICE) || (Minor != IRP_MN_QUERY_ID))
+        if ((Minor != IRP_MN_REMOVE_DEVICE) && (Minor != IRP_MN_QUERY_ID))
         {
             //
             // Fail anything else
@@ -1986,50 +2119,66 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
     {
         case IRP_MN_START_DEVICE:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_QUERY_STOP_DEVICE:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_CANCEL_STOP_DEVICE:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_STOP_DEVICE:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_QUERY_REMOVE_DEVICE:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_CANCEL_REMOVE_DEVICE:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_REMOVE_DEVICE:
-            
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
-            break;
+
+            //
+            // Remove the proper device
+            //
+            if (DeviceExtension->Type == RamdiskBus)
+            {
+                Status = RamdiskRemoveBusDevice(DeviceObject, Irp);
+
+                //
+                // Return here, lower device has already been called
+                // And remove lock released. This is needed by the function.
+                //
+                return Status;
+            }
+            else
+            {
+                Status = RamdiskDeleteDiskDevice(DeviceObject, Irp);
+
+                //
+                // Complete the IRP here and return
+                // Here again we don't have to release remove lock
+                // This has already been done by the function.
+                //
+                Irp->IoStatus.Status = Status;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return Status;
+            }
 
         case IRP_MN_SURPRISE_REMOVAL:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_QUERY_ID:
@@ -2039,8 +2188,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                DPRINT1("PnP IRP: %lx\n", Minor);
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             }
             break;
             
@@ -2051,15 +2199,13 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                DPRINT1("PnP IRP: %lx\n", Minor);
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             }
             break;
             
         case IRP_MN_EJECT:
             
-            DPRINT1("PnP IRP: %lx\n", Minor);
-            while (TRUE);
+            UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             break;
             
         case IRP_MN_QUERY_DEVICE_TEXT:
@@ -2069,8 +2215,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                DPRINT1("PnP IRP: %lx\n", Minor);
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             }
             break;
             
@@ -2093,8 +2238,7 @@ RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
             //
             if (DeviceExtension->Type == RamdiskDrive)
             {
-                DPRINT1("PnP IRP: %lx\n", Minor);
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("PnP IRP: %lx\n", Minor);
             }
             break;
             
@@ -2144,9 +2288,87 @@ NTAPI
 RamdiskPower(IN PDEVICE_OBJECT DeviceObject,
              IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_SUCCESS;
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStackLocation;
+    PRAMDISK_BUS_EXTENSION DeviceExtension;
+
+    DeviceExtension = DeviceObject->DeviceExtension;
+
+    //
+    // If we have a device extension, take extra caution
+    // with the lower driver
+    //
+    if (DeviceExtension != NULL)
+    {
+        PoStartNextPowerIrp(Irp);
+
+        //
+        // Device has not been removed yet, so
+        // pass to the attached/lower driver
+        //
+        if (DeviceExtension->State < RamdiskStateBusRemoved)
+        {
+            IoSkipCurrentIrpStackLocation(Irp);
+            return PoCallDriver(DeviceExtension->AttachedDevice, Irp);
+        }
+        //
+        // Otherwise, simply complete the IRP
+        // Notifying that deletion is pending
+        //
+        else
+        {
+            Irp->IoStatus.Status = STATUS_DELETE_PENDING;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_DELETE_PENDING;
+        }
+    }
+
+    //
+    // Get stack and deal with minor functions
+    //
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    switch (IoStackLocation->MinorFunction)
+    {
+        case IRP_MN_SET_POWER:
+            //
+            // If setting device power state
+            // it's all fine and return success
+            //
+            if (DevicePowerState)
+            {
+                Irp->IoStatus.Status = STATUS_SUCCESS;
+            }
+
+            //
+            // Get appropriate status for return
+            //
+            Status = Irp->IoStatus.Status;
+            PoStartNextPowerIrp(Irp);
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        case IRP_MN_QUERY_POWER:
+            //
+            // We can obviously accept all states
+            // So just return success
+            //
+            Status =
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            PoStartNextPowerIrp(Irp);
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+
+        default:
+            //
+            // Just complete and save status for return
+            //
+            Status = Irp->IoStatus.Status;
+            PoStartNextPowerIrp(Irp);
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            break;
+    }
+
+    return Status;
 }
 
 NTSTATUS
@@ -2154,9 +2376,31 @@ NTAPI
 RamdiskSystemControl(IN PDEVICE_OBJECT DeviceObject,
                      IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_SUCCESS;
+    NTSTATUS Status;
+    PRAMDISK_BUS_EXTENSION DeviceExtension;
+
+    DeviceExtension = DeviceObject->DeviceExtension;
+
+    //
+    // If we have a device extension, forward the IRP
+    // to the attached device
+    //
+    if (DeviceExtension != NULL)
+    {
+        IoSkipCurrentIrpStackLocation(Irp);
+        Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
+    }
+    //
+    // Otherwise just complete the request
+    // And return the status with which we complete it
+    //
+    else
+    {
+        Status = Irp->IoStatus.Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
+    return Status;
 }
 
 NTSTATUS
@@ -2164,9 +2408,51 @@ NTAPI
 RamdiskScsi(IN PDEVICE_OBJECT DeviceObject,
             IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_SUCCESS;
+    NTSTATUS Status;
+    PRAMDISK_BUS_EXTENSION DeviceExtension;
+
+    DeviceExtension = DeviceObject->DeviceExtension;
+
+    //
+    // Having a proper device is mandatory
+    //
+    if (DeviceExtension->State > RamdiskStateStopped)
+    {
+        Status = STATUS_DEVICE_DOES_NOT_EXIST;
+        goto CompleteIRP;
+    }
+
+    //
+    // Acquire the remove lock
+    //
+    Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
+    if (!NT_SUCCESS(Status))
+    {
+        goto CompleteIRP;
+    }
+
+    //
+    // Queue the IRP for worker
+    //
+    Status = SendIrpToThread(DeviceObject, Irp);
+    if (Status != STATUS_PENDING)
+    {
+        goto CompleteIRP;
+    }
+
+    //
+    // Release the remove lock
+    //
+    IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
+    goto Quit;
+
+CompleteIRP:
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+Quit:
+    return Status;
 }
 
 NTSTATUS
@@ -2174,17 +2460,54 @@ NTAPI
 RamdiskFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_SUCCESS;
+    NTSTATUS Status;
+    PRAMDISK_DRIVE_EXTENSION DeviceExtension;
+
+    DeviceExtension = DeviceObject->DeviceExtension;
+
+    //
+    // Ensure we have drive extension
+    // Only perform flush on disks that have been created
+    // from registry entries
+    //
+    if (DeviceExtension->Type != RamdiskDrive ||
+        DeviceExtension->DiskType > RAMDISK_MEMORY_MAPPED_DISK)
+    {
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
+
+    //
+    // Queue the IRP for worker
+    //
+    Status = SendIrpToThread(DeviceObject, Irp);
+    if (Status != STATUS_PENDING)
+    {
+        //
+        // Queueing failed - complete the IRP
+        // and return failure
+        //
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
+    return Status;
 }
 
 VOID
 NTAPI
 RamdiskUnload(IN PDRIVER_OBJECT DriverObject)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    //
+    // Just release registry path if previously allocated
+    //
+    if (DriverRegistryPath.Buffer)
+    {
+        ExFreePoolWithTag(DriverRegistryPath.Buffer, 'dmaR');
+    }
 }
 
 NTSTATUS