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