+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;
+}
+