winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
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
List overview
wine-commits
August 2021
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
1 participants
1051 discussions
Start a n
N
ew thread
Martin Storsjö : loader: Add support for ARM linux in the preloader.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: 29922c22765bb65352d48a3922c8fc07eebe7353 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=29922c22765bb65352d48a39…
Author: Martin Storsjö <martin(a)martin.st> Date: Tue Aug 3 23:24:12 2021 +0300 loader: Add support for ARM linux in the preloader. Since 28fe84da45bea7de56539b50eac8ebcec54342de, the main exe image must be mappable at its desired base address, which essentially requires the preloader. Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=51539
Signed-off-by: Martin Storsjö <martin(a)martin.st> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- configure | 4 +- configure.ac | 4 +- dlls/ntdll/unix/loader.c | 6 +-- loader/preloader.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 128 insertions(+), 10 deletions(-) diff --git a/configure b/configure index d3c60b4ff4c..1be0aa9d217 100755 --- a/configure +++ b/configure @@ -9473,7 +9473,7 @@ fi WINEPRELOADER_LDFLAGS="-static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7d400000" case $host_cpu in - *i[3456789]86* | x86_64 | *aarch64*) + *i[3456789]86* | x86_64 | *aarch64* | arm*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -Wl,-Ttext-segment=0x7bc00000" >&5 $as_echo_n "checking whether the compiler supports -Wl,-Ttext-segment=0x7bc00000... " >&6; } if ${ac_cv_cflags__Wl__Ttext_segment_0x7bc00000+:} false; then : @@ -18025,7 +18025,7 @@ esac case $host_os in linux*) case $host_cpu in - *i[3456789]86*|x86_64*|*aarch64*) + *i[3456789]86*|x86_64*|*aarch64*|arm*) test "$wine_binary" = wine || wine_fn_append_file CONFIGURE_TARGETS "loader/wine-preloader" WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader" ;; diff --git a/configure.ac b/configure.ac index 5d9ca31099e..69e27147088 100644 --- a/configure.ac +++ b/configure.ac @@ -940,7 +940,7 @@ case $host_os in WINEPRELOADER_LDFLAGS="-static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7d400000" case $host_cpu in - *i[[3456789]]86* | x86_64 | *aarch64*) + *i[[3456789]]86* | x86_64 | *aarch64* | arm*) WINE_TRY_CFLAGS([-Wl,-Ttext-segment=0x7bc00000], [case $host_os in freebsd* | kfreebsd*-gnu) WINELOADER_LDFLAGS="$WINELOADER_LDFLAGS -Wl,-Ttext-segment=0x60000000" ;; @@ -2161,7 +2161,7 @@ esac case $host_os in linux*) case $host_cpu in - *i[[3456789]]86*|x86_64*|*aarch64*) + *i[[3456789]]86*|x86_64*|*aarch64*|arm*) test "$wine_binary" = wine || WINE_IGNORE_FILE("loader/wine-preloader") WINELOADER_PROGRAMS="$WINELOADER_PROGRAMS $wine_binary-preloader" ;; diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 8888376f2f0..55fc73d2d06 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -2155,11 +2155,7 @@ static int pre_exec(void) int temp; check_vmsplit( &temp ); -#ifdef __i386__ - return 1; /* we have a preloader on x86 */ -#else - return 0; -#endif + return 1; /* we have a preloader on x86/arm */ } #elif defined(__linux__) && (defined(__x86_64__) || defined(__aarch64__)) diff --git a/loader/preloader.c b/loader/preloader.c index bb16ecd96a4..86308484182 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -111,7 +111,7 @@ static struct wine_preload_info preload_info[] = { -#ifdef __i386__ +#if defined(__i386__) || defined(__arm__) { (void *)0x00000000, 0x00010000 }, /* low 64k */ { (void *)0x00010000, 0x00100000 }, /* DOS area */ { (void *)0x00110000, 0x67ef0000 }, /* low memory area */ @@ -536,6 +536,125 @@ SYSCALL_NOERR( wld_geteuid, 175 /* SYS_geteuid */ ); gid_t wld_getegid(void); SYSCALL_NOERR( wld_getegid, 177 /* SYS_getegid */ ); +#elif defined(__arm__) + +void *thread_data[256]; + +/* + * The _start function is the entry and exit point of this program + * + * It calls wld_start, passing a pointer to the args it receives + * then jumps to the address wld_start returns. + */ +void _start(void); +extern char _end[]; +__ASM_GLOBAL_FUNC(_start, + "mov r0, sp\n\t" + "sub sp, sp, #144\n\t" /* allocate some space for extra aux values */ + "str r0, [sp]\n\t" /* orig stack pointer */ + "ldr r0, =thread_data\n\t" + "movw r7, #0x0005\n\t" /* __ARM_NR_set_tls */ + "movt r7, #0xf\n\t" /* __ARM_NR_set_tls */ + "svc #0\n\t" + "mov r0, sp\n\t" /* ptr to orig stack pointer */ + "bl wld_start\n\t" + "ldr r1, [sp]\n\t" /* new stack pointer */ + "mov sp, r1\n\t" + "mov lr, r0\n\t" + "mov r0, #0\n\t" + "mov r1, #0\n\t" + "mov r2, #0\n\t" + "mov r3, #0\n\t" + "mov r12, #0\n\t" + "bx lr\n\t" + ".ltorg\n\t") + +#define SYSCALL_FUNC( name, nr ) \ + __ASM_GLOBAL_FUNC( name, \ + "push {r4-r5,r7,lr}\n\t" \ + "ldr r4, [sp, #16]\n\t" \ + "ldr r5, [sp, #20]\n\t" \ + "mov r7, #" #nr "\n\t" \ + "svc #0\n\t" \ + "cmn r0, #4096\n\t" \ + "it hi\n\t" \ + "movhi r0, #-1\n\t" \ + "pop {r4-r5,r7,pc}\n\t" ) + +#define SYSCALL_NOERR( name, nr ) \ + __ASM_GLOBAL_FUNC( name, \ + "push {r7,lr}\n\t" \ + "mov r7, #" #nr "\n\t" \ + "svc #0\n\t" \ + "pop {r7,pc}\n\t" ) + +void wld_exit( int code ) __attribute__((noreturn)); +SYSCALL_NOERR( wld_exit, 1 /* SYS_exit */ ); + +ssize_t wld_read( int fd, void *buffer, size_t len ); +SYSCALL_FUNC( wld_read, 3 /* SYS_read */ ); + +ssize_t wld_write( int fd, const void *buffer, size_t len ); +SYSCALL_FUNC( wld_write, 4 /* SYS_write */ ); + +int wld_openat( int dirfd, const char *name, int flags ); +SYSCALL_FUNC( wld_openat, 322 /* SYS_openat */ ); + +int wld_open( const char *name, int flags ) +{ + return wld_openat(-100 /* AT_FDCWD */, name, flags); +} + +int wld_close( int fd ); +SYSCALL_FUNC( wld_close, 6 /* SYS_close */ ); + +void *wld_mmap2( void *start, size_t len, int prot, int flags, int fd, int offset ); +SYSCALL_FUNC( wld_mmap2, 192 /* SYS_mmap2 */ ); + +void *wld_mmap( void *start, size_t len, int prot, int flags, int fd, off_t offset ) +{ + return wld_mmap2(start, len, prot, flags, fd, offset >> 12); +} + +int wld_mprotect( const void *addr, size_t len, int prot ); +SYSCALL_FUNC( wld_mprotect, 125 /* SYS_mprotect */ ); + +int wld_prctl( int code, long arg ); +SYSCALL_FUNC( wld_prctl, 172 /* SYS_prctl */ ); + +uid_t wld_getuid(void); +SYSCALL_NOERR( wld_getuid, 24 /* SYS_getuid */ ); + +gid_t wld_getgid(void); +SYSCALL_NOERR( wld_getgid, 47 /* SYS_getgid */ ); + +uid_t wld_geteuid(void); +SYSCALL_NOERR( wld_geteuid, 49 /* SYS_geteuid */ ); + +gid_t wld_getegid(void); +SYSCALL_NOERR( wld_getegid, 50 /* SYS_getegid */ ); + +unsigned long long __aeabi_uidivmod(unsigned int num, unsigned int den) +{ + unsigned int bit = 1; + unsigned int quota = 0; + if (!den) + wld_exit(1); + while (den < num && !(den & 0x80000000)) { + den <<= 1; + bit <<= 1; + } + do { + if (den <= num) { + quota |= bit; + num -= den; + } + bit >>= 1; + den >>= 1; + } while (bit); + return ((unsigned long long)num << 32) | quota; +} + #else #error preloader not implemented for this CPU #endif @@ -809,6 +928,9 @@ static void map_so_lib( const char *name, struct wld_link_map *l) #elif defined(__aarch64__) if( header->e_machine != EM_AARCH64 ) fatal_error("%s: not an aarch64 ELF binary... don't know how to load it\n", name ); +#elif defined(__arm__) + if( header->e_machine != EM_ARM ) + fatal_error("%s: not an arm ELF binary... don't know how to load it\n", name ); #endif if (header->e_phnum > sizeof(loadcmds)/sizeof(loadcmds[0]))
1
0
0
0
Alex Henrie : shell32: Fix use of uninitialized variable in paste_pidls (Clang).
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: adb4259aa92599bf7bbad8271f1a372027443a46 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=adb4259aa92599bf7bbad827…
Author: Alex Henrie <alexhenrie24(a)gmail.com> Date: Tue Aug 3 22:03:48 2021 -0600 shell32: Fix use of uninitialized variable in paste_pidls (Clang). Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/shell32/shlview_cmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index ef11957e921..e116e343446 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -1158,7 +1158,7 @@ static HRESULT paste_pidls(ContextMenu *This, ITEMIDLIST **pidls, UINT count) if (psfFrom) { /* get source and destination shellfolder */ - ISFHelper *psfhlpdst, *psfhlpsrc; + ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL; hr = IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst); if (SUCCEEDED(hr)) hr = IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc);
1
0
0
0
Rémi Bernon : xinput1_3: Access controller list in HID code directly.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: db1160672802fcc34a4bce1174423d3f4aed266e URL:
https://source.winehq.org/git/wine.git/?a=commit;h=db1160672802fcc34a4bce11…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 17:12:09 2021 +0200 xinput1_3: Access controller list in HID code directly. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/xinput1_3/hid.c | 14 +++++++------- dlls/xinput1_3/xinput_main.c | 10 +++++----- dlls/xinput1_3/xinput_private.h | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c index 382469a0be9..00907b54bed 100644 --- a/dlls/xinput1_3/hid.c +++ b/dlls/xinput1_3/hid.c @@ -71,7 +71,7 @@ struct hid_platform_private { static DWORD last_check = 0; -static BOOL find_opened_device(xinput_controller *devices, SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail, int *free_slot) +static BOOL find_opened_device(SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail, int *free_slot) { struct hid_platform_private *private; int i; @@ -79,7 +79,7 @@ static BOOL find_opened_device(xinput_controller *devices, SP_DEVICE_INTERFACE_D *free_slot = XUSER_MAX_COUNT; for (i = XUSER_MAX_COUNT; i > 0; i--) { - if (!(private = devices[i - 1].platform_private)) *free_slot = i - 1; + if (!(private = controllers[i - 1].platform_private)) *free_slot = i - 1; else if (!wcscmp(detail->DevicePath, private->device_path)) return TRUE; } return FALSE; @@ -221,7 +221,7 @@ failed: return FALSE; } -void HID_find_gamepads(xinput_controller *devices) +void HID_find_gamepads(void) { char buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR)]; SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)buffer; @@ -266,7 +266,7 @@ void HID_find_gamepads(xinput_controller *devices) if (!wcsstr(detail->DevicePath, L"IG_")) continue; - if (find_opened_device(devices, detail, &i)) continue; /* already opened */ + if (find_opened_device(detail, &i)) continue; /* already opened */ if (i == XUSER_MAX_COUNT) break; /* no more slots */ device = CreateFileW(detail->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); @@ -282,7 +282,7 @@ void HID_find_gamepads(xinput_controller *devices) WARN("ignoring HID device, unsupported usage page %04x\n", caps.UsagePage); else if (caps.Usage != HID_USAGE_GENERIC_GAMEPAD && caps.Usage != HID_USAGE_GENERIC_JOYSTICK && caps.Usage != HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER) WARN("ignoring HID device, unsupported usage %04x:%04x\n", caps.UsagePage, caps.Usage); - else if (!init_controller(&devices[i], ppd, &caps, device, detail->DevicePath)) + else if (!init_controller(&controllers[i], ppd, &caps, device, detail->DevicePath)) WARN("ignoring HID device, failed to initialize\n"); else continue; @@ -317,11 +317,11 @@ static void remove_gamepad(xinput_controller *device) LeaveCriticalSection(&device->crit); } -void HID_destroy_gamepads(xinput_controller *devices) +void HID_destroy_gamepads(void) { int i; for (i = 0; i < XUSER_MAX_COUNT; i++) - remove_gamepad(&devices[i]); + remove_gamepad(&controllers[i]); } static SHORT scale_short(LONG value, const struct axis_info *axis) diff --git a/dlls/xinput1_3/xinput_main.c b/dlls/xinput1_3/xinput_main.c index 63b7dd7f0b5..2d9f54c83f2 100644 --- a/dlls/xinput1_3/xinput_main.c +++ b/dlls/xinput1_3/xinput_main.c @@ -104,7 +104,7 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) break; case DLL_PROCESS_DETACH: if (reserved) break; - HID_destroy_gamepads(controllers); + HID_destroy_gamepads(); break; } return TRUE; @@ -120,7 +120,7 @@ void WINAPI DECLSPEC_HOTPATCH XInputEnable(BOOL enable) to the controllers. Setting to true will send the last vibration value (sent to XInputSetState) to the controller and allow messages to be sent */ - HID_find_gamepads(controllers); + HID_find_gamepads(); for (index = 0; index < XUSER_MAX_COUNT; index ++) { @@ -136,7 +136,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputSetState(DWORD index, XINPUT_VIBRATION* vib TRACE("(index %u, vibration %p)\n", index, vibration); - HID_find_gamepads(controllers); + HID_find_gamepads(); if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS; @@ -157,7 +157,7 @@ static DWORD xinput_get_state(DWORD index, XINPUT_STATE *state) if (!state) return ERROR_BAD_ARGUMENTS; - HID_find_gamepads(controllers); + HID_find_gamepads(); if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS; @@ -421,7 +421,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputGetCapabilities(DWORD index, DWORD flags, X { TRACE("(index %u, flags 0x%x, capabilities %p)\n", index, flags, capabilities); - HID_find_gamepads(controllers); + HID_find_gamepads(); if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS; diff --git a/dlls/xinput1_3/xinput_private.h b/dlls/xinput1_3/xinput_private.h index 0de4f3b0b03..2bf16c0ffce 100644 --- a/dlls/xinput1_3/xinput_private.h +++ b/dlls/xinput1_3/xinput_private.h @@ -30,8 +30,8 @@ typedef struct _xinput_controller extern CRITICAL_SECTION xinput_crit; extern xinput_controller controllers[XUSER_MAX_COUNT]; -void HID_find_gamepads(xinput_controller *devices) DECLSPEC_HIDDEN; -void HID_destroy_gamepads(xinput_controller *devices) DECLSPEC_HIDDEN; +void HID_find_gamepads(void) DECLSPEC_HIDDEN; +void HID_destroy_gamepads(void) DECLSPEC_HIDDEN; void HID_update_state(xinput_controller* device, XINPUT_STATE *state) DECLSPEC_HIDDEN; DWORD HID_set_state(xinput_controller* device, XINPUT_VIBRATION* state) DECLSPEC_HIDDEN; void HID_enable(xinput_controller* device, BOOL enable) DECLSPEC_HIDDEN;
1
0
0
0
Rémi Bernon : xinput1_3: Continue enumeration until there's no more slot.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: 1371bcf3ad8d6107dab30d49e40bf6ea1765e97f URL:
https://source.winehq.org/git/wine.git/?a=commit;h=1371bcf3ad8d6107dab30d49…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 17:12:08 2021 +0200 xinput1_3: Continue enumeration until there's no more slot. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/xinput1_3/hid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c index ac95ad3c402..382469a0be9 100644 --- a/dlls/xinput1_3/hid.c +++ b/dlls/xinput1_3/hid.c @@ -285,13 +285,12 @@ void HID_find_gamepads(xinput_controller *devices) else if (!init_controller(&devices[i], ppd, &caps, device, detail->DevicePath)) WARN("ignoring HID device, failed to initialize\n"); else - goto done; + continue; CloseHandle(device); HidD_FreePreparsedData(ppd); } -done: SetupDiDestroyDeviceInfoList(device_info_set); LeaveCriticalSection(&xinput_crit); }
1
0
0
0
Rémi Bernon : xinput1_3: Statically allocate SP_DEVICE_INTERFACE_DETAIL_DATA_W.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: 47ac0b0bdcfb0ade7af1e3de4df9a0ad7ec6031d URL:
https://source.winehq.org/git/wine.git/?a=commit;h=47ac0b0bdcfb0ade7af1e3de…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 17:12:07 2021 +0200 xinput1_3: Statically allocate SP_DEVICE_INTERFACE_DETAIL_DATA_W. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/xinput1_3/hid.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c index e7a77813c71..ac95ad3c402 100644 --- a/dlls/xinput1_3/hid.c +++ b/dlls/xinput1_3/hid.c @@ -223,12 +223,12 @@ failed: void HID_find_gamepads(xinput_controller *devices) { + char buffer[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR)]; + SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *)buffer; HDEVINFO device_info_set; GUID hid_guid; SP_DEVICE_INTERFACE_DATA interface_data; - SP_DEVICE_INTERFACE_DETAIL_DATA_W *data; PHIDP_PREPARSED_DATA ppd; - DWORD detail_size = MAX_PATH * sizeof(WCHAR); HANDLE device; HIDP_CAPS caps; NTSTATUS status; @@ -251,9 +251,7 @@ void HID_find_gamepads(xinput_controller *devices) HidD_GetHidGuid(&hid_guid); device_info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); - - if (!(data = malloc(sizeof(*data) + detail_size))) goto done; - data->cbSize = sizeof(*data); + detail->cbSize = sizeof(*detail); ZeroMemory(&interface_data, sizeof(interface_data)); interface_data.cbSize = sizeof(interface_data); @@ -262,17 +260,16 @@ void HID_find_gamepads(xinput_controller *devices) while (SetupDiEnumDeviceInterfaces(device_info_set, NULL, &hid_guid, idx++, &interface_data)) { - if (!SetupDiGetDeviceInterfaceDetailW(device_info_set, - &interface_data, data, sizeof(*data) + detail_size, NULL, NULL)) + if (!SetupDiGetDeviceInterfaceDetailW(device_info_set, &interface_data, detail, sizeof(buffer), NULL, NULL)) continue; - if (!wcsstr(data->DevicePath, L"IG_")) + if (!wcsstr(detail->DevicePath, L"IG_")) continue; - if (find_opened_device(devices, data, &i)) continue; /* already opened */ + if (find_opened_device(devices, detail, &i)) continue; /* already opened */ if (i == XUSER_MAX_COUNT) break; /* no more slots */ - device = CreateFileW(data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); + device = CreateFileW(detail->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); if (device == INVALID_HANDLE_VALUE) continue; @@ -285,7 +282,7 @@ void HID_find_gamepads(xinput_controller *devices) WARN("ignoring HID device, unsupported usage page %04x\n", caps.UsagePage); else if (caps.Usage != HID_USAGE_GENERIC_GAMEPAD && caps.Usage != HID_USAGE_GENERIC_JOYSTICK && caps.Usage != HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER) WARN("ignoring HID device, unsupported usage %04x:%04x\n", caps.UsagePage, caps.Usage); - else if (!init_controller(&devices[i], ppd, &caps, device, data->DevicePath)) + else if (!init_controller(&devices[i], ppd, &caps, device, detail->DevicePath)) WARN("ignoring HID device, failed to initialize\n"); else goto done; @@ -295,7 +292,6 @@ void HID_find_gamepads(xinput_controller *devices) } done: - free(data); SetupDiDestroyDeviceInfoList(device_info_set); LeaveCriticalSection(&xinput_crit); }
1
0
0
0
Rémi Bernon : xinput1_3: Introduce new find_opened_device helper.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: 828b9b8cc49fe24a306235c056a38c7ae079560f URL:
https://source.winehq.org/git/wine.git/?a=commit;h=828b9b8cc49fe24a306235c0…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 17:12:06 2021 +0200 xinput1_3: Introduce new find_opened_device helper. To look for already opened device, or available device index. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/xinput1_3/hid.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c index 0f4dec44ee3..e7a77813c71 100644 --- a/dlls/xinput1_3/hid.c +++ b/dlls/xinput1_3/hid.c @@ -71,6 +71,20 @@ struct hid_platform_private { static DWORD last_check = 0; +static BOOL find_opened_device(xinput_controller *devices, SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail, int *free_slot) +{ + struct hid_platform_private *private; + int i; + + *free_slot = XUSER_MAX_COUNT; + for (i = XUSER_MAX_COUNT; i > 0; i--) + { + if (!(private = devices[i - 1].platform_private)) *free_slot = i - 1; + else if (!wcscmp(detail->DevicePath, private->device_path)) return TRUE; + } + return FALSE; +} + static void MarkUsage(struct hid_platform_private *private, WORD usage, LONG min, LONG max, USHORT bits) { struct axis_info info = {min, max-min, bits}; @@ -219,7 +233,7 @@ void HID_find_gamepads(xinput_controller *devices) HIDP_CAPS caps; NTSTATUS status; DWORD idx; - int i, open_device_idx; + int i; idx = GetTickCount(); if ((idx - last_check) < 2000) @@ -255,24 +269,9 @@ void HID_find_gamepads(xinput_controller *devices) if (!wcsstr(data->DevicePath, L"IG_")) continue; - open_device_idx = -1; - for (i = 0; i < XUSER_MAX_COUNT; i++) - { - struct hid_platform_private *private = devices[i].platform_private; - if (devices[i].platform_private) - { - if (!wcscmp(data->DevicePath, private->device_path)) - break; - } - else if(open_device_idx < 0) - open_device_idx = i; - } - if (i != XUSER_MAX_COUNT) - /* this device is already opened */ - continue; - if (open_device_idx < 0) - /* no open device slots */ - break; + if (find_opened_device(devices, data, &i)) continue; /* already opened */ + if (i == XUSER_MAX_COUNT) break; /* no more slots */ + device = CreateFileW(data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); if (device == INVALID_HANDLE_VALUE) continue; @@ -286,7 +285,7 @@ void HID_find_gamepads(xinput_controller *devices) WARN("ignoring HID device, unsupported usage page %04x\n", caps.UsagePage); else if (caps.Usage != HID_USAGE_GENERIC_GAMEPAD && caps.Usage != HID_USAGE_GENERIC_JOYSTICK && caps.Usage != HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER) WARN("ignoring HID device, unsupported usage %04x:%04x\n", caps.UsagePage, caps.Usage); - else if (!init_controller(&devices[open_device_idx], ppd, &caps, device, data->DevicePath)) + else if (!init_controller(&devices[i], ppd, &caps, device, data->DevicePath)) WARN("ignoring HID device, failed to initialize\n"); else goto done;
1
0
0
0
Rémi Bernon : hidclass.sys: Introduce new hid_device_xfer_report helper.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: 6fd356e009faa11456f811de2f2aa399837ecb59 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=6fd356e009faa11456f811de…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 10:36:07 2021 +0200 hidclass.sys: Introduce new hid_device_xfer_report helper. >From HID_IOCTL_GET_INPUT_REPORT code, to factor report buffer transfer, and use it for HID_IOCTL_GET_FEATURE. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/hidclass.sys/device.c | 100 ++++++++++++----------------------- dlls/ntoskrnl.exe/tests/driver_hid.c | 3 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 10 ++-- 3 files changed, 39 insertions(+), 74 deletions(-) diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index a7cb6a843e0..81ddd7e6d7e 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -299,46 +299,48 @@ static void handle_minidriver_string( BASE_DEVICE_EXTENSION *ext, IRP *irp, SHOR } } -static void HID_get_feature( BASE_DEVICE_EXTENSION *ext, IRP *irp ) +static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP *irp ) { - IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); - HID_XFER_PACKET *packet; - DWORD len; - BYTE *out_buffer; - - irp->IoStatus.Information = 0; + const WINE_HIDP_PREPARSED_DATA *preparsed = ext->u.pdo.preparsed_data; + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); + ULONG report_len = 0, buffer_len = stack->Parameters.DeviceIoControl.OutputBufferLength; + BYTE *buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ); + BYTE report_id = HID_INPUT_VALUE_CAPS( preparsed )->report_id; + HID_XFER_PACKET packet; - out_buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); - TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", ext, irpsp->Parameters.DeviceIoControl.OutputBufferLength, out_buffer); + switch (code) + { + case IOCTL_HID_GET_INPUT_REPORT: + report_len = preparsed->caps.InputReportByteLength; + break; + case IOCTL_HID_GET_FEATURE: + report_len = preparsed->caps.FeatureReportByteLength; + break; + } - if (!irpsp->Parameters.DeviceIoControl.OutputBufferLength || !out_buffer) + if (!buffer) { - irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER; + return; + } + if (buffer_len < report_len) + { + irp->IoStatus.Status = STATUS_INVALID_PARAMETER; return; } - len = sizeof(*packet) + irpsp->Parameters.DeviceIoControl.OutputBufferLength; - packet = malloc(len); - packet->reportBufferLen = irpsp->Parameters.DeviceIoControl.OutputBufferLength; - packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet); - packet->reportId = out_buffer[0]; - - TRACE_(hid_report)("(id %i, len %i buffer %p)\n", packet->reportId, packet->reportBufferLen, packet->reportBuffer); - - call_minidriver( IOCTL_HID_GET_FEATURE, ext->u.pdo.parent_fdo, NULL, 0, packet, sizeof(*packet), - &irp->IoStatus ); + packet.reportId = buffer[0]; + packet.reportBuffer = buffer; + packet.reportBufferLen = buffer_len; - if (irp->IoStatus.Status == STATUS_SUCCESS) + if (!report_id) { - irp->IoStatus.Information = packet->reportBufferLen; - memcpy(out_buffer, packet->reportBuffer, packet->reportBufferLen); + packet.reportId = 0; + packet.reportBuffer++; + packet.reportBufferLen--; } - else - irp->IoStatus.Information = 0; - - TRACE_(hid_report)( "Result 0x%x get %li bytes\n", irp->IoStatus.Status, irp->IoStatus.Information ); - free(packet); + call_minidriver( code, ext->u.pdo.parent_fdo, NULL, 0, &packet, sizeof(packet), &irp->IoStatus ); } static void HID_set_to_device( DEVICE_OBJECT *device, IRP *irp ) @@ -390,10 +392,9 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; - const WINE_HIDP_PREPARSED_DATA *data = ext->u.pdo.preparsed_data; - BYTE report_id = HID_INPUT_VALUE_CAPS( data )->report_id; NTSTATUS status; BOOL removed; + ULONG code; KIRQL irql; irp->IoStatus.Information = 0; @@ -411,7 +412,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) return STATUS_DELETE_PENDING; } - switch (irpsp->Parameters.DeviceIoControl.IoControlCode) + switch ((code = irpsp->Parameters.DeviceIoControl.IoControlCode)) { case IOCTL_HID_GET_POLL_FREQUENCY_MSEC: TRACE("IOCTL_HID_GET_POLL_FREQUENCY_MSEC\n"); @@ -469,38 +470,6 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) handle_IOCTL_HID_GET_COLLECTION_DESCRIPTOR( irp, ext ); break; } - case IOCTL_HID_GET_INPUT_REPORT: - { - HID_XFER_PACKET packet; - ULONG buffer_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength; - BYTE *buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ); - - if (!buffer) - { - irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER; - break; - } - if (buffer_len < data->caps.InputReportByteLength) - { - irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - break; - } - - packet.reportId = buffer[0]; - packet.reportBuffer = buffer; - packet.reportBufferLen = buffer_len; - - if (!report_id) - { - packet.reportId = 0; - packet.reportBuffer++; - packet.reportBufferLen--; - } - - call_minidriver( IOCTL_HID_GET_INPUT_REPORT, ext->u.pdo.parent_fdo, NULL, 0, &packet, - sizeof(packet), &irp->IoStatus ); - break; - } case IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS: { irp->IoStatus.Information = 0; @@ -527,7 +496,8 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) break; } case IOCTL_HID_GET_FEATURE: - HID_get_feature( ext, irp ); + case IOCTL_HID_GET_INPUT_REPORT: + hid_device_xfer_report( ext, code, irp ); break; case IOCTL_HID_SET_FEATURE: case IOCTL_HID_SET_OUTPUT_REPORT: diff --git a/dlls/ntoskrnl.exe/tests/driver_hid.c b/dlls/ntoskrnl.exe/tests/driver_hid.c index 831b08c5c97..d268b62d288 100644 --- a/dlls/ntoskrnl.exe/tests/driver_hid.c +++ b/dlls/ntoskrnl.exe/tests/driver_hid.c @@ -570,9 +570,8 @@ static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) ok(!in_size, "got input size %u\n", in_size); ok(out_size == sizeof(*packet), "got output size %u\n", out_size); - todo_wine_if(packet->reportId == 0x5a || packet->reportId == 0xa5) + todo_wine_if(packet->reportId == 0x5a) ok(packet->reportId == report_id, "got id %u\n", packet->reportId); - todo_wine_if(packet->reportBufferLen == 16) ok(packet->reportBufferLen >= expected_size, "got len %u\n", packet->reportBufferLen); ok(!!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer); diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 17d82fa3482..f5ebf21b7f9 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -2486,13 +2486,11 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled SetLastError(0xdeadbeef); ret = HidD_GetFeature(file, report, 0); ok(!ret, "HidD_GetFeature succeeded\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_GetFeature returned error %u\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "HidD_GetFeature returned error %u\n", GetLastError()); SetLastError(0xdeadbeef); ret = HidD_GetFeature(file, report, caps.FeatureReportByteLength - 1); - todo_wine ok(!ret, "HidD_GetFeature succeeded\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_CRC), "HidD_GetFeature returned error %u\n", GetLastError()); @@ -2510,21 +2508,19 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled else { ok(ret, "HidD_GetFeature failed, last error %u\n", GetLastError()); - todo_wine ok(buffer[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE)buffer[0]); + ok(buffer[0] == 0x5a, "got buffer[0] %x, expected 0x5a\n", (BYTE)buffer[0]); } SetLastError(0xdeadbeef); ret = HidD_GetFeature(file, report, caps.FeatureReportByteLength); ok(ret, "HidD_GetFeature failed, last error %u\n", GetLastError()); - todo_wine_if(!report_id) ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id); value = caps.FeatureReportByteLength * 2; SetLastError(0xdeadbeef); ret = sync_ioctl(file, IOCTL_HID_GET_FEATURE, NULL, 0, report, &value); ok(ret, "IOCTL_HID_GET_FEATURE failed, last error %u\n", GetLastError()); - todo_wine ok(value == 3, "got length %u, expected 3\n", value); - todo_wine_if(!report_id) + ok(value == 3, "got length %u, expected 3\n", value); ok(report[0] == report_id, "got report[0] %02x, expected %02x\n", report[0], report_id);
1
0
0
0
Rémi Bernon : hidclass.sys: Adjust buffer length according to report IDs usage.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: 1f3fdb3cb637d0fffc5034e6362d2f191c5edf80 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=1f3fdb3cb637d0fffc5034e6…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 10:36:06 2021 +0200 hidclass.sys: Adjust buffer length according to report IDs usage. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/hidclass.sys/device.c | 117 ++++++++++++++++++++--------------- dlls/ntoskrnl.exe/tests/driver_hid.c | 4 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 10 +-- 3 files changed, 72 insertions(+), 59 deletions(-) Diff:
https://source.winehq.org/git/wine.git/?a=commitdiff;h=1f3fdb3cb637d0fffc50…
1
0
0
0
Rémi Bernon : hidclass.sys: Always copy InputReportByteLength bytes into read buffer.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: e8c6f130714a96783c684f51e031bb062aba73cf URL:
https://source.winehq.org/git/wine.git/?a=commit;h=e8c6f130714a96783c684f51…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 10:36:05 2021 +0200 hidclass.sys: Always copy InputReportByteLength bytes into read buffer. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/hidclass.sys/device.c | 60 +++++++++++--------------------------- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 15 +++++----- 2 files changed, 25 insertions(+), 50 deletions(-) diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index f1b0083fffd..a465cc53369 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -77,32 +77,6 @@ static void WINAPI read_cancel_routine(DEVICE_OBJECT *device, IRP *irp) IoCompleteRequest(irp, IO_NO_INCREMENT); } -static NTSTATUS copy_packet_into_buffer(HID_XFER_PACKET *packet, BYTE* buffer, ULONG buffer_length, ULONG *out_length) -{ - BOOL zero_id = (packet->reportId == 0); - - *out_length = 0; - - if ((zero_id && buffer_length > packet->reportBufferLen) || - (!zero_id && buffer_length >= packet->reportBufferLen)) - { - if (packet->reportId != 0) - { - memcpy(buffer, packet->reportBuffer, packet->reportBufferLen); - *out_length = packet->reportBufferLen; - } - else - { - buffer[0] = 0; - memcpy(&buffer[1], packet->reportBuffer, packet->reportBufferLen); - *out_length = packet->reportBufferLen + 1; - } - return STATUS_SUCCESS; - } - else - return STATUS_BUFFER_OVERFLOW; -} - static void hid_device_send_input(DEVICE_OBJECT *device, HID_XFER_PACKET *packet) { BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; @@ -145,24 +119,24 @@ static void HID_Device_processQueue(DEVICE_OBJECT *device) IRP *irp; BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; UINT buffer_size = RingBuffer_GetBufferSize(ext->u.pdo.ring_buffer); + const WINE_HIDP_PREPARSED_DATA *data = ext->u.pdo.preparsed_data; HID_XFER_PACKET *packet; packet = malloc(buffer_size); while((irp = pop_irp_from_queue(ext))) { - int ptr; - ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext ); + BYTE *buffer = irp->AssociatedIrp.SystemBuffer, *dst = buffer; + int ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext ); RingBuffer_Read(ext->u.pdo.ring_buffer, ptr, packet, &buffer_size); if (buffer_size) { - ULONG out_length; - IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); - packet->reportBuffer = (BYTE *)packet + sizeof(*packet); TRACE_(hid_report)("Processing Request (%i)\n",ptr); - irp->IoStatus.Status = copy_packet_into_buffer( packet, irp->AssociatedIrp.SystemBuffer, irpsp->Parameters.Read.Length, &out_length ); - irp->IoStatus.Information = out_length; + if (!data->reports[0].reportID) *dst++ = 0; + memcpy( dst, packet + 1, data->caps.InputReportByteLength - (dst - buffer) ); + irp->IoStatus.Information = packet->reportBufferLen; + irp->IoStatus.Status = STATUS_SUCCESS; } else { @@ -483,8 +457,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) HID_XFER_PACKET *packet; ULONG buffer_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength; UINT packet_size = sizeof(*packet) + buffer_len; - BYTE *buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); - ULONG out_length; + BYTE *buffer = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ), *dst = buffer; if (!buffer) { @@ -510,7 +483,10 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp) sizeof(*packet), &irp->IoStatus ); if (irp->IoStatus.Status == STATUS_SUCCESS) - irp->IoStatus.Status = copy_packet_into_buffer( packet, buffer, buffer_len, &out_length ); + { + if (!data->reports[0].reportID) *dst++ = 0; + memcpy( dst, packet + 1, data->caps.InputReportByteLength - (dst - buffer) ); + } free(packet); break; } @@ -568,6 +544,7 @@ NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp) const WINE_HIDP_PREPARSED_DATA *data = ext->u.pdo.preparsed_data; UINT buffer_size = RingBuffer_GetBufferSize(ext->u.pdo.ring_buffer); IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); + BYTE *buffer = irp->AssociatedIrp.SystemBuffer, *dst = buffer; NTSTATUS status; int ptr = -1; BOOL removed; @@ -599,13 +576,10 @@ NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp) if (buffer_size) { - IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); - ULONG out_length; - packet->reportBuffer = (BYTE *)packet + sizeof(*packet); - TRACE_(hid_report)("Got Packet %p %i\n", packet->reportBuffer, packet->reportBufferLen); - - irp->IoStatus.Status = copy_packet_into_buffer( packet, irp->AssociatedIrp.SystemBuffer, irpsp->Parameters.Read.Length, &out_length ); - irp->IoStatus.Information = out_length; + if (!data->reports[0].reportID) *dst++ = 0; + memcpy( dst, packet + 1, data->caps.InputReportByteLength - (dst - buffer) ); + irp->IoStatus.Information = packet->reportBufferLen; + irp->IoStatus.Status = STATUS_SUCCESS; } else { diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 02f37773c67..aa22d72828c 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -2684,9 +2684,9 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled memset(report, 0xcd, sizeof(report)); SetLastError(0xdeadbeef); ret = ReadFile(file, report, caps.InputReportByteLength, &value, NULL); - todo_wine ok(ret, "ReadFile failed, last error %u\n", GetLastError()); + ok(ret, "ReadFile failed, last error %u\n", GetLastError()); todo_wine ok(value == (report_id ? 3 : 4), "ReadFile returned %x\n", value); - todo_wine ok(report[0] == report_id, "unexpected report data\n"); + ok(report[0] == report_id, "unexpected report data\n"); overlapped.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); overlapped2.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); @@ -2695,9 +2695,9 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled SetLastError(0xdeadbeef); while (ReadFile(async_file, report, caps.InputReportByteLength, NULL, &overlapped)) ResetEvent(overlapped.hEvent); - todo_wine ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); + ok(GetLastError() == ERROR_IO_PENDING, "ReadFile returned error %u\n", GetLastError()); ret = GetOverlappedResult(async_file, &overlapped, &value, TRUE); - todo_wine ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); + ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); todo_wine ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); ResetEvent(overlapped.hEvent); @@ -2716,13 +2716,14 @@ static void test_hidp(HANDLE file, HANDLE async_file, int report_id, BOOL polled /* wait for first report to be ready */ ret = GetOverlappedResult(async_file, &overlapped, &value, TRUE); - todo_wine ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); + ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); todo_wine ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); /* second report should be ready and the same */ ret = GetOverlappedResult(async_file, &overlapped2, &value, FALSE); - todo_wine ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); + ok(ret, "GetOverlappedResult failed, last error %u\n", GetLastError()); todo_wine ok(value == (report_id ? 3 : 4), "GetOverlappedResult returned length %u, expected 3\n", value); - todo_wine ok(memcmp(report, buffer + caps.InputReportByteLength, caps.InputReportByteLength), "expected different report\n"); + ok(memcmp(report, buffer + caps.InputReportByteLength, caps.InputReportByteLength), + "expected different report\n"); ok(!memcmp(report, buffer, caps.InputReportByteLength), "expected identical reports\n"); CloseHandle(overlapped.hEvent);
1
0
0
0
Rémi Bernon : hidclass.sys: Rename IO_STATUS_BLOCK irp_status to io.
by Alexandre Julliard
05 Aug '21
05 Aug '21
Module: wine Branch: master Commit: 88bc48fbac52e5f6c20f1ed0c57ce597baa0dacb URL:
https://source.winehq.org/git/wine.git/?a=commit;h=88bc48fbac52e5f6c20f1ed0…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Aug 5 10:36:04 2021 +0200 hidclass.sys: Rename IO_STATUS_BLOCK irp_status to io. Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/hidclass.sys/device.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index ab449b9b0d9..f1b0083fffd 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -177,9 +177,8 @@ static void HID_Device_processQueue(DEVICE_OBJECT *device) static DWORD CALLBACK hid_device_thread(void *args) { DEVICE_OBJECT *device = (DEVICE_OBJECT*)args; - - IO_STATUS_BLOCK irp_status; HID_XFER_PACKET *packet; + IO_STATUS_BLOCK io; DWORD rc; BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; @@ -196,9 +195,9 @@ static DWORD CALLBACK hid_device_thread(void *args) packet->reportId = 0; call_minidriver( IOCTL_HID_GET_INPUT_REPORT, ext->u.pdo.parent_fdo, NULL, 0, packet, - sizeof(*packet), &irp_status ); + sizeof(*packet), &io ); - if (irp_status.Status == STATUS_SUCCESS) + if (io.Status == STATUS_SUCCESS) { RingBuffer_Write(ext->u.pdo.ring_buffer, packet); hid_device_send_input(device, packet); @@ -221,15 +220,15 @@ static DWORD CALLBACK hid_device_thread(void *args) while(1) { call_minidriver( IOCTL_HID_READ_REPORT, ext->u.pdo.parent_fdo, NULL, 0, - packet->reportBuffer, report_size, &irp_status ); + packet->reportBuffer, report_size, &io ); rc = WaitForSingleObject(ext->u.pdo.halt_event, 0); if (rc == WAIT_OBJECT_0) exit_now = TRUE; - if (!exit_now && irp_status.Status == STATUS_SUCCESS) + if (!exit_now && io.Status == STATUS_SUCCESS) { - packet->reportBufferLen = irp_status.Information; + packet->reportBufferLen = io.Information; if (ext->u.pdo.preparsed_data->reports[0].reportID) packet->reportId = packet->reportBuffer[0]; else
1
0
0
0
← Newer
1
...
85
86
87
88
89
90
91
...
106
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
Results per page:
10
25
50
100
200