From fba3903235daf0fed1c438e2c1ce084fd61631a5 Mon Sep 17 00:00:00 2001 From: Rankyn Bass Date: Mon, 6 Jan 2025 17:12:09 -0800 Subject: [PATCH] Add new dualsense patches to valvexbe --- wine-tkg-git/customization.cfg | 2 +- .../wine-tkg-valve-exp-bleeding.cfg | 2 +- ...mdevapi-support-VT_CLSID-for-contain.patch | 38 ++++++ ...mdevapi-decode-ContainerId-property-.patch | 39 ++++++ ...mdevapi-copy-ContainerID-from-audio-.patch | 30 +++++ ...mdevapi-Invalidate-ContainerID-of-un.patch | 74 ++++++++++++ ...Store-PulseAudio-device-s-sysfs-path.patch | 52 ++++++++ ...Add-support-for-containerId-property.patch | 112 ++++++++++++++++++ ...ore-container-sysfs-path-from-udev-b.patch | 80 +++++++++++++ ...plement-BusQueryContainerID-based-on.patch | 86 ++++++++++++++ ...tupDiGetDeviceInterfacePropertyW-for.patch | 87 ++++++++++++++ .../valvexbe/xiv-dualsense1.patch | 33 ------ .../valvexbe/xiv-dualsense2.patch | 90 -------------- 13 files changed, 600 insertions(+), 125 deletions(-) create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds1-pending-review-mmdevapi-support-VT_CLSID-for-contain.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds2-pending-review-mmdevapi-decode-ContainerId-property-.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds3-pending-review-mmdevapi-copy-ContainerID-from-audio-.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds4-pending-review-mmdevapi-Invalidate-ContainerID-of-un.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds5--draft-winepulse-Store-PulseAudio-device-s-sysfs-path.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds6-draft-winepulse-Add-support-for-containerId-property.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds7-draft-winebus-store-container-sysfs-path-from-udev-b.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds8-draft-winebus-implement-BusQueryContainerID-based-on.patch create mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/ds9-WiP-Implement-SetupDiGetDeviceInterfacePropertyW-for.patch delete mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense1.patch delete mode 100644 wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense2.patch diff --git a/wine-tkg-git/customization.cfg b/wine-tkg-git/customization.cfg index 3f0eae0d6..7baeb73b2 100644 --- a/wine-tkg-git/customization.cfg +++ b/wine-tkg-git/customization.cfg @@ -153,7 +153,7 @@ _win10_default="true" # Other misc proton patches and hacks - Notably contains fixes for some native vk games (such as Doom Eternal) as well as Rockstar launcher # Also enables some winevulkan performance optimizations - https://github.com/Joshua-Ashton/proton-wine/tree/winevulkan-opt (fs hack) - https://github.com/Joshua-Ashton/wine/commits/winevulkan-opt-mainline (no fs hack) -_protonify="true" +_protonify="false" #### USER PATCHES - See README in ./wine-tkg-userpatches dir for instructions #### diff --git a/wine-tkg-git/wine-tkg-profiles/wine-tkg-valve-exp-bleeding.cfg b/wine-tkg-git/wine-tkg-profiles/wine-tkg-valve-exp-bleeding.cfg index b9dc4fc07..1dfd1b7b3 100644 --- a/wine-tkg-git/wine-tkg-profiles/wine-tkg-valve-exp-bleeding.cfg +++ b/wine-tkg-git/wine-tkg-profiles/wine-tkg-valve-exp-bleeding.cfg @@ -9,7 +9,7 @@ _proton_branch="experimental_9.0" _staging_version="cab93f47b8d095eb968bb3c7debf9117a91307ce" # Optionally set a bleeding edge tag - Leave empty to use latest bleeding edge -_bleeding_tag="" +_bleeding_tag="e4b6a6aeece72336a1d2973bc2e1dd1f6eb3ff18" # Enable wow64 mode and wayland _NOLIB32="wow64" diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds1-pending-review-mmdevapi-support-VT_CLSID-for-contain.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds1-pending-review-mmdevapi-support-VT_CLSID-for-contain.patch new file mode 100644 index 000000000..3bc612c5b --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds1-pending-review-mmdevapi-support-VT_CLSID-for-contain.patch @@ -0,0 +1,38 @@ +From 5357232357bf12a766be1fdc4080abfc0bd7b0bc Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Fri, 15 Jul 2022 22:09:57 +0200 +Subject: [PATCH 1/9] [pending review] mmdevapi: support VT_CLSID for + containerId property in MMDevice_SetPropValue. + +CLSID is special-cased to this property because we can't safely differentiate +an encoded VT_CLSID from an encoded VT_BLOB. +--- + dlls/mmdevapi/devenum.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c +index daafb4a822e..24f25628831 100644 +--- a/dlls/mmdevapi/devenum.c ++++ b/dlls/mmdevapi/devenum.c +@@ -227,6 +227,18 @@ static HRESULT MMDevice_SetPropValue(const GUID *devguid, DWORD flow, REFPROPERT + ret = RegSetValueExW(regkey, buffer, 0, REG_SZ, (const BYTE*)pv->pwszVal, sizeof(WCHAR)*(1+lstrlenW(pv->pwszVal))); + break; + } ++ case VT_CLSID: ++ { ++ if (IsEqualPropertyKey(*key, DEVPKEY_Device_ContainerId)) { ++ BYTE value[24] = { VT_CLSID, 0, 0, 0, 1, 0, 0, 0 }; ++ memcpy(value + 8, pv->puuid, sizeof(GUID)); ++ ++ ret = RegSetValueExW(regkey, buffer, 0, REG_BINARY, (const BYTE*)value, 24); ++ break; ++ } ++ /* If it's not containerId, fall through the default unsupported case as we can't ++ ensure it will be decoded as CLSID. */ ++ } + default: + ret = 0; + FIXME("Unhandled type %u\n", pv->vt); +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds2-pending-review-mmdevapi-decode-ContainerId-property-.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds2-pending-review-mmdevapi-decode-ContainerId-property-.patch new file mode 100644 index 000000000..8c6f5e520 --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds2-pending-review-mmdevapi-decode-ContainerId-property-.patch @@ -0,0 +1,39 @@ +From c39a2e52706b6f3cdd23f266484cf3ea4b1ddeaa Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Fri, 15 Jul 2022 22:09:57 +0200 +Subject: [PATCH 2/9] [pending review] mmdevapi: decode ContainerId property to + CLSID in MMDevice_GetPropValue. + +--- + dlls/mmdevapi/devenum.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c +index 24f25628831..8a427d347d9 100644 +--- a/dlls/mmdevapi/devenum.c ++++ b/dlls/mmdevapi/devenum.c +@@ -191,6 +191,21 @@ static HRESULT MMDevice_GetPropValue(const GUID *devguid, DWORD flow, REFPROPERT + break; + } + RegCloseKey(regkey); ++ ++ /* Special case ContainerID as CLSID */ ++ if(pv->vt == VT_BLOB && pv->blob.pBlobData && pv->blob.cbSize == 24 && pv->blob.pBlobData[0] == VT_CLSID && IsEqualPropertyKey(*key, DEVPKEY_Device_ContainerId)) { ++ GUID *guid = CoTaskMemAlloc(sizeof(GUID)); ++ if (!guid) { ++ PropVariantClear(pv); ++ hr = E_OUTOFMEMORY; ++ } else { ++ memcpy(guid, pv->blob.pBlobData + 8, sizeof(GUID)); ++ CoTaskMemFree(pv->blob.pBlobData); ++ pv->vt = VT_CLSID; ++ pv->puuid = guid; ++ } ++ } ++ + return hr; + } + +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds3-pending-review-mmdevapi-copy-ContainerID-from-audio-.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds3-pending-review-mmdevapi-copy-ContainerID-from-audio-.patch new file mode 100644 index 000000000..3aca68515 --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds3-pending-review-mmdevapi-copy-ContainerID-from-audio-.patch @@ -0,0 +1,30 @@ +From 2585851b3e426eaacfd0700296eddde10cab88cc Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Fri, 15 Jul 2022 22:09:57 +0200 +Subject: [PATCH 3/9] [pending review] mmdevapi: copy ContainerID from audio + driver if available. + +Some games with support for the haptic feedback and speaker features of the +Sony DualSense controller select the controller's audio output by filtering on +the ContainerId IMMDevice property to find one that matches the controller's +HID's. +--- + dlls/mmdevapi/devenum.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c +index 8a427d347d9..8a39886f918 100644 +--- a/dlls/mmdevapi/devenum.c ++++ b/dlls/mmdevapi/devenum.c +@@ -421,6 +421,8 @@ static MMDevice *MMDevice_Create(const WCHAR *name, GUID *id, EDataFlow flow, DW + MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_FriendlyName, &pv); + MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_DeviceDesc, &pv); + ++ set_driver_prop_value(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_ContainerId); ++ + pv.pwszVal = guidstr; + MMDevice_SetPropValue(id, flow, &deviceinterface_key, &pv); + +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds4-pending-review-mmdevapi-Invalidate-ContainerID-of-un.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds4-pending-review-mmdevapi-Invalidate-ContainerID-of-un.patch new file mode 100644 index 000000000..09409a1b4 --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds4-pending-review-mmdevapi-Invalidate-ContainerID-of-un.patch @@ -0,0 +1,74 @@ +From 3b7eb04cd53690c024d74a1309bae245b23a62c6 Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Fri, 15 Jul 2022 22:10:06 +0200 +Subject: [PATCH 4/9] [pending review] mmdevapi: Invalidate ContainerID of + unavailable audio devices. + +Some games, like Deathloop, enumerate all unavailable audio devices, including +unavailable ones, and stop at the first one matching the ContainerID. + +Depending on how ContainerIDs end up being attributed, an active device may end +up sharing a ContainerID with an unplugged device that was previously plugged +in the same physical port. Depending on the audio backend, the same audio +device plugged in the same port may be seen as a different audio device by Wine +depending on things like in which order devices were discovered. + +In those cases, a game might find an inactive matching device before the active +one, and thus fail to open the audio output. + +By invalidating the ContainerID of unavailable devices, we this issue can be +avoided. +--- + dlls/mmdevapi/devenum.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c +index 8a39886f918..cbc38e46213 100644 +--- a/dlls/mmdevapi/devenum.c ++++ b/dlls/mmdevapi/devenum.c +@@ -209,6 +209,26 @@ static HRESULT MMDevice_GetPropValue(const GUID *devguid, DWORD flow, REFPROPERT + return hr; + } + ++static HRESULT MMDevice_DeletePropValue(const GUID *devguid, DWORD flow, REFPROPERTYKEY key) ++{ ++ WCHAR buffer[80]; ++ const GUID *id = &key->fmtid; ++ HRESULT hr; ++ HKEY regkey; ++ LONG ret; ++ ++ hr = MMDevPropStore_OpenPropKey(devguid, flow, ®key); ++ if (FAILED(hr)) ++ return hr; ++ wsprintfW( buffer, propkey_formatW, id->Data1, id->Data2, id->Data3, ++ id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], ++ id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], key->pid ); ++ ret = RegDeleteValueW(regkey, buffer); ++ RegCloseKey(regkey); ++ TRACE("Deleting %s returned %lu\n", debugstr_w(buffer), ret); ++ return hr; ++} ++ + static HRESULT MMDevice_SetPropValue(const GUID *devguid, DWORD flow, REFPROPERTYKEY key, REFPROPVARIANT pv) + { + WCHAR buffer[80]; +@@ -421,7 +441,14 @@ static MMDevice *MMDevice_Create(const WCHAR *name, GUID *id, EDataFlow flow, DW + MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_FriendlyName, &pv); + MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_DeviceDesc, &pv); + +- set_driver_prop_value(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_ContainerId); ++ /* The mechanism we use to attribute Container IDs is not very robust and could end up making ++ an active device share a ContainerID with inactive devices, and some games enumerate even ++ inactive devices, stopping at the first matching one. ++ To avoid issues, invalidate the ContainerID of devices that are not present. */ ++ if (state & DEVICE_STATE_ACTIVE) ++ set_driver_prop_value(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_ContainerId); ++ else if (state & DEVICE_STATE_NOTPRESENT) ++ MMDevice_DeletePropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_ContainerId); + + pv.pwszVal = guidstr; + MMDevice_SetPropValue(id, flow, &deviceinterface_key, &pv); +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds5--draft-winepulse-Store-PulseAudio-device-s-sysfs-path.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds5--draft-winepulse-Store-PulseAudio-device-s-sysfs-path.patch new file mode 100644 index 000000000..e8590d0ee --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds5--draft-winepulse-Store-PulseAudio-device-s-sysfs-path.patch @@ -0,0 +1,52 @@ +From 5f19f38096754765ab6acb2015ef2a18e40e5a1e Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Sat, 2 Jul 2022 12:15:47 +0200 +Subject: [PATCH 5/9] [draft] winepulse: Store PulseAudio device's sysfs path + when available. + +--- + dlls/winepulse.drv/pulse.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c +index 944cf938bdc..db4289777da 100644 +--- a/dlls/winepulse.drv/pulse.c ++++ b/dlls/winepulse.drv/pulse.c +@@ -104,6 +104,7 @@ typedef struct _PhysDevice { + UINT index; + REFERENCE_TIME min_period, def_period; + WAVEFORMATEXTENSIBLE fmt; ++ char *sysfs_path; + char pulse_name[0]; + } PhysDevice; + +@@ -169,6 +170,8 @@ static void free_phys_device_lists(void) + do { + LIST_FOR_EACH_ENTRY_SAFE(dev, dev_next, *list, PhysDevice, entry) { + free(dev->name); ++ if (dev->sysfs_path) ++ free(dev->sysfs_path); + free(dev); + } + } while (*(++list)); +@@ -541,6 +544,7 @@ static void fill_device_info(PhysDevice *dev, pa_proplist *p) + dev->bus_type = phys_device_bus_invalid; + dev->vendor_id = 0; + dev->product_id = 0; ++ dev->sysfs_path = NULL; + + if (!p) + return; +@@ -557,6 +561,9 @@ static void fill_device_info(PhysDevice *dev, pa_proplist *p) + + if ((buffer = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_ID))) + dev->product_id = strtol(buffer, NULL, 16); ++ ++ if ((buffer = pa_proplist_gets(p, "sysfs.path"))) ++ dev->sysfs_path = strdup(buffer); + } + + static void pulse_add_device(struct list *list, pa_proplist *proplist, int index, EndpointFormFactor form, +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds6-draft-winepulse-Add-support-for-containerId-property.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds6-draft-winepulse-Add-support-for-containerId-property.patch new file mode 100644 index 000000000..41217fc37 --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds6-draft-winepulse-Add-support-for-containerId-property.patch @@ -0,0 +1,112 @@ +From 407c9eb19c951b6574450348f8733cb86554646c Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Sat, 2 Jul 2022 12:16:34 +0200 +Subject: [PATCH 6/9] [draft] winepulse: Add support for containerId property + from sysfs path. + +--- + dlls/winepulse.drv/pulse.c | 74 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + +diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c +index db4289777da..8212b8004a5 100644 +--- a/dlls/winepulse.drv/pulse.c ++++ b/dlls/winepulse.drv/pulse.c +@@ -45,6 +45,7 @@ + #include "../mmdevapi/unixlib.h" + + #include "mult.h" ++#include "devpkey.h" + + WINE_DEFAULT_DEBUG_CHANNEL(pulse); + +@@ -2536,6 +2537,76 @@ static BOOL get_device_path(PhysDevice *dev, struct get_prop_value_params *param + return TRUE; + } + ++static BOOL get_device_container(PhysDevice *dev, struct get_prop_value_params *params) ++{ ++ char buffer[10]; ++ char *path, *p; ++ PROPVARIANT *out = params->value; ++ ++ if (*params->buffer_size < sizeof(GUID)) { ++ params->result = E_NOT_SUFFICIENT_BUFFER; ++ *params->buffer_size = sizeof(GUID); ++ return FALSE; ++ } ++ ++ if (dev->sysfs_path == NULL) { ++ params->result = E_FAIL; ++ return FALSE; ++ } ++ ++ path = malloc(strlen(dev->sysfs_path) + strlen("/sys") + strlen("/removable") + 1); ++ path[0] = 0; ++ ++ if (strncmp(dev->sysfs_path, "/sys", 4) != 0) ++ strcpy(path, "/sys"); ++ ++ strcat(path, dev->sysfs_path); ++ ++ while ((p = strrchr(path, '/'))) { ++ FILE *f; ++ ++ strcpy(p, "/removable"); ++ f = fopen(path, "r"); ++ *p = 0; ++ ++ if (f) { ++ if (fgets(buffer, 10, f)) { ++ if (strcmp(buffer, "fixed") != 0) { ++ /* It's a potentially removable device, so treat it as a container */ ++ fclose(f); ++ break; ++ } ++ } ++ fclose(f); ++ } ++ } ++ ++ /* Get just the USB bus-devpath part */ ++ p = strrchr(path, '/'); ++ if (p && (p - path) > 12) { ++ char *guid = (char*) params->buffer; ++ out->puuid = params->buffer; ++ ++ memset(out->puuid, 0, sizeof(GUID)); ++ out->puuid->Data1 = (dev->vendor_id << 16) | dev->product_id; ++ ++ for (int i = 0; p[i]; i++) { ++ guid[4 + i % 12] ^= p[i]; ++ } ++ ++ out->vt = VT_CLSID; ++ params->result = S_OK; ++ ++ free(path); ++ return TRUE; ++ } ++ ++ free(path); ++ ++ params->result = E_FAIL; ++ return FALSE; ++} ++ + static NTSTATUS pulse_get_prop_value(void *args) + { + static const GUID PKEY_AudioEndpoint_GUID = { +@@ -2554,6 +2625,9 @@ static NTSTATUS pulse_get_prop_value(void *args) + if (IsEqualPropertyKey(*params->prop, devicepath_key)) { + get_device_path(dev, params); + return STATUS_SUCCESS; ++ } else if (IsEqualPropertyKey(*params->prop, DEVPKEY_Device_ContainerId)) { ++ get_device_container(dev, params); ++ return STATUS_SUCCESS; + } else if (IsEqualGUID(¶ms->prop->fmtid, &PKEY_AudioEndpoint_GUID)) { + switch (params->prop->pid) { + case 0: /* FormFactor */ +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds7-draft-winebus-store-container-sysfs-path-from-udev-b.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds7-draft-winebus-store-container-sysfs-path-from-udev-b.patch new file mode 100644 index 000000000..96f7a33b2 --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds7-draft-winebus-store-container-sysfs-path-from-udev-b.patch @@ -0,0 +1,80 @@ +From 4a73984f287b2f85adb14223361bcd38ef45632e Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Tue, 26 Jul 2022 11:13:45 +0200 +Subject: [PATCH 7/9] [draft] winebus: store container sysfs path from udev + backend. + +Store the sysfs path of container USB devices detected by the udev backend +so a container ID can be assigned. +--- + dlls/winebus.sys/bus_udev.c | 34 ++++++++++++++++++++++++++++++++++ + dlls/winebus.sys/unixlib.h | 1 + + 2 files changed, 35 insertions(+) + +diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c +index 5da979c6c5a..aec40455e72 100644 +--- a/dlls/winebus.sys/bus_udev.c ++++ b/dlls/winebus.sys/bus_udev.c +@@ -1543,6 +1543,36 @@ static const struct hid_device_vtbl lnxev_device_vtbl = + }; + #endif /* HAS_PROPER_INPUT_HEADER */ + ++static void get_device_container_syspath(const char *syspath, struct device_desc *desc) ++{ ++ char path[MAX_PATH], buffer[10], *p; ++ ++ if (strlen(syspath) + strlen("/removable") + 1 > MAX_PATH) ++ return; ++ ++ strcpy(path, syspath); ++ ++ while ((p = strrchr(path, '/'))) { ++ FILE *f; ++ ++ strcpy(p, "/removable"); ++ f = fopen(path, "r"); ++ *p = 0; ++ ++ if (f) { ++ if (fgets(buffer, 10, f) && strcmp(buffer, "fixed") != 0) { ++ /* It's a potentially removable device, so treat it as a container */ ++ fclose(f); ++ break; ++ } ++ fclose(f); ++ } ++ } ++ ++ if (p && (p - path) > 12) ++ lstrcpynA(desc->container_syspath, path, sizeof(desc->container_syspath)); ++} ++ + static void get_device_subsystem_info(struct udev_device *dev, char const *subsystem, struct device_desc *desc, + int *bus) + { +@@ -1601,6 +1631,10 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy + + if (!desc->serialnumber[0] && (tmp = udev_device_get_sysattr_value(dev, "serial"))) + ntdll_umbstowcs(tmp, strlen(tmp) + 1, desc->serialnumber, ARRAY_SIZE(desc->serialnumber)); ++ ++ if (!desc->container_syspath[0] && (tmp = udev_device_get_syspath(dev))) { ++ get_device_container_syspath(tmp, desc); ++ } + } + + static void hidraw_set_quirks(struct hidraw_device *impl, DWORD bus_type, WORD vid, WORD pid) +diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h +index 731745bb9a4..dde366df3c2 100644 +--- a/dlls/winebus.sys/unixlib.h ++++ b/dlls/winebus.sys/unixlib.h +@@ -42,6 +42,7 @@ struct device_desc + WCHAR manufacturer[MAX_PATH]; + WCHAR product[MAX_PATH]; + WCHAR serialnumber[MAX_PATH]; ++ char container_syspath[MAX_PATH]; + }; + + struct sdl_bus_options +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds8-draft-winebus-implement-BusQueryContainerID-based-on.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds8-draft-winebus-implement-BusQueryContainerID-based-on.patch new file mode 100644 index 000000000..c6c64754c --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds8-draft-winebus-implement-BusQueryContainerID-based-on.patch @@ -0,0 +1,86 @@ +From 7bb3d51a0b2dbb12d36a4407089b0ec391432130 Mon Sep 17 00:00:00 2001 +From: Claire Girka +Date: Tue, 26 Jul 2022 11:14:40 +0200 +Subject: [PATCH 8/9] [draft] winebus: implement BusQueryContainerID based on + container sysfs path + +--- + dlls/winebus.sys/Makefile.in | 2 +- + dlls/winebus.sys/main.c | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/dlls/winebus.sys/Makefile.in b/dlls/winebus.sys/Makefile.in +index db32faee5b3..63de33b8aee 100644 +--- a/dlls/winebus.sys/Makefile.in ++++ b/dlls/winebus.sys/Makefile.in +@@ -1,6 +1,6 @@ + MODULE = winebus.sys + UNIXLIB = winebus.so +-IMPORTS = ntoskrnl hidparse ++IMPORTS = ntoskrnl hidparse ole32 + UNIX_LIBS = $(IOKIT_LIBS) $(UDEV_LIBS) $(PTHREAD_LIBS) $(INOTIFY_LIBS) + UNIX_CFLAGS = $(UDEV_CFLAGS) $(SDL2_CFLAGS) + +diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c +index dae6850415d..a722500b22a 100644 +--- a/dlls/winebus.sys/main.c ++++ b/dlls/winebus.sys/main.c +@@ -37,6 +37,7 @@ + #include "wine/debug.h" + #include "wine/list.h" + #include "wine/unixlib.h" ++#include "ole2.h" + + #include "unixlib.h" + +@@ -198,6 +199,36 @@ static WCHAR *get_instance_id(DEVICE_OBJECT *device) + return dst; + } + ++static WCHAR *get_container_id(DEVICE_OBJECT *device) ++{ ++ struct device_extension *ext = (struct device_extension *)device->DeviceExtension; ++ UINT len = (38+1)*sizeof(WCHAR); ++ WCHAR *dst; ++ GUID guid; ++ const char *p; ++ ++ if (!ext->desc.container_syspath[0]) ++ return NULL; ++ ++ memset(&guid, 0, sizeof(GUID)); ++ guid.Data1 = (ext->desc.vid << 16) | ext->desc.pid; ++ ++ /* Get just the USB bus-devpath part */ ++ p = strrchr(ext->desc.container_syspath, '/'); ++ if (!p || (p - ext->desc.container_syspath) <= 12) ++ return NULL; ++ ++ for (int i = 0; p[i]; i++) { ++ ((char *) &guid)[4 + i % 12] ^= p[i]; ++ } ++ ++ if (!(dst = ExAllocatePool(PagedPool, len))) ++ return NULL; ++ ++ StringFromGUID2(&guid, dst, len); ++ return dst; ++} ++ + static WCHAR *get_device_id(DEVICE_OBJECT *device) + { + static const WCHAR input_format[] = L"&MI_%02u"; +@@ -522,6 +553,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: + FIXME("Unhandled type %08x\n", type); + return status; +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds9-WiP-Implement-SetupDiGetDeviceInterfacePropertyW-for.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds9-WiP-Implement-SetupDiGetDeviceInterfacePropertyW-for.patch new file mode 100644 index 000000000..ac573569d --- /dev/null +++ b/wine-tkg-git/wine-tkg-userpatches/valvexbe/ds9-WiP-Implement-SetupDiGetDeviceInterfacePropertyW-for.patch @@ -0,0 +1,87 @@ +From 871155a9442ef563381afc861476a06dcfbfb07c Mon Sep 17 00:00:00 2001 +From: Claire +Date: Tue, 29 Nov 2022 17:37:44 +0100 +Subject: [PATCH 9/9] [WiP] Implement SetupDiGetDeviceInterfacePropertyW for + DEVPKEY_Device_InstanceId + +Fixes a crash in Marvel's Spider-Man +--- + dlls/setupapi/devinst.c | 49 +++++++++++++++++++++++++++++++++++++ + dlls/setupapi/setupapi.spec | 1 + + 2 files changed, 50 insertions(+) + +diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c +index 0b827d3ab9b..ef328491994 100644 +--- a/dlls/setupapi/devinst.c ++++ b/dlls/setupapi/devinst.c +@@ -3049,6 +3049,55 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo) + return TRUE; + } + ++/*********************************************************************** ++ * SetupDiGetDeviceInterfacePropertyW (SETUPAPI.@) ++ */ ++BOOL WINAPI SetupDiGetDeviceInterfacePropertyW(HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_data, ++ const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, BYTE *prop_buff, ++ DWORD prop_buff_size, DWORD *required_size, DWORD flags) { ++ ++ // TODO: should probably use DEVPKEY_Device_InstanceId ++ static const DEVPROPKEY device_instanceid_key = { ++ {0x78c34fc8, 0x104a, 0x4aca, {0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57}}, 256 ++ }; ++ ++ TRACE("%p, %p, (%s, %04lx), %p, %p, %ld, %p, %#lx\n", devinfo, iface_data, wine_dbgstr_guid(&prop_key->fmtid), prop_key->pid, prop_type, prop_buff, prop_buff_size, ++ required_size, flags); ++ ++ // Special case for InstanceID ++ if (IsEqualDevPropKey(*prop_key, device_instanceid_key)) { ++ struct device *device; ++ struct device_iface *iface; ++ ++ if (!(iface = get_device_iface(devinfo, iface_data))) ++ return FALSE; ++ ++ if (!(device = iface->device)) ++ return FALSE; ++ ++ TRACE("instance ID: %s\n", debugstr_w(device->instanceId)); ++ if (prop_buff_size < lstrlenW(device->instanceId) + 1) ++ { ++ SetLastError(ERROR_INSUFFICIENT_BUFFER); ++ if (required_size) ++ *required_size = lstrlenW(device->instanceId) + 1; ++ return FALSE; ++ } ++ ++ lstrcpyW((WCHAR *) prop_buff, device->instanceId); ++ if (required_size) ++ *required_size = lstrlenW(device->instanceId) + 1; ++ *prop_type = DEVPROP_TYPE_STRING; ++ ++ return TRUE; ++ } else { ++ // TODO: maybe fall back as SetupDiGetDevicePropertyW? ++ FIXME("stub\n"); ++ } ++ ++ return FALSE; ++} ++ + /*********************************************************************** + * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@) + */ +diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec +index 4d144fe739b..48a3564cb48 100644 +--- a/dlls/setupapi/setupapi.spec ++++ b/dlls/setupapi/setupapi.spec +@@ -349,6 +349,7 @@ + @ stub SetupDiGetDeviceInterfaceAlias + @ stdcall SetupDiGetDeviceInterfaceDetailA(long ptr ptr long ptr ptr) + @ stdcall SetupDiGetDeviceInterfaceDetailW(long ptr ptr long ptr ptr) ++@ stdcall SetupDiGetDeviceInterfacePropertyW(ptr ptr ptr ptr ptr long ptr long) + @ stdcall SetupDiGetDevicePropertyW(ptr ptr ptr ptr ptr long ptr long) + @ stdcall SetupDiGetDeviceRegistryPropertyA(long ptr long ptr ptr long ptr) + @ stdcall SetupDiGetDeviceRegistryPropertyW(long ptr long ptr ptr long ptr) +-- +2.47.1 + diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense1.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense1.patch deleted file mode 100644 index 8e3b0b02c..000000000 --- a/wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense1.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d8b7a8d587b5375ac014746f59409fe96d0f0eff Mon Sep 17 00:00:00 2001 -From: Claire -Date: Sat, 18 Jun 2022 12:39:35 +0200 -Subject: [PATCH 1/3] Override device name for DualSense audio devices as games - match the audio output by name - -It's needed for games like FF7R and FF14 ---- - dlls/winepulse.drv/pulse.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c -index 60b1c7126dc..a4048fbf267 100644 ---- a/dlls/winepulse.drv/pulse.c -+++ b/dlls/winepulse.drv/pulse.c -@@ -521,6 +521,15 @@ static void fill_device_info(PhysDevice *dev, pa_proplist *p) - - if ((buffer = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_ID))) - dev->product_id = strtol(buffer, NULL, 16); -+ -+ /* Some games with DualSense support need the audio device to be called "Wireless Controller" */ -+ if (dev->vendor_id == 0x054c && dev->product_id == 0x0ce6) { -+ WCHAR *new_name = get_device_name("Wireless Controller", NULL); -+ if (new_name) { -+ free(dev->name); -+ dev->name = new_name; -+ } -+ } - } - - static void pulse_add_device(struct list *list, pa_proplist *proplist, int index, EndpointFormFactor form, --- -2.35.1 diff --git a/wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense2.patch b/wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense2.patch deleted file mode 100644 index 6bb375efe..000000000 --- a/wine-tkg-git/wine-tkg-userpatches/valvexbe/xiv-dualsense2.patch +++ /dev/null @@ -1,90 +0,0 @@ -From f69a94ee3b268111d8f9601213fce0a13667bf59 Mon Sep 17 00:00:00 2001 -From: Claire -Date: Mon, 27 Jun 2022 19:36:02 +0200 -Subject: [PATCH 3/3] [WiP] setupapi: Add fake Container ID for DualSense - devices - ---- - dlls/mmdevapi/devenum.c | 24 ++++++++++++++++++++++++ - dlls/setupapi/devinst.c | 21 +++++++++++++++++++++ - 2 files changed, 45 insertions(+) - -diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c -index f36dcb20b72..c68ec6f78ba 100644 ---- a/dlls/mmdevapi/devenum.c -+++ b/dlls/mmdevapi/devenum.c -@@ -359,6 +359,11 @@ static MMDevice *MMDevice_Create(WCHAR *name, GUID *id, EDataFlow flow, DWORD st - MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_DeviceInterface_FriendlyName, &pv); - MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_DeviceDesc, &pv); - -+ if (wcscmp(name, L"Wireless Controller") == 0) { -+ pv.pwszVal = L"{12345678-9ABC-DEF0-1234-56789ABCDEF0}"; -+ MMDevice_SetPropValue(id, flow, (const PROPERTYKEY*)&DEVPKEY_Device_ContainerId, &pv); -+ } -+ - pv.pwszVal = guidstr; - MMDevice_SetPropValue(id, flow, &deviceinterface_key, &pv); - -@@ -1450,9 +1455,28 @@ static HRESULT WINAPI MMDevPropStore_GetValue(IPropertyStore *iface, REFPROPERTY - } - - hres = MMDevice_GetPropValue(&This->parent->devguid, This->parent->flow, key, pv); -+ - if (FAILED(hres)) - return hres; - -+ /* Clients apps expect a CLSID */ -+ if(IsEqualPropertyKey(*key,DEVPKEY_Device_ContainerId) && pv->vt == VT_LPWSTR && pv->pwszVal) { -+ LPWSTR guidstr = pv->pwszVal; -+ -+ pv->puuid = CoTaskMemAlloc(sizeof(*pv->puuid)); -+ if (!pv->puuid) -+ return E_OUTOFMEMORY; -+ -+ hres = CLSIDFromString(guidstr, pv->puuid); -+ if (FAILED(hres)) -+ return hres; -+ -+ pv->vt = VT_CLSID; -+ CoTaskMemFree(guidstr); -+ -+ return hres; -+ } -+ - if (WARN_ON(mmdevapi)) - { - if ((IsEqualPropertyKey(*key, DEVPKEY_Device_FriendlyName) || -diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c -index aea0e605f1d..217997e8bb3 100644 ---- a/dlls/setupapi/devinst.c -+++ b/dlls/setupapi/devinst.c -@@ -3227,6 +3227,27 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(HDEVINFO devinfo, - return FALSE; - } - -+ if (Property == 36) { -+ /* Container ID. Returning a fake one so that games using the DualSense can match devices together. */ -+ STRING *guid = L"{12345678-9abc-def0-1234-56789abcdef0}"; -+ if (PropertyRegDataType != NULL) { -+ *PropertyRegDataType = REG_SZ; -+ } -+ -+ DWORD size = (wcslen(guid) + 1) * sizeof(WCHAR); -+ -+ if (PropertyBufferSize > size) { -+ wcscpy(PropertyBuffer, guid); -+ -+ if (RequiredSize) -+ *RequiredSize = size; -+ -+ TRACE("output: %s\n", debugstr_w(PropertyBuffer)); -+ -+ ret = TRUE; -+ } -+ } -+ - if (Property < ARRAY_SIZE(PropertyMap) && PropertyMap[Property].nameW) - { - DWORD size = PropertyBufferSize; --- -2.35.1