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