FdoDestroy(Fdo);
}
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoQueryIdCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
+ )
+{
+ PKEVENT Event = Context;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static NTSTATUS
+FdoQueryId(
+ IN PXENDISK_FDO Fdo,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN BUS_QUERY_ID_TYPE Type,
+ OUT PCHAR Id
+ )
+{
+ PIRP Irp;
+ KEVENT Event;
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(Fdo);
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ if (Irp == NULL)
+ goto fail1;
+
+ StackLocation = IoGetNextIrpStackLocation(Irp);
+
+ StackLocation->MajorFunction = IRP_MJ_PNP;
+ StackLocation->MinorFunction = IRP_MN_QUERY_ID;
+ StackLocation->Flags = 0;
+ StackLocation->Parameters.QueryId.IdType = Type;
+ StackLocation->DeviceObject = DeviceObject;
+ StackLocation->FileObject = NULL;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ IoSetCompletionRoutine(Irp,
+ FdoQueryIdCompletion,
+ &Event,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ // Default completion status
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ status = IoCallDriver(DeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = Irp->IoStatus.Status;
+ } else {
+ ASSERT3U(status, ==, Irp->IoStatus.Status);
+ }
+
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = RtlStringCbPrintfA(Id,
+ MAX_DEVICE_ID_LEN,
+ "%ws",
+ (PWCHAR)Irp->IoStatus.Information);
+ ASSERT(NT_SUCCESS(status));
+
+ ExFreePool((PVOID)Irp->IoStatus.Information);
+
+ IoFreeIrp(Irp);
+
+ return STATUS_SUCCESS;
+
+fail2:
+ IoFreeIrp(Irp);
+
+fail1:
+ return status;
+}
+
+static NTSTATUS
+FdoAddDevice(
+ IN PXENDISK_FDO Fdo,
+ IN PDEVICE_OBJECT PhysicalDeviceObject
+ )
+{
+ CHAR DeviceID[MAX_DEVICE_ID_LEN];
+ CHAR InstanceID[MAX_DEVICE_ID_LEN];
+ NTSTATUS status;
+
+ status = FdoQueryId(Fdo,
+ PhysicalDeviceObject,
+ BusQueryDeviceID,
+ DeviceID);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ status = FdoQueryId(Fdo,
+ PhysicalDeviceObject,
+ BusQueryInstanceID,
+ InstanceID);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = PdoCreate(Fdo,
+ PhysicalDeviceObject,
+ DeviceID,
+ InstanceID);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ return STATUS_SUCCESS;
+
+fail3:
+fail2:
+fail1:
+ return status;
+}
+
static FORCEINLINE VOID
__FdoEnumerate(
IN PXENDISK_FDO Fdo,
for (Index = 0; Index < Count; Index++) {
#pragma warning(suppress:6385) // Reading invalid data from 'PhysicalDeviceObject'
if (PhysicalDeviceObject[Index] != NULL) {
- (VOID) PdoCreate(Fdo,
- PhysicalDeviceObject[Index]);
+ (VOID) FdoAddDevice(Fdo,
+ PhysicalDeviceObject[Index]);
}
}
#define PDO_TAG 'ODP'
+#define MAXNAMELEN 128
+
struct _XENDISK_PDO {
PXENDISK_DX Dx;
PDEVICE_OBJECT LowerDeviceObject;
PDEVICE_OBJECT PhysicalDeviceObject;
+ CHAR Name[MAXNAMELEN];
PXENDISK_THREAD SystemPowerThread;
PIRP SystemPowerIrp;
return Pdo->Fdo;
}
+static FORCEINLINE VOID
+__PdoSetName(
+ IN PXENDISK_PDO Pdo,
+ IN PCHAR DeviceID,
+ IN PCHAR InstanceID
+ )
+{
+ NTSTATUS status;
+
+ status = RtlStringCbPrintfA(Pdo->Name,
+ MAXNAMELEN,
+ "%s\\%s",
+ DeviceID,
+ InstanceID);
+ ASSERT(NT_SUCCESS(status));
+}
+
+static FORCEINLINE PCHAR
+__PdoGetName(
+ IN PXENDISK_PDO Pdo
+ )
+{
+ return Pdo->Name;
+}
+
__drv_functionClass(IO_COMPLETION_ROUTINE)
__drv_sameIRQL
static NTSTATUS
if (!NT_SUCCESS(status))
goto done;
- Verbose("%p: %s -> %s\n",
- Pdo->Dx->DeviceObject,
- PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
- PowerDeviceStateName(DeviceState));
+ Verbose("%s: %s -> %s\n",
+ __PdoGetName(Pdo),
+ PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
+ PowerDeviceStateName(DeviceState));
__PdoSetDevicePowerState(Pdo, DeviceState);
ASSERT3U(DeviceState, >, __PdoGetDevicePowerState(Pdo));
- Verbose("%p: %s -> %s\n",
- Pdo->Dx->DeviceObject,
- PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
- PowerDeviceStateName(DeviceState));
+ Verbose("%s: %s -> %s\n",
+ __PdoGetName(Pdo),
+ PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
+ PowerDeviceStateName(DeviceState));
__PdoSetDevicePowerState(Pdo, DeviceState);
if (!NT_SUCCESS(status))
goto done;
- Verbose("%p: %s -> %s\n",
- Pdo->Dx->DeviceObject,
- PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
- PowerSystemStateName(SystemState));
+ Verbose("%s: %s -> %s\n",
+ __PdoGetName(Pdo),
+ PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
+ PowerSystemStateName(SystemState));
__PdoSetSystemPowerState(Pdo, SystemState);
static FORCEINLINE NTSTATUS
__PdoSetSystemPowerDown(
- IN PXENDISK_PDO Pdo,
+ IN PXENDISK_PDO Pdo,
IN PIRP Irp
)
{
ASSERT3U(SystemState, >, __PdoGetSystemPowerState(Pdo));
- Verbose("%p: %s -> %s\n",
- Pdo->Dx->DeviceObject,
- PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
- PowerSystemStateName(SystemState));
+ Verbose("%s: %s -> %s\n",
+ __PdoGetName(Pdo),
+ PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
+ PowerSystemStateName(SystemState));
__PdoSetSystemPowerState(Pdo, SystemState);
NTSTATUS
PdoCreate(
- PXENDISK_FDO Fdo,
- PDEVICE_OBJECT PhysicalDeviceObject
- )
-{
- PDEVICE_OBJECT LowerDeviceObject;
- ULONG DeviceType;
- PDEVICE_OBJECT FilterDeviceObject;
- PXENDISK_DX Dx;
- PXENDISK_PDO Pdo;
- HANDLE ParametersKey;
- ULONG InterceptTrim;
- NTSTATUS status;
+ IN PXENDISK_FDO Fdo,
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN PCHAR DeviceID,
+ IN PCHAR InstanceID
+ )
+{
+ PDEVICE_OBJECT LowerDeviceObject;
+ ULONG DeviceType;
+ PDEVICE_OBJECT FilterDeviceObject;
+ PXENDISK_DX Dx;
+ PXENDISK_PDO Pdo;
+ HANDLE ParametersKey;
+ ULONG InterceptTrim;
+ NTSTATUS status;
LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
DeviceType = LowerDeviceObject->DeviceType;
if (!NT_SUCCESS(status))
goto fail5;
+ __PdoSetName(Pdo, DeviceID, InstanceID);
+
ParametersKey = DriverGetParametersKey();
Pdo->InterceptTrim = TRUE;
if (NT_SUCCESS(status))
Pdo->InterceptTrim = (InterceptTrim != 0) ? TRUE : FALSE;
- Verbose("%p\n", FilterDeviceObject);
+ Verbose("%p (%s)\n", FilterDeviceObject, __PdoGetName(Pdo));
Dx->Pdo = Pdo;
__PdoUnlink(Pdo);
- Verbose("%p\n", FilterDeviceObject);
+ Verbose("%s\n", __PdoGetName(Pdo));
Dx->Pdo = NULL;
Pdo->InterceptTrim = FALSE;
+ RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
+
ThreadAlert(Pdo->DevicePowerThread);
ThreadJoin(Pdo->DevicePowerThread);
Pdo->DevicePowerThread = NULL;