Author: ros-arm-bringup
Date: Sat Jul 19 13:44:31 2008
New Revision: 34589
URL:
http://svn.reactos.org/svn/reactos?rev=34589&view=rev
Log:
- Seperate the Ramdisk device extension into the Bus Device Extension and the Drive Device
Extension.
- Rename the device types to Bus vs Drive, not FDO vs PDO (they're both FDOs).
- Use a common extension (the first 0x60 bytes or so) between Bus and Drive devices.
- Implement first pass of RamdiskCreateDiskDevice -- doesn't create anything, just
validates the parameters.
- Implement our delayed work queue for handling requests asynchronously --
SendIrpToThread. Doesn't do anything for now.
- Implement RamdiskQueryDeviceRelations... not sure if we're doing the right thing.
According to PnP, we get a warning that we are "misbehaving".
- Driver seems to crash right now, needs fixes.
- Some reformatting to make more lines fit inside 80 characters so it looks nice in joe.
Modified:
trunk/reactos/drivers/storage/class/ramdisk/ramdisk.c
Modified: trunk/reactos/drivers/storage/class/ramdisk/ramdisk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/class/ramd…
==============================================================================
--- trunk/reactos/drivers/storage/class/ramdisk/ramdisk.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/storage/class/ramdisk/ramdisk.c [iso-8859-1] Sat Jul 19 13:44:31
2008
@@ -28,8 +28,8 @@
typedef enum _RAMDISK_DEVICE_TYPE
{
- RamdiskFdo,
- RamdiskPdo
+ RamdiskBus,
+ RamdiskDrive
} RAMDISK_DEVICE_TYPE;
typedef enum _RAMDISK_DEVICE_STATE
@@ -40,6 +40,7 @@
RamdiskStateStopped,
RamdiskStateRemoved,
RamdiskStateBusRemoved,
+ RamdiskStateEnumerated,
} RAMDISK_DEVICE_STATE;
DEFINE_GUID(RamdiskBusInterface,
@@ -48,18 +49,29 @@
0x410F,
0x80, 0xE4, 0x05, 0xF8, 0x10, 0xE7, 0xA8, 0x8A);
-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 SymbolicLinkName;
- FAST_MUTEX DiskListLock;
- LIST_ENTRY DiskListHead;
-} RAMDISK_EXTENSION, *PRAMDISK_EXTENSION;
+//
+// 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; \
+ LIST_ENTRY DiskList;
+
+typedef struct _RAMDISK_BUS_EXTENSION
+{
+ RAMDISK_EXTENSION;
+} RAMDISK_BUS_EXTENSION, *PRAMDISK_BUS_EXTENSION;
+
+typedef struct _RAMDISK_DRIVE_EXTENSION
+{
+ RAMDISK_EXTENSION;
+} RAMDISK_DRIVE_EXTENSION, *PRAMDISK_DRIVE_EXTENSION;
ULONG MaximumViewLength;
ULONG MaximumPerDiskViewLength;
@@ -231,6 +243,49 @@
}
}
+VOID
+NTAPI
+RamdiskWorkerThread(IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+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
RamdiskOpenClose(IN PDEVICE_OBJECT DeviceObject,
@@ -257,11 +312,73 @@
NTSTATUS
NTAPI
-RamdiskCreateDiskDevice(IN PRAMDISK_EXTENSION DeviceExtension,
+RamdiskCreateDiskDevice(IN PRAMDISK_BUS_EXTENSION DeviceExtension,
IN PRAMDISK_CREATE_INPUT Input,
IN BOOLEAN ValidateOnly,
OUT PDEVICE_OBJECT *DeviceObject)
{
+ ULONG BasePage, ViewCount, DiskType;
+
+ //
+ // Check if we're a CDROM-type RAM disk
+ //
+ DiskType = Input->DiskType;
+ if (DiskType > FILE_DEVICE_CD_ROM)
+ {
+ //
+ // Check if we're an ISO
+ //
+ if (DiskType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
+ {
+ //
+ // NTLDR mounted us somewhere
+ //
+ BasePage = Input->BasePage;
+ if (!BasePage) return STATUS_INVALID_PARAMETER;
+
+ //
+ // Sanitize disk options
+ //
+ Input->Options.Fixed = TRUE;
+ Input->Options.Readonly = Input->Options.ExportAsCd |
+ Input->Options.Readonly;
+ Input->Options.Hidden = FALSE;
+ Input->Options.NoDosDevice = FALSE;
+ Input->Options.NoDriveLetter = IsWinPEBoot ? TRUE : FALSE;
+ }
+ else
+ {
+ //
+ // The only other possibility is a controller
+ //
+ if (DiskType != FILE_DEVICE_CONTROLLER)
+ return STATUS_INVALID_PARAMETER;
+
+ //
+ // Read the view count instead
+ //
+ ViewCount = Input->ViewCount;
+
+ //
+ // Sanitize disk options
+ //
+ Input->Options.Hidden = FALSE;
+ Input->Options.NoDosDevice = FALSE;
+ Input->Options.Readonly = FALSE;
+ Input->Options.NoDriveLetter = TRUE;
+ Input->Options.Fixed = TRUE;
+ }
+
+ //
+ // Are we just validating and returning to the user?
+ //
+ if (ValidateOnly) return STATUS_SUCCESS;
+
+ //
+ // FIXME-TODO: Implement the rest of the code
+ //
+ }
+
UNIMPLEMENTED;
while (TRUE);
return STATUS_SUCCESS;
@@ -275,7 +392,7 @@
{
PRAMDISK_CREATE_INPUT Input;
ULONG Length;
- PRAMDISK_EXTENSION DeviceExtension;
+ PRAMDISK_BUS_EXTENSION DeviceExtension;
ULONG DiskType;
PWCHAR FileNameStart, FileNameEnd;
NTSTATUS Status;
@@ -284,7 +401,7 @@
//
// Get the device extension and our input data
//
- DeviceExtension = (PRAMDISK_EXTENSION)DeviceObject->DeviceExtension;
+ DeviceExtension = DeviceObject->DeviceExtension;
Length = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
Input = (PRAMDISK_CREATE_INPUT)Irp->AssociatedIrp.SystemBuffer;
@@ -326,7 +443,8 @@
//
// Validate the disk type
//
- if ((Input->Options.ExportAsCd) && (DiskType !=
FILE_DEVICE_CD_ROM_FILE_SYSTEM))
+ if ((Input->Options.ExportAsCd) &&
+ (DiskType != FILE_DEVICE_CD_ROM_FILE_SYSTEM))
{
//
// If the type isn't CDFS, it has to at least be raw CD
@@ -377,7 +495,7 @@
{
NTSTATUS Status;
PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
- PRAMDISK_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+ PRAMDISK_BUS_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
ULONG Information = 0;
//
@@ -396,9 +514,9 @@
}
//
- // Check if this is an FDO or PDO
- //
- if (DeviceExtension->Type == RamdiskFdo)
+ // Check if this is an bus device or the drive
+ //
+ if (DeviceExtension->Type == RamdiskBus)
{
//
// Check what the request is
@@ -429,7 +547,7 @@
else
{
//
- // PDO code not yet done
+ // Drive code not yet done
//
ASSERT(FALSE);
}
@@ -437,8 +555,7 @@
//
// Queue the request to our worker thread
//
- UNIMPLEMENTED;
- while (TRUE);
+ Status = SendIrpToThread(DeviceObject, Irp);
CompleteRequest:
//
@@ -463,11 +580,211 @@
NTSTATUS
NTAPI
+RamdiskQueryDeviceRelations(IN DEVICE_RELATION_TYPE Type,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PRAMDISK_BUS_EXTENSION DeviceExtension;
+ PRAMDISK_DRIVE_EXTENSION DriveExtension;
+ PDEVICE_RELATIONS DeviceRelations, OurDeviceRelations;
+ ULONG Count, DiskCount, FinalCount;
+ PLIST_ENTRY ListHead, NextEntry;
+ PDEVICE_OBJECT* DriveDeviceObject;
+ RAMDISK_DEVICE_STATE State;
+
+ //
+ // Get the device extension and check if this is a drive
+ //
+ DeviceExtension = DeviceObject->DeviceExtension;
+ if (DeviceExtension->Type == RamdiskDrive)
+ {
+ //
+ // FIXME: TODO
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+
+ //
+ // Anything but bus relations, we don't handle
+ //
+ if (Type) goto PassToNext;
+
+ //
+ // Acquire the disk list lock
+ //
+ KeEnterCriticalRegion();
+ ExAcquireFastMutex(&DeviceExtension->DiskListLock);
+
+ //
+ // Did a device already fill relations?
+ //
+ DeviceRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
+ if (DeviceRelations)
+ {
+ //
+ // Use the data
+ //
+ Count = DeviceRelations->Count;
+ }
+ else
+ {
+ //
+ // We're the first
+ //
+ Count = 0;
+ }
+
+ //
+ // Now loop our drives
+ //
+ DiskCount = 0;
+ ListHead = &DeviceExtension->DiskList;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ //
+ // As long as it wasn't removed, count it in
+ //
+ DriveExtension = CONTAINING_RECORD(NextEntry,
+ RAMDISK_DRIVE_EXTENSION,
+ DiskList);
+ if (DriveExtension->State < RamdiskStateBusRemoved) DiskCount++;
+
+ //
+ // Move to the next one
+ //
+ NextEntry = NextEntry->Flink;
+ }
+
+ //
+ // Now we know our final count
+ //
+ FinalCount = Count + DiskCount;
+
+ //
+ // Allocate the structure
+ //
+ OurDeviceRelations = ExAllocatePoolWithTag(PagedPool,
+ FIELD_OFFSET(DEVICE_RELATIONS,
+ Objects) +
+ FinalCount *
+ sizeof(PDEVICE_OBJECT),
+ TAG('R', 'a', 'm',
'd'));
+ if (!OurDeviceRelations)
+ {
+ //
+ // Fail
+ //
+ ExReleaseFastMutex(&DeviceExtension->DiskListLock);
+ KeLeaveCriticalRegion();
+ Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // Check if we already had some relations
+ //
+ if (Count)
+ {
+ //
+ // Copy them in
+ //
+ RtlCopyMemory(OurDeviceRelations->Objects,
+ DeviceRelations->Objects,
+ Count * sizeof(PDEVICE_OBJECT));
+ }
+
+ //
+ // Now loop our drives again
+ //
+ ListHead = &DeviceExtension->DiskList;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ //
+ // Go to the end of the list
+ //
+ DriveDeviceObject = &OurDeviceRelations->Objects[Count];
+
+ //
+ // Get the drive state
+ //
+ DriveExtension = CONTAINING_RECORD(NextEntry,
+ RAMDISK_DRIVE_EXTENSION,
+ DiskList);
+ State = DriveExtension->State;
+
+ //
+ // If it was removed or enumerated, we don't touch the device object
+ //
+ if (State >= RamdiskStateBusRemoved)
+ {
+ //
+ // If it was removed, we still have to keep track of this though
+ //
+ if (State == RamdiskStateBusRemoved)
+ {
+ //
+ // Mark it as enumerated now, but don't actually reference it
+ //
+ DriveExtension->State = RamdiskStateEnumerated;
+ }
+ }
+ else
+ {
+ //
+ // First time it's enumerated, reference the device object
+ //
+ ObReferenceObject(DriveExtension->DeviceObject);
+
+ //
+ // Save the object pointer, and move on
+ //
+ *DriveDeviceObject++ = DriveExtension->DeviceObject;
+ }
+
+ if (DriveExtension->State < RamdiskStateBusRemoved) DiskCount++;
+
+ //
+ // Move to the next one
+ //
+ NextEntry = NextEntry->Flink;
+ }
+
+ //
+ // Release the lock
+ //
+ ExReleaseFastMutex(&DeviceExtension->DiskListLock);
+ KeLeaveCriticalRegion();
+
+ //
+ // Cleanup old relations
+ //
+ if (DeviceRelations) ExFreePool(DeviceRelations);
+
+ //
+ // Complete our IRP
+ //
+ Irp->IoStatus.Information = (ULONG_PTR)OurDeviceRelations;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ //
+ // Pass to the next driver
+ //
+PassToNext:
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ return IoCallDriver(DeviceExtension->AttachedDevice, Irp);
+}
+
+NTSTATUS
+NTAPI
RamdiskPnp(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStackLocation;
- PRAMDISK_EXTENSION DeviceExtension;
+ PRAMDISK_BUS_EXTENSION DeviceExtension;
NTSTATUS Status;
UCHAR Minor;
@@ -569,9 +886,9 @@
case IRP_MN_QUERY_ID:
//
- // Are we a PDO?
- //
- if (DeviceExtension->Type == RamdiskPdo)
+ // Are we a drive?
+ //
+ if (DeviceExtension->Type == RamdiskDrive)
{
DPRINT1("PnP IRP: %lx\n", Minor);
while (TRUE);
@@ -581,9 +898,9 @@
case IRP_MN_QUERY_BUS_INFORMATION:
//
- // Are we a PDO?
- //
- if (DeviceExtension->Type == RamdiskPdo)
+ // Are we a drive?
+ //
+ if (DeviceExtension->Type == RamdiskDrive)
{
DPRINT1("PnP IRP: %lx\n", Minor);
while (TRUE);
@@ -599,9 +916,9 @@
case IRP_MN_QUERY_DEVICE_TEXT:
//
- // Are we a PDO?
- //
- if (DeviceExtension->Type == RamdiskPdo)
+ // Are we a drive?
+ //
+ if (DeviceExtension->Type == RamdiskDrive)
{
DPRINT1("PnP IRP: %lx\n", Minor);
while (TRUE);
@@ -610,16 +927,22 @@
case IRP_MN_QUERY_DEVICE_RELATIONS:
- DPRINT1("PnP IRP: %lx\n", Minor);
- while (TRUE);
- break;
+ //
+ // Call our main routine
+ //
+ Status = RamdiskQueryDeviceRelations(IoStackLocation->
+ Parameters.
+ QueryDeviceRelations.Type,
+ DeviceObject,
+ Irp);
+ goto ReleaseAndReturn;
case IRP_MN_QUERY_CAPABILITIES:
//
- // Are we a PDO?
- //
- if (DeviceExtension->Type == RamdiskPdo)
+ // Are we a drive?
+ //
+ if (DeviceExtension->Type == RamdiskDrive)
{
DPRINT1("PnP IRP: %lx\n", Minor);
while (TRUE);
@@ -642,9 +965,9 @@
}
//
- // Are we an FDO?
- //
- if (DeviceExtension->Type == RamdiskFdo)
+ // Are we the bus?
+ //
+ if (DeviceExtension->Type == RamdiskBus)
{
//
// Do we have an attached device?
@@ -720,23 +1043,23 @@
RamdiskAddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
- PRAMDISK_EXTENSION DeviceExtension;
+ PRAMDISK_BUS_EXTENSION DeviceExtension;
PDEVICE_OBJECT AttachedDevice;
NTSTATUS Status;
UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject;
//
- // Only create the FDO once
+ // Only create the bus FDO once
//
if (RamdiskBusFdo) return STATUS_DEVICE_ALREADY_ATTACHED;
//
- // Create the FDO
+ // Create the bus FDO
//
RtlInitUnicodeString(&DeviceName, L"\\Device\\Ramdisk");
Status = IoCreateDevice(DriverObject,
- sizeof(RAMDISK_EXTENSION),
+ sizeof(RAMDISK_BUS_EXTENSION),
&DeviceName,
FILE_DEVICE_BUS_EXTENDER,
FILE_DEVICE_SECURE_OPEN,
@@ -745,26 +1068,27 @@
if (NT_SUCCESS(Status))
{
//
- // Initialize the FDO extension
- //
- DeviceExtension = (PRAMDISK_EXTENSION)DeviceObject->DeviceExtension;
- RtlZeroMemory(DeviceObject->DeviceExtension, sizeof(RAMDISK_EXTENSION));
-
- //
- // Set FDO flags
+ // Initialize the bus FDO extension
+ //
+ DeviceExtension = DeviceObject->DeviceExtension;
+ RtlZeroMemory(DeviceObject->DeviceExtension,
+ sizeof(RAMDISK_BUS_EXTENSION));
+
+ //
+ // Set bus FDO flags
//
DeviceObject->Flags |= DO_POWER_PAGABLE | DO_DIRECT_IO;
//
- // Setup the FDO extension
- //
- DeviceExtension->Type = RamdiskFdo;
+ // Setup the bus FDO extension
+ //
+ DeviceExtension->Type = RamdiskBus;
ExInitializeFastMutex(&DeviceExtension->DiskListLock);
IoInitializeRemoveLock(&DeviceExtension->RemoveLock,
TAG('R', 'a', 'm', 'd'),
0,
1);
- InitializeListHead(&DeviceExtension->DiskListHead);
+ InitializeListHead(&DeviceExtension->DiskList);
DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
DeviceExtension->DeviceObject = DeviceObject;
@@ -802,7 +1126,7 @@
}
//
- // FDO is initialized
+ // Bus FDO is initialized
//
RamdiskBusFdo = DeviceObject;
@@ -955,7 +1279,9 @@
// the required keys when reporting a detected device.
// We hack around this ourselves.
//
-
RtlCreateUnicodeString(&((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath,
+ RtlCreateUnicodeString(&((PEXTENDED_DEVOBJ_EXTENSION)
+ PhysicalDeviceObject->DeviceObjectExtension)
+ ->DeviceNode->InstancePath,
L"Root\\UNKNOWN\\0000");
//