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/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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue