[bus,driver] Move WvBusGetDevCapabilities as WvDriverGetDevCapabilities
[people/sha0/winvblock.git] / src / winvblock / driver.c
index c7ebf58..24c6781 100644 (file)
@@ -711,3 +711,57 @@ NTSTATUS STDCALL WvDriverBusDevCtl_(
     IoCompleteRequest(irp, IO_NO_INCREMENT);
     return status;
   }
+
+NTSTATUS STDCALL WvDriverGetDevCapabilities(
+    IN PDEVICE_OBJECT DevObj,
+    IN PDEVICE_CAPABILITIES DevCapabilities
+  ) {
+    IO_STATUS_BLOCK io_status;
+    KEVENT pnp_event;
+    NTSTATUS status;
+    PDEVICE_OBJECT target_obj;
+    PIO_STACK_LOCATION io_stack_loc;
+    PIRP pnp_irp;
+
+    RtlZeroMemory(DevCapabilities, sizeof *DevCapabilities);
+    DevCapabilities->Size = sizeof *DevCapabilities;
+    DevCapabilities->Version = 1;
+    DevCapabilities->Address = -1;
+    DevCapabilities->UINumber = -1;
+
+    KeInitializeEvent(&pnp_event, NotificationEvent, FALSE);
+    target_obj = IoGetAttachedDeviceReference(DevObj);
+    pnp_irp = IoBuildSynchronousFsdRequest(
+        IRP_MJ_PNP,
+        target_obj,
+        NULL,
+        0,
+        NULL,
+        &pnp_event,
+        &io_status
+      );
+    if (pnp_irp == NULL) {
+        status = STATUS_INSUFFICIENT_RESOURCES;
+      } else {
+        pnp_irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+        io_stack_loc = IoGetNextIrpStackLocation(pnp_irp);
+        RtlZeroMemory(io_stack_loc, sizeof *io_stack_loc);
+        io_stack_loc->MajorFunction = IRP_MJ_PNP;
+        io_stack_loc->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
+        io_stack_loc->Parameters.DeviceCapabilities.Capabilities =
+          DevCapabilities;
+        status = IoCallDriver(target_obj, pnp_irp);
+        if (status == STATUS_PENDING) {
+            KeWaitForSingleObject(
+                &pnp_event,
+                Executive,
+                KernelMode,
+                FALSE,
+                NULL
+              );
+            status = io_status.Status;
+          }
+      }
+    ObDereferenceObject(target_obj);
+    return status;
+  }