diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 86b6d1b9dd3..93187b54ac9 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -75,6 +75,8 @@ NTSTATUS HID_CreateDevice(DEVICE_OBJECT *native_device, HID_MINIDRIVER_REGISTRAT NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device) { + static const WCHAR backslashW[] = {'\\',0}; + WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; SP_DEVINFO_DATA Data; UNICODE_STRING nameW; NTSTATUS status; @@ -87,6 +89,10 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device) RtlInitUnicodeString( &nameW, ext->device_name); + lstrcpyW(device_instance_id, ext->device_id); + lstrcatW(device_instance_id, backslashW); + lstrcatW(device_instance_id, ext->instance_id); + devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_HIDCLASS, NULL); if (devinfo == INVALID_HANDLE_VALUE) { @@ -94,7 +100,7 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device) return STATUS_UNSUCCESSFUL; } Data.cbSize = sizeof(Data); - if (SetupDiCreateDeviceInfoW(devinfo, ext->instance_id, &GUID_DEVCLASS_HIDCLASS, NULL, NULL, DICD_INHERIT_CLASSDRVS, &Data)) + if (SetupDiCreateDeviceInfoW(devinfo, device_instance_id, &GUID_DEVCLASS_HIDCLASS, NULL, NULL, DICD_INHERIT_CLASSDRVS, &Data)) { if (!SetupDiRegisterDeviceInfo(devinfo, &Data, 0, NULL, NULL, NULL)) { diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index ce755e815f9..826ade92a48 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -32,8 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(hid); static const WCHAR device_enumeratorW[] = {'H','I','D',0}; static const WCHAR separator_W[] = {'\\',0}; -static const WCHAR device_deviceid_fmtW[] = {'%','s','\\', - 'v','i','d','_','%','0','4','x','&','p','i','d','_','%', '0','4','x',0}; static NTSTATUS WINAPI internalComplete(DEVICE_OBJECT *deviceObject, IRP *irp, void *context) @@ -43,7 +41,7 @@ static NTSTATUS WINAPI internalComplete(DEVICE_OBJECT *deviceObject, IRP *irp, return STATUS_MORE_PROCESSING_REQUIRED; } -static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCHAR **id) +static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCHAR *id) { NTSTATUS status; IO_STACK_LOCATION *irpsp; @@ -65,7 +63,8 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH if (status == STATUS_PENDING) WaitForSingleObject(event, INFINITE); - *id = (WCHAR*)irp->IoStatus.Information; + lstrcpyW(id, (WCHAR *)irp->IoStatus.Information); + ExFreePool( (WCHAR *)irp->IoStatus.Information ); status = irp->IoStatus.u.Status; IoCompleteRequest(irp, IO_NO_INCREMENT ); CloseHandle(event); @@ -75,6 +74,7 @@ static NTSTATUS get_device_id(DEVICE_OBJECT *device, BUS_QUERY_ID_TYPE type, WCH NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) { + WCHAR device_id[MAX_DEVICE_ID_LEN], instance_id[MAX_DEVICE_ID_LEN]; hid_device *hiddev; DEVICE_OBJECT *device = NULL; NTSTATUS status; @@ -84,17 +84,20 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) HID_DESCRIPTOR descriptor; BYTE *reportDescriptor; INT i; - WCHAR *PDO_id; - WCHAR *id_ptr; - status = get_device_id(PDO, BusQueryInstanceID, &PDO_id); - if (status != STATUS_SUCCESS) + if ((status = get_device_id(PDO, BusQueryDeviceID, device_id))) { - ERR("Failed to get PDO id(%x)\n",status); + ERR("Failed to get PDO device id, status %#x.\n", status); return status; } - TRACE("PDO add device(%p:%s)\n", PDO, debugstr_w(PDO_id)); + if ((status = get_device_id(PDO, BusQueryInstanceID, instance_id))) + { + ERR("Failed to get PDO instance id, status %#x.\n", status); + return status; + } + + TRACE("Adding device to PDO %p, id %s\\%s.\n", PDO, debugstr_w(device_id), debugstr_w(instance_id)); minidriver = find_minidriver(driver); hiddev = HeapAlloc(GetProcessHeap(), 0, sizeof(*hiddev)); @@ -105,7 +108,6 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (status != STATUS_SUCCESS) { ERR("Failed to create HID object (%x)\n",status); - HeapFree(GetProcessHeap(), 0, PDO_id); HeapFree(GetProcessHeap(), 0, hiddev); return status; } @@ -120,7 +122,6 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) if (status != STATUS_SUCCESS) { ERR("Minidriver AddDevice failed (%x)\n",status); - HeapFree(GetProcessHeap(), 0, PDO_id); HID_DeleteDevice(&minidriver->minidriver, device); return status; } @@ -132,7 +133,6 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) { ERR("Minidriver failed to get Attributes(%x)\n",status); HID_DeleteDevice(&minidriver->minidriver, device); - HeapFree(GetProcessHeap(), 0, PDO_id); return status; } @@ -147,7 +147,6 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) { ERR("Cannot get Device Descriptor(%x)\n",status); HID_DeleteDevice(&minidriver->minidriver, device); - HeapFree(GetProcessHeap(), 0, PDO_id); return status; } for (i = 0; i < descriptor.bNumDescriptors; i++) @@ -158,7 +157,6 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) { ERR("No Report Descriptor found in reply\n"); HID_DeleteDevice(&minidriver->minidriver, device); - HeapFree(GetProcessHeap(), 0, PDO_id); return status; } @@ -170,7 +168,6 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) ERR("Cannot get Report Descriptor(%x)\n",status); HID_DeleteDevice(&minidriver->minidriver, device); HeapFree(GetProcessHeap(), 0, reportDescriptor); - HeapFree(GetProcessHeap(), 0, PDO_id); return status; } @@ -181,7 +178,6 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) { ERR("Cannot parse Report Descriptor\n"); HID_DeleteDevice(&minidriver->minidriver, device); - HeapFree(GetProcessHeap(), 0, PDO_id); return STATUS_NOT_SUPPORTED; } @@ -189,16 +185,11 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) ext->information.DescriptorSize = ext->preparseData->dwSize; - lstrcpyW(ext->instance_id, device_enumeratorW); - lstrcatW(ext->instance_id, separator_W); - /* Skip the original enumerator */ - id_ptr = wcschr(PDO_id, '\\'); - id_ptr++; - lstrcatW(ext->instance_id, id_ptr); - HeapFree(GetProcessHeap(), 0, PDO_id); + lstrcpyW(ext->instance_id, instance_id); - swprintf(ext->device_id, ARRAY_SIZE(ext->device_id), device_deviceid_fmtW, - device_enumeratorW, ext->information.VendorID, ext->information.ProductID); + lstrcpyW(ext->device_id, device_enumeratorW); + lstrcatW(ext->device_id, separator_W); + lstrcatW(ext->device_id, wcschr(device_id, '\\') + 1); HID_LinkDevice(device); @@ -261,7 +252,11 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp) { WCHAR *ptr; ptr = id; - /* Instance ID */ + /* Device instance ID */ + lstrcpyW(ptr, ext->device_id); + ptr += lstrlenW(ext->device_id); + lstrcpyW(ptr, separator_W); + ptr += 1; lstrcpyW(ptr, ext->instance_id); ptr += lstrlenW(ext->instance_id) + 1; /* Device ID */ diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index b88b9f1e0c2..20e1538c1af 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -204,6 +204,36 @@ static NTSTATUS send_pnp_irp( DEVICE_OBJECT *device, UCHAR minor ) return send_device_irp( device, irp, NULL ); } +static NTSTATUS get_device_instance_id( DEVICE_OBJECT *device, WCHAR *buffer ) +{ + static const WCHAR backslashW[] = {'\\',0}; + NTSTATUS status; + WCHAR *id; + + if ((status = get_device_id( device, BusQueryDeviceID, &id ))) + { + ERR("Failed to get device ID, status %#x.\n", status); + return status; + } + + strcpyW( buffer, id ); + ExFreePool( id ); + + if ((status = get_device_id( device, BusQueryInstanceID, &id ))) + { + ERR("Failed to get instance ID, status %#x.\n", status); + return status; + } + + strcatW( buffer, backslashW ); + strcatW( buffer, id ); + ExFreePool( id ); + + TRACE("Returning ID %s.\n", debugstr_w(buffer)); + + return STATUS_SUCCESS; +} + static BOOL get_driver_for_id( const WCHAR *id, WCHAR *driver ) { static const WCHAR serviceW[] = {'S','e','r','v','i','c','e',0}; @@ -593,22 +623,6 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable return ret; } -static NTSTATUS get_instance_id(DEVICE_OBJECT *device, WCHAR **instance_id) -{ - WCHAR *id, *ptr; - NTSTATUS status; - - status = get_device_id( device, BusQueryInstanceID, &id ); - if (status != STATUS_SUCCESS) return status; - - struprW( id ); - for (ptr = id; *ptr; ptr++) - if (*ptr == '\\') *ptr = '#'; - - *instance_id = id; - return STATUS_SUCCESS; -} - /*********************************************************************** * IoRegisterDeviceInterface (NTOSKRNL.EXE.@) */ @@ -617,29 +631,28 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla { SP_DEVICE_INTERFACE_DATA sp_iface = {sizeof(sp_iface)}; SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; + WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; SP_DEVICE_INTERFACE_DETAIL_DATA_W *data; NTSTATUS status = STATUS_SUCCESS; struct device_interface *iface; - WCHAR *instance_id; DWORD required; HDEVINFO set; TRACE("device %p, class_guid %s, refstr %s, symbolic_link %p.\n", device, debugstr_guid(class_guid), debugstr_us(refstr), symbolic_link); + if ((status = get_device_instance_id( device, device_instance_id ))) + return status; + set = SetupDiGetClassDevsW( class_guid, NULL, NULL, DIGCF_DEVICEINTERFACE ); if (set == INVALID_HANDLE_VALUE) return STATUS_UNSUCCESSFUL; - status = get_instance_id( device, &instance_id ); - if (status != STATUS_SUCCESS) return status; - - if (!SetupDiCreateDeviceInfoW( set, instance_id, class_guid, NULL, NULL, 0, &sp_device ) - && !SetupDiOpenDeviceInfoW( set, instance_id, NULL, 0, &sp_device )) + if (!SetupDiCreateDeviceInfoW( set, device_instance_id, class_guid, NULL, NULL, 0, &sp_device ) + && !SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device )) { - ERR("Failed to create device %s, error %#x.\n", debugstr_w(instance_id), GetLastError()); + ERR("Failed to create device %s, error %#x.\n", debugstr_w(device_instance_id), GetLastError()); return GetLastError(); } - ExFreePool( instance_id ); if (!SetupDiCreateDeviceInterfaceW( set, &sp_device, class_guid, refstr ? refstr->Buffer : NULL, 0, &sp_iface )) return STATUS_UNSUCCESSFUL; diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index b649bfb4d94..3616ebe8152 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -31,6 +31,7 @@ #include "winternl.h" #include "winreg.h" #include "setupapi.h" +#include "cfgmgr32.h" #include "winioctl.h" #include "ddk/wdm.h" #include "ddk/hidport.h" @@ -43,6 +44,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay); WINE_DECLARE_DEBUG_CHANNEL(hid_report); +static const WCHAR backslashW[] = {'\\',0}; + #define VID_MICROSOFT 0x045e static const WORD PID_XBOX_CONTROLLERS[] = { @@ -140,28 +143,14 @@ static DWORD get_device_index(WORD vid, WORD pid, WORD input) static WCHAR *get_instance_id(DEVICE_OBJECT *device) { - static const WCHAR formatW[] = {'%','s','\\','v','i','d','_','%','0','4','x','&','p','i','d','_','%','0','4','x', - '\\','%','i','&','%','s','&','%','x','&','%','i',0}; - static const WCHAR format_inputW[] = {'%','s','\\','v','i','d','_','%','0','4','x','&','p','i','d','_','%','0','4','x','&', - '%','s','_','%','i','\\','%','i','&','%','s','&','%','x','&','%','i',0}; + static const WCHAR formatW[] = {'%','i','&','%','s','&','%','x','&','%','i',0}; struct device_extension *ext = (struct device_extension *)device->DeviceExtension; const WCHAR *serial = ext->serial ? ext->serial : zero_serialW; - DWORD len = strlenW(ext->busid) + strlenW(serial) + 64; + DWORD len = strlenW(serial) + 33; WCHAR *dst; if ((dst = ExAllocatePool(PagedPool, len * sizeof(WCHAR)))) - { - if (ext->input == (WORD)-1) - { - sprintfW(dst, formatW, ext->busid, ext->vid, ext->pid, - ext->version, serial, ext->uid, ext->index); - } - else - { - sprintfW(dst, format_inputW, ext->busid, ext->vid, ext->pid, ext->is_gamepad ? igW : miW, - ext->input, ext->version, serial, ext->uid, ext->index); - } - } + sprintfW(dst, formatW, ext->version, serial, ext->uid, ext->index); return dst; } @@ -211,6 +200,7 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size) { static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0}; + WCHAR *id, instance[MAX_DEVICE_ID_LEN]; struct device_extension *ext; struct pnp_device *pnp_dev; DEVICE_OBJECT *device; @@ -218,7 +208,6 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, WCHAR dev_name[256]; HDEVINFO devinfo; SP_DEVINFO_DATA data = {sizeof(data)}; - WCHAR *instance = NULL; NTSTATUS status; DWORD length; @@ -279,12 +268,22 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, goto error; } - instance = get_instance_id(device); - if (!instance) + if (!(id = get_device_id(device))) { ERR("failed to generate instance id\n"); goto error; } + strcpyW(instance, id); + ExFreePool(id); + + if (!(id = get_instance_id(device))) + { + ERR("failed to generate instance id\n"); + goto error; + } + strcatW(instance, backslashW); + strcatW(instance, id); + ExFreePool(id); if (SetupDiCreateDeviceInfoW(devinfo, instance, class, NULL, NULL, DICD_INHERIT_CLASSDRVS, &data)) { @@ -295,7 +294,6 @@ DEVICE_OBJECT *bus_create_hid_device(const WCHAR *busidW, WORD vid, WORD pid, ERR("failed to create device info, error %#x\n", GetLastError()); error: - HeapFree(GetProcessHeap(), 0, instance); SetupDiDestroyDeviceInfoList(devinfo); return device; }