From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/winebus.sys/main.c | 47 ++++++++++++++++++++++++++++++++++++++ dlls/winebus.sys/unixlib.h | 2 ++ 2 files changed, 49 insertions(+)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 0a871269fa9..49b805b713e 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -41,6 +41,9 @@
#include "unixlib.h"
+#include "initguid.h" +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); + WINE_DEFAULT_DEBUG_CHANNEL(hid);
static DRIVER_OBJECT *driver_obj; @@ -264,6 +267,24 @@ static WCHAR *get_compatible_ids(DEVICE_OBJECT *device) return dst; }
+#define GUID_STRING_LENGTH 39 +static WCHAR *get_container_id(DEVICE_OBJECT *device) +{ + struct device_extension *ext = (struct device_extension *)device->DeviceExtension; + GUID *guid = &ext->desc.container_id; + WCHAR *dst; + + if ((dst = ExAllocatePool(PagedPool, GUID_STRING_LENGTH * sizeof(WCHAR)))) + { + swprintf(dst, GUID_STRING_LENGTH, L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); + } + + TRACE("Returning container ID %s.\n", debugstr_w(dst)); + return dst; +} + static IRP *pop_pending_read(struct device_extension *ext) { IRP *pending; @@ -301,6 +322,21 @@ static void make_unique_serial(struct device_extension *device) device->index, device->desc.input, device->desc.pid, device->desc.vid); }
+static void make_unique_container_id(struct device_extension *device) +{ + struct device_extension *ext; + + LIST_FOR_EACH_ENTRY(ext, &device_list, struct device_extension, entry) + if (IsEqualGUID(&device->desc.container_id, &ext->desc.container_id)) break; + if (&ext->entry == &device_list && !IsEqualGUID(&device->desc.container_id, &GUID_NULL)) return; + + device->desc.container_id.Data1 = device->desc.input; + device->desc.container_id.Data2 = device->index; + device->desc.container_id.Data3 = device->desc.pid; + device->desc.container_id.Data4[0] = (device->desc.vid >> 8) & 0xff; + device->desc.container_id.Data4[1] = (device->desc.vid) & 0xff; +} + static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, UINT64 unix_device) { struct device_extension *ext; @@ -349,6 +385,13 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, UINT64 uni * Prefer keeping serial numbers unique over keeping them consistent across runs */ make_unique_serial(ext);
+ /* + * Some games use container ID to match the bus device to the HID + * device in order to get things like DEVPKEY_Device_BusReportedDeviceDesc. + * Create a unique container ID to facilitate this. + */ + make_unique_container_id(ext); + /* add to list of pnp devices */ if (before) list_add_before(before, &ext->entry); @@ -707,6 +750,10 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp) TRACE("BusQueryInstanceID\n"); irp->IoStatus.Information = (ULONG_PTR)get_instance_id(device); break; + case BusQueryContainerID: + TRACE("BusQueryContainerID\n"); + irp->IoStatus.Information = (ULONG_PTR)get_container_id(device); + break; default: WARN("Unhandled type %08x\n", type); return status; diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h index 8dab8af0d57..f8626438c92 100644 --- a/dlls/winebus.sys/unixlib.h +++ b/dlls/winebus.sys/unixlib.h @@ -45,6 +45,8 @@ struct device_desc WCHAR manufacturer[MAX_PATH]; WCHAR product[MAX_PATH]; WCHAR serialnumber[MAX_PATH]; + + GUID container_id; };
struct device_options