Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2022
- 51 participants
- 1216 messages
[PATCH 4/4] wineusb.sys: Create a separate unix_device struct to wrap the libusb device handle.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
Keep unix_device objects in a separate list.
---
dlls/wineusb.sys/Makefile.in | 2 +-
dlls/wineusb.sys/wineusb.c | 100 +++++++++++++++++++++++++++--------
2 files changed, 78 insertions(+), 24 deletions(-)
diff --git a/dlls/wineusb.sys/Makefile.in b/dlls/wineusb.sys/Makefile.in
index ee3bfffdbeb..5547200596e 100644
--- a/dlls/wineusb.sys/Makefile.in
+++ b/dlls/wineusb.sys/Makefile.in
@@ -2,7 +2,7 @@ EXTRADEFS = -DWINE_NO_LONG_TYPES
MODULE = wineusb.sys
UNIXLIB = wineusb.so
IMPORTS = ntoskrnl
-UNIX_LIBS = $(USB_LIBS)
+UNIX_LIBS = $(USB_LIBS) $(PTHREAD_LIBS)
UNIX_CFLAGS = $(USB_CFLAGS)
EXTRADLLFLAGS = -Wl,--subsystem,native -mcygwin
diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c
index 59d8bd93fc4..cfa88616a8f 100644
--- a/dlls/wineusb.sys/wineusb.c
+++ b/dlls/wineusb.sys/wineusb.c
@@ -21,6 +21,7 @@
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <pthread.h>
#include <libusb.h>
#include "ntstatus.h"
@@ -68,8 +69,18 @@ DECLARE_CRITICAL_SECTION(wineusb_cs);
static unixlib_handle_t unix_handle;
+static pthread_mutex_t unix_device_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static struct list unix_device_list = LIST_INIT(unix_device_list);
static struct list device_list = LIST_INIT(device_list);
+struct unix_device
+{
+ struct list entry;
+
+ libusb_device_handle *handle;
+};
+
struct usb_device
{
struct list entry;
@@ -86,7 +97,7 @@ struct usb_device
uint16_t vendor, product, revision;
- libusb_device_handle *handle;
+ struct unix_device *unix_device;
LIST_ENTRY irp_list;
};
@@ -96,6 +107,15 @@ static DEVICE_OBJECT *bus_fdo, *bus_pdo;
static libusb_hotplug_callback_handle hotplug_cb_handle;
+static void destroy_unix_device(struct unix_device *unix_device)
+{
+ pthread_mutex_lock(&unix_device_mutex);
+ libusb_close(unix_device->handle);
+ list_remove(&unix_device->entry);
+ pthread_mutex_unlock(&unix_device_mutex);
+ free(unix_device);
+}
+
static void add_usb_interface(struct usb_device *parent, const struct libusb_interface_descriptor *desc)
{
struct usb_device *device;
@@ -112,7 +132,7 @@ static void add_usb_interface(struct usb_device *parent, const struct libusb_int
device = device_obj->DeviceExtension;
device->device_obj = device_obj;
device->parent = parent;
- device->handle = parent->handle;
+ device->unix_device = parent->unix_device;
device->interface_index = desc->bInterfaceNumber;
device->class = desc->bInterfaceClass;
device->subclass = desc->bInterfaceSubClass;
@@ -127,13 +147,13 @@ static void add_usb_interface(struct usb_device *parent, const struct libusb_int
LeaveCriticalSection(&wineusb_cs);
}
-static void add_usb_device(libusb_device *libusb_device)
+static void add_unix_device(struct unix_device *unix_device)
{
static const WCHAR formatW[] = {'\\','D','e','v','i','c','e','\\','U','S','B','P','D','O','-','%','u',0};
+ libusb_device *libusb_device = libusb_get_device(unix_device->handle);
struct libusb_config_descriptor *config_desc;
struct libusb_device_descriptor device_desc;
static unsigned int name_index;
- libusb_device_handle *handle;
struct usb_device *device;
DEVICE_OBJECT *device_obj;
UNICODE_STRING string;
@@ -143,28 +163,21 @@ static void add_usb_device(libusb_device *libusb_device)
libusb_get_device_descriptor(libusb_device, &device_desc);
- TRACE("Adding new device %p, vendor %04x, product %04x.\n", libusb_device,
+ TRACE("Adding new device %p, vendor %04x, product %04x.\n", unix_device,
device_desc.idVendor, device_desc.idProduct);
- if ((ret = libusb_open(libusb_device, &handle)))
- {
- WARN("Failed to open device: %s\n", libusb_strerror(ret));
- return;
- }
-
sprintfW(name, formatW, name_index++);
RtlInitUnicodeString(&string, name);
if ((status = IoCreateDevice(driver_obj, sizeof(*device), &string,
FILE_DEVICE_USB, 0, FALSE, &device_obj)))
{
ERR("Failed to create device, status %#x.\n", status);
- libusb_close(handle);
return;
}
device = device_obj->DeviceExtension;
device->device_obj = device_obj;
- device->handle = handle;
+ device->unix_device = unix_device;
InitializeListHead(&device->irp_list);
EnterCriticalSection(&wineusb_cs);
@@ -215,16 +228,43 @@ static void add_usb_device(libusb_device *libusb_device)
IoInvalidateDeviceRelations(bus_pdo, BusRelations);
}
-static void remove_usb_device(libusb_device *libusb_device)
+static void add_usb_device(libusb_device *libusb_device)
+{
+ struct libusb_device_descriptor device_desc;
+ struct unix_device *unix_device;
+ int ret;
+
+ libusb_get_device_descriptor(libusb_device, &device_desc);
+
+ TRACE("Adding new device %p, vendor %04x, product %04x.\n", libusb_device,
+ device_desc.idVendor, device_desc.idProduct);
+
+ if (!(unix_device = calloc(1, sizeof(*unix_device))))
+ return;
+
+ if ((ret = libusb_open(libusb_device, &unix_device->handle)))
+ {
+ WARN("Failed to open device: %s\n", libusb_strerror(ret));
+ free(unix_device);
+ return;
+ }
+ pthread_mutex_lock(&unix_device_mutex);
+ list_add_tail(&unix_device_list, &unix_device->entry);
+ pthread_mutex_unlock(&unix_device_mutex);
+
+ add_unix_device(unix_device);
+}
+
+static void remove_unix_device(struct unix_device *unix_device)
{
struct usb_device *device;
- TRACE("Removing device %p.\n", libusb_device);
+ TRACE("Removing device %p.\n", unix_device);
EnterCriticalSection(&wineusb_cs);
LIST_FOR_EACH_ENTRY(device, &device_list, struct usb_device, entry)
{
- if (libusb_get_device(device->handle) == libusb_device)
+ if (device->unix_device == unix_device)
{
if (!device->removed)
{
@@ -239,6 +279,19 @@ static void remove_usb_device(libusb_device *libusb_device)
IoInvalidateDeviceRelations(bus_pdo, BusRelations);
}
+static void remove_usb_device(libusb_device *libusb_device)
+{
+ struct unix_device *unix_device;
+
+ TRACE("Removing device %p.\n", libusb_device);
+
+ LIST_FOR_EACH_ENTRY(unix_device, &unix_device_list, struct unix_device, entry)
+ {
+ if (libusb_get_device(unix_device->handle) == libusb_device)
+ remove_unix_device(unix_device);
+ }
+}
+
static BOOL thread_shutdown;
static HANDLE event_thread;
@@ -361,7 +414,7 @@ static NTSTATUS fdo_pnp(IRP *irp)
{
assert(!device->removed);
if (!device->parent)
- libusb_close(device->handle);
+ destroy_unix_device(device->unix_device);
list_remove(&device->entry);
IoDeleteDevice(device->device_obj);
}
@@ -558,7 +611,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp)
remove_pending_irps(device);
if (!device->parent)
- libusb_close(device->handle);
+ destroy_unix_device(device->unix_device);
IoDeleteDevice(device->device_obj);
ret = STATUS_SUCCESS;
@@ -691,6 +744,7 @@ static struct pipe get_pipe(HANDLE handle)
static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
{
URB *urb = IoGetCurrentIrpStackLocation(irp)->Parameters.Others.Argument1;
+ libusb_device_handle *handle = device->unix_device->handle;
struct libusb_transfer *transfer;
int ret;
@@ -727,7 +781,7 @@ static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
struct _URB_PIPE_REQUEST *req = &urb->UrbPipeRequest;
struct pipe pipe = get_pipe(req->PipeHandle);
- if ((ret = libusb_clear_halt(device->handle, pipe.endpoint)) < 0)
+ if ((ret = libusb_clear_halt(handle, pipe.endpoint)) < 0)
ERR("Failed to clear halt: %s\n", libusb_strerror(ret));
return STATUS_SUCCESS;
@@ -746,12 +800,12 @@ static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
if (pipe.type == UsbdPipeTypeBulk)
{
- libusb_fill_bulk_transfer(transfer, device->handle, pipe.endpoint,
+ libusb_fill_bulk_transfer(transfer, handle, pipe.endpoint,
req->TransferBuffer, req->TransferBufferLength, transfer_cb, irp, 0);
}
else if (pipe.type == UsbdPipeTypeInterrupt)
{
- libusb_fill_interrupt_transfer(transfer, device->handle, pipe.endpoint,
+ libusb_fill_interrupt_transfer(transfer, handle, pipe.endpoint,
req->TransferBuffer, req->TransferBufferLength, transfer_cb, irp, 0);
}
else
@@ -792,7 +846,7 @@ static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
LIBUSB_REQUEST_GET_DESCRIPTOR, (req->DescriptorType << 8) | req->Index,
req->LanguageId, req->TransferBufferLength);
- libusb_fill_control_transfer(transfer, device->handle, buffer, transfer_cb, irp, 0);
+ libusb_fill_control_transfer(transfer, handle, buffer, transfer_cb, irp, 0);
transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
ret = libusb_submit_transfer(transfer);
if (ret < 0)
@@ -849,7 +903,7 @@ static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
req->Value, req->Index, req->TransferBufferLength);
if (!(req->TransferFlags & USBD_TRANSFER_DIRECTION_IN))
memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, req->TransferBuffer, req->TransferBufferLength);
- libusb_fill_control_transfer(transfer, device->handle, buffer, transfer_cb, irp, 0);
+ libusb_fill_control_transfer(transfer, handle, buffer, transfer_cb, irp, 0);
transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
ret = libusb_submit_transfer(transfer);
if (ret < 0)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/356
July 1, 2022
[PATCH 3/4] wineusb.sys: Do not store a reference to the libusb device in the usb_device structure.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
Retrieve it from the handle if necessary.
For simplicity.
---
dlls/wineusb.sys/wineusb.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c
index f5c727fa823..59d8bd93fc4 100644
--- a/dlls/wineusb.sys/wineusb.c
+++ b/dlls/wineusb.sys/wineusb.c
@@ -86,7 +86,6 @@ struct usb_device
uint16_t vendor, product, revision;
- libusb_device *libusb_device;
libusb_device_handle *handle;
LIST_ENTRY irp_list;
@@ -114,7 +113,6 @@ static void add_usb_interface(struct usb_device *parent, const struct libusb_int
device->device_obj = device_obj;
device->parent = parent;
device->handle = parent->handle;
- device->libusb_device = parent->libusb_device;
device->interface_index = desc->bInterfaceNumber;
device->class = desc->bInterfaceClass;
device->subclass = desc->bInterfaceSubClass;
@@ -166,7 +164,6 @@ static void add_usb_device(libusb_device *libusb_device)
device = device_obj->DeviceExtension;
device->device_obj = device_obj;
- device->libusb_device = libusb_ref_device(libusb_device);
device->handle = handle;
InitializeListHead(&device->irp_list);
@@ -227,7 +224,7 @@ static void remove_usb_device(libusb_device *libusb_device)
EnterCriticalSection(&wineusb_cs);
LIST_FOR_EACH_ENTRY(device, &device_list, struct usb_device, entry)
{
- if (device->libusb_device == libusb_device)
+ if (libusb_get_device(device->handle) == libusb_device)
{
if (!device->removed)
{
@@ -364,10 +361,7 @@ static NTSTATUS fdo_pnp(IRP *irp)
{
assert(!device->removed);
if (!device->parent)
- {
- libusb_unref_device(device->libusb_device);
libusb_close(device->handle);
- }
list_remove(&device->entry);
IoDeleteDevice(device->device_obj);
}
@@ -564,10 +558,7 @@ static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp)
remove_pending_irps(device);
if (!device->parent)
- {
- libusb_unref_device(device->libusb_device);
libusb_close(device->handle);
- }
IoDeleteDevice(device->device_obj);
ret = STATUS_SUCCESS;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/356
July 1, 2022
[PATCH 2/4] wineusb.sys: Cache members of the device descriptor in the usb_device structure.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
These are already cached by libusb, but for convenience we want to cache them on the PE side.
---
dlls/wineusb.sys/wineusb.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c
index 1f3435b67a4..f5c727fa823 100644
--- a/dlls/wineusb.sys/wineusb.c
+++ b/dlls/wineusb.sys/wineusb.c
@@ -84,6 +84,8 @@ struct usb_device
uint8_t class, subclass, protocol;
+ uint16_t vendor, product, revision;
+
libusb_device *libusb_device;
libusb_device_handle *handle;
@@ -117,6 +119,9 @@ static void add_usb_interface(struct usb_device *parent, const struct libusb_int
device->class = desc->bInterfaceClass;
device->subclass = desc->bInterfaceSubClass;
device->protocol = desc->bInterfaceProtocol;
+ device->vendor = parent->vendor;
+ device->product = parent->product;
+ device->revision = parent->revision;
InitializeListHead(&device->irp_list);
EnterCriticalSection(&wineusb_cs);
@@ -173,6 +178,9 @@ static void add_usb_device(libusb_device *libusb_device)
device->class = device_desc.bDeviceClass;
device->subclass = device_desc.bDeviceSubClass;
device->protocol = device_desc.bDeviceProtocol;
+ device->vendor = device_desc.idVendor;
+ device->product = device_desc.idProduct;
+ device->revision = device_desc.bcdDevice;
if (!(ret = libusb_get_active_config_descriptor(libusb_device, &config_desc)))
{
@@ -423,13 +431,11 @@ static void get_device_id(const struct usb_device *device, struct string_buffer
'&','P','I','D','_','%','0','4','X','&','M','I','_','%','0','2','X',0};
static const WCHAR formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
'&','P','I','D','_','%','0','4','X',0};
- struct libusb_device_descriptor desc;
- libusb_get_device_descriptor(device->libusb_device, &desc);
if (device->parent)
- append_id(buffer, interface_formatW, desc.idVendor, desc.idProduct, device->interface_index);
+ append_id(buffer, interface_formatW, device->vendor, device->product, device->interface_index);
else
- append_id(buffer, formatW, desc.idVendor, desc.idProduct);
+ append_id(buffer, formatW, device->vendor, device->product);
}
static void get_hardware_ids(const struct usb_device *device, struct string_buffer *buffer)
@@ -438,14 +444,11 @@ static void get_hardware_ids(const struct usb_device *device, struct string_buff
'&','P','I','D','_','%','0','4','X','&','R','E','V','_','%','0','4','X','&','M','I','_','%','0','2','X',0};
static const WCHAR formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
'&','P','I','D','_','%','0','4','X','&','R','E','V','_','%','0','4','X',0};
- struct libusb_device_descriptor desc;
-
- libusb_get_device_descriptor(device->libusb_device, &desc);
if (device->parent)
- append_id(buffer, interface_formatW, desc.idVendor, desc.idProduct, desc.bcdDevice, device->interface_index);
+ append_id(buffer, interface_formatW, device->vendor, device->product, device->revision, device->interface_index);
else
- append_id(buffer, formatW, desc.idVendor, desc.idProduct, desc.bcdDevice);
+ append_id(buffer, formatW, device->vendor, device->product, device->revision);
get_device_id(device, buffer);
append_id(buffer, emptyW);
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/356
July 1, 2022
[PATCH 1/4] wineusb.sys: Move the libusb_cancel_transfer() call to a new Unix library.
by Zebediah Figura
From: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wineusb.sys/Makefile.in | 2 ++
dlls/wineusb.sys/unixlib.c | 50 ++++++++++++++++++++++++++++++++++++
dlls/wineusb.sys/unixlib.h | 38 +++++++++++++++++++++++++++
dlls/wineusb.sys/wineusb.c | 21 +++++++++++++--
4 files changed, 109 insertions(+), 2 deletions(-)
create mode 100644 dlls/wineusb.sys/unixlib.c
create mode 100644 dlls/wineusb.sys/unixlib.h
diff --git a/dlls/wineusb.sys/Makefile.in b/dlls/wineusb.sys/Makefile.in
index 8145213fbef..ee3bfffdbeb 100644
--- a/dlls/wineusb.sys/Makefile.in
+++ b/dlls/wineusb.sys/Makefile.in
@@ -1,5 +1,6 @@
EXTRADEFS = -DWINE_NO_LONG_TYPES
MODULE = wineusb.sys
+UNIXLIB = wineusb.so
IMPORTS = ntoskrnl
UNIX_LIBS = $(USB_LIBS)
UNIX_CFLAGS = $(USB_CFLAGS)
@@ -7,6 +8,7 @@ UNIX_CFLAGS = $(USB_CFLAGS)
EXTRADLLFLAGS = -Wl,--subsystem,native -mcygwin
C_SRCS = \
+ unixlib.c \
wineusb.c
RC_SRCS = wineusb.rc
diff --git a/dlls/wineusb.sys/unixlib.c b/dlls/wineusb.sys/unixlib.c
new file mode 100644
index 00000000000..cdc84d98ede
--- /dev/null
+++ b/dlls/wineusb.sys/unixlib.c
@@ -0,0 +1,50 @@
+/*
+ * libusb backend
+ *
+ * Copyright 2020 Zebediah Figura
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include <libusb.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "wine/debug.h"
+#include "wine/list.h"
+
+#include "unixlib.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wineusb);
+
+static NTSTATUS usb_cancel_transfer(void *args)
+{
+ const struct usb_cancel_transfer_params *params = args;
+ int ret;
+
+ if ((ret = libusb_cancel_transfer(params->transfer)) < 0)
+ ERR("Failed to cancel transfer: %s\n", libusb_strerror(ret));
+
+ return STATUS_SUCCESS;
+}
+
+const unixlib_entry_t __wine_unix_call_funcs[] =
+{
+#define X(name) [unix_ ## name] = name
+ X(usb_cancel_transfer),
+};
diff --git a/dlls/wineusb.sys/unixlib.h b/dlls/wineusb.sys/unixlib.h
new file mode 100644
index 00000000000..d046062cd5f
--- /dev/null
+++ b/dlls/wineusb.sys/unixlib.h
@@ -0,0 +1,38 @@
+/*
+ * wineusb Unix library interface
+ *
+ * Copyright 2022 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_WINEUSB_UNIXLIB_H
+#define __WINE_WINEUSB_UNIXLIB_H
+
+#include "windef.h"
+#include "winternl.h"
+#include "wine/unixlib.h"
+
+struct usb_cancel_transfer_params
+{
+ void *transfer;
+};
+
+enum unix_funcs
+{
+ unix_usb_cancel_transfer,
+};
+
+#endif
diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c
index 87669b5c65d..1f3435b67a4 100644
--- a/dlls/wineusb.sys/wineusb.c
+++ b/dlls/wineusb.sys/wineusb.c
@@ -36,6 +36,8 @@
#include "wine/list.h"
#include "wine/unicode.h"
+#include "unixlib.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(wineusb);
#ifdef __ASM_USE_FASTCALL_WRAPPER
@@ -64,6 +66,8 @@ __ASM_STDCALL_FUNC( wrap_fastcall_func1, 8,
DECLARE_CRITICAL_SECTION(wineusb_cs);
+static unixlib_handle_t unix_handle;
+
static struct list device_list = LIST_INIT(device_list);
struct usb_device
@@ -712,9 +716,12 @@ static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
{
IRP *queued_irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
+ struct usb_cancel_transfer_params params =
+ {
+ .transfer = queued_irp->Tail.Overlay.DriverContext[0],
+ };
- if ((ret = libusb_cancel_transfer(queued_irp->Tail.Overlay.DriverContext[0])) < 0)
- ERR("Failed to cancel transfer: %s\n", libusb_strerror(ret));
+ __wine_unix_call(unix_handle, unix_usb_cancel_transfer, ¶ms);
}
LeaveCriticalSection(&wineusb_cs);
@@ -930,10 +937,20 @@ static void WINAPI driver_unload(DRIVER_OBJECT *driver)
NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path)
{
+ NTSTATUS status;
+ void *instance;
int err;
TRACE("driver %p, path %s.\n", driver, debugstr_w(path->Buffer));
+ RtlPcToFileHeader(DriverEntry, &instance);
+ if ((status = NtQueryVirtualMemory(GetCurrentProcess(), instance,
+ MemoryWineUnixFuncs, &unix_handle, sizeof(unix_handle), NULL)))
+ {
+ ERR("Failed to initialize Unix library, status %#x.\n", status);
+ return status;
+ }
+
driver_obj = driver;
if ((err = libusb_init(NULL)))
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/356
July 1, 2022
[PATCH 0/4] MR356: wineusb: PE conversion
by Zebediah Figura (@zfigura)
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/356
July 1, 2022
[PATCH 5/5] win32u: Move writing mode to registry out of graphics drivers.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/win32u/sysparams.c | 59 +++++++++++++++++++--
dlls/winemac.drv/display.c | 102 +------------------------------------
dlls/winex11.drv/display.c | 92 +--------------------------------
3 files changed, 58 insertions(+), 195 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index 9b3a41756a8..8ed1efaaa31 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -408,6 +408,35 @@ static void release_display_device_init_mutex( HANDLE mutex )
NtClose( mutex );
}
+static BOOL write_adapter_mode( HKEY adapter_key, const DEVMODEW *mode )
+{
+ static const WCHAR default_settingsW[] = {'D','e','f','a','u','l','t','S','e','t','t','i','n','g','s','.',0};
+ WCHAR bufferW[MAX_PATH];
+
+#define set_mode_field( name, field, flag ) \
+ do \
+ { \
+ lstrcpyW( bufferW, default_settingsW ); \
+ lstrcatW( bufferW, (name) ); \
+ if (mode->dmFields & (flag)) \
+ set_reg_value( adapter_key, (name), REG_DWORD, &mode->field, sizeof(mode->field) ); \
+ } while (0)
+
+ set_mode_field( bits_per_pelW, dmBitsPerPel, DM_BITSPERPEL );
+ set_mode_field( x_resolutionW, dmPelsWidth, DM_PELSWIDTH );
+ set_mode_field( y_resolutionW, dmPelsHeight, DM_PELSHEIGHT );
+ set_mode_field( v_refreshW, dmDisplayFrequency, DM_DISPLAYFREQUENCY );
+ set_mode_field( flagsW, dmDisplayFlags, DM_DISPLAYFLAGS );
+ set_mode_field( orientationW, dmDisplayOrientation, DM_DISPLAYORIENTATION );
+ set_mode_field( fixed_outputW, dmDisplayFixedOutput, DM_DISPLAYFIXEDOUTPUT );
+ set_mode_field( x_panningW, dmPosition.x, DM_POSITION );
+ set_mode_field( y_panningW, dmPosition.y, DM_POSITION );
+
+#undef set_mode_field
+
+ return TRUE;
+}
+
static BOOL read_adapter_mode( HKEY adapter_key, DEVMODEW *mode )
{
static const WCHAR default_settingsW[] = {'D','e','f','a','u','l','t','S','e','t','t','i','n','g','s','.',0};
@@ -464,6 +493,27 @@ static BOOL read_registry_settings( const WCHAR *adapter_path, DEVMODEW *mode )
return ret;
}
+static BOOL write_registry_settings( const WCHAR *adapter_path, const DEVMODEW *mode )
+{
+ HANDLE mutex;
+ HKEY hkey;
+ BOOL ret;
+
+ mutex = get_display_device_init_mutex();
+
+ if (!config_key && !(config_key = reg_open_key( NULL, config_keyW, sizeof(config_keyW) ))) return FALSE;
+ if (!(hkey = reg_open_key( config_key, adapter_path, lstrlenW( adapter_path ) * sizeof(WCHAR) )))
+ {
+ release_display_device_init_mutex( mutex );
+ return FALSE;
+ }
+ ret = write_adapter_mode( hkey, mode );
+ NtClose( hkey );
+
+ release_display_device_init_mutex( mutex );
+ return ret;
+}
+
static BOOL read_display_adapter_settings( unsigned int index, struct adapter *info )
{
char buffer[4096];
@@ -1949,9 +1999,12 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, ¤t_mode, 0 )) current_mode.dmSize = 0;
if (!(devmode = validate_display_settings( &default_mode, ¤t_mode, devmode ))) return DISP_CHANGE_BADMODE;
- ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam );
- if (ret != DISP_CHANGE_SUCCESSFUL)
- ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret );
+ ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags | CDS_TEST, lparam );
+ if (!ret && (flags & CDS_UPDATEREGISTRY) && !write_registry_settings( adapter_path, devmode )) ret = DISP_CHANGE_NOTUPDATED;
+ else if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL;
+ else ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam );
+
+ if (ret) ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret );
return ret;
}
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c
index 6444f7bef30..55f95af4e39 100644
--- a/dlls/winemac.drv/display.c
+++ b/dlls/winemac.drv/display.c
@@ -79,100 +79,6 @@ static void release_display_device_init_mutex(HANDLE mutex)
NtClose(mutex);
}
-static HKEY get_display_device_reg_key(const WCHAR *device_name)
-{
- static const WCHAR display[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
- static const WCHAR video_key[] = {
- '\\','R','e','g','i','s','t','r','y',
- '\\','M','a','c','h','i','n','e',
- '\\','H','A','R','D','W','A','R','E',
- '\\','D','E','V','I','C','E','M','A','P',
- '\\','V','I','D','E','O'};
- static const WCHAR current_config_key[] = {
- '\\','R','e','g','i','s','t','r','y',
- '\\','M','a','c','h','i','n','e',
- '\\','S','y','s','t','e','m',
- '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
- '\\','H','a','r','d','w','a','r','e',' ','P','r','o','f','i','l','e','s',
- '\\','C','u','r','r','e','n','t'};
- WCHAR value_name[MAX_PATH], buffer[4096], *end_ptr;
- KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer;
- DWORD adapter_index, size;
- char adapter_name[100];
- HKEY hkey;
-
- /* Device name has to be \\.\DISPLAY%d */
- if (wcsnicmp(device_name, display, ARRAY_SIZE(display)))
- return FALSE;
-
- /* Parse \\.\DISPLAY* */
- adapter_index = wcstol(device_name + ARRAY_SIZE(display), &end_ptr, 10) - 1;
- if (*end_ptr)
- return FALSE;
-
- /* Open \Device\Video* in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
- if (!(hkey = reg_open_key(NULL, video_key, sizeof(video_key)))) return FALSE;
- sprintf(adapter_name, "\\Device\\Video%d", adapter_index);
- asciiz_to_unicode(value_name, adapter_name);
- size = query_reg_value(hkey, value_name, value, sizeof(buffer));
- NtClose(hkey);
- if (!size || value->Type != REG_SZ) return FALSE;
-
- /* Replace \Registry\Machine\ prefix with HKEY_CURRENT_CONFIG */
- memmove(buffer + ARRAYSIZE(current_config_key), (const WCHAR *)value->Data + 17,
- size - 17 * sizeof(WCHAR));
- memcpy(buffer, current_config_key, sizeof(current_config_key));
- TRACE("display device %s registry settings key %s.\n", wine_dbgstr_w(device_name),
- wine_dbgstr_w(buffer));
- return reg_open_key(NULL, buffer, lstrlenW(buffer) * sizeof(WCHAR));
-}
-
-
-static BOOL query_display_setting(HKEY hkey, const char *name, DWORD *ret)
-{
- char buffer[1024];
- WCHAR nameW[128];
- KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer;
-
- asciiz_to_unicode(nameW, name);
- if (query_reg_value(hkey, nameW, value, sizeof(buffer)) != sizeof(DWORD) ||
- value->Type != REG_DWORD)
- return FALSE;
-
- *ret = *(DWORD *)value->Data;
- return TRUE;
-}
-
-
-static BOOL write_registry_settings(const WCHAR *device_name, const DEVMODEW *dm)
-{
- HANDLE mutex;
- HKEY hkey;
- BOOL ret = TRUE;
-
- mutex = get_display_device_init_mutex();
- if (!(hkey = get_display_device_reg_key(device_name)))
- {
- release_display_device_init_mutex(mutex);
- return FALSE;
- }
-
- ret &= set_setting_value(hkey, "DefaultSettings.BitsPerPel", dm->dmBitsPerPel);
- ret &= set_setting_value(hkey, "DefaultSettings.XResolution", dm->dmPelsWidth);
- ret &= set_setting_value(hkey, "DefaultSettings.YResolution", dm->dmPelsHeight);
- ret &= set_setting_value(hkey, "DefaultSettings.VRefresh", dm->dmDisplayFrequency);
- ret &= set_setting_value(hkey, "DefaultSettings.Flags", dm->dmDisplayFlags);
- ret &= set_setting_value(hkey, "DefaultSettings.XPanning", dm->dmPosition.x);
- ret &= set_setting_value(hkey, "DefaultSettings.YPanning", dm->dmPosition.y);
- ret &= set_setting_value(hkey, "DefaultSettings.Orientation", dm->dmDisplayOrientation);
- ret &= set_setting_value(hkey, "DefaultSettings.FixedOutput", dm->dmDisplayFixedOutput);
-
- NtClose(hkey);
- release_display_device_init_mutex(mutex);
- return ret;
-}
-
-
static BOOL write_display_settings(HKEY parent_hkey, CGDirectDisplayID displayID)
{
BOOL ret = FALSE;
@@ -942,13 +848,7 @@ better:
/* we have a valid mode */
TRACE("Requested display settings match mode %ld\n", best);
- if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings(devname, devmode))
- {
- WARN("Failed to update registry\n");
- ret = DISP_CHANGE_NOTUPDATED;
- }
- else if (flags & (CDS_TEST | CDS_NORESET))
- ret = DISP_CHANGE_SUCCESSFUL;
+ if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL;
else if (wcsicmp(primary_adapter, devname))
{
FIXME("Changing non-primary adapter settings is currently unsupported.\n");
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index b45a317603a..faec892459f 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -209,89 +209,6 @@ void init_registry_display_settings(void)
}
}
-static HKEY get_display_device_reg_key( const WCHAR *device_name )
-{
- static const WCHAR display[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
- static const WCHAR video_key[] = {
- '\\','R','e','g','i','s','t','r','y',
- '\\','M','a','c','h','i','n','e',
- '\\','H','A','R','D','W','A','R','E',
- '\\','D','E','V','I','C','E','M','A','P',
- '\\','V','I','D','E','O'};
- static const WCHAR current_config_key[] = {
- '\\','R','e','g','i','s','t','r','y',
- '\\','M','a','c','h','i','n','e',
- '\\','S','y','s','t','e','m',
- '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t',
- '\\','H','a','r','d','w','a','r','e',' ','P','r','o','f','i','l','e','s',
- '\\','C','u','r','r','e','n','t'};
- WCHAR value_name[MAX_PATH], buffer[4096], *end_ptr;
- KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer;
- DWORD adapter_index, size;
- char adapter_name[100];
- HKEY hkey;
-
- /* Device name has to be \\.\DISPLAY%d */
- if (wcsnicmp( device_name, display, ARRAY_SIZE(display) ))
- return FALSE;
-
- /* Parse \\.\DISPLAY* */
- adapter_index = wcstol( device_name + ARRAY_SIZE(display), &end_ptr, 10 ) - 1;
- if (*end_ptr)
- return FALSE;
-
- /* Open \Device\Video* in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
- if (!(hkey = reg_open_key( NULL, video_key, sizeof(video_key) ))) return FALSE;
- sprintf( adapter_name, "\\Device\\Video%d", adapter_index );
- asciiz_to_unicode( value_name, adapter_name );
- size = query_reg_value( hkey, value_name, value, sizeof(buffer) );
- NtClose( hkey );
- if (!size || value->Type != REG_SZ) return FALSE;
-
- /* Replace \Registry\Machine\ prefix with HKEY_CURRENT_CONFIG */
- memmove( buffer + ARRAYSIZE(current_config_key), (const WCHAR *)value->Data + 17,
- size - 17 * sizeof(WCHAR) );
- memcpy( buffer, current_config_key, sizeof(current_config_key) );
- TRACE( "display device %s registry settings key %s.\n", wine_dbgstr_w(device_name),
- wine_dbgstr_w(buffer) );
- return reg_open_key( NULL, buffer, lstrlenW(buffer) * sizeof(WCHAR) );
-}
-
-static BOOL set_setting_value( HKEY hkey, const char *name, DWORD val )
-{
- WCHAR nameW[128];
- UNICODE_STRING str = { asciiz_to_unicode( nameW, name ) - sizeof(WCHAR), sizeof(nameW), nameW };
- return !NtSetValueKey( hkey, &str, 0, REG_DWORD, &val, sizeof(val) );
-}
-
-static BOOL write_registry_settings(const WCHAR *device_name, const DEVMODEW *dm)
-{
- HANDLE mutex;
- HKEY hkey;
- BOOL ret = TRUE;
-
- mutex = get_display_device_init_mutex();
- if (!(hkey = get_display_device_reg_key( device_name )))
- {
- release_display_device_init_mutex(mutex);
- return FALSE;
- }
-
- ret &= set_setting_value( hkey, "DefaultSettings.BitsPerPel", dm->dmBitsPerPel );
- ret &= set_setting_value( hkey, "DefaultSettings.XResolution", dm->dmPelsWidth );
- ret &= set_setting_value( hkey, "DefaultSettings.YResolution", dm->dmPelsHeight );
- ret &= set_setting_value( hkey, "DefaultSettings.VRefresh", dm->dmDisplayFrequency );
- ret &= set_setting_value( hkey, "DefaultSettings.Flags", dm->dmDisplayFlags );
- ret &= set_setting_value( hkey, "DefaultSettings.XPanning", dm->dmPosition.x );
- ret &= set_setting_value( hkey, "DefaultSettings.YPanning", dm->dmPosition.y );
- ret &= set_setting_value( hkey, "DefaultSettings.Orientation", dm->dmDisplayOrientation );
- ret &= set_setting_value( hkey, "DefaultSettings.FixedOutput", dm->dmDisplayFixedOutput );
-
- NtClose( hkey );
- release_display_device_init_mutex(mutex);
- return ret;
-}
-
BOOL get_primary_adapter(WCHAR *name)
{
DISPLAY_DEVICEW dd;
@@ -883,14 +800,7 @@ LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
return DISP_CHANGE_BADMODE;
}
- if (!write_registry_settings(devname, full_mode))
- {
- ERR("Failed to write %s display settings to registry.\n", wine_dbgstr_w(devname));
- free_full_mode(full_mode);
- free(displays);
- return DISP_CHANGE_NOTUPDATED;
- }
-
+ *devmode = *full_mode;
free_full_mode(full_mode);
break;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/355
July 1, 2022
[PATCH 4/5] win32u: Move NtUserChangeDisplaySettings mode validation to a separate helper.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/win32u/sysparams.c | 94 ++++++++++++++++++-----------------------
1 file changed, 42 insertions(+), 52 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index 5f4a3bd9311..9b3a41756a8 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -1872,16 +1872,53 @@ static BOOL is_detached_mode( const DEVMODEW *mode )
mode->dmPelsHeight == 0;
}
+static DEVMODEW *validate_display_settings( DEVMODEW *default_mode, DEVMODEW *current_mode, DEVMODEW *devmode )
+{
+ if (devmode)
+ {
+ trace_devmode( devmode );
+
+ if (devmode->dmSize < offsetof(DEVMODEW, dmICMMethod)) return NULL;
+ if (!is_detached_mode( devmode ) &&
+ (!(devmode->dmFields & DM_BITSPERPEL) || !devmode->dmBitsPerPel) &&
+ (!(devmode->dmFields & DM_PELSWIDTH) || !devmode->dmPelsWidth) &&
+ (!(devmode->dmFields & DM_PELSHEIGHT) || !devmode->dmPelsHeight) &&
+ (!(devmode->dmFields & DM_DISPLAYFREQUENCY) || !devmode->dmDisplayFrequency))
+ devmode = NULL;
+ }
+
+ if (!devmode)
+ {
+ if (!default_mode->dmSize) return NULL;
+ TRACE( "Return to original display mode\n" );
+ devmode = default_mode;
+ }
+
+ if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
+ {
+ WARN( "devmode doesn't specify the resolution: %#x\n", devmode->dmFields );
+ return NULL;
+ }
+
+ if (!is_detached_mode( devmode ) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight))
+ {
+ if (!current_mode->dmSize) return NULL;
+ if (!devmode->dmPelsWidth) devmode->dmPelsWidth = current_mode->dmPelsWidth;
+ if (!devmode->dmPelsHeight) devmode->dmPelsHeight = current_mode->dmPelsHeight;
+ }
+
+ return devmode;
+}
+
/***********************************************************************
* NtUserChangeDisplaySettingsExW (win32u.@)
*/
LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd,
DWORD flags, void *lparam )
{
+ DEVMODEW default_mode = {.dmSize = sizeof(DEVMODEW)}, current_mode = {.dmSize = sizeof(DEVMODEW)};
WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH];
struct adapter *adapter;
- BOOL def_mode = TRUE;
- DEVMODEW dm;
LONG ret;
TRACE( "%s %p %p %#x %p\n", debugstr_us(devname), devmode, hwnd, flags, lparam );
@@ -1908,56 +1945,9 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
return DISP_CHANGE_BADPARAM;
}
- if (devmode)
- {
- trace_devmode( devmode );
-
- if (devmode->dmSize < FIELD_OFFSET(DEVMODEW, dmICMMethod))
- return DISP_CHANGE_BADMODE;
-
- if (is_detached_mode(devmode) ||
- ((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel) ||
- ((devmode->dmFields & DM_PELSWIDTH) && devmode->dmPelsWidth) ||
- ((devmode->dmFields & DM_PELSHEIGHT) && devmode->dmPelsHeight) ||
- ((devmode->dmFields & DM_DISPLAYFREQUENCY) && devmode->dmDisplayFrequency))
- def_mode = FALSE;
- }
-
- if (def_mode)
- {
- memset( &dm, 0, sizeof(dm) );
- dm.dmSize = sizeof(dm);
- if (!read_registry_settings( adapter_path, &dm ))
- {
- ERR( "Default mode not found!\n" );
- return DISP_CHANGE_BADMODE;
- }
-
- TRACE( "Return to original display mode\n" );
- devmode = &dm;
- }
-
- if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
- {
- WARN( "devmode doesn't specify the resolution: %#x\n", devmode->dmFields );
- return DISP_CHANGE_BADMODE;
- }
-
- if (!is_detached_mode(devmode) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight))
- {
- memset(&dm, 0, sizeof(dm));
- dm.dmSize = sizeof(dm);
- if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, &dm, 0 ))
- {
- ERR( "Current mode not found!\n" );
- return DISP_CHANGE_BADMODE;
- }
-
- if (!devmode->dmPelsWidth)
- devmode->dmPelsWidth = dm.dmPelsWidth;
- if (!devmode->dmPelsHeight)
- devmode->dmPelsHeight = dm.dmPelsHeight;
- }
+ if (!read_registry_settings( adapter_path, &default_mode )) default_mode.dmSize = 0;
+ if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, ¤t_mode, 0 )) current_mode.dmSize = 0;
+ if (!(devmode = validate_display_settings( &default_mode, ¤t_mode, devmode ))) return DISP_CHANGE_BADMODE;
ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam );
if (ret != DISP_CHANGE_SUCCESSFUL)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/355
July 1, 2022
[PATCH 3/5] win32u: Move reading mode from registry out of graphics drivers.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/win32u/sysparams.c | 86 ++++++++++++++++++++++++++++++++++---
dlls/wineandroid.drv/init.c | 2 +-
dlls/winemac.drv/display.c | 52 ----------------------
dlls/winex11.drv/display.c | 62 --------------------------
4 files changed, 81 insertions(+), 121 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index c99f0d39ac2..5f4a3bd9311 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -169,6 +169,15 @@ static const WCHAR displayW[] = {'D','i','s','p','l','a','y',0};
static const WCHAR monitorW[] = {'M','o','n','i','t','o','r',0};
static const WCHAR yesW[] = {'Y','e','s',0};
static const WCHAR noW[] = {'N','o',0};
+static const WCHAR bits_per_pelW[] = {'B','i','t','s','P','e','r','P','e','l',0};
+static const WCHAR x_resolutionW[] = {'X','R','e','s','o','l','u','t','i','o','n',0};
+static const WCHAR y_resolutionW[] = {'Y','R','e','s','o','l','u','t','i','o','n',0};
+static const WCHAR v_refreshW[] = {'V','R','e','f','r','e','s','h',0};
+static const WCHAR flagsW[] = {'F','l','a','g','s',0};
+static const WCHAR x_panningW[] = {'X','P','a','n','n','i','n','g',0};
+static const WCHAR y_panningW[] = {'Y','P','a','n','n','i','n','g',0};
+static const WCHAR orientationW[] = {'O','r','i','e','n','t','a','t','i','o','n',0};
+static const WCHAR fixed_outputW[] = {'F','i','x','e','d','O','u','t','p','u','t',0};
static const char guid_devclass_displayA[] = "{4D36E968-E325-11CE-BFC1-08002BE10318}";
static const WCHAR guid_devclass_displayW[] =
@@ -399,6 +408,62 @@ static void release_display_device_init_mutex( HANDLE mutex )
NtClose( mutex );
}
+static BOOL read_adapter_mode( HKEY adapter_key, DEVMODEW *mode )
+{
+ static const WCHAR default_settingsW[] = {'D','e','f','a','u','l','t','S','e','t','t','i','n','g','s','.',0};
+ char value_buf[offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data[sizeof(DWORD)])];
+ KEY_VALUE_PARTIAL_INFORMATION *value = (void *)value_buf;
+ WCHAR bufferW[MAX_PATH];
+
+#define query_mode_field( name, field, flag ) \
+ do \
+ { \
+ lstrcpyW( bufferW, default_settingsW ); \
+ lstrcatW( bufferW, (name) ); \
+ if (query_reg_value( adapter_key, bufferW, value, sizeof(value_buf) ) && \
+ value->Type == REG_DWORD) \
+ { \
+ mode->field = *(const DWORD *)value->Data; \
+ mode->dmFields |= (flag); \
+ } \
+ } while (0)
+
+ query_mode_field( bits_per_pelW, dmBitsPerPel, DM_BITSPERPEL );
+ query_mode_field( x_resolutionW, dmPelsWidth, DM_PELSWIDTH );
+ query_mode_field( y_resolutionW, dmPelsHeight, DM_PELSHEIGHT );
+ query_mode_field( v_refreshW, dmDisplayFrequency, DM_DISPLAYFREQUENCY );
+ query_mode_field( flagsW, dmDisplayFlags, DM_DISPLAYFLAGS );
+ query_mode_field( orientationW, dmDisplayOrientation, DM_DISPLAYORIENTATION );
+ query_mode_field( fixed_outputW, dmDisplayFixedOutput, DM_DISPLAYFIXEDOUTPUT );
+ query_mode_field( x_panningW, dmPosition.x, DM_POSITION );
+ query_mode_field( y_panningW, dmPosition.y, DM_POSITION );
+
+#undef query_mode_field
+
+ return TRUE;
+}
+
+static BOOL read_registry_settings( const WCHAR *adapter_path, DEVMODEW *mode )
+{
+ HANDLE mutex;
+ HKEY hkey;
+ BOOL ret;
+
+ mutex = get_display_device_init_mutex();
+
+ if (!config_key && !(config_key = reg_open_key( NULL, config_keyW, sizeof(config_keyW) ))) return FALSE;
+ if (!(hkey = reg_open_key( config_key, adapter_path, lstrlenW( adapter_path ) * sizeof(WCHAR) )))
+ {
+ release_display_device_init_mutex( mutex );
+ return FALSE;
+ }
+ ret = read_adapter_mode( hkey, mode );
+ NtClose( hkey );
+
+ release_display_device_init_mutex( mutex );
+ return ret;
+}
+
static BOOL read_display_adapter_settings( unsigned int index, struct adapter *info )
{
char buffer[4096];
@@ -1813,7 +1878,7 @@ static BOOL is_detached_mode( const DEVMODEW *mode )
LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd,
DWORD flags, void *lparam )
{
- WCHAR device_name[CCHDEVICENAME];
+ WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH];
struct adapter *adapter;
BOOL def_mode = TRUE;
DEVMODEW dm;
@@ -1831,7 +1896,11 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
}
if (!lock_display_devices()) return DISP_CHANGE_FAILED;
- if ((adapter = find_adapter( devname ))) lstrcpyW( device_name, adapter->dev.device_name );
+ if ((adapter = find_adapter( devname )))
+ {
+ lstrcpyW( device_name, adapter->dev.device_name );
+ lstrcpyW( adapter_path, adapter->config_key );
+ }
unlock_display_devices();
if (!adapter)
{
@@ -1858,7 +1927,7 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
{
memset( &dm, 0, sizeof(dm) );
dm.dmSize = sizeof(dm);
- if (!NtUserEnumDisplaySettings( devname, ENUM_REGISTRY_SETTINGS, &dm, 0 ))
+ if (!read_registry_settings( adapter_path, &dm ))
{
ERR( "Default mode not found!\n" );
return DISP_CHANGE_BADMODE;
@@ -1902,14 +1971,18 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVMODEW *devmode, DWORD flags )
{
static const WCHAR wine_display_driverW[] = {'W','i','n','e',' ','D','i','s','p','l','a','y',' ','D','r','i','v','e','r',0};
- WCHAR device_name[CCHDEVICENAME];
+ WCHAR device_name[CCHDEVICENAME], adapter_path[MAX_PATH];
struct adapter *adapter;
BOOL ret;
TRACE( "device %s, index %#x, devmode %p, flags %#x\n", debugstr_us(device), index, devmode, flags );
if (!lock_display_devices()) return FALSE;
- if ((adapter = find_adapter( device ))) lstrcpyW( device_name, adapter->dev.device_name );
+ if ((adapter = find_adapter( device )))
+ {
+ lstrcpyW( device_name, adapter->dev.device_name );
+ lstrcpyW( adapter_path, adapter->config_key );
+ }
unlock_display_devices();
if (!adapter)
{
@@ -1923,7 +1996,8 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM
devmode->dmSize = offsetof(DEVMODEW, dmICMMethod);
memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) );
- ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags );
+ if (index == ENUM_REGISTRY_SETTINGS) ret = read_registry_settings( adapter_path, devmode );
+ else ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags );
if (!ret) WARN( "Failed to query %s display settings.\n", debugstr_w(device_name) );
else TRACE( "position %dx%d, resolution %ux%u, frequency %u, depth %u, orientation %#x.\n",
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index e2cebb974c3..a82932bf65f 100644
--- a/dlls/wineandroid.drv/init.c
+++ b/dlls/wineandroid.drv/init.c
@@ -310,7 +310,7 @@ BOOL ANDROID_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, D
devmode->u1.s2.dmDisplayOrientation = 0;
devmode->u1.s2.dmDisplayFixedOutput = 0;
- if (n == ENUM_CURRENT_SETTINGS || n == ENUM_REGISTRY_SETTINGS) n = 0;
+ if (n == ENUM_CURRENT_SETTINGS) n = 0;
if (n == 0)
{
devmode->dmPelsWidth = screen_width;
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c
index 191dc1f789b..6444f7bef30 100644
--- a/dlls/winemac.drv/display.c
+++ b/dlls/winemac.drv/display.c
@@ -144,52 +144,6 @@ static BOOL query_display_setting(HKEY hkey, const char *name, DWORD *ret)
}
-static BOOL read_registry_settings(const WCHAR *device_name, DEVMODEW *dm)
-{
- HANDLE mutex;
- HKEY hkey;
- BOOL ret = TRUE;
-
- dm->dmFields = 0;
-
- mutex = get_display_device_init_mutex();
- if (!(hkey = get_display_device_reg_key(device_name)))
- {
- release_display_device_init_mutex(mutex);
- return FALSE;
- }
-
- ret &= query_display_setting(hkey, "DefaultSettings.BitsPerPel", &dm->dmBitsPerPel);
- dm->dmFields |= DM_BITSPERPEL;
- ret &= query_display_setting(hkey, "DefaultSettings.XResolution", &dm->dmPelsWidth);
- dm->dmFields |= DM_PELSWIDTH;
- ret &= query_display_setting(hkey, "DefaultSettings.YResolution", &dm->dmPelsHeight);
- dm->dmFields |= DM_PELSHEIGHT;
- ret &= query_display_setting(hkey, "DefaultSettings.VRefresh", &dm->dmDisplayFrequency);
- dm->dmFields |= DM_DISPLAYFREQUENCY;
- ret &= query_display_setting(hkey, "DefaultSettings.Flags", &dm->dmDisplayFlags);
- dm->dmFields |= DM_DISPLAYFLAGS;
- ret &= query_display_setting(hkey, "DefaultSettings.XPanning", (DWORD *)&dm->dmPosition.x);
- ret &= query_display_setting(hkey, "DefaultSettings.YPanning", (DWORD *)&dm->dmPosition.y);
- dm->dmFields |= DM_POSITION;
- ret &= query_display_setting(hkey, "DefaultSettings.Orientation", &dm->dmDisplayOrientation);
- dm->dmFields |= DM_DISPLAYORIENTATION;
- ret &= query_display_setting(hkey, "DefaultSettings.FixedOutput", &dm->dmDisplayFixedOutput);
-
- NtClose(hkey);
- release_display_device_init_mutex(mutex);
- return ret;
-}
-
-
-static BOOL set_setting_value(HKEY hkey, const char *name, DWORD val)
-{
- WCHAR nameW[128];
- UNICODE_STRING str = { asciiz_to_unicode(nameW, name) - sizeof(WCHAR), sizeof(nameW), nameW };
- return !NtSetValueKey(hkey, &str, 0, REG_DWORD, &val, sizeof(val));
-}
-
-
static BOOL write_registry_settings(const WCHAR *device_name, const DEVMODEW *dm)
{
HANDLE mutex;
@@ -1056,12 +1010,6 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, DEVMODEW *devmode
init_original_display_mode();
- if (mode == ENUM_REGISTRY_SETTINGS)
- {
- TRACE("mode %d (registry) -- getting default mode\n", mode);
- return read_registry_settings(devname, devmode);
- }
-
if (macdrv_get_displays(&displays, &num_displays))
goto failed;
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 740e018247b..b45a317603a 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -257,58 +257,6 @@ static HKEY get_display_device_reg_key( const WCHAR *device_name )
return reg_open_key( NULL, buffer, lstrlenW(buffer) * sizeof(WCHAR) );
}
-static BOOL query_display_setting( HKEY hkey, const char *name, DWORD *ret )
-{
- char buffer[1024];
- WCHAR nameW[128];
- KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer;
-
- asciiz_to_unicode( nameW, name );
- if (query_reg_value( hkey, nameW, value, sizeof(buffer) ) != sizeof(DWORD) ||
- value->Type != REG_DWORD)
- return FALSE;
-
- *ret = *(DWORD *)value->Data;
- return TRUE;
-}
-
-static BOOL read_registry_settings(const WCHAR *device_name, DEVMODEW *dm)
-{
- HANDLE mutex;
- HKEY hkey;
- BOOL ret = TRUE;
-
- dm->dmFields = 0;
-
- mutex = get_display_device_init_mutex();
- if (!(hkey = get_display_device_reg_key( device_name )))
- {
- release_display_device_init_mutex(mutex);
- return FALSE;
- }
-
- ret &= query_display_setting( hkey, "DefaultSettings.BitsPerPel", &dm->dmBitsPerPel );
- dm->dmFields |= DM_BITSPERPEL;
- ret &= query_display_setting( hkey, "DefaultSettings.XResolution", &dm->dmPelsWidth );
- dm->dmFields |= DM_PELSWIDTH;
- ret &= query_display_setting( hkey, "DefaultSettings.YResolution", &dm->dmPelsHeight );
- dm->dmFields |= DM_PELSHEIGHT;
- ret &= query_display_setting( hkey, "DefaultSettings.VRefresh", &dm->dmDisplayFrequency );
- dm->dmFields |= DM_DISPLAYFREQUENCY;
- ret &= query_display_setting( hkey, "DefaultSettings.Flags", &dm->dmDisplayFlags );
- dm->dmFields |= DM_DISPLAYFLAGS;
- ret &= query_display_setting( hkey, "DefaultSettings.XPanning", (DWORD *)&dm->dmPosition.x );
- ret &= query_display_setting( hkey, "DefaultSettings.YPanning", (DWORD *)&dm->dmPosition.y );
- dm->dmFields |= DM_POSITION;
- ret &= query_display_setting( hkey, "DefaultSettings.Orientation", &dm->dmDisplayOrientation );
- dm->dmFields |= DM_DISPLAYORIENTATION;
- ret &= query_display_setting( hkey, "DefaultSettings.FixedOutput", &dm->dmDisplayFixedOutput );
-
- NtClose( hkey );
- release_display_device_init_mutex(mutex);
- return ret;
-}
-
static BOOL set_setting_value( HKEY hkey, const char *name, DWORD val )
{
WCHAR nameW[128];
@@ -468,16 +416,6 @@ BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DW
UINT mode_count;
ULONG_PTR id;
- if (n == ENUM_REGISTRY_SETTINGS)
- {
- if (!read_registry_settings(name, devmode))
- {
- ERR("Failed to get %s registry display settings.\n", wine_dbgstr_w(name));
- return FALSE;
- }
- return TRUE;
- }
-
if (n == ENUM_CURRENT_SETTINGS)
{
if (!settings_handler.get_id( name, &id ) || !settings_handler.get_current_mode( id, &mode ))
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/355
July 1, 2022
[PATCH 2/5] win32u: Set generic DEVMODEW fields in NtUserEnumDisplaySettings.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/win32u/sysparams.c | 27 +++++++++++++++------------
dlls/wineandroid.drv/init.c | 8 --------
dlls/winemac.drv/display.c | 9 ---------
dlls/winex11.drv/display.c | 25 ++++++++-----------------
4 files changed, 23 insertions(+), 46 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index 2b1ac6fb707..c99f0d39ac2 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -1899,14 +1899,14 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
/***********************************************************************
* NtUserEnumDisplaySettings (win32u.@)
*/
-BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD mode,
- DEVMODEW *dev_mode, DWORD flags )
+BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVMODEW *devmode, DWORD flags )
{
+ static const WCHAR wine_display_driverW[] = {'W','i','n','e',' ','D','i','s','p','l','a','y',' ','D','r','i','v','e','r',0};
WCHAR device_name[CCHDEVICENAME];
struct adapter *adapter;
BOOL ret;
- TRACE( "%s %#x %p %#x\n", debugstr_us(device), mode, dev_mode, flags );
+ TRACE( "device %s, index %#x, devmode %p, flags %#x\n", debugstr_us(device), index, devmode, flags );
if (!lock_display_devices()) return FALSE;
if ((adapter = find_adapter( device ))) lstrcpyW( device_name, adapter->dev.device_name );
@@ -1917,15 +1917,18 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD mode,
return FALSE;
}
- ret = user_driver->pEnumDisplaySettingsEx( device_name, mode, dev_mode, flags );
- if (ret)
- TRACE( "device:%s mode index:%#x position:(%d,%d) resolution:%ux%u frequency:%uHz "
- "depth:%ubits orientation:%#x.\n", debugstr_w(device_name), mode,
- dev_mode->dmPosition.x, dev_mode->dmPosition.y, dev_mode->dmPelsWidth,
- dev_mode->dmPelsHeight, dev_mode->dmDisplayFrequency, dev_mode->dmBitsPerPel,
- dev_mode->dmDisplayOrientation );
- else
- WARN( "Failed to query %s display settings.\n", wine_dbgstr_w(device_name) );
+ lstrcpynW( devmode->dmDeviceName, wine_display_driverW, ARRAY_SIZE(devmode->dmDeviceName) );
+ devmode->dmSpecVersion = DM_SPECVERSION;
+ devmode->dmDriverVersion = DM_SPECVERSION;
+ devmode->dmSize = offsetof(DEVMODEW, dmICMMethod);
+ memset( &devmode->dmDriverExtra, 0, devmode->dmSize - offsetof(DEVMODEW, dmDriverExtra) );
+
+ ret = user_driver->pEnumDisplaySettingsEx( device_name, index, devmode, flags );
+
+ if (!ret) WARN( "Failed to query %s display settings.\n", debugstr_w(device_name) );
+ else TRACE( "position %dx%d, resolution %ux%u, frequency %u, depth %u, orientation %#x.\n",
+ devmode->dmPosition.x, devmode->dmPosition.y, devmode->dmPelsWidth, devmode->dmPelsHeight,
+ devmode->dmDisplayFrequency, devmode->dmBitsPerPel, devmode->dmDisplayOrientation );
return ret;
}
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index 5d1c81a77bf..e2cebb974c3 100644
--- a/dlls/wineandroid.drv/init.c
+++ b/dlls/wineandroid.drv/init.c
@@ -303,14 +303,6 @@ BOOL ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag
*/
BOOL ANDROID_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags )
{
- static const WCHAR dev_name[CCHDEVICENAME] =
- { 'W','i','n','e',' ','A','n','d','r','o','i','d',' ','d','r','i','v','e','r',0 };
-
- devmode->dmSize = offsetof( DEVMODEW, dmICMMethod );
- devmode->dmSpecVersion = DM_SPECVERSION;
- devmode->dmDriverVersion = DM_SPECVERSION;
- memcpy( devmode->dmDeviceName, dev_name, sizeof(dev_name) );
- devmode->dmDriverExtra = 0;
devmode->u2.dmDisplayFlags = 0;
devmode->dmDisplayFrequency = 0;
devmode->u1.s2.dmPosition.x = 0;
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c
index 0507acae1a9..191dc1f789b 100644
--- a/dlls/winemac.drv/display.c
+++ b/dlls/winemac.drv/display.c
@@ -1044,8 +1044,6 @@ better:
*/
BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, DEVMODEW *devmode, DWORD flags)
{
- static const WCHAR dev_name[CCHDEVICENAME] =
- { 'W','i','n','e',' ','M','a','c',' ','d','r','i','v','e','r',0 };
struct macdrv_display *displays = NULL;
int num_displays;
CGDisplayModeRef display_mode;
@@ -1058,13 +1056,6 @@ BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, DEVMODEW *devmode
init_original_display_mode();
- memcpy(devmode->dmDeviceName, dev_name, sizeof(dev_name));
- devmode->dmSpecVersion = DM_SPECVERSION;
- devmode->dmDriverVersion = DM_SPECVERSION;
- devmode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod);
- devmode->dmDriverExtra = 0;
- memset(&devmode->dmFields, 0, devmode->dmSize - FIELD_OFFSET(DEVMODEW, dmFields));
-
if (mode == ENUM_REGISTRY_SETTINGS)
{
TRACE("mode %d (registry) -- getting default mode\n", mode);
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 31f73898897..740e018247b 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -464,9 +464,7 @@ static DWORD get_display_depth(ULONG_PTR display_id)
*/
BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags)
{
- static const WCHAR dev_name[CCHDEVICENAME] =
- { 'W','i','n','e',' ','X','1','1',' ','d','r','i','v','e','r',0 };
- DEVMODEW *modes;
+ DEVMODEW *modes, mode;
UINT mode_count;
ULONG_PTR id;
@@ -477,21 +475,20 @@ BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DW
ERR("Failed to get %s registry display settings.\n", wine_dbgstr_w(name));
return FALSE;
}
- goto done;
+ return TRUE;
}
if (n == ENUM_CURRENT_SETTINGS)
{
- if (!settings_handler.get_id(name, &id) || !settings_handler.get_current_mode(id, devmode))
+ if (!settings_handler.get_id( name, &id ) || !settings_handler.get_current_mode( id, &mode ))
{
ERR("Failed to get %s current display settings.\n", wine_dbgstr_w(name));
return FALSE;
}
- if (!is_detached_mode(devmode))
- devmode->dmBitsPerPel = get_display_depth(id);
-
- goto done;
+ memcpy( &devmode->dmFields, &mode.dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) );
+ if (!is_detached_mode( devmode )) devmode->dmBitsPerPel = get_display_depth( id );
+ return TRUE;
}
pthread_mutex_lock( &settings_mutex );
@@ -522,16 +519,10 @@ BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DW
return FALSE;
}
- memcpy(devmode, (BYTE *)cached_modes + (sizeof(*cached_modes) + cached_modes[0].dmDriverExtra) * n, sizeof(*devmode));
+ mode = *(DEVMODEW *)((BYTE *)cached_modes + (sizeof(*cached_modes) + cached_modes[0].dmDriverExtra) * n);
pthread_mutex_unlock( &settings_mutex );
-done:
- /* Set generic fields */
- devmode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod);
- devmode->dmDriverExtra = 0;
- devmode->dmSpecVersion = DM_SPECVERSION;
- devmode->dmDriverVersion = DM_SPECVERSION;
- lstrcpyW(devmode->dmDeviceName, dev_name);
+ memcpy( &devmode->dmFields, &mode.dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) );
return TRUE;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/355
July 1, 2022
[PATCH 1/5] win32u: Move default UpdateDisplayDevices implementation out of nulldrv.
by Rémi Bernon
From: Rémi Bernon <rbernon(a)codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/win32u/driver.c | 10 ++---
dlls/win32u/sysparams.c | 74 ++++++++++++-------------------------
dlls/wineandroid.drv/init.c | 12 +++++-
dlls/winemac.drv/display.c | 8 ++--
dlls/winemac.drv/macdrv.h | 2 +-
dlls/winex11.drv/display.c | 9 ++---
dlls/winex11.drv/x11drv.h | 2 +-
include/wine/gdi_driver.h | 2 +-
8 files changed, 48 insertions(+), 71 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c
index 4a853b516f4..baa0143be61 100644
--- a/dlls/win32u/driver.c
+++ b/dlls/win32u/driver.c
@@ -764,10 +764,9 @@ static BOOL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW m
return FALSE;
}
-static void nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manager,
- BOOL force, void *param )
+static BOOL nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manager, BOOL force, void *param )
{
- manager->add_monitor( NULL, param ); /* use virtual monitor */
+ return FALSE;
}
static BOOL nulldrv_CreateDesktopWindow( HWND hwnd )
@@ -1112,10 +1111,9 @@ static void loaderdrv_UpdateClipboard(void)
load_driver()->pUpdateClipboard();
}
-static void loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager *manager,
- BOOL force, void *param )
+static BOOL loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager *manager, BOOL force, void *param )
{
- load_driver()->pUpdateDisplayDevices( manager, force, param );
+ return load_driver()->pUpdateDisplayDevices( manager, force, param );
}
static BOOL loaderdrv_CreateDesktopWindow( HWND hwnd )
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index a5a69a84bd9..2b1ac6fb707 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -192,8 +192,6 @@ static const WCHAR guid_devinterface_monitorW[] =
{'{','E','6','F','0','7','B','5','F','-','E','E','9','7','-','4','A','9','0','-',
'B','0','7','6','-','3','3','F','5','7','B','F','4','E','A','A','7','}',0};
-#define NULLDRV_DEFAULT_HMONITOR ((HMONITOR)(UINT_PTR)(0x10000 + 1))
-
/* Cached display device information */
struct display_device
{
@@ -233,17 +231,6 @@ static pthread_mutex_t display_lock = PTHREAD_MUTEX_INITIALIZER;
BOOL enable_thunk_lock = FALSE;
-static struct monitor virtual_monitor =
-{
- .handle = NULLDRV_DEFAULT_HMONITOR,
- .flags = MONITORINFOF_PRIMARY,
- .rc_monitor.right = 1024,
- .rc_monitor.bottom = 768,
- .rc_work.right = 1024,
- .rc_work.bottom = 768,
- .dev.state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED,
-};
-
/* the various registry keys that are used to store parameters */
enum parameter_key
{
@@ -804,7 +791,6 @@ struct device_manager_ctx
WCHAR gpu_guid[64];
LUID gpu_luid;
HKEY adapter_key;
- BOOL virtual_monitor;
};
static void link_device( const WCHAR *instance, const WCHAR *class )
@@ -1009,13 +995,6 @@ static void add_adapter( const struct gdi_adapter *adapter, void *param )
TRACE( "\n" );
- if (!ctx->gpu_count)
- {
- static const struct gdi_gpu default_gpu;
- TRACE( "adding default fake GPU\n" );
- add_gpu( &default_gpu, ctx );
- }
-
if (ctx->adapter_key)
{
NtClose( ctx->adapter_key );
@@ -1078,26 +1057,9 @@ static void add_monitor( const struct gdi_monitor *monitor, void *param )
static const WCHAR default_monitorW[] =
{'M','O','N','I','T','O','R','\\','D','e','f','a','u','l','t','_','M','o','n','i','t','o','r',0,0};
- if (!monitor)
- {
- ctx->virtual_monitor = TRUE;
- return;
- }
-
TRACE( "%s %s %s\n", debugstr_w(monitor->name), wine_dbgstr_rect(&monitor->rc_monitor),
wine_dbgstr_rect(&monitor->rc_work) );
- if (!ctx->adapter_count)
- {
- static const struct gdi_adapter default_adapter =
- {
- .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE |
- DISPLAY_DEVICE_VGA_COMPATIBLE,
- };
- TRACE( "adding default fake adapter\n" );
- add_adapter( &default_adapter, ctx );
- }
-
monitor_index = ctx->monitor_count++;
output_index = ctx->output_count++;
@@ -1224,12 +1186,6 @@ static void clear_display_devices(void)
struct adapter *adapter;
struct monitor *monitor;
- if (list_head( &monitors ) == &virtual_monitor.entry)
- {
- list_init( &monitors );
- return;
- }
-
while (!list_empty( &monitors ))
{
monitor = LIST_ENTRY( list_head( &monitors ), struct monitor, entry );
@@ -1323,12 +1279,6 @@ static BOOL update_display_cache(void)
user_driver->pUpdateDisplayDevices( &device_manager, FALSE, &ctx );
release_display_manager_ctx( &ctx );
- if (ctx.virtual_monitor)
- {
- clear_display_devices();
- list_add_tail( &monitors, &virtual_monitor.entry );
- return TRUE;
- }
if (update_display_cache_from_registry()) return TRUE;
if (ctx.gpu_count)
@@ -1337,7 +1287,29 @@ static BOOL update_display_cache(void)
return FALSE;
}
- user_driver->pUpdateDisplayDevices( &device_manager, TRUE, &ctx );
+ if (!user_driver->pUpdateDisplayDevices( &device_manager, TRUE, &ctx ))
+ {
+ static const struct gdi_gpu gpu;
+ static const struct gdi_adapter adapter =
+ {
+ .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE,
+ };
+ struct gdi_monitor monitor =
+ {
+ .state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED,
+ };
+ DEVMODEW mode = {.dmPelsWidth = 1024, .dmPelsHeight = 768};
+
+ add_gpu( &gpu, &ctx );
+ add_adapter( &adapter, &ctx );
+
+ monitor.rc_monitor.right = mode.dmPelsWidth;
+ monitor.rc_monitor.bottom = mode.dmPelsHeight;
+ monitor.rc_work.right = mode.dmPelsWidth;
+ monitor.rc_work.bottom = mode.dmPelsHeight;
+
+ add_monitor( &monitor, &ctx );
+ }
release_display_manager_ctx( &ctx );
if (!update_display_cache_from_registry())
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index 170ccb064a7..5d1c81a77bf 100644
--- a/dlls/wineandroid.drv/init.c
+++ b/dlls/wineandroid.drv/init.c
@@ -273,20 +273,28 @@ LONG ANDROID_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
/***********************************************************************
* ANDROID_UpdateDisplayDevices
*/
-void ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
- BOOL force, void *param )
+BOOL ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param )
{
if (force || force_display_devices_refresh)
{
+ static const struct gdi_gpu gpu;
+ static const struct gdi_adapter adapter =
+ {
+ .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE,
+ };
struct gdi_monitor gdi_monitor =
{
.rc_monitor = virtual_screen_rect,
.rc_work = monitor_rc_work,
.state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED,
};
+ device_manager->add_gpu( &gpu, param );
+ device_manager->add_adapter( &adapter, param );
device_manager->add_monitor( &gdi_monitor, param );
force_display_devices_refresh = FALSE;
}
+
+ return TRUE;
}
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c
index 19b9a9cdd9d..0507acae1a9 100644
--- a/dlls/winemac.drv/display.c
+++ b/dlls/winemac.drv/display.c
@@ -1457,8 +1457,7 @@ void macdrv_displays_changed(const macdrv_event *event)
static BOOL force_display_devices_refresh;
-void macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
- BOOL force, void *param )
+BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param )
{
struct macdrv_adapter *adapters, *adapter;
struct macdrv_monitor *monitors, *monitor;
@@ -1466,14 +1465,14 @@ void macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
INT gpu_count, adapter_count, monitor_count;
DWORD len;
- if (!force && !force_display_devices_refresh) return;
+ if (!force && !force_display_devices_refresh) return TRUE;
force_display_devices_refresh = FALSE;
/* Initialize GPUs */
if (macdrv_get_gpus(&gpus, &gpu_count))
{
ERR("could not get GPUs\n");
- return;
+ return FALSE;
}
TRACE("GPU count: %d\n", gpu_count);
@@ -1528,6 +1527,7 @@ void macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
}
macdrv_free_gpus(gpus);
+ return TRUE;
}
/***********************************************************************
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index 7c0f7127883..72bd1cefaeb 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -131,7 +131,7 @@ extern LONG macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode,
extern BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode,
LPDEVMODEW devmode, DWORD flags) DECLSPEC_HIDDEN;
extern LRESULT macdrv_ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) DECLSPEC_HIDDEN;
-extern void macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
+extern BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
BOOL force, void *param ) DECLSPEC_HIDDEN;
extern BOOL macdrv_GetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp) DECLSPEC_HIDDEN;
extern BOOL macdrv_SetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp) DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index dec9d0afba8..31f73898897 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -1198,8 +1198,7 @@ void X11DRV_DisplayDevices_Update(BOOL send_display_change)
static BOOL force_display_devices_refresh;
-void X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
- BOOL force, void *param )
+BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param )
{
struct x11drv_display_device_handler *handler;
struct gdi_adapter *adapters;
@@ -1208,15 +1207,14 @@ void X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
INT gpu_count, adapter_count, monitor_count;
INT gpu, adapter, monitor;
- if (!force && !force_display_devices_refresh) return;
+ if (!force && !force_display_devices_refresh) return TRUE;
force_display_devices_refresh = FALSE;
handler = is_virtual_desktop() ? &desktop_handler : &host_handler;
TRACE("via %s\n", wine_dbgstr_a(handler->name));
/* Initialize GPUs */
- if (!handler->get_gpus(&gpus, &gpu_count))
- return;
+ if (!handler->get_gpus( &gpus, &gpu_count )) return FALSE;
TRACE("GPU count: %d\n", gpu_count);
for (gpu = 0; gpu < gpu_count; gpu++)
@@ -1248,6 +1246,7 @@ void X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
}
handler->free_gpus(gpus);
+ return TRUE;
}
void X11DRV_DisplayDevices_Init(BOOL force)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 003604cd97d..cd0d33f59bf 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -217,7 +217,7 @@ extern LONG X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW devmode,
HWND hwnd, DWORD flags, LPVOID lpvoid ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode,
DWORD flags ) DECLSPEC_HIDDEN;
-extern void X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
+extern BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
BOOL force, void *param ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_CreateDesktopWindow( HWND hwnd ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_CreateWindow( HWND hwnd ) DECLSPEC_HIDDEN;
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index 998aa3ed3e9..465934d41c2 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -296,7 +296,7 @@ struct user_driver_funcs
/* display modes */
LONG (*pChangeDisplaySettingsEx)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
BOOL (*pEnumDisplaySettingsEx)(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
- void (*pUpdateDisplayDevices)(const struct gdi_device_manager *,BOOL,void*);
+ BOOL (*pUpdateDisplayDevices)(const struct gdi_device_manager *,BOOL,void*);
/* windowing functions */
BOOL (*pCreateDesktopWindow)(HWND);
BOOL (*pCreateWindow)(HWND);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/355
July 1, 2022