Aric Stewart : hidclass.sys: Implement IRP_MN_QUERY_ID for HID devices.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Apr 6 11:12:04 CDT 2016


Module: wine
Branch: master
Commit: 4b5bed455798569a142cebc77c59e42029d5df2d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4b5bed455798569a142cebc77c59e42029d5df2d

Author: Aric Stewart <aric at codeweavers.com>
Date:   Tue Apr  5 08:45:34 2016 -0500

hidclass.sys: Implement IRP_MN_QUERY_ID for HID devices.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hidclass.sys/hid.h  |  5 ++++
 dlls/hidclass.sys/main.c |  3 ++
 dlls/hidclass.sys/pnp.c  | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index 0dcc3a6..8d384c6 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -27,6 +27,7 @@
 #include "ddk/hidport.h"
 #include "ddk/hidclass.h"
 #include "ddk/hidpi.h"
+#include "cfgmgr32.h"
 #include "wine/list.h"
 #include "parse.h"
 
@@ -47,6 +48,8 @@ typedef struct _BASE_DEVICE_EXTENSTION {
     ULONG poll_interval;
     WCHAR *device_name;
     WCHAR *link_name;
+    WCHAR device_id[MAX_DEVICE_ID_LEN];
+    WCHAR instance_id[MAX_DEVICE_ID_LEN];
     struct ReportRingBuffer *ring_buffer;
     HANDLE halt_event;
     HANDLE thread;
@@ -75,6 +78,7 @@ typedef struct _minidriver
     PDRIVER_UNLOAD DriverUnload;
 
     pAddDevice AddDevice;
+    PDRIVER_DISPATCH PNPDispatch;
 } minidriver;
 
 NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG in_size, void *out_buff, ULONG out_size) DECLSPEC_HIDDEN;
@@ -91,6 +95,7 @@ NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN
 NTSTATUS WINAPI HID_Device_write(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
 NTSTATUS WINAPI HID_Device_create(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
 NTSTATUS WINAPI HID_Device_close(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
+NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
 
 /* Pseudo-Plug and Play support*/
 NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT* PDO) DECLSPEC_HIDDEN;
diff --git a/dlls/hidclass.sys/main.c b/dlls/hidclass.sys/main.c
index b124218..7fdcd59 100644
--- a/dlls/hidclass.sys/main.c
+++ b/dlls/hidclass.sys/main.c
@@ -74,6 +74,9 @@ NTSTATUS WINAPI HidRegisterMinidriver(HID_MINIDRIVER_REGISTRATION *registration)
     registration->DriverObject->MajorFunction[IRP_MJ_CREATE] = HID_Device_create;
     registration->DriverObject->MajorFunction[IRP_MJ_CLOSE] = HID_Device_close;
 
+    driver->PNPDispatch = registration->DriverObject->MajorFunction[IRP_MJ_PNP];
+    registration->DriverObject->MajorFunction[IRP_MJ_PNP] = HID_PNP_Dispatch;
+
     driver->AddDevice = registration->DriverObject->DriverExtension->AddDevice;
     registration->DriverObject->DriverExtension->AddDevice = PNP_AddDevice;
 
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 5de7522..fe3371f 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -23,12 +23,20 @@
 #include <stdarg.h>
 #include "hid.h"
 #include "ddk/hidtypes.h"
+#include "regstr.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
 #include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(hid);
 
+static const WCHAR device_enumeratorW[] = {'H','I','D',0};
+static const WCHAR device_deviceid_fmtW[] = {'%','s','\\',
+    'v','i','d','_','%','0','4','x','&','p','i','d','_','%', '0','4','x'};
+static const WCHAR device_instanceid_fmtW[] = {'%','s','\\',
+    'v','i','d','_','%','0','4','x','&','p','i','d','_','%',
+    '0','4','x','&','%','s','\\','%','i','&','%','s',0};
+
 typedef struct _NATIVE_DEVICE {
     struct list entry;
 
@@ -239,6 +247,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
         sprintfW(interface, ig_fmtW, interface_index);
     else
         sprintfW(interface, im_fmtW, interface_index);
+    sprintfW(ext->instance_id, device_instanceid_fmtW, device_enumeratorW, ext->information.VendorID, ext->information.ProductID, interface, ext->information.VersionNumber, serial);
+    sprintfW(ext->device_id, device_deviceid_fmtW, device_enumeratorW, ext->information.VendorID, ext->information.ProductID);
 
     HID_LinkDevice(device, serial, interface);
 
@@ -269,3 +279,65 @@ void PNP_CleanupPNP(DRIVER_OBJECT *driver)
         }
     }
 }
+
+NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp)
+{
+    NTSTATUS rc = STATUS_NOT_SUPPORTED;
+    IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp);
+
+    TRACE("%p, %p\n", device, irp);
+
+    switch(irpsp->MinorFunction)
+    {
+        case IRP_MN_QUERY_ID:
+        {
+            BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
+            ULONG type = irpsp->Parameters.QueryId.IdType;
+            WCHAR *id = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR)*REGSTR_VAL_MAX_HCID_LEN);
+            TRACE("IRP_MN_QUERY_ID[%i]\n", type);
+            switch (type)
+            {
+                case BusQueryHardwareIDs:
+                case BusQueryCompatibleIDs:
+                {
+                    WCHAR *ptr;
+                    ptr = id;
+                    /* Instance ID */
+                    strcpyW(ptr, ext->instance_id);
+                    ptr += lstrlenW(ext->instance_id) + 1;
+                    /* Device ID */
+                    strcpyW(ptr, ext->device_id);
+                    ptr += lstrlenW(ext->device_id) + 1;
+                    /* Bus ID */
+                    strcpyW(ptr, device_enumeratorW);
+                    ptr += lstrlenW(device_enumeratorW) + 1;
+                    *ptr = 0;
+                    irp->IoStatus.Information = (ULONG_PTR)id;
+                    rc = STATUS_SUCCESS;
+                    break;
+                }
+                case BusQueryDeviceID:
+                    strcpyW(id, ext->device_id);
+                    irp->IoStatus.Information = (ULONG_PTR)id;
+                    rc = STATUS_SUCCESS;
+                    break;
+                case BusQueryInstanceID:
+                    strcpyW(id, ext->instance_id);
+                    irp->IoStatus.Information = (ULONG_PTR)id;
+                    rc = STATUS_SUCCESS;
+                    break;
+            }
+            break;
+        }
+        default:
+        {
+            /* Forward IRP to the minidriver */
+            minidriver *minidriver = find_minidriver(device->DriverObject);
+            return minidriver->PNPDispatch(device, irp);
+        }
+    }
+
+    irp->IoStatus.u.Status = rc;
+    IoCompleteRequest( irp, IO_NO_INCREMENT );
+    return rc;
+}




More information about the wine-cvs mailing list