[RAMDISK] Remove support for IOCTL_CDROM_GET_LAST_SESSION (useless since r64106)
[reactos.git] / reactos / drivers / storage / class / ramdisk / ramdisk.c
index ea7f07f..1b2b223 100644 (file)
@@ -772,8 +772,7 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
     }
     
 FailCreate:
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_SUCCESS;
 }
 
@@ -881,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,
@@ -935,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;
                 }
                 
@@ -974,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;
                 
             //
@@ -984,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;
                 
             //
@@ -994,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;
 
             //
@@ -1004,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;
         }
         
@@ -1195,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,
@@ -1434,8 +1468,7 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                 //
                 // We don't handle anything else yet
                 //
-                ASSERT(FALSE);
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
         }
     }
     else
@@ -1450,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:
@@ -1490,47 +1522,6 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
                 Information = sizeof(DISK_GEOMETRY);
                 break;
             
-            //
-            // Hack to support ReactOS's broken CDFS
-            //
-            case IOCTL_CDROM_GET_LAST_SESSION:
-            
-                //
-                // Validate the length
-                //
-                if (IoStackLocation->Parameters.DeviceIoControl.
-                    OutputBufferLength < RAMDISK_SESSION_SIZE)
-                {
-                    //
-                    // Invalid length
-                    //
-                    Status = STATUS_BUFFER_TOO_SMALL;
-                    break;
-                }
-                
-                //
-                // Fill out the TOC
-                //
-                Toc = Irp->AssociatedIrp.SystemBuffer;
-                Toc->Length[0] = 0;
-                Toc->Length[1] = RAMDISK_SESSION_SIZE - sizeof(Toc->Length);
-                Toc->FirstTrack = 1;
-                Toc->LastTrack = 1;
-                Toc->TrackData[0].Adr = 1;
-                Toc->TrackData[0].Control = TOC_DATA_TRACK;
-                Toc->TrackData[0].TrackNumber = 1;
-                Toc->TrackData[0].Address[0] =
-                Toc->TrackData[0].Address[1] =
-                Toc->TrackData[0].Address[2] =
-                Toc->TrackData[0].Address[3] = 0;
-                                
-                //
-                // We're done
-                //
-                Status = STATUS_SUCCESS;
-                Information = RAMDISK_SESSION_SIZE;
-                break;
-                                
             case IOCTL_CDROM_READ_TOC:
                 
                 //
@@ -1572,8 +1563,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:
@@ -1617,68 +1607,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:
@@ -1746,8 +1725,7 @@ RamdiskQueryDeviceRelations(IN DEVICE_RELATION_TYPE Type,
         //
         // FIXME: TODO
         //
-        UNIMPLEMENTED;
-        while (TRUE);
+        UNIMPLEMENTED_DBGBREAK();
     }
     
     //
@@ -1928,6 +1906,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,
@@ -1987,50 +2078,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:
@@ -2040,8 +2147,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;
             
@@ -2052,15 +2158,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:
@@ -2070,8 +2174,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;
             
@@ -2094,8 +2197,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;
             
@@ -2145,9 +2247,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
@@ -2155,9 +2335,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
@@ -2165,9 +2367,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
@@ -2175,17 +2419,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