[HEADERS]
[reactos.git] / reactos / drivers / storage / class / ramdisk / ramdisk.c
index 754d785..1ebe196 100644 (file)
 
 #include <initguid.h>
 #include <ntddk.h>
+#include <ntifs.h>
 #include <ntdddisk.h>
+#include <ntddcdrm.h>
 #include <scsi.h>
 #include <ntddscsi.h>
+#include <ntddvol.h>
 #include <mountdev.h>
 #include <mountmgr.h>
-#include <helper.h>
 #include <ketypes.h>
 #include <iotypes.h>
 #include <rtlfuncs.h>
 #include <arc/arc.h>
 #include <reactos/drivers/ntddrdsk.h>
+#include "../../../filesystems/fs_rec/fs_rec.h"
+#include <stdio.h>
 #define NDEBUG
 #include <debug.h>
 
+#define DO_XIP   0x00020000
+
 /* GLOBALS ********************************************************************/
 
+#define RAMDISK_SESSION_SIZE \
+    FIELD_OFFSET(CDROM_TOC, TrackData) + sizeof(TRACK_DATA)
+    
+#define RAMDISK_TOC_SIZE \
+    FIELD_OFFSET(CDROM_TOC, TrackData) + 2 * sizeof(TRACK_DATA)
+                                    
+#define TOC_DATA_TRACK              (0x04)
+
 typedef enum _RAMDISK_DEVICE_TYPE
 {
     RamdiskBus,
@@ -49,19 +63,19 @@ DEFINE_GUID(RamdiskBusInterface,
                        0x410F,
                        0x80, 0xE4, 0x05, 0xF8, 0x10, 0xE7, 0xA8, 0x8A);
 
-//
-// GCC does not seem to support anonymous structures
-//
-#define RAMDISK_EXTENSION                    \
-    RAMDISK_DEVICE_TYPE Type;                \
-    RAMDISK_DEVICE_STATE State;              \
-    PDEVICE_OBJECT DeviceObject;             \
-    PDEVICE_OBJECT PhysicalDeviceObject;     \
-    PDEVICE_OBJECT AttachedDevice;           \
-    IO_REMOVE_LOCK RemoveLock;               \
-    UNICODE_STRING SymbolicLinkName;         \
-    FAST_MUTEX DiskListLock;                 \
+typedef struct _RAMDISK_EXTENSION
+{
+    RAMDISK_DEVICE_TYPE Type;
+    RAMDISK_DEVICE_STATE State;
+    PDEVICE_OBJECT DeviceObject;
+    PDEVICE_OBJECT PhysicalDeviceObject;
+    PDEVICE_OBJECT AttachedDevice;
+    IO_REMOVE_LOCK RemoveLock;
+    UNICODE_STRING DriveDeviceName;
+    UNICODE_STRING BusDeviceName;
+    FAST_MUTEX DiskListLock;
     LIST_ENTRY DiskList;
+} RAMDISK_EXTENSION, *PRAMDISK_EXTENSION;
 
 typedef struct _RAMDISK_BUS_EXTENSION
 {
@@ -70,7 +84,32 @@ typedef struct _RAMDISK_BUS_EXTENSION
 
 typedef struct _RAMDISK_DRIVE_EXTENSION
 {
+    //
+    // Inherited base class
+    //
     RAMDISK_EXTENSION;
+    
+    //
+    // Data we get from the creator
+    //
+    GUID DiskGuid;
+    UNICODE_STRING GuidString;
+    UNICODE_STRING SymbolicLinkName;
+    ULONG DiskType;
+    RAMDISK_CREATE_OPTIONS DiskOptions;
+    LARGE_INTEGER DiskLength;
+    LONG DiskOffset;
+    WCHAR DriveLetter;
+    ULONG BasePage;
+    
+    //
+    // Data we get from the disk
+    //
+    ULONG BytesPerSector;
+    ULONG SectorsPerTrack;
+    ULONG NumberOfHeads;
+    ULONG Cylinders;
+    ULONG HiddenSectors;
 } RAMDISK_DRIVE_EXTENSION, *PRAMDISK_DRIVE_EXTENSION;
 
 ULONG MaximumViewLength;
@@ -243,71 +282,118 @@ QueryParameters(IN PUNICODE_STRING RegistryPath)
     }
 }
 
-VOID
-NTAPI
-RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
-                    IN PVOID Context)
-{
-    UNIMPLEMENTED;
-    while (TRUE);
-}
-
-NTSTATUS
+PVOID
 NTAPI
-SendIrpToThread(IN PDEVICE_OBJECT DeviceObject,
-                IN PIRP Irp)
+RamdiskMapPages(IN PRAMDISK_DRIVE_EXTENSION DeviceExtension,
+                IN LARGE_INTEGER Offset,
+                IN ULONG Length,
+                OUT PULONG OutputLength)
 {
-    PIO_WORKITEM WorkItem;
+    PHYSICAL_ADDRESS PhysicalAddress;
+    PVOID MappedBase;
+    ULONG PageOffset;
+    SIZE_T ActualLength;
+    LARGE_INTEGER ActualOffset;
+    LARGE_INTEGER ActualPages;
     
     //
-    // Mark the IRP pending
+    // We only support boot disks for now
     //
-    IoMarkIrpPending(Irp);
+    ASSERT(DeviceExtension->DiskType == RAMDISK_BOOT_DISK);
     
     //
-    // Allocate a work item
+    // Calculate the actual offset in the drive
     //
-    WorkItem = IoAllocateWorkItem(DeviceObject);
-    if (WorkItem)
-    {
-        //
-        // Queue it up
-        //
-        Irp->Tail.Overlay.DriverContext[0] = WorkItem;
-        IoQueueWorkItem(WorkItem, RamdiskWorkerThread, DelayedWorkQueue, Irp);
-        return STATUS_PENDING;
-    }
-    else
-    {
-        //
-        // Fail
-        //
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-}
-
-NTSTATUS
-NTAPI
-RamdiskOpenClose(IN PDEVICE_OBJECT DeviceObject,
-                 IN PIRP Irp)
-{
+    ActualOffset.QuadPart = DeviceExtension->DiskOffset + Offset.QuadPart;
+    
     //
-    // Complete the IRP
+    // Convert to pages
     //
-    Irp->IoStatus.Information = 1;
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return STATUS_SUCCESS;
+    ActualPages.QuadPart = ActualOffset.QuadPart >> PAGE_SHIFT;
+    
+    //
+    // Now add the base page
+    //
+    ActualPages.QuadPart = DeviceExtension->BasePage + ActualPages.QuadPart;
+    
+    //
+    // Calculate final amount of bytes
+    //
+    PhysicalAddress.QuadPart = ActualPages.QuadPart << PAGE_SHIFT;
+    
+    //
+    // Calculate pages spanned for the mapping
+    //
+    ActualLength = ADDRESS_AND_SIZE_TO_SPAN_PAGES(ActualOffset.QuadPart, Length);
+    
+    //
+    // And convert this back to bytes
+    //
+    ActualLength <<= PAGE_SHIFT;
+    
+    //
+    // Get the offset within the page
+    //
+    PageOffset = BYTE_OFFSET(ActualOffset.QuadPart);
+    
+    //
+    // Map the I/O Space from the loader
+    //
+    MappedBase = MmMapIoSpace(PhysicalAddress, ActualLength, MmCached);
+    
+    //
+    // Return actual offset within the page as well as the length
+    //
+    if (MappedBase) MappedBase = (PVOID)((ULONG_PTR)MappedBase + PageOffset);
+    *OutputLength = Length;
+    return MappedBase;
 }
 
-NTSTATUS
+VOID
 NTAPI
-RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject,
-                 IN PIRP Irp)
+RamdiskUnmapPages(IN PRAMDISK_DRIVE_EXTENSION DeviceExtension,
+                  IN PVOID BaseAddress,
+                  IN LARGE_INTEGER Offset,
+                  IN ULONG Length)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_SUCCESS;
+    LARGE_INTEGER ActualOffset;
+    SIZE_T ActualLength;
+    ULONG PageOffset;
+    
+    //
+    // We only support boot disks for now
+    //
+    ASSERT(DeviceExtension->DiskType == RAMDISK_BOOT_DISK);
+    
+    //
+    // Calculate the actual offset in the drive
+    //
+    ActualOffset.QuadPart = DeviceExtension->DiskOffset + Offset.QuadPart;
+    
+    //
+    // Calculate pages spanned for the mapping
+    //
+    ActualLength = ADDRESS_AND_SIZE_TO_SPAN_PAGES(ActualOffset.QuadPart, Length);
+    
+    //
+    // And convert this back to bytes
+    //
+    ActualLength <<= PAGE_SHIFT;
+    
+    //
+    // Get the offset within the page
+    //
+    PageOffset = BYTE_OFFSET(ActualOffset.QuadPart);
+    
+    //
+    // Calculate actual base address where we mapped this
+    //
+    BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - PageOffset);
+    
+    //
+    // Unmap the I/O space we got from the loader
+    //
+    MmUnmapIoSpace(BaseAddress, ActualLength);
 }
 
 NTSTATUS
@@ -315,20 +401,32 @@ NTAPI
 RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
                                                IN PRAMDISK_CREATE_INPUT Input,
                                                IN BOOLEAN ValidateOnly,
-                                               OUT PDEVICE_OBJECT *DeviceObject)
+                                               OUT PRAMDISK_DRIVE_EXTENSION *NewDriveExtension)
 {
-       ULONG BasePage, ViewCount, DiskType;
+       ULONG BasePage, ViewCount, DiskType, Length;
+    NTSTATUS Status;
+    PDEVICE_OBJECT DeviceObject;
+    PRAMDISK_DRIVE_EXTENSION DriveExtension;
+    PVOID Buffer;
+    WCHAR LocalBuffer[16];
+    UNICODE_STRING SymbolicLinkName, DriveString, GuidString, DeviceName;
+    PPACKED_BOOT_SECTOR BootSector;
+    BIOS_PARAMETER_BLOCK BiosBlock;
+    ULONG BytesPerSector, SectorsPerTrack, Heads, BytesRead;
+    PVOID BaseAddress;
+    LARGE_INTEGER CurrentOffset, CylinderSize, DiskLength;
+    ULONG CylinderCount, SizeByCylinders;
        
        //
-       // Check if we're a CDROM-type RAM disk
+       // Check if we're a boot RAM disk
        //
        DiskType = Input->DiskType;
-       if (DiskType > FILE_DEVICE_CD_ROM)
+       if (DiskType >= RAMDISK_BOOT_DISK)
        {
                //
                // Check if we're an ISO
                // 
-               if (DiskType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
+               if (DiskType == RAMDISK_BOOT_DISK)
                {
                        //
                        // NTLDR mounted us somewhere
@@ -349,10 +447,15 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
                else
                {
                        //
-                       // The only other possibility is a controller
+                       // The only other possibility is a WIM disk
                        //
-                       if (DiskType != FILE_DEVICE_CONTROLLER)
+                       if (DiskType != RAMDISK_WIM_DISK)
+            {
+                //
+                // Fail
+                //
                 return STATUS_INVALID_PARAMETER;
+            }
                        
                        //
                        // Read the view count instead
@@ -375,10 +478,299 @@ RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
                if (ValidateOnly) return STATUS_SUCCESS;
         
         //
-        // FIXME-TODO: Implement the rest of the code
+        // Build the GUID string
         //
-       }
+        Status = RtlStringFromGUID(&Input->DiskGuid, &GuidString);
+        if (!(NT_SUCCESS(Status)) || !(GuidString.Buffer))
+        {
+            //
+            // Fail
+            //
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto FailCreate;
+        }
+        
+        //
+        // Allocate our device name
+        //
+        Length = GuidString.Length + 32;
+        Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                       Length,
+                                       'dmaR');
+        if (!Buffer)
+        {
+            //
+            // Fail
+            //
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto FailCreate;
+        }
+        
+        // 
+        // Build the device name string
+        //
+        DeviceName.Buffer = Buffer;
+        DeviceName.Length = Length - 2;
+        DeviceName.MaximumLength = Length;
+        wcsncpy(Buffer, L"\\Device\\Ramdisk", Length / sizeof(WCHAR));
+        wcsncat(Buffer, GuidString.Buffer, Length / sizeof(WCHAR));
+        
+        //
+        // Create the drive device
+        //
+        Status = IoCreateDevice(DeviceExtension->DeviceObject->DriverObject,
+                                sizeof(RAMDISK_DRIVE_EXTENSION),
+                                &DeviceName,
+                                (Input->Options.ExportAsCd) ?
+                                FILE_DEVICE_CD_ROM : FILE_DEVICE_DISK,
+                                0,
+                                0,
+                                &DeviceObject);
+        if (!NT_SUCCESS(Status)) goto FailCreate;
+        
+        //
+        // Grab the drive extension
+        //
+        DriveExtension = DeviceObject->DeviceExtension;
+       
+        //
+        // Check if we need a DOS device
+        //
+        if (!Input->Options.NoDosDevice)
+        {
+            //
+            // Build the symbolic link name
+            //
+            SymbolicLinkName.MaximumLength = GuidString.Length + 36;
+            SymbolicLinkName.Length = GuidString.Length + 34;
+            Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                           SymbolicLinkName.MaximumLength,
+                                           'dmaR');
+            SymbolicLinkName.Buffer = Buffer;
+            if (Buffer)
+            {
+                //
+                // Create it
+                //
+                wcsncpy(Buffer,
+                        L"\\GLOBAL??\\Ramdisk",
+                        SymbolicLinkName.MaximumLength / sizeof(WCHAR));
+                wcsncat(Buffer,
+                        GuidString.Buffer,
+                        SymbolicLinkName.MaximumLength / sizeof(WCHAR));
+                Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
+                if (!NT_SUCCESS(Status))
+                {
+                    //
+                    // Nevermind...
+                    //
+                    Input->Options.NoDosDevice = TRUE;
+                    ExFreePool(Buffer);
+                    SymbolicLinkName.Buffer = NULL;
+                }
+            }
+            else
+            {
+                //
+                // No DOS device
+                //
+                Input->Options.NoDosDevice = TRUE;
+            }
+            
+            //
+            // It this an ISO boot ramdisk?
+            //
+            if (Input->DiskType == RAMDISK_BOOT_DISK)
+            {
+                //
+                // Does it need a drive letter?
+                //
+                if (!Input->Options.NoDriveLetter)
+                {
+                    //
+                    // Build it and take over the existing symbolic link
+                    //
+                    _snwprintf(LocalBuffer,
+                               30,
+                               L"\\DosDevices\\%wc:",
+                               Input->DriveLetter);
+                    RtlInitUnicodeString(&DriveString, LocalBuffer);
+                    IoDeleteSymbolicLink(&DriveString);
+                    IoCreateSymbolicLink(&DriveString, &DeviceName);
+                    
+                    //
+                    // Save the drive letter
+                    //
+                    DriveExtension->DriveLetter = Input->DriveLetter;
+                }
+            }
+            
+        }
+        
+        //
+        // Setup the device object flags
+        //
+        DeviceObject->Flags |= (DO_XIP | DO_POWER_PAGABLE | DO_DIRECT_IO);
+        DeviceObject->AlignmentRequirement = 1;
+        
+        //
+        // Build the drive FDO
+        //
+        *NewDriveExtension = DriveExtension;
+        DriveExtension->Type = RamdiskDrive;
+        DiskLength = Input->DiskLength;
+               ExInitializeFastMutex(&DriveExtension->DiskListLock);
+           IoInitializeRemoveLock(&DriveExtension->RemoveLock,
+                               'dmaR',
+                               0,
+                               1);
+        DriveExtension->DriveDeviceName = DeviceName;
+        DriveExtension->SymbolicLinkName = SymbolicLinkName;
+        DriveExtension->GuidString = GuidString;
+        DriveExtension->DiskGuid = Input->DiskGuid;
+           DriveExtension->PhysicalDeviceObject = DeviceObject;
+           DriveExtension->DeviceObject = RamdiskBusFdo;
+        DriveExtension->AttachedDevice = RamdiskBusFdo;
+        DriveExtension->DiskType = Input->DiskType;
+        DriveExtension->DiskOptions = Input->Options;
+        DriveExtension->DiskLength = DiskLength;
+        DriveExtension->DiskOffset = Input->DiskOffset;
+        DriveExtension->BasePage = Input->BasePage;
+        DriveExtension->BytesPerSector = 0;
+        DriveExtension->SectorsPerTrack = 0;
+        DriveExtension->NumberOfHeads = 0;
+        
+        //
+        // Make sure we don't free it later
+        //
+        DeviceName.Buffer = NULL;
+        SymbolicLinkName.Buffer = NULL;
+        GuidString.Buffer = NULL;
+        
+        //
+        // Check if this is an boot disk, or a registry ram drive
+        //
+        if (!(Input->Options.ExportAsCd) &&
+            (Input->DiskType == RAMDISK_BOOT_DISK))
+        {
+            //
+            // Not an ISO boot, but it's a boot FS -- map it to figure out the
+            // drive settings
+            //
+            CurrentOffset.QuadPart = 0;
+            BaseAddress = RamdiskMapPages(DriveExtension,
+                                          CurrentOffset,
+                                          PAGE_SIZE,
+                                          &BytesRead);
+            if (BaseAddress)
+            {
+                //
+                // Get the data
+                //
+                BootSector = (PPACKED_BOOT_SECTOR)BaseAddress;
+                FatUnpackBios(&BiosBlock, &BootSector->PackedBpb);
+                BytesPerSector = BiosBlock.BytesPerSector;
+                SectorsPerTrack = BiosBlock.SectorsPerTrack;
+                Heads = BiosBlock.Heads;
+                
+                //
+                // Save it
+                //
+                DriveExtension->BytesPerSector = BytesPerSector;
+                DriveExtension->SectorsPerTrack = SectorsPerTrack;
+                DriveExtension->NumberOfHeads = Heads;
+                
+                //
+                // Unmap now
+                //
+                CurrentOffset.QuadPart = 0;
+                RamdiskUnmapPages(DriveExtension,
+                                  BaseAddress,
+                                  CurrentOffset,
+                                  BytesRead);
+            }
+            else
+            {
+                //
+                // Fail
+                //
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                goto FailCreate;
+            }
+        }
+                
+        //
+        // Check if the drive settings haven't been set yet
+        //
+        if ((DriveExtension->BytesPerSector == 0) ||
+            (DriveExtension->SectorsPerTrack == 0) ||
+            (DriveExtension->NumberOfHeads == 0))
+        {
+            //
+            // Check if this is a CD
+            //
+            if (Input->Options.ExportAsCd)
+            {
+                //
+                // Setup partition parameters default for ISO 9660
+                //
+                DriveExtension->BytesPerSector = 2048;
+                DriveExtension->SectorsPerTrack = 32;
+                DriveExtension->NumberOfHeads = 64;
+            }
+            else
+            {
+                //
+                // Setup partition parameters default for FAT
+                //
+                DriveExtension->BytesPerSector = 512;
+                DriveExtension->SectorsPerTrack = 128;
+                DriveExtension->NumberOfHeads = 16;
+            }
+        }
+        
+        //
+        // Calculate the cylinder size
+        //
+        CylinderSize.QuadPart = DriveExtension->BytesPerSector *
+                                DriveExtension->SectorsPerTrack *
+                                DriveExtension->NumberOfHeads;
+        CylinderCount = DiskLength.QuadPart / CylinderSize.QuadPart;
+        SizeByCylinders = CylinderSize.QuadPart * CylinderCount;
+        DriveExtension->Cylinders = CylinderCount;
+        if ((DiskLength.HighPart > 0) || (SizeByCylinders < DiskLength.LowPart))
+        {
+            //
+            // Align cylinder size up
+            //
+            DriveExtension->Cylinders++;
+        }
+        
+        //
+        // Acquire the disk lock
+        //
+        KeEnterCriticalRegion();
+        ExAcquireFastMutex(&DeviceExtension->DiskListLock);
+        
+        //
+        // Insert us
+        //
+        InsertTailList(&DeviceExtension->DiskList, &DriveExtension->DiskList);
+        
+        //
+        // Release the lock
+        //
+        ExReleaseFastMutex(&DeviceExtension->DiskListLock);
+        KeLeaveCriticalRegion();
+        
+        //
+        // Clear init flag
+        //
+        DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+        return STATUS_SUCCESS;
+    }
     
+FailCreate:
     UNIMPLEMENTED;
     while (TRUE);
     return STATUS_SUCCESS;
@@ -392,7 +784,8 @@ RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject,
 {
        PRAMDISK_CREATE_INPUT Input;
        ULONG Length;
-       PRAMDISK_BUS_EXTENSION DeviceExtension; 
+       PRAMDISK_BUS_EXTENSION DeviceExtension;
+    PRAMDISK_DRIVE_EXTENSION DriveExtension; 
        ULONG DiskType;
        PWCHAR FileNameStart, FileNameEnd;
        NTSTATUS Status;
@@ -421,12 +814,12 @@ RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject,
        // Validate the disk type
        //
        DiskType = Input->DiskType;
-       if (DiskType == FILE_DEVICE_CONTROLLER) return STATUS_INVALID_PARAMETER;
+       if (DiskType == RAMDISK_WIM_DISK) return STATUS_INVALID_PARAMETER;
        
        //
        // Look at the disk type
        //
-       if (DiskType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
+       if (DiskType == RAMDISK_BOOT_DISK)
        {
                //
                // We only allow this as an early-init boot
@@ -443,19 +836,18 @@ RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject,
        //
        // Validate the disk type
        //
-       if ((Input->Options.ExportAsCd) &&
-        (DiskType != FILE_DEVICE_CD_ROM_FILE_SYSTEM))
+       if ((Input->Options.ExportAsCd) && (DiskType != RAMDISK_BOOT_DISK))
        {
                //
                // If the type isn't CDFS, it has to at least be raw CD
                //
-               if (DiskType != FILE_DEVICE_CD_ROM) return STATUS_INVALID_PARAMETER;
+               if (DiskType != RAMDISK_MEMORY_MAPPED_DISK) return STATUS_INVALID_PARAMETER;
        }
        
        //
        // Check if this is an actual file
        //
-       if (DiskType <= FILE_DEVICE_CD_ROM)
+       if (DiskType <= RAMDISK_MEMORY_MAPPED_DISK)
        {
                //
                // Validate the file name
@@ -472,7 +864,7 @@ RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject,
        Status = RamdiskCreateDiskDevice(DeviceExtension,
                                                                         Input, 
                                                                         ValidateOnly,
-                                                                        &DeviceObject);
+                                                                        &DriveExtension);
        if (NT_SUCCESS(Status))
        {
                //
@@ -488,21 +880,516 @@ RamdiskCreateRamdisk(IN PDEVICE_OBJECT DeviceObject,
        return Status;
 }
 
-NTSTATUS
+VOID
 NTAPI
-RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
-                     IN PIRP Irp)
+RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
+                    IN PVOID Context)
 {
+    PRAMDISK_BUS_EXTENSION DeviceExtension;
     NTSTATUS Status;
-    PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
-    PRAMDISK_BUS_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
-    ULONG Information = 0;
+    PIO_STACK_LOCATION IoStackLocation;
+    PIRP Irp = Context;
     
     //
-    // Grab the remove lock
+    // Get the stack location
+    //
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    
+    //
+    // Free the work item
+    //
+    IoFreeWorkItem(Irp->Tail.Overlay.DriverContext[0]);
+    
+    //
+    // Grab the device extension and lock it
     //
+    DeviceExtension = DeviceObject->DeviceExtension;
     Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
-    if (!NT_SUCCESS(Status))
+    if (NT_SUCCESS(Status))
+    {
+        //
+        // Discriminate by major code
+        //
+        switch (IoStackLocation->MajorFunction)
+        {
+            //
+            // Device control
+            //
+            case IRP_MJ_DEVICE_CONTROL:
+                               
+                //
+                // Let's take a look at the IOCTL
+                //
+                switch (IoStackLocation->Parameters.DeviceIoControl.IoControlCode)
+                {
+                    //
+                    // Ramdisk create request
+                    //
+                    case FSCTL_CREATE_RAM_DISK:
+                        
+                        //
+                        // This time we'll do it for real
+                        //
+                        Status = RamdiskCreateRamdisk(DeviceObject, Irp, FALSE);
+                        break;
+                        
+                    case IOCTL_DISK_SET_PARTITION_INFO:
+                        
+                        DPRINT1("Set partition info request\n");
+                        UNIMPLEMENTED;
+                        while (TRUE);
+                        break;
+                        
+                    case IOCTL_DISK_GET_DRIVE_LAYOUT:
+                        
+                        DPRINT1("Get drive layout request\n");
+                        UNIMPLEMENTED;
+                        while (TRUE);
+                        break;
+                        
+                    case IOCTL_DISK_GET_PARTITION_INFO:
+                        
+                        DPRINT1("Get partitinon info request\n");
+                        UNIMPLEMENTED;
+                        while (TRUE);
+                        break;
+                        
+                    default:
+                        
+                        DPRINT1("Invalid request\n");
+                        UNIMPLEMENTED;
+                        while (TRUE);
+                        break;
+                }
+                
+                //
+                // We're  here
+                //
+                break;
+                
+            //
+            // Read or write request
+            //
+            case IRP_MJ_READ:
+            case IRP_MJ_WRITE:
+                
+                DPRINT1("Read/Write request\n");
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            //
+            // Internal request (SCSI?)
+            //
+            case IRP_MJ_INTERNAL_DEVICE_CONTROL:
+
+                DPRINT1("SCSI request\n");
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            //
+            // Flush request
+            //
+            case IRP_MJ_FLUSH_BUFFERS:
+                
+                DPRINT1("Flush request\n");
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+
+            //
+            // Anything else
+            //
+            default:
+                
+                DPRINT1("Invalid request: %lx\n", IoStackLocation->MajorFunction);
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+        }
+        
+        //
+        // Complete the I/O
+        //
+        IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
+        Irp->IoStatus.Status = Status;
+        Irp->IoStatus.Information = 0;
+        IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+        return;
+    }
+    
+    //
+    // Fail the I/O
+    //
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+NTSTATUS
+NTAPI
+SendIrpToThread(IN PDEVICE_OBJECT DeviceObject,
+                IN PIRP Irp)
+{
+    PIO_WORKITEM WorkItem;
+    
+    //
+    // Mark the IRP pending
+    //
+    IoMarkIrpPending(Irp);
+    
+    //
+    // Allocate a work item
+    //
+    WorkItem = IoAllocateWorkItem(DeviceObject);
+    if (WorkItem)
+    {
+        //
+        // Queue it up
+        //
+        Irp->Tail.Overlay.DriverContext[0] = WorkItem;
+        IoQueueWorkItem(WorkItem, RamdiskWorkerThread, DelayedWorkQueue, Irp);
+        return STATUS_PENDING;
+    }
+    else
+    {
+        //
+        // Fail
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+}
+
+NTSTATUS
+NTAPI
+RamdiskReadWriteReal(IN PIRP Irp,
+                     IN PRAMDISK_DRIVE_EXTENSION DeviceExtension)
+{
+    PMDL Mdl;
+    PVOID CurrentBase, SystemVa, BaseAddress;
+    PIO_STACK_LOCATION IoStackLocation;
+    LARGE_INTEGER CurrentOffset;
+    ULONG BytesRead, BytesLeft, CopyLength;
+    PVOID Source, Destination;
+    NTSTATUS Status;
+    
+    //
+    // Get the MDL and check if it's mapped
+    //
+    Mdl = Irp->MdlAddress;
+    if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))
+    {
+        //
+        // Use the mapped address
+        //
+        SystemVa = Mdl->MappedSystemVa;
+    }
+    else
+    {
+        //
+        // Map it ourselves
+        //
+        SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
+                                                0,
+                                                MmCached,
+                                                NULL,
+                                                0, 
+                                                NormalPagePriority);
+    }
+    
+    //
+    // Make sure we were able to map it
+    //
+    CurrentBase = SystemVa;
+    if (!SystemVa) return STATUS_INSUFFICIENT_RESOURCES;
+    
+    //
+    // Initialize default
+    //
+    Irp->IoStatus.Information = 0;
+    
+    //
+    // Get the I/O Stack Location and capture the data
+    //
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    CurrentOffset = IoStackLocation->Parameters.Read.ByteOffset;
+    BytesLeft = IoStackLocation->Parameters.Read.Length;
+    if (!BytesLeft) return STATUS_INVALID_PARAMETER;
+    
+    //
+    // Do the copy loop
+    //
+    while (TRUE)
+    {
+        //
+        // Map the pages
+        //
+        BaseAddress = RamdiskMapPages(DeviceExtension,
+                                      CurrentOffset,
+                                      BytesLeft,
+                                      &BytesRead);
+        if (!BaseAddress) return STATUS_INSUFFICIENT_RESOURCES;
+        
+        //
+        // Update our lengths
+        //
+        Irp->IoStatus.Information += BytesRead;
+        CopyLength = BytesRead;
+        
+        //
+        // Check if this was a read or write
+        //
+        Status = STATUS_SUCCESS;
+        if (IoStackLocation->MajorFunction == IRP_MJ_READ)
+        {
+            //
+            // Set our copy parameters
+            //
+            Destination = CurrentBase;
+            Source = BaseAddress;
+            goto DoCopy;
+        }
+        else if (IoStackLocation->MajorFunction == IRP_MJ_WRITE)
+        {
+            //
+            // Set our copy parameters
+            //
+            Destination = BaseAddress;
+            Source = CurrentBase;
+DoCopy:
+            //
+            // Copy the data
+            //
+            RtlCopyMemory(Destination, Source, CopyLength);
+        }
+        else
+        {
+            //
+            // Prepare us for failure
+            //
+            BytesLeft = CopyLength;
+            Status = STATUS_INVALID_PARAMETER;
+        }
+        
+        //
+        // Unmap the pages
+        //
+        RamdiskUnmapPages(DeviceExtension,
+                          BaseAddress,
+                          CurrentOffset,
+                          BytesRead);
+        
+        //
+        // Update offset and bytes left
+        //
+        BytesLeft -= BytesRead;
+        CurrentOffset.QuadPart += BytesRead;
+        CurrentBase = (PVOID)((ULONG_PTR)CurrentBase + BytesRead);
+        
+        //
+        // Check if we're done
+        //
+        if (!BytesLeft) 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 = 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,
+                 IN PIRP Irp)
+{
+    //
+    // Complete the IRP
+    //
+    Irp->IoStatus.Information = 1;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+RamdiskReadWrite(IN PDEVICE_OBJECT DeviceObject,
+                 IN PIRP Irp)
+{
+    PRAMDISK_DRIVE_EXTENSION DeviceExtension;
+    ULONG Length;
+    LARGE_INTEGER ByteOffset;
+    PIO_STACK_LOCATION IoStackLocation;
+    NTSTATUS Status, ReturnStatus;
+    
+    //
+    // Get the device extension and make sure this isn't a bus
+    //
+    DeviceExtension = DeviceObject->DeviceExtension;
+    if (DeviceExtension->Type == RamdiskBus)
+    {
+        //
+        // Fail
+        //
+        Status = STATUS_INVALID_DEVICE_REQUEST;
+        goto Complete;
+    }
+    
+    //
+    // Capture parameters
+    //
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    Length = IoStackLocation->Parameters.Read.Length;
+    ByteOffset = IoStackLocation->Parameters.Read.ByteOffset;
+    
+    //
+    // FIXME: Validate offset
+    //
+    
+    //
+    // FIXME: Validate sector
+    //
+    
+    //
+    // Validate write
+    //
+    if ((IoStackLocation->MajorFunction == IRP_MJ_WRITE) &&
+        (DeviceExtension->DiskOptions.Readonly))
+    {
+        //
+        // Fail, this is read-only
+        //
+        Status = STATUS_MEDIA_WRITE_PROTECTED;
+        goto Complete;
+    }
+    
+    //
+    // See if we want to do this sync or async
+    //
+    if (DeviceExtension->DiskType > RAMDISK_MEMORY_MAPPED_DISK)
+    {
+        //
+        // Do it sync
+        //
+        Status = RamdiskReadWriteReal(Irp, DeviceExtension);
+        goto Complete;
+    }
+    
+    //
+    // Queue it to the worker
+    //
+    Status = SendIrpToThread(DeviceObject, Irp);
+    ReturnStatus = STATUS_PENDING;
+    
+    //
+    // Check if we're pending or not
+    //
+    if (Status != STATUS_PENDING)
+    {
+Complete:
+        //
+        // Complete the IRP
+        //
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+        ReturnStatus = Status;
+    }
+    
+    //
+    // Return to caller
+    //
+    return ReturnStatus;
+}
+
+NTSTATUS
+NTAPI
+RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
+                     IN PIRP Irp)
+{
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    PRAMDISK_BUS_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    PRAMDISK_DRIVE_EXTENSION DriveExtension = (PVOID)DeviceExtension;
+    ULONG Information;
+    PCDROM_TOC Toc;
+    PDISK_GEOMETRY DiskGeometry;
+    
+    //
+    // Grab the remove lock
+    //
+    Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
+    if (!NT_SUCCESS(Status))
     {
         //
         // Fail the IRP
@@ -513,6 +1400,12 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
         return Status;
     }
     
+    //
+    // Setup some defaults
+    //
+    Status = STATUS_INVALID_DEVICE_REQUEST;
+    Information = 0;
+    
     //
     // Check if this is an bus device or the drive
     //
@@ -547,14 +1440,265 @@ RamdiskDeviceControl(IN PDEVICE_OBJECT DeviceObject,
     else
     {
         //
-        // Drive code not yet done
+        // Check what the request is
+        //
+        switch (IoStackLocation->Parameters.DeviceIoControl.IoControlCode)
+        {
+            case IOCTL_DISK_CHECK_VERIFY:
+            case IOCTL_STORAGE_CHECK_VERIFY:
+            case IOCTL_STORAGE_CHECK_VERIFY2:
+            case IOCTL_CDROM_CHECK_VERIFY:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+
+            case IOCTL_STORAGE_GET_MEDIA_TYPES:
+            case IOCTL_DISK_GET_MEDIA_TYPES:
+            case IOCTL_DISK_GET_DRIVE_GEOMETRY:
+            case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
+                
+                //
+                // Validate the length
+                //
+                if (IoStackLocation->Parameters.DeviceIoControl.
+                    OutputBufferLength < sizeof(DISK_GEOMETRY))
+                {
+                    //
+                    // Invalid length
+                    //
+                    Status = STATUS_BUFFER_TOO_SMALL;
+                    break;
+                }
+                
+                //
+                // Fill it out
+                //
+                DiskGeometry = Irp->AssociatedIrp.SystemBuffer;
+                DiskGeometry->Cylinders.QuadPart = DriveExtension->Cylinders;
+                DiskGeometry->BytesPerSector = DriveExtension->BytesPerSector;
+                DiskGeometry->SectorsPerTrack = DriveExtension->SectorsPerTrack;
+                DiskGeometry->TracksPerCylinder = DriveExtension->NumberOfHeads;
+                DiskGeometry->MediaType = DriveExtension->DiskOptions.Fixed ?
+                                          FixedMedia : RemovableMedia;
+                
+                //
+                // We're done
+                //
+                Status = STATUS_SUCCESS;
+                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:
+                
+                //
+                // Validate the length
+                //
+                if (IoStackLocation->Parameters.DeviceIoControl.
+                    OutputBufferLength < sizeof(CDROM_TOC))
+                {
+                    //
+                    // Invalid length
+                    //
+                    Status = STATUS_BUFFER_TOO_SMALL;
+                    break;
+                }
+                
+                //
+                // Clear the TOC
+                //
+                Toc = Irp->AssociatedIrp.SystemBuffer;
+                RtlZeroMemory(Toc, sizeof(CDROM_TOC));
+                
+                //
+                // Fill it out
+                //
+                Toc->Length[0] = 0;
+                Toc->Length[1] = RAMDISK_TOC_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;
+                
+                //
+                // We're done
+                //
+                Status = STATUS_SUCCESS;
+                Information = RAMDISK_TOC_SIZE;
+                break;
+                
+            case IOCTL_DISK_SET_PARTITION_INFO:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_DISK_GET_PARTITION_INFO:
+                
+                //
+                // Validate the length
+                //
+                if (IoStackLocation->Parameters.DeviceIoControl.
+                    OutputBufferLength < sizeof(PARTITION_INFORMATION))
+                {
+                    //
+                    // Invalid length
+                    //
+                    Status = STATUS_BUFFER_TOO_SMALL;
+                    break;
+                }
+                
+                //
+                // Check if we need to do this sync or async
+                //
+                if (DriveExtension->DiskType > RAMDISK_MEMORY_MAPPED_DISK)
+                {
+                    //
+                    // Call the helper function
+                    //
+                    Status = RamdiskGetPartitionInfo(Irp, DriveExtension);
+                }
+                else
+                {
+                    //
+                    // Do it asynchronously later
+                    //
+                    goto CallWorker;
+                }
+                
+                //
+                // We're done
+                //
+                Information = Irp->IoStatus.Information;
+                break;
+                
+            case IOCTL_DISK_GET_DRIVE_LAYOUT:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_DISK_GET_LENGTH_INFO:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_DISK_IS_WRITABLE:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_SCSI_MINIPORT:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_STORAGE_QUERY_PROPERTY:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_MOUNTDEV_QUERY_STABLE_GUID:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_VOLUME_SET_GPT_ATTRIBUTES:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_VOLUME_GET_GPT_ATTRIBUTES:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            case IOCTL_VOLUME_OFFLINE:
+                
+                UNIMPLEMENTED;
+                while (TRUE);
+                break;
+                
+            default:
+         
+                //
+                // Drive code not emulated
+                //
+                DPRINT1("IOCTL: %lx\n", IoStackLocation->Parameters.DeviceIoControl.IoControlCode);                
+                break;
+        }
+
+        //
+        // If requests drop down here, we just return them complete them
         //
-        ASSERT(FALSE);
+        goto CompleteRequest;
     }
     
     //
     // Queue the request to our worker thread
     //
+CallWorker:
     Status = SendIrpToThread(DeviceObject, Irp);
     
 CompleteRequest:
@@ -670,7 +1814,7 @@ RamdiskQueryDeviceRelations(IN DEVICE_RELATION_TYPE Type,
                                                             Objects) +
                                                FinalCount *
                                                sizeof(PDEVICE_OBJECT),
-                                               TAG('R', 'a', 'm', 'd'));
+                                               'dmaR');
     if (!OurDeviceRelations)
     {
         //
@@ -1090,7 +2234,7 @@ RamdiskAddDevice(IN PDRIVER_OBJECT DriverObject,
            DeviceExtension->Type = RamdiskBus;
                ExInitializeFastMutex(&DeviceExtension->DiskListLock);
            IoInitializeRemoveLock(&DeviceExtension->RemoveLock,
-                               TAG('R', 'a', 'm', 'd'),
+                               'dmaR',
                                0,
                                1);
                InitializeListHead(&DeviceExtension->DiskList);
@@ -1103,7 +2247,7 @@ RamdiskAddDevice(IN PDRIVER_OBJECT DriverObject,
            Status = IoRegisterDeviceInterface(PhysicalDeviceObject,
                                                                                   &RamdiskBusInterface,
                                                                                   NULL,
-                                                                                  &DeviceExtension->SymbolicLinkName);
+                                                                                  &DeviceExtension->BusDeviceName);
            if (!NT_SUCCESS(Status))
            {
                        //
@@ -1124,8 +2268,8 @@ RamdiskAddDevice(IN PDRIVER_OBJECT DriverObject,
                        //
                        // Fail
                        //
-                       IoSetDeviceInterfaceState(&DeviceExtension->SymbolicLinkName, 0);
-                       RtlFreeUnicodeString(&DeviceExtension->SymbolicLinkName);
+                       IoSetDeviceInterfaceState(&DeviceExtension->BusDeviceName, 0);
+                       RtlFreeUnicodeString(&DeviceExtension->BusDeviceName);
                        IoDeleteDevice(DeviceObject);
                        return STATUS_NO_SUCH_DEVICE;
            }
@@ -1143,7 +2287,7 @@ RamdiskAddDevice(IN PDRIVER_OBJECT DriverObject,
                        //
                        // Are we being booted from setup? Not yet supported
                        //
-                       ASSERT (!KeLoaderBlock->SetupLdrBlock);
+                       //ASSERT(!KeLoaderBlock->SetupLdrBlock);
            }
 
                //
@@ -1167,6 +2311,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
     PCHAR BootDeviceName, CommandLine;
     PDEVICE_OBJECT PhysicalDeviceObject = NULL;
     NTSTATUS Status;
+    DPRINT("RAM Disk Driver Initialized\n");
     
     //
     // Query ramdisk parameters
@@ -1180,7 +2325,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
     DriverRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
                                                       RegistryPath->Length +
                                                       sizeof(WCHAR),
-                                                      TAG('R', 'a', 'm', 'd'));
+                                                      'dmaR');
     if (!DriverRegistryPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
     RtlCopyUnicodeString(&DriverRegistryPath, RegistryPath);
     
@@ -1258,7 +2403,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
     //
     // Installing from Ramdisk isn't supported yet
     //
-    ASSERT(!KeLoaderBlock->SetupLdrBlock);
+    //ASSERT(!KeLoaderBlock->SetupLdrBlock);
     
     //
     // Are we reporting the device