hidclass.sys: Implement IRP_MN_QUERY_ID for HID devices.
Signed-off-by: Aric Stewart <aric@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7b76d61372
commit
4b5bed4557
|
@ -27,6 +27,7 @@
|
||||||
#include "ddk/hidport.h"
|
#include "ddk/hidport.h"
|
||||||
#include "ddk/hidclass.h"
|
#include "ddk/hidclass.h"
|
||||||
#include "ddk/hidpi.h"
|
#include "ddk/hidpi.h"
|
||||||
|
#include "cfgmgr32.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
|
||||||
|
@ -47,6 +48,8 @@ typedef struct _BASE_DEVICE_EXTENSTION {
|
||||||
ULONG poll_interval;
|
ULONG poll_interval;
|
||||||
WCHAR *device_name;
|
WCHAR *device_name;
|
||||||
WCHAR *link_name;
|
WCHAR *link_name;
|
||||||
|
WCHAR device_id[MAX_DEVICE_ID_LEN];
|
||||||
|
WCHAR instance_id[MAX_DEVICE_ID_LEN];
|
||||||
struct ReportRingBuffer *ring_buffer;
|
struct ReportRingBuffer *ring_buffer;
|
||||||
HANDLE halt_event;
|
HANDLE halt_event;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
|
@ -75,6 +78,7 @@ typedef struct _minidriver
|
||||||
PDRIVER_UNLOAD DriverUnload;
|
PDRIVER_UNLOAD DriverUnload;
|
||||||
|
|
||||||
pAddDevice AddDevice;
|
pAddDevice AddDevice;
|
||||||
|
PDRIVER_DISPATCH PNPDispatch;
|
||||||
} minidriver;
|
} minidriver;
|
||||||
|
|
||||||
NTSTATUS call_minidriver(ULONG code, DEVICE_OBJECT *device, void *in_buff, ULONG in_size, void *out_buff, ULONG out_size) DECLSPEC_HIDDEN;
|
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_write(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
|
||||||
NTSTATUS WINAPI HID_Device_create(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_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*/
|
/* Pseudo-Plug and Play support*/
|
||||||
NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT* PDO) DECLSPEC_HIDDEN;
|
NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT* PDO) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -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_CREATE] = HID_Device_create;
|
||||||
registration->DriverObject->MajorFunction[IRP_MJ_CLOSE] = HID_Device_close;
|
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;
|
driver->AddDevice = registration->DriverObject->DriverExtension->AddDevice;
|
||||||
registration->DriverObject->DriverExtension->AddDevice = PNP_AddDevice;
|
registration->DriverObject->DriverExtension->AddDevice = PNP_AddDevice;
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,20 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
#include "ddk/hidtypes.h"
|
#include "ddk/hidtypes.h"
|
||||||
|
#include "regstr.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(hid);
|
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 {
|
typedef struct _NATIVE_DEVICE {
|
||||||
struct list entry;
|
struct list entry;
|
||||||
|
|
||||||
|
@ -239,6 +247,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
|
||||||
sprintfW(interface, ig_fmtW, interface_index);
|
sprintfW(interface, ig_fmtW, interface_index);
|
||||||
else
|
else
|
||||||
sprintfW(interface, im_fmtW, interface_index);
|
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);
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue