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>
oldstable
Aric Stewart 2016-04-05 08:45:34 -05:00 committed by Alexandre Julliard
parent 7b76d61372
commit 4b5bed4557
3 changed files with 80 additions and 0 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}