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
September 2016
- 41 participants
- 277 messages
RE: [PATCH] make_unicode: Change handling of Turkish i to match Windows
by Daniel Lehman
>> Since you are modifying the win32 side of the unicode tables please add
>> the correponding tests for LCMapString() to dlls/kernel32/tests/locale.c.
>> It's quite possible that msvcrt doesn't use a win32 backend and has its
>> own locale support.
>>
>I could imagine LCMAP_LINGUISTIC_CASING making a difference here.
Windows' LCMapString behaves differently but only if LCMAP_LINGUISTIC_CASING is specified. if that flag is not specified, it works just like tolower/toupper
Wine's LCMapString currently calls tolowerW and doesn't support the LCMAP_LINGUISTIC_CASING flag. But the current table contains the conversions the LCMAP_LINGUISTIC_CASING flag needs if added in the future
Should I change the fix to something like one of the following? Or just add tests with todo_wine for now?
I could have msvcrt tolower call LCMapString(LOWERCASE)? Then:
- LCMapString(LOWERCASE|CASING) calls the current tolowerW with the conversion
- LCMapString(LOWER) calls tolowerW except on certain characters (like Turkish i)
- msvcrt tolower variants call LCMapString(LOWER)
Or alternatively could there be new tolowerW function that doesn't do the conversion (maybe from a second table make_unicode produces)? Then:
- LCMapString(LOWERCASE|CASING) call the current tolowerW with the conversion
- LCMapString(LOWERCASE) and msvcrt tolower variants call new tolowerW without the conversion
This patch was for the Turkish I but I have 1 other character with the same issue and I'm sure there are more
Thanks
daniel
Sept. 30, 2016
Re: [PATCH] make_unicode: Change handling of Turkish i to match Windows
by Henri Verbeet
On 30 September 2016 at 14:23, Dmitry Timoshkov <dmitry(a)baikal.ru> wrote:
> Daniel Lehman <dlehman(a)esri.com> wrote:
>
>> Windows does not lowercase the Turkish dotted i (0x130) as 'i' (0x69)
>> It also does not uppercase the small dotless I (0x131) to 'I' (0x49)
>>
>> Wine does the conversion for both, but Windows leaves them as-is
>>
>> the change here is to make Wine mimic Windows for the Turkish i
>
> Since you are modifying the win32 side of the unicode tables please add
> the correponding tests for LCMapString() to dlls/kernel32/tests/locale.c.
> It's quite possible that msvcrt doesn't use a win32 backend and has its
> own locale support.
>
I could imagine LCMAP_LINGUISTIC_CASING making a difference here.
Sept. 30, 2016
Re: [PATCH] make_unicode: Change handling of Turkish i to match Windows
by Dmitry Timoshkov
Daniel Lehman <dlehman(a)esri.com> wrote:
> Windows does not lowercase the Turkish dotted i (0x130) as 'i' (0x69)
> It also does not uppercase the small dotless I (0x131) to 'I' (0x49)
>
> Wine does the conversion for both, but Windows leaves them as-is
>
> the change here is to make Wine mimic Windows for the Turkish i
Since you are modifying the win32 side of the unicode tables please add
the correponding tests for LCMapString() to dlls/kernel32/tests/locale.c.
It's quite possible that msvcrt doesn't use a win32 backend and has its
own locale support.
--
Dmitry.
Sept. 30, 2016
Re: [PATCH v6] winebus.sys: Watch for hid raw device addition and removal
by Aric Stewart
Thanks for the review, just 1 comment
On 9/29/16 2:44 PM, Sebastian Lackner wrote:
> On 29.09.2016 20:48, Aric Stewart wrote:
>> v2: Correct poll timeout
>> Style changes
>> v3: vtable style instead of a callback
>> v4: Suggestions from Sebastian Lackner
>> v5: Fixing handling of other native in the compare function
>> v6: Tweaks suggested by Sebastian Lackner
>>
>> Includes an implementation of a common bus_remove_hid_device
>>
>> Signed-off-by: Aric Stewart <aric(a)codeweavers.com>
>> ---
>> dlls/winebus.sys/bus.h | 13 +++++-
>> dlls/winebus.sys/bus_udev.c | 106 +++++++++++++++++++++++++++++++++++++++++++-
>> dlls/winebus.sys/main.c | 64 +++++++++++++++++++++-----
>> 3 files changed, 169 insertions(+), 14 deletions(-)
>>
>>
>>
>> v6-0001-winebus.sys-Watch-for-hid-raw-device-addition-and-r.txt
>>
>>
>> diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
.
.
.
>> -DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, void *native, WORD vid,
>> +DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid,
>> WORD pid, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
>> - const GUID *class)
>> + const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size)
>> {
>> - static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0};
>> + static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p','#','%','x',0};
>> struct device_extension *ext;
>> struct pnp_device *pnp_dev;
>> DEVICE_OBJECT *device;
>> @@ -169,16 +171,18 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
>> WCHAR dev_name[256];
>> HDEVINFO devinfo;
>> NTSTATUS status;
>> + DWORD length;
>>
>> - TRACE("(%p, %s, %p, %04x, %04x, %u, %u, %s, %u, %s)\n", driver, debugstr_w(busidW), native,
>> + TRACE("(%p, %s, %04x, %04x, %u, %u, %s, %u, %s)\n", driver, debugstr_w(busidW),
>> vid, pid, version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class));
>
> You forgot to add the vtbl and platform_data_size parameters to the TRACE.
>
>>
>> if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev))))
>> return NULL;
>>
>> - sprintfW(dev_name, device_name_fmtW, busidW, native);
>> + sprintfW(dev_name, device_name_fmtW, busidW, pnp_dev, GetTickCount());
>
> Do you think the memory pointer (pnp_dev) alone is not sufficient? If not, it was already
> a problem before because "native" is also just a memory address for UDEV.
This was mostly because I know that when a memory address is freed wine can give out the same address quite easily. I was unsure how robust our device deletion creation process was for identically named devices so I wanted to add just that one more element of uniqueness so as to avoid this possible problem.
I am sure just using native would exhibit the same potential issues.
-aric
>
>> RtlInitUnicodeString(&nameW, dev_name);
>> - status = IoCreateDevice(driver, sizeof(*ext), &nameW, 0, 0, FALSE, &device);
>> + length = FIELD_OFFSET(struct device_extension, platform_private[platform_data_size]);
>> + status = IoCreateDevice(driver, length, &nameW, 0, 0, FALSE, &device);
>> if (status)
>> {
>> FIXME("failed to create device error %x\n", status);
>> @@ -190,7 +194,6 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
>>
>> /* fill out device_extension struct */
>> ext = (struct device_extension *)device->DeviceExtension;
>> - ext->native = native;
>> ext->vid = vid;
>> ext->pid = pid;
>> ext->uid = uid;
>> @@ -199,6 +202,8 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
>> ext->is_gamepad = is_gamepad;
>> ext->serial = strdupW(serialW);
>> ext->busid = busidW;
>> + ext->pnp_device = pnp_dev;
>> + ext->vtbl = vtbl;
>>
>> /* add to list of pnp devices */
>> pnp_dev->device = device;
>> @@ -226,7 +231,6 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
>> else
>> ERR("failed to get ClassDevs: %x\n", GetLastError());
>>
>> - IoInvalidateDeviceRelations(device, BusRelations);
>> return device;
>> }
>>
>> @@ -265,6 +269,46 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp)
>> return status;
>> }
>>
>> +void *get_platform_private(DEVICE_OBJECT *device)
>> +{
>> + struct device_extension *ext = (struct device_extension*)device->DeviceExtension;
>> + return ext->platform_private;
>> +}
>> +
>> +DEVICE_OBJECT *find_hid_device(const platform_vtbl* vtbl, void *device)
>> +{
>> + struct pnp_device *dev, *ptr;
>> + DEVICE_OBJECT *ret = NULL;
>> +
>> + EnterCriticalSection(&device_list_cs);
>> + LIST_FOR_EACH_ENTRY_SAFE(dev, ptr, &pnp_devset, struct pnp_device, entry)
>
> You do no longer need the _SAFE enumeration here because the deletion is done separately.
>
>> + {
>> + struct device_extension *ext = (struct device_extension*)dev->device->DeviceExtension;
>> + if ((vtbl == ext->vtbl) &&
>> + (ext->vtbl->compare_platform_device(dev->device, device) == 0))
>> + {
>> + TRACE("Found as device %p\n", dev->device);
>> + ret = dev->device;
>> + break;
>> + }
>> + }
>> + LeaveCriticalSection(&device_list_cs);
>> + return ret;
>> +}
>> +
>> +void bus_remove_hid_device(DEVICE_OBJECT *device)
>> +{
>> + struct device_extension *ext = (struct device_extension*)device->DeviceExtension;
>> + TRACE("Remove hid device %p\n", device);
>> + EnterCriticalSection(&device_list_cs);
>> + list_remove(&ext->pnp_device->entry);
>> + LeaveCriticalSection(&device_list_cs);
>> + IoInvalidateDeviceRelations(device, RemovalRelations);
>> + HeapFree(GetProcessHeap(), 0, ext->serial);
>> + HeapFree(GetProcessHeap(), 0, ext->pnp_device);
>> + IoDeleteDevice(device);
>> +}
>> +
>> NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
>> {
>> NTSTATUS status = irp->IoStatus.u.Status;
>>
>>
>>
>
Sept. 30, 2016
Some code ambiguity in tab control code.
by John Found
Hi.
Trying without success to show tooltips for a tabcontrol, I found the following problems in the source code. Notice, that my skills in C++ are poor, so it is very possible the following is a false alarm.
I am quote https://github.com/wine-mirror/wine/blob/master/dlls/comctl32/tab.c (hope it is the proper source code)
This seems to be a bug: WM_LBUTTONDOWN is relayed in the WM_MOUSEMOVE handler. But WM_LBUTTONDOWN will always hide the tooltip. WM_MOUSEMOVE instead will set the timer for showing the tooltip.
> static LRESULT
> TAB_MouseMove (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
> {
> int redrawLeave;
> int redrawEnter;
>
> if (infoPtr->hwndToolTip)
> TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
> WM_LBUTTONDOWN, wParam, lParam);
>
> /* Determine which tab to highlight. Redraw tabs which change highlight
> ** status. */
> TAB_RecalcHotTrack(infoPtr, &lParam, &redrawLeave, &redrawEnter);
>
> hottrack_refresh (infoPtr, redrawLeave);
> hottrack_refresh (infoPtr, redrawEnter);
>
> return 0;
> }
The WM_LBUTTONDOWN is relayed twice? Why? It is not exactly a bug, but sub-optimal.
> static LRESULT
> TAB_LButtonDown (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
> {
> POINT pt;
> INT newItem;
> UINT dummy;
>
> if (infoPtr->hwndToolTip)
> TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
> WM_LBUTTONDOWN, wParam, lParam);
>
> if (!(infoPtr->dwStyle & TCS_FOCUSNEVER)) {
> SetFocus (infoPtr->hwnd);
> }
>
> if (infoPtr->hwndToolTip)
> TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
> WM_LBUTTONDOWN, wParam, lParam);
>
--
http://fresh.flatassembler.net
http://asm32.info
John Found <johnfound(a)asm32.info>
Sept. 29, 2016
Re: [PATCH v6] winebus.sys: Watch for hid raw device addition and removal
by Sebastian Lackner
On 29.09.2016 20:48, Aric Stewart wrote:
> v2: Correct poll timeout
> Style changes
> v3: vtable style instead of a callback
> v4: Suggestions from Sebastian Lackner
> v5: Fixing handling of other native in the compare function
> v6: Tweaks suggested by Sebastian Lackner
>
> Includes an implementation of a common bus_remove_hid_device
>
> Signed-off-by: Aric Stewart <aric(a)codeweavers.com>
> ---
> dlls/winebus.sys/bus.h | 13 +++++-
> dlls/winebus.sys/bus_udev.c | 106 +++++++++++++++++++++++++++++++++++++++++++-
> dlls/winebus.sys/main.c | 64 +++++++++++++++++++++-----
> 3 files changed, 169 insertions(+), 14 deletions(-)
>
>
>
> v6-0001-winebus.sys-Watch-for-hid-raw-device-addition-and-r.txt
>
>
> diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
> index dcb50f2..719d8fd 100644
> --- a/dlls/winebus.sys/bus.h
> +++ b/dlls/winebus.sys/bus.h
> @@ -19,8 +19,17 @@
> /* Busses */
> NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path) DECLSPEC_HIDDEN;
>
> +/* Native device function table */
> +typedef struct {
> + int(*compare_platform_device)(DEVICE_OBJECT *device, void *platform_dev);
> +} platform_vtbl;
> +
> +void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
> +DEVICE_OBJECT *find_hid_device(const platform_vtbl* vtbl, void *device) DECLSPEC_HIDDEN;
> +
> /* HID Plug and Play Bus */
> NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
> -DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, void *native, WORD vid,
> +DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid,
> WORD pid, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
> - const GUID *class) DECLSPEC_HIDDEN;
> + const GUID *class, const platform_vtbl* vtbl, DWORD platform_data_size) DECLSPEC_HIDDEN;
> +void bus_remove_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
> diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
> index 1525861..b7995bc 100644
> --- a/dlls/winebus.sys/bus_udev.c
> +++ b/dlls/winebus.sys/bus_udev.c
> @@ -26,6 +26,11 @@
> #ifdef HAVE_UNISTD_H
> # include <unistd.h>
> #endif
> +
> +#ifdef HAVE_SYS_POLL_H
> +# include <sys/poll.h>
> +#endif
> +
> #ifdef HAVE_LIBUDEV_H
> # include <libudev.h>
> #endif
> @@ -55,6 +60,10 @@ static const WCHAR hidraw_busidW[] = {'H','I','D','R','A','W',0};
> #include "initguid.h"
> DEFINE_GUID(GUID_DEVCLASS_HIDRAW, 0x3def44ad,0x242e,0x46e5,0x82,0x6d,0x70,0x72,0x13,0xf3,0xaa,0x81);
>
> +struct platform_private {
> + struct udev_device *udev_device;
> +};
> +
> static DWORD get_sysattr_dword(struct udev_device *dev, const char *sysattr, int base)
> {
> const char *attr = udev_device_get_sysattr_value(dev, sysattr);
> @@ -82,6 +91,17 @@ static WCHAR *get_sysattr_string(struct udev_device *dev, const char *sysattr)
> return dst;
> }
>
> +static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
> +{
> + struct udev_device *dev1 = ((struct platform_private*)get_platform_private(device))->udev_device;
There is a whitespace issue in the line above. Also, I would suggest to use a wrapper like for COM
interfaces to avoid having this conversion at multiple places. For example:
static inline platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *device) { ... }
> + struct udev_device *dev2 = platform_dev;
> + return (strcmp(udev_device_get_syspath(dev1), udev_device_get_syspath(dev2)));
> +}
> +
> +static const platform_vtbl hidraw_vtbl = {
> + compare_platform_device,
> +};
> +
> static void try_add_device(struct udev_device *dev)
> {
> DWORD vid = 0, pid = 0, version = 0;
> @@ -117,12 +137,16 @@ static void try_add_device(struct udev_device *dev)
> subsystem = udev_device_get_subsystem(dev);
> if (strcmp(subsystem, "hidraw") == 0)
> {
> - device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, dev, vid, pid,
> - version, 0, serial, FALSE, &GUID_DEVCLASS_HIDRAW);
> + device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, vid, pid,
> + version, 0, serial, FALSE, &GUID_DEVCLASS_HIDRAW, &hidraw_vtbl, sizeof(struct platform_private));
> }
>
> if (device)
> + {
> + ((struct platform_private*)get_platform_private(device))->udev_device = dev;
> udev_device_ref(dev);
udev_device_ref returns the device, so you could also do the assignment and incref in one line if you prefer. ;)
Not really an issue though.
> + IoInvalidateDeviceRelations(device, BusRelations);
> + }
> else
> WARN("Ignoring device %s with subsystem %s\n", debugstr_a(devnode), subsystem);
>
> @@ -164,6 +188,77 @@ static void build_initial_deviceset(void)
> udev_enumerate_unref(enumerate);
> }
>
> +/* This is our main even loop for reading devices */
> +static DWORD CALLBACK deviceloop_thread(void *args)
> +{
> + struct pollfd plfds[1];
> + struct udev_monitor *monitor = NULL;
> +
> + monitor = udev_monitor_new_from_netlink(udev_context, "udev");
> + if (!monitor)
> + {
> + WARN("Unable to get udev monitor, device insertion and removal cannot be tracked\n");
> + goto exit;
> + }
> + if (udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw", NULL) < 0)
> + {
> + WARN("Failed to add 'hidraw' subsystem to monitor\n");
> + goto exit;
> + }
> +
> + if (udev_monitor_enable_receiving(monitor) < 0)
> + {
> + WARN("Failed to start monitoring\n");
> + goto exit;
> + }
> +
> + plfds[0].fd = udev_monitor_get_fd(monitor);
> + plfds[0].events = POLLIN;
> + if (plfds[0].fd < 0)
> + {
> + WARN("Failed to get monitor fd\n");
> + goto exit;
> + }
> + /* Run the event loop */
> + while (1)
> + {
> + struct udev_device *dev;
> + const char* action;
> +
> + if (poll(plfds, 1, -1) <= 0) continue;
> +
> + TRACE("udev reports device changes\n");
> + dev = udev_monitor_receive_device(monitor);
> + if (!dev)
> + {
> + FIXME("Failed to get device that has changed\n");
> + continue;
> + }
> + action = udev_device_get_action(dev);
> + if (!action)
> + WARN("No action recieved\n");
> + else if (strcmp(action, "add") == 0)
> + try_add_device(dev);
> + else if (strcmp(action, "remove") == 0)
> + {
> + DEVICE_OBJECT *device = find_hid_device(&hidraw_vtbl, dev);
> + if (device)
> + {
> + struct udev_device *original = ((struct platform_private*)get_platform_private(device))->udev_device;
> + bus_remove_hid_device(device);
> + udev_device_unref(original);
> + }
> + }
> + udev_device_unref(dev);
> + }
> +
> +exit:
> + TRACE("Monitor thread exiting\n");
> + if (monitor)
> + udev_monitor_unref(monitor);
> + return 1;
> +}
> +
> NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_path)
> {
> TRACE("(%p, %s)\n", driver, debugstr_w(registry_path->Buffer));
> @@ -178,6 +273,13 @@ NTSTATUS WINAPI udev_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry
> driver->MajorFunction[IRP_MJ_PNP] = common_pnp_dispatch;
>
> build_initial_deviceset();
> +
> + if (!CreateThread(NULL, 0, deviceloop_thread, NULL, 0, NULL))
> + {
> + ERR("Unable to create udev device thread\n");
> + return STATUS_UNSUCCESSFUL;
Wouldn't it make sense to proceed anyway? The initial device set could still
be working properly (and, you are not cleaning up already added drivers here).
> + }
> +
> return STATUS_SUCCESS;
> }
>
> diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
> index 1364eab..1cb8031 100644
> --- a/dlls/winebus.sys/main.c
> +++ b/dlls/winebus.sys/main.c
> @@ -47,13 +47,15 @@ struct pnp_device
>
> struct device_extension
> {
> - void *native; /* Must be the first member of the structure */
> -
> WORD vid, pid;
> DWORD uid, version, index;
> BOOL is_gamepad;
> WCHAR *serial;
> const WCHAR *busid; /* Expected to be a static constant */
> + struct pnp_device *pnp_device;
> + const platform_vtbl *vtbl;
> +
> + BYTE platform_private[1];
> };
>
> static CRITICAL_SECTION device_list_cs;
> @@ -157,11 +159,11 @@ static WCHAR *get_compatible_ids(DEVICE_OBJECT *device)
> return dst;
> }
>
> -DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, void *native, WORD vid,
> +DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid,
> WORD pid, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
> - const GUID *class)
> + const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size)
> {
> - static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0};
> + static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p','#','%','x',0};
> struct device_extension *ext;
> struct pnp_device *pnp_dev;
> DEVICE_OBJECT *device;
> @@ -169,16 +171,18 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
> WCHAR dev_name[256];
> HDEVINFO devinfo;
> NTSTATUS status;
> + DWORD length;
>
> - TRACE("(%p, %s, %p, %04x, %04x, %u, %u, %s, %u, %s)\n", driver, debugstr_w(busidW), native,
> + TRACE("(%p, %s, %04x, %04x, %u, %u, %s, %u, %s)\n", driver, debugstr_w(busidW),
> vid, pid, version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class));
You forgot to add the vtbl and platform_data_size parameters to the TRACE.
>
> if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev))))
> return NULL;
>
> - sprintfW(dev_name, device_name_fmtW, busidW, native);
> + sprintfW(dev_name, device_name_fmtW, busidW, pnp_dev, GetTickCount());
Do you think the memory pointer (pnp_dev) alone is not sufficient? If not, it was already
a problem before because "native" is also just a memory address for UDEV.
> RtlInitUnicodeString(&nameW, dev_name);
> - status = IoCreateDevice(driver, sizeof(*ext), &nameW, 0, 0, FALSE, &device);
> + length = FIELD_OFFSET(struct device_extension, platform_private[platform_data_size]);
> + status = IoCreateDevice(driver, length, &nameW, 0, 0, FALSE, &device);
> if (status)
> {
> FIXME("failed to create device error %x\n", status);
> @@ -190,7 +194,6 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
>
> /* fill out device_extension struct */
> ext = (struct device_extension *)device->DeviceExtension;
> - ext->native = native;
> ext->vid = vid;
> ext->pid = pid;
> ext->uid = uid;
> @@ -199,6 +202,8 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
> ext->is_gamepad = is_gamepad;
> ext->serial = strdupW(serialW);
> ext->busid = busidW;
> + ext->pnp_device = pnp_dev;
> + ext->vtbl = vtbl;
>
> /* add to list of pnp devices */
> pnp_dev->device = device;
> @@ -226,7 +231,6 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
> else
> ERR("failed to get ClassDevs: %x\n", GetLastError());
>
> - IoInvalidateDeviceRelations(device, BusRelations);
> return device;
> }
>
> @@ -265,6 +269,46 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp)
> return status;
> }
>
> +void *get_platform_private(DEVICE_OBJECT *device)
> +{
> + struct device_extension *ext = (struct device_extension*)device->DeviceExtension;
> + return ext->platform_private;
> +}
> +
> +DEVICE_OBJECT *find_hid_device(const platform_vtbl* vtbl, void *device)
> +{
> + struct pnp_device *dev, *ptr;
> + DEVICE_OBJECT *ret = NULL;
> +
> + EnterCriticalSection(&device_list_cs);
> + LIST_FOR_EACH_ENTRY_SAFE(dev, ptr, &pnp_devset, struct pnp_device, entry)
You do no longer need the _SAFE enumeration here because the deletion is done separately.
> + {
> + struct device_extension *ext = (struct device_extension*)dev->device->DeviceExtension;
> + if ((vtbl == ext->vtbl) &&
> + (ext->vtbl->compare_platform_device(dev->device, device) == 0))
> + {
> + TRACE("Found as device %p\n", dev->device);
> + ret = dev->device;
> + break;
> + }
> + }
> + LeaveCriticalSection(&device_list_cs);
> + return ret;
> +}
> +
> +void bus_remove_hid_device(DEVICE_OBJECT *device)
> +{
> + struct device_extension *ext = (struct device_extension*)device->DeviceExtension;
> + TRACE("Remove hid device %p\n", device);
> + EnterCriticalSection(&device_list_cs);
> + list_remove(&ext->pnp_device->entry);
> + LeaveCriticalSection(&device_list_cs);
> + IoInvalidateDeviceRelations(device, RemovalRelations);
> + HeapFree(GetProcessHeap(), 0, ext->serial);
> + HeapFree(GetProcessHeap(), 0, ext->pnp_device);
> + IoDeleteDevice(device);
> +}
> +
> NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
> {
> NTSTATUS status = irp->IoStatus.u.Status;
>
>
>
Sept. 29, 2016
Re: uianimation: add stub dll
by Alexandre Julliard
Austin English <austinenglish(a)gmail.com> writes:
> For https://bugs.winehq.org/show_bug.cgi?id=41369
>
> --
> -Austin
> GPG: 14FB D7EA A041 937B
>
> From ddd3a6f3212f620f6f8379f295e6211f0db17129 Mon Sep 17 00:00:00 2001
> From: Austin English <austinenglish(a)gmail.com>
> Date: Thu, 22 Sep 2016 01:23:54 -0500
> Subject: [PATCH] uianimation: add stub dll
That doesn't seem very useful without the corresponding registrations.
--
Alexandre Julliard
julliard(a)winehq.org
Sept. 28, 2016
Re: shell32/tests: Move test after return
by Alexandre Julliard
André Hentschel <nerv(a)dawncrow.de> writes:
> diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
> index 1591b7b..1f5dc33 100644
> --- a/dlls/shell32/tests/shlfolder.c
> +++ b/dlls/shell32/tests/shlfolder.c
> @@ -1588,11 +1588,11 @@ static void test_FolderShortcut(void) {
> if (hr != S_OK) return;
>
> hr = IShellFolder_GetDisplayNameOf(pShellFolder, NULL, SHGDN_FORPARSING, &strret);
> - ok(hr == S_OK, "IShellFolder_GetDisplayNameOf(NULL) failed! hr = %08x\n", hr);
> if (hr != S_OK) {
> IShellFolder_Release(pShellFolder);
> return;
> }
> + ok(hr == S_OK, "IShellFolder_GetDisplayNameOf(NULL) failed! hr = %08x\n", hr);
It would be better to check for the expected error instead of disabling
the test.
--
Alexandre Julliard
julliard(a)winehq.org
Sept. 28, 2016
Re: [10/11] kernel32: Implement LCMAP_FULLWIDTH.
by Alexandre Julliard
Akihiro Sagawa <sagawa.aki(a)gmail.com> writes:
> @@ -3246,6 +3385,24 @@ INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPW
> goto done;
> }
>
> + if (flags & LCMAP_FULLWIDTH)
> + {
> + len = min(srclen, dstlen);
> + buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
> + if (!buffer)
> + {
> + SetLastError(ERROR_NOT_ENOUGH_MEMORY);
> + return 0;
> + }
> + srclen = map_to_fullwidth(src, srclen, buffer, len);
> + if (!srclen)
> + {
> + HeapFree(GetProcessHeap(), 0, buffer);
> + return 0;
> + }
> + src = buffer;
> + }
It seems to me that you should be able to do this without allocating an
intermediate buffer.
--
Alexandre Julliard
julliard(a)winehq.org
Sept. 28, 2016
Re: [PATCH 5/5] wined3d: Call glGetIntegerv() through the gl_info function pointer.
by Józef Kucia
On Tue, Sep 27, 2016 at 12:04 AM, Matteo Bruni <mbruni(a)codeweavers.com> wrote:
> Fixes a1e718ccabc7c330dd16c7face78022965b03e20.
>
> Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
> ---
> dlls/wined3d/directx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
> index 7ab68aa..05e04e8 100644
> --- a/dlls/wined3d/directx.c
> +++ b/dlls/wined3d/directx.c
> @@ -3629,7 +3629,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD
>
> if (gl_version >= MAKEDWORD_VERSION(3, 2))
> {
> - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile);
> + gl_info->gl_ops.gl.p_glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile);
> checkGLcall("Querying context profile");
> }
> if (context_profile & GL_CONTEXT_CORE_PROFILE_BIT)
FWIW, there are other places where GL functions aren't called through
gl_ops. I've got patches to fix others.
Sept. 27, 2016