diff --git a/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch b/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch index 6f442c58..2aac17df 100644 --- a/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch +++ b/patches/loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch @@ -1,4 +1,4 @@ -From 0572bef41d224ebb69c6c3fd647bddf844a3a29d Mon Sep 17 00:00:00 2001 +From 8db4007bfa0d09e3d75d00a48b7762e9ec746357 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 9 Jul 2019 14:13:28 +1000 Subject: [PATCH] user32: Do not enumerate the registry in @@ -7,70 +7,28 @@ Subject: [PATCH] user32: Do not enumerate the registry in This function returns the current list of *installed* Keyboard layouts not the complete list from the registry. --- - dlls/user32/input.c | 32 +++----------------------------- - dlls/user32/tests/input.c | 35 +++++++++++++++++++++++++++++++++++ - 2 files changed, 38 insertions(+), 29 deletions(-) + dlls/user32/input.c | 1 - + dlls/user32/tests/input.c | 35 +++++++++++++++++++++++++++++++ + dlls/win32u/input.c | 43 +-------------------------------------- + 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/dlls/user32/input.c b/dlls/user32/input.c -index 97be83369d9..42145c13105 100644 +index 7349d865f01..23ef817ff29 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c -@@ -1336,9 +1336,7 @@ BOOL WINAPI BlockInput(BOOL fBlockIt) - */ - UINT WINAPI GetKeyboardLayoutList( INT size, HKL *layouts ) - { -- WCHAR klid[KL_NAMELENGTH], value[5]; -- DWORD value_size, count, tmp, i = 0; -- HKEY hkey; -+ DWORD count; - HKL layout; - - TRACE_(keyboard)( "size %d, layouts %p.\n", size, layouts ); -@@ -1346,37 +1344,13 @@ UINT WINAPI GetKeyboardLayoutList( INT size, HKL *layouts ) - if ((count = USER_Driver->pGetKeyboardLayoutList( size, layouts )) != ~0) return count; - - layout = get_locale_kbd_layout(); -- count = 0; - -- count++; - if (size && layouts) - { -- layouts[count - 1] = layout; -- if (count == size) return count; -+ layouts[0] = layout; - } - -- if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Keyboard Layouts", &hkey )) -- { -- while (!RegEnumKeyW( hkey, i++, klid, ARRAY_SIZE(klid) )) -- { -- tmp = wcstoul( klid, NULL, 16 ); -- value_size = sizeof(value); -- if (!RegGetValueW( hkey, klid, L"Layout Id", RRF_RT_REG_SZ, NULL, (void *)&value, &value_size )) -- tmp = MAKELONG( LOWORD( tmp ), 0xf000 | (wcstoul( value, NULL, 16 ) & 0xfff) ); -- -- if (layout == UlongToHandle( tmp )) continue; -- -- count++; -- if (size && layouts) -- { -- layouts[count - 1] = UlongToHandle( tmp ); -- if (count == size) break; -- } -- } -- RegCloseKey( hkey ); -- } -- -- return count; -+ return 1; +@@ -883,7 +883,6 @@ BOOL WINAPI BlockInput(BOOL fBlockIt) + return FALSE; } - +- + /*********************************************************************** + * RegisterHotKey (USER32.@) + */ diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c -index c4c361575cd..070c22a4349 100644 +index 79f3dfc3dc0..b3c1bd560ae 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c -@@ -4363,6 +4363,40 @@ static void test_SendInput(void) +@@ -4481,6 +4481,40 @@ static void test_SendInput(void) DestroyWindow( hwnd ); } @@ -111,7 +69,7 @@ index c4c361575cd..070c22a4349 100644 START_TEST(input) { char **argv; -@@ -4405,6 +4439,7 @@ START_TEST(input) +@@ -4523,6 +4557,7 @@ START_TEST(input) test_GetRawInputBuffer(); test_RegisterRawInputDevices(); test_rawinput(argv[0]); @@ -119,6 +77,69 @@ index c4c361575cd..070c22a4349 100644 if(pGetMouseMovePointsEx) test_GetMouseMovePointsEx(argv[0]); +diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c +index bc3cd17a29e..4ae1b0c900f 100644 +--- a/dlls/win32u/input.c ++++ b/dlls/win32u/input.c +@@ -611,23 +611,9 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ) + */ + UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts ) + { +- char buffer[4096]; +- KEY_NODE_INFORMATION *key_info = (KEY_NODE_INFORMATION *)buffer; +- KEY_VALUE_PARTIAL_INFORMATION *value_info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; +- DWORD count, tmp, i = 0; +- HKEY hkey, subkey; ++ DWORD count; + HKL layout; + +- static const WCHAR keyboard_layouts_keyW[] = +- { +- '\\','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', +- '\\','C','o','n','t','r','o','l', +- '\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s' +- }; +- + TRACE_(keyboard)( "size %d, layouts %p.\n", size, layouts ); + + if ((count = user_driver->pGetKeyboardLayoutList( size, layouts )) != ~0) return count; +@@ -639,33 +625,6 @@ UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts ) + if (size && layouts) + { + layouts[count - 1] = layout; +- if (count == size) return count; +- } +- +- if ((hkey = reg_open_key( NULL, keyboard_layouts_keyW, sizeof(keyboard_layouts_keyW) ))) +- { +- while (!NtEnumerateKey( hkey, i++, KeyNodeInformation, key_info, +- sizeof(buffer) - sizeof(WCHAR), &tmp )) +- { +- if (!(subkey = reg_open_key( hkey, key_info->Name, key_info->NameLength ))) continue; +- key_info->Name[key_info->NameLength / sizeof(WCHAR)] = 0; +- tmp = wcstoul( key_info->Name, NULL, 16 ); +- if (query_reg_ascii_value( subkey, "Layout Id", value_info, sizeof(buffer) ) && +- value_info->Type == REG_SZ) +- tmp = MAKELONG( LOWORD( tmp ), +- 0xf000 | (wcstoul( (const WCHAR *)value_info->Data, NULL, 16 ) & 0xfff) ); +- NtClose( subkey ); +- +- if (layout == UlongToHandle( tmp )) continue; +- +- count++; +- if (size && layouts) +- { +- layouts[count - 1] = UlongToHandle( tmp ); +- if (count == size) break; +- } +- } +- NtClose( hkey ); + } + + return count; -- -2.30.2 +2.33.0 diff --git a/patches/ntdll-NtAlertThreadByThreadId/0003-ntdll-Implement-NtAlertThreadByThreadId-and-NtWaitFo.patch b/patches/ntdll-NtAlertThreadByThreadId/0003-ntdll-Implement-NtAlertThreadByThreadId-and-NtWaitFo.patch deleted file mode 100644 index a5a33520..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0003-ntdll-Implement-NtAlertThreadByThreadId-and-NtWaitFo.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 2bb6291b369ff7d7a84cbd28c76b0f19fddc9026 Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Fri, 30 Apr 2021 15:07:04 -0500 -Subject: [PATCH] ntdll: Implement NtAlertThreadByThreadId and - NtWaitForAlertByThreadId. - -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/ntdll.spec | 4 ++ - dlls/ntdll/unix/loader.c | 2 + - dlls/ntdll/unix/sync.c | 93 ++++++++++++++++++++++++++++++++++++++++ - dlls/wow64/sync.c | 23 ++++++++++ - dlls/wow64/syscall.h | 2 + - include/winternl.h | 2 + - 6 files changed, 126 insertions(+) - -diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 13e65f65139..71d95517a63 100644 ---- a/dlls/ntdll/ntdll.spec -+++ b/dlls/ntdll/ntdll.spec -@@ -140,6 +140,7 @@ - @ stdcall -syscall NtAdjustPrivilegesToken(long long ptr long ptr ptr) - @ stdcall -syscall NtAlertResumeThread(long ptr) - @ stdcall -syscall NtAlertThread(long) -+@ stdcall -syscall NtAlertThreadByThreadId(ptr) - @ stdcall -syscall NtAllocateLocallyUniqueId(ptr) - # @ stub NtAllocateUserPhysicalPages - @ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr) -@@ -424,6 +425,7 @@ - @ stdcall -syscall NtUnmapViewOfSection(long ptr) - # @ stub NtVdmControl - # @ stub NtW32Call -+@ stdcall -syscall NtWaitForAlertByThreadId(ptr ptr) - @ stdcall -syscall NtWaitForDebugEvent(long long ptr ptr) - @ stdcall -syscall NtWaitForKeyedEvent(long ptr long ptr) - @ stdcall -syscall NtWaitForMultipleObjects(long ptr long long ptr) -@@ -1161,6 +1163,7 @@ - @ stdcall -private -syscall ZwAdjustPrivilegesToken(long long ptr long ptr ptr) NtAdjustPrivilegesToken - @ stdcall -private -syscall ZwAlertResumeThread(long ptr) NtAlertResumeThread - @ stdcall -private -syscall ZwAlertThread(long) NtAlertThread -+@ stdcall -private -syscall ZwAlertThreadByThreadId(ptr) NtAlertThreadByThreadId - @ stdcall -private -syscall ZwAllocateLocallyUniqueId(ptr) NtAllocateLocallyUniqueId - # @ stub ZwAllocateUserPhysicalPages - @ stdcall -private -syscall ZwAllocateUuids(ptr ptr ptr ptr) NtAllocateUuids -@@ -1443,6 +1446,7 @@ - @ stdcall -private -syscall ZwUnmapViewOfSection(long ptr) NtUnmapViewOfSection - # @ stub ZwVdmControl - # @ stub ZwW32Call -+@ stdcall -private -syscall ZwWaitForAlertByThreadId(ptr ptr) NtWaitForAlertByThreadId - @ stdcall -private -syscall ZwWaitForDebugEvent(long long ptr ptr) NtWaitForDebugEvent - @ stdcall -private -syscall ZwWaitForKeyedEvent(long ptr long ptr) NtWaitForKeyedEvent - @ stdcall -private -syscall ZwWaitForMultipleObjects(long ptr long long ptr) NtWaitForMultipleObjects -diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c -index 9527e21dc0b..2089e6e45f2 100644 ---- a/dlls/ntdll/unix/loader.c -+++ b/dlls/ntdll/unix/loader.c -@@ -131,6 +131,7 @@ static void * const syscalls[] = - NtAdjustPrivilegesToken, - NtAlertResumeThread, - NtAlertThread, -+ NtAlertThreadByThreadId, - NtAllocateLocallyUniqueId, - NtAllocateUuids, - NtAllocateVirtualMemory, -@@ -333,6 +334,7 @@ static void * const syscalls[] = - NtUnlockFile, - NtUnlockVirtualMemory, - NtUnmapViewOfSection, -+ NtWaitForAlertByThreadId, - NtWaitForDebugEvent, - NtWaitForKeyedEvent, - NtWaitForMultipleObjects, -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index a5a4581ce58..98b1a487ff6 100644 ---- a/dlls/ntdll/unix/sync.c -+++ b/dlls/ntdll/unix/sync.c -@@ -33,6 +33,9 @@ - #include - #include - #include -+#ifdef HAVE_SYS_MMAN_H -+#include -+#endif - #ifdef HAVE_SYS_SYSCALL_H - #include - #endif -@@ -80,6 +83,12 @@ static const LARGE_INTEGER zero_timeout; - - static pthread_mutex_t addr_mutex = PTHREAD_MUTEX_INITIALIZER; - -+static const char *debugstr_timeout( const LARGE_INTEGER *timeout ) -+{ -+ if (!timeout) return "(infinite)"; -+ return wine_dbgstr_longlong( timeout->QuadPart ); -+} -+ - /* return a monotonic time counter, in Win32 ticks */ - static inline ULONGLONG monotonic_counter(void) - { -@@ -2393,6 +2402,90 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl - } - - -+union tid_alert_entry -+{ -+ HANDLE event; -+}; -+ -+#define TID_ALERT_BLOCK_SIZE (65536 / sizeof(union tid_alert_entry)) -+static union tid_alert_entry *tid_alert_blocks[4096]; -+ -+static unsigned int handle_to_index( HANDLE handle, unsigned int *block_idx ) -+{ -+ unsigned int idx = (wine_server_obj_handle(handle) >> 2) - 1; -+ *block_idx = idx / TID_ALERT_BLOCK_SIZE; -+ return idx % TID_ALERT_BLOCK_SIZE; -+} -+ -+static union tid_alert_entry *get_tid_alert_entry( HANDLE tid ) -+{ -+ unsigned int block_idx, idx = handle_to_index( tid, &block_idx ); -+ union tid_alert_entry *entry; -+ -+ if (block_idx > ARRAY_SIZE(tid_alert_blocks)) -+ { -+ FIXME( "tid %p is too high\n", tid ); -+ return NULL; -+ } -+ -+ if (!tid_alert_blocks[block_idx]) -+ { -+ static const size_t size = TID_ALERT_BLOCK_SIZE * sizeof(union tid_alert_entry); -+ void *ptr = anon_mmap_alloc( size, PROT_READ | PROT_WRITE ); -+ if (ptr == MAP_FAILED) return NULL; -+ if (InterlockedCompareExchangePointer( (void **)&tid_alert_blocks[block_idx], ptr, NULL )) -+ munmap( ptr, size ); /* someone beat us to it */ -+ } -+ -+ entry = &tid_alert_blocks[block_idx][idx % TID_ALERT_BLOCK_SIZE]; -+ -+ if (!entry->event) -+ { -+ HANDLE event; -+ -+ if (NtCreateEvent( &event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE )) -+ return NULL; -+ if (InterlockedCompareExchangePointer( &entry->event, event, NULL )) -+ NtClose( event ); -+ } -+ -+ return entry; -+} -+ -+ -+/*********************************************************************** -+ * NtAlertThreadByThreadId (NTDLL.@) -+ */ -+NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid ) -+{ -+ union tid_alert_entry *entry = get_tid_alert_entry( tid ); -+ -+ TRACE( "%p\n", tid ); -+ -+ if (!entry) return STATUS_INVALID_CID; -+ -+ return NtSetEvent( entry->event, NULL ); -+} -+ -+ -+/*********************************************************************** -+ * NtWaitForAlertByThreadId (NTDLL.@) -+ */ -+NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout ) -+{ -+ union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread ); -+ NTSTATUS status; -+ -+ TRACE( "%p %s\n", address, debugstr_timeout( timeout ) ); -+ -+ if (!entry) return STATUS_INVALID_CID; -+ -+ status = NtWaitForSingleObject( entry->event, FALSE, timeout ); -+ if (!status) return STATUS_ALERTED; -+ return status; -+} -+ -+ - #ifdef __linux__ - - NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) -diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c -index e2e9468a727..fbd039f644c 100644 ---- a/dlls/wow64/sync.c -+++ b/dlls/wow64/sync.c -@@ -1587,3 +1587,26 @@ NTSTATUS WINAPI wow64_NtYieldExecution( UINT *args ) - { - return NtYieldExecution(); - } -+ -+ -+/********************************************************************** -+ * wow64_NtAlertThreadByThreadId -+ */ -+NTSTATUS WINAPI wow64_NtAlertThreadByThreadId( UINT *args ) -+{ -+ HANDLE tid = get_handle( &args ); -+ -+ return NtAlertThreadByThreadId( tid ); -+} -+ -+ -+/********************************************************************** -+ * wow64_NtWaitForAlertByThreadId -+ */ -+NTSTATUS WINAPI wow64_NtWaitForAlertByThreadId( UINT *args ) -+{ -+ const void *address = get_ptr( &args ); -+ const LARGE_INTEGER *timeout = get_ptr( &args ); -+ -+ return NtWaitForAlertByThreadId( address, timeout ); -+} -diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h -index bc403dd6d31..112711875f7 100644 ---- a/dlls/wow64/syscall.h -+++ b/dlls/wow64/syscall.h -@@ -30,6 +30,7 @@ - SYSCALL_ENTRY( NtAdjustPrivilegesToken ) \ - SYSCALL_ENTRY( NtAlertResumeThread ) \ - SYSCALL_ENTRY( NtAlertThread ) \ -+ SYSCALL_ENTRY( NtAlertThreadByThreadId ) \ - SYSCALL_ENTRY( NtAllocateLocallyUniqueId ) \ - SYSCALL_ENTRY( NtAllocateUuids ) \ - SYSCALL_ENTRY( NtAllocateVirtualMemory ) \ -@@ -231,6 +232,7 @@ - SYSCALL_ENTRY( NtUnlockFile ) \ - SYSCALL_ENTRY( NtUnlockVirtualMemory ) \ - SYSCALL_ENTRY( NtUnmapViewOfSection ) \ -+ SYSCALL_ENTRY( NtWaitForAlertByThreadId ) \ - SYSCALL_ENTRY( NtWaitForDebugEvent ) \ - SYSCALL_ENTRY( NtWaitForKeyedEvent ) \ - SYSCALL_ENTRY( NtWaitForMultipleObjects ) \ -diff --git a/include/winternl.h b/include/winternl.h -index aeffea80674..b21563213e6 100644 ---- a/include/winternl.h -+++ b/include/winternl.h -@@ -3845,6 +3845,7 @@ NTSYSAPI NTSTATUS WINAPI NtAdjustGroupsToken(HANDLE,BOOLEAN,PTOKEN_GROUPS,ULONG - NTSYSAPI NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD); - NTSYSAPI NTSTATUS WINAPI NtAlertResumeThread(HANDLE,PULONG); - NTSYSAPI NTSTATUS WINAPI NtAlertThread(HANDLE ThreadHandle); -+NTSYSAPI NTSTATUS WINAPI NtAlertThreadByThreadId(HANDLE); - NTSYSAPI NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID lpLuid); - NTSYSAPI NTSTATUS WINAPI NtAllocateUuids(PULARGE_INTEGER,PULONG,PULONG,PUCHAR); - NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,ULONG_PTR,SIZE_T*,ULONG,ULONG); -@@ -4084,6 +4085,7 @@ NTSYSAPI NTSTATUS WINAPI NtUnlockFile(HANDLE,PIO_STATUS_BLOCK,PLARGE_INTEGER,PL - NTSYSAPI NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,SIZE_T*,ULONG); - NTSYSAPI NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID); - NTSYSAPI NTSTATUS WINAPI NtVdmControl(ULONG,PVOID); -+NTSYSAPI NTSTATUS WINAPI NtWaitForAlertByThreadId(const void*,const LARGE_INTEGER*); - NTSYSAPI NTSTATUS WINAPI NtWaitForDebugEvent(HANDLE,BOOLEAN,LARGE_INTEGER*,DBGUI_WAIT_STATE_CHANGE*); - NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE,const void*,BOOLEAN,const LARGE_INTEGER*); - NTSYSAPI NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,const LARGE_INTEGER*); --- -2.33.0 - diff --git a/patches/ntdll-NtAlertThreadByThreadId/0004-ntdll-tests-Add-basic-tests-for-thread-id-alert-func.patch b/patches/ntdll-NtAlertThreadByThreadId/0004-ntdll-tests-Add-basic-tests-for-thread-id-alert-func.patch deleted file mode 100644 index 845db309..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0004-ntdll-tests-Add-basic-tests-for-thread-id-alert-func.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 775dcb8ca2ee8f16de16193570995dfe306be24d Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Mon, 31 Aug 2020 23:01:25 -0500 -Subject: [PATCH] ntdll/tests: Add basic tests for thread-id alert functions. - -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/tests/sync.c | 95 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 95 insertions(+) - -diff --git a/dlls/ntdll/tests/sync.c b/dlls/ntdll/tests/sync.c -index 21124dae922..be49405d8de 100644 ---- a/dlls/ntdll/tests/sync.c -+++ b/dlls/ntdll/tests/sync.c -@@ -26,6 +26,7 @@ - #include "winternl.h" - #include "wine/test.h" - -+static NTSTATUS (WINAPI *pNtAlertThreadByThreadId)( HANDLE ); - static NTSTATUS (WINAPI *pNtClose)( HANDLE ); - static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const OBJECT_ATTRIBUTES *, EVENT_TYPE, BOOLEAN); - static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG ); -@@ -43,6 +44,7 @@ static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, LONG * ); - static NTSTATUS (WINAPI *pNtReleaseSemaphore)( HANDLE, ULONG, ULONG * ); - static NTSTATUS (WINAPI *pNtResetEvent)( HANDLE, LONG * ); - static NTSTATUS (WINAPI *pNtSetEvent)( HANDLE, LONG * ); -+static NTSTATUS (WINAPI *pNtWaitForAlertByThreadId)( void *, const LARGE_INTEGER * ); - static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * ); - static BOOLEAN (WINAPI *pRtlAcquireResourceExclusive)( RTL_RWLOCK *, BOOLEAN ); - static BOOLEAN (WINAPI *pRtlAcquireResourceShared)( RTL_RWLOCK *, BOOLEAN ); -@@ -753,10 +755,101 @@ static void test_resource(void) - pRtlDeleteResource(&resource); - } - -+static DWORD WINAPI tid_alert_thread( void *arg ) -+{ -+ NTSTATUS ret; -+ -+ ret = pNtAlertThreadByThreadId( arg ); -+ ok(!ret, "got %#x\n", ret); -+ -+ ret = pNtWaitForAlertByThreadId( (void *)0x123, NULL ); -+ ok(ret == STATUS_ALERTED, "got %#x\n", ret); -+ -+ return 0; -+} -+ -+static void test_tid_alert( char **argv ) -+{ -+ LARGE_INTEGER timeout = {0}; -+ char cmdline[MAX_PATH]; -+ STARTUPINFOA si = {0}; -+ PROCESS_INFORMATION pi; -+ HANDLE thread; -+ NTSTATUS ret; -+ DWORD tid; -+ -+ if (!pNtWaitForAlertByThreadId) -+ { -+ win_skip("NtWaitForAlertByThreadId is not available\n"); -+ return; -+ } -+ -+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout ); -+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret); -+ -+ ret = pNtAlertThreadByThreadId( 0 ); -+ ok(ret == STATUS_INVALID_CID, "got %#x\n", ret); -+ -+ ret = pNtAlertThreadByThreadId( (HANDLE)0xdeadbeef ); -+ ok(ret == STATUS_INVALID_CID, "got %#x\n", ret); -+ -+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)GetCurrentThreadId() ); -+ ok(!ret, "got %#x\n", ret); -+ -+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)GetCurrentThreadId() ); -+ ok(!ret, "got %#x\n", ret); -+ -+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout ); -+ ok(ret == STATUS_ALERTED, "got %#x\n", ret); -+ -+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout ); -+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret); -+ -+ ret = pNtWaitForAlertByThreadId( (void *)0x321, &timeout ); -+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret); -+ -+ thread = CreateThread( NULL, 0, tid_alert_thread, (HANDLE)(DWORD_PTR)GetCurrentThreadId(), 0, &tid ); -+ timeout.QuadPart = -1000 * 10000; -+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout ); -+ ok(ret == STATUS_ALERTED, "got %#x\n", ret); -+ -+ ret = WaitForSingleObject( thread, 100 ); -+ ok(ret == WAIT_TIMEOUT, "got %d\n", ret); -+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tid ); -+ ok(!ret, "got %#x\n", ret); -+ -+ ret = WaitForSingleObject( thread, 1000 ); -+ ok(!ret, "got %d\n", ret); -+ -+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tid ); -+ ok(!ret, "got %#x\n", ret); -+ -+ CloseHandle(thread); -+ -+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tid ); -+ todo_wine ok(ret == STATUS_INVALID_CID, "got %#x\n", ret); -+ -+ sprintf( cmdline, "%s %s subprocess", argv[0], argv[1] ); -+ ret = CreateProcessA( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); -+ ok(ret, "failed to create process, error %u\n", GetLastError()); -+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)pi.dwThreadId ); -+ todo_wine ok(ret == STATUS_ACCESS_DENIED, "got %#x\n", ret); -+ ok(!WaitForSingleObject( pi.hProcess, 1000 ), "wait failed\n"); -+ CloseHandle( pi.hProcess ); -+ CloseHandle( pi.hThread ); -+} -+ - START_TEST(sync) - { - HMODULE module = GetModuleHandleA("ntdll.dll"); -+ char **argv; -+ int argc; - -+ argc = winetest_get_mainargs( &argv ); -+ -+ if (argc > 2) return; -+ -+ pNtAlertThreadByThreadId = (void *)GetProcAddress(module, "NtAlertThreadByThreadId"); - pNtClose = (void *)GetProcAddress(module, "NtClose"); - pNtCreateEvent = (void *)GetProcAddress(module, "NtCreateEvent"); - pNtCreateKeyedEvent = (void *)GetProcAddress(module, "NtCreateKeyedEvent"); -@@ -774,6 +867,7 @@ START_TEST(sync) - pNtReleaseSemaphore = (void *)GetProcAddress(module, "NtReleaseSemaphore"); - pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent"); - pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent"); -+ pNtWaitForAlertByThreadId = (void *)GetProcAddress(module, "NtWaitForAlertByThreadId"); - pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent"); - pRtlAcquireResourceExclusive = (void *)GetProcAddress(module, "RtlAcquireResourceExclusive"); - pRtlAcquireResourceShared = (void *)GetProcAddress(module, "RtlAcquireResourceShared"); -@@ -791,4 +885,5 @@ START_TEST(sync) - test_semaphore(); - test_keyed_events(); - test_resource(); -+ test_tid_alert( argv ); - } --- -2.30.2 - diff --git a/patches/ntdll-NtAlertThreadByThreadId/0005-ntdll-Implement-thread-ID-alerts-using-futexes-if-po.patch b/patches/ntdll-NtAlertThreadByThreadId/0005-ntdll-Implement-thread-ID-alerts-using-futexes-if-po.patch deleted file mode 100644 index 624ecb82..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0005-ntdll-Implement-thread-ID-alerts-using-futexes-if-po.patch +++ /dev/null @@ -1,125 +0,0 @@ -From f910f81d3c8f3c01f7582738e61071ae7a24dfea Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -Date: Fri, 30 Apr 2021 16:35:13 -0500 -Subject: [PATCH] ntdll: Implement thread-ID alerts using futexes if possible. - -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/unix/sync.c | 76 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 76 insertions(+) - -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index 014e5e5d0a7..058262ac0ad 100644 ---- a/dlls/ntdll/unix/sync.c -+++ b/dlls/ntdll/unix/sync.c -@@ -2289,6 +2289,9 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl - union tid_alert_entry - { - HANDLE event; -+#ifdef __linux__ -+ int futex; -+#endif - }; - - #define TID_ALERT_BLOCK_SIZE (65536 / sizeof(union tid_alert_entry)) -@@ -2323,6 +2326,11 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid ) - - entry = &tid_alert_blocks[block_idx][idx % TID_ALERT_BLOCK_SIZE]; - -+#ifdef __linux__ -+ if (use_futexes()) -+ return entry; -+#endif -+ - if (!entry->event) - { - HANDLE event; -@@ -2348,10 +2356,43 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid ) - - if (!entry) return STATUS_INVALID_CID; - -+#ifdef __linux__ -+ if (use_futexes()) -+ { -+ int *futex = &entry->futex; -+ if (!InterlockedExchange( futex, 1 )) -+ futex_wake( futex, 1 ); -+ return STATUS_SUCCESS; -+ } -+#endif -+ - return NtSetEvent( entry->event, NULL ); - } - - -+#ifdef __linux__ -+static LONGLONG get_absolute_timeout( const LARGE_INTEGER *timeout ) -+{ -+ LARGE_INTEGER now; -+ -+ if (timeout->QuadPart >= 0) return timeout->QuadPart; -+ NtQuerySystemTime( &now ); -+ return now.QuadPart - timeout->QuadPart; -+} -+ -+static LONGLONG update_timeout( ULONGLONG end ) -+{ -+ LARGE_INTEGER now; -+ LONGLONG timeleft; -+ -+ NtQuerySystemTime( &now ); -+ timeleft = end - now.QuadPart; -+ if (timeleft < 0) timeleft = 0; -+ return timeleft; -+} -+#endif -+ -+ - /*********************************************************************** - * NtWaitForAlertByThreadId (NTDLL.@) - */ -@@ -2364,6 +2405,41 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG - - if (!entry) return STATUS_INVALID_CID; - -+#ifdef __linux__ -+ if (use_futexes()) -+ { -+ int *futex = &entry->futex; -+ ULONGLONG end; -+ int ret; -+ -+ if (timeout) -+ { -+ if (timeout->QuadPart == TIMEOUT_INFINITE) -+ timeout = NULL; -+ else -+ end = get_absolute_timeout( timeout ); -+ } -+ -+ while (!InterlockedExchange( futex, 0 )) -+ { -+ if (timeout) -+ { -+ LONGLONG timeleft = update_timeout( end ); -+ struct timespec timespec; -+ -+ timespec.tv_sec = timeleft / (ULONGLONG)TICKSPERSEC; -+ timespec.tv_nsec = (timeleft % TICKSPERSEC) * 100; -+ ret = futex_wait( futex, 0, ×pec ); -+ } -+ else -+ ret = futex_wait( futex, 0, NULL ); -+ -+ if (ret == -1 && errno == ETIMEDOUT) return STATUS_TIMEOUT; -+ } -+ return STATUS_ALERTED; -+ } -+#endif -+ - status = NtWaitForSingleObject( entry->event, FALSE, timeout ); - if (!status) return STATUS_ALERTED; - return status; --- -2.30.2 - diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 132c6f43..038e2499 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -51,7 +51,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "b65ef71fc0a7044557e0ba530e3b95497644867c" + echo "161d61481f5d5ab8ee0b6237853af830e992afb1" } # Show version information @@ -2260,7 +2260,7 @@ fi # | * [#47439] loader: Add Keyboard Layouts registry enteries. # | # | Modified files: -# | * dlls/user32/input.c, dlls/user32/tests/input.c, loader/wine.inf.in +# | * dlls/user32/input.c, dlls/user32/tests/input.c, dlls/win32u/input.c, loader/wine.inf.in # | if test "$enable_loader_KeyboardLayouts" -eq 1; then patch_apply loader-KeyboardLayouts/0001-loader-Add-Keyboard-Layouts-registry-enteries.patch @@ -2502,13 +2502,10 @@ fi # | * [#50292] Process-local synchronization objects use private interfaces into the Unix library # | # | Modified files: -# | * dlls/ntdll/ntdll.spec, dlls/ntdll/sync.c, dlls/ntdll/tests/sync.c, dlls/ntdll/unix/loader.c, dlls/ntdll/unix/sync.c, -# | dlls/ntdll/unix/unix_private.h, dlls/ntdll/unixlib.h, dlls/wow64/sync.c, dlls/wow64/syscall.h, include/winternl.h +# | * dlls/ntdll/sync.c, dlls/ntdll/unix/loader.c, dlls/ntdll/unix/sync.c, dlls/ntdll/unix/unix_private.h, +# | dlls/ntdll/unixlib.h # | if test "$enable_ntdll_NtAlertThreadByThreadId" -eq 1; then - patch_apply ntdll-NtAlertThreadByThreadId/0003-ntdll-Implement-NtAlertThreadByThreadId-and-NtWaitFo.patch - patch_apply ntdll-NtAlertThreadByThreadId/0004-ntdll-tests-Add-basic-tests-for-thread-id-alert-func.patch - patch_apply ntdll-NtAlertThreadByThreadId/0005-ntdll-Implement-thread-ID-alerts-using-futexes-if-po.patch patch_apply ntdll-NtAlertThreadByThreadId/0006-ntdll-Implement-thread-ID-alerts-using-Mach-semaphor.patch patch_apply ntdll-NtAlertThreadByThreadId/0007-ntdll-Reimplement-Win32-futexes-on-top-of-thread-ID-.patch patch_apply ntdll-NtAlertThreadByThreadId/0009-ntdll-Reimplement-the-critical-section-fast-path-on-.patch diff --git a/patches/winex11-_NET_ACTIVE_WINDOW/0001-winex11.drv-Add-support-for-_NET_ACTIVE_WINDOW.patch b/patches/winex11-_NET_ACTIVE_WINDOW/0001-winex11.drv-Add-support-for-_NET_ACTIVE_WINDOW.patch index 3c691473..ca381c28 100644 --- a/patches/winex11-_NET_ACTIVE_WINDOW/0001-winex11.drv-Add-support-for-_NET_ACTIVE_WINDOW.patch +++ b/patches/winex11-_NET_ACTIVE_WINDOW/0001-winex11.drv-Add-support-for-_NET_ACTIVE_WINDOW.patch @@ -1,4 +1,4 @@ -From 2fe6229038238f33b7fbbc400ca38cb1f53c59f1 Mon Sep 17 00:00:00 2001 +From 51c2e2f0cd60b07077c6f3169924d4aea696ea31 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 10 Feb 2016 15:09:29 +0800 Subject: [PATCH] winex11.drv: Add support for _NET_ACTIVE_WINDOW. (v2) @@ -19,11 +19,11 @@ For bug #2155. 9 files changed, 72 insertions(+), 1 deletion(-) diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c -index f979630c707..420922076f1 100644 +index 1b7cdece90d..c51974649b5 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c -@@ -163,6 +163,10 @@ static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update ) - hdc, rect.left - dx, rect.top - dy, SRCCOPY ); +@@ -154,6 +154,10 @@ static void CDECL nulldrv_ReleaseDC( HWND hwnd, HDC hdc ) + { } +static void CDECL nulldrv_SetActiveWindow( HWND hwnd ) @@ -33,19 +33,19 @@ index f979630c707..420922076f1 100644 static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags ) { } -@@ -402,6 +406,7 @@ static struct user_driver_funcs lazy_load_driver = +@@ -362,6 +366,7 @@ static struct user_driver_funcs lazy_load_driver = nulldrv_MsgWaitForMultipleObjectsEx, nulldrv_ReleaseDC, - nulldrv_ScrollDC, + NULL, + nulldrv_SetActiveWindow, nulldrv_SetCapture, nulldrv_SetFocus, loaderdrv_SetLayeredWindowAttributes, diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c -index 34cc3880cc9..0805e1704c9 100644 +index 775a8f428c1..bd6d12cd355 100644 --- a/dlls/user32/focus.c +++ b/dlls/user32/focus.c -@@ -166,6 +166,8 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) +@@ -178,6 +178,8 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) PostMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd ); } @@ -55,7 +55,7 @@ index 34cc3880cc9..0805e1704c9 100644 if (focus) { diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c -index bcca0c30353..26cce1edbea 100644 +index 119bda91fd1..635924f231a 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -914,6 +914,10 @@ static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update ) @@ -69,7 +69,7 @@ index bcca0c30353..26cce1edbea 100644 static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags ) { } -@@ -1061,6 +1065,7 @@ void CDECL __wine_set_display_driver( struct user_driver_funcs *driver, UINT ver +@@ -1105,6 +1109,7 @@ void CDECL __wine_set_display_driver( struct user_driver_funcs *driver, UINT ver SET_USER_FUNC(MsgWaitForMultipleObjectsEx); SET_USER_FUNC(ReleaseDC); SET_USER_FUNC(ScrollDC); @@ -78,10 +78,10 @@ index bcca0c30353..26cce1edbea 100644 SET_USER_FUNC(SetFocus); SET_USER_FUNC(SetLayeredWindowAttributes); diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c -index 170111e9c28..e437132a763 100644 +index 6a4f3b5db08..50cb77037c1 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c -@@ -596,6 +596,9 @@ static void set_focus( Display *display, HWND hwnd, Time time ) +@@ -609,6 +609,9 @@ static void set_focus( Display *display, HWND hwnd, Time time ) Window win; GUITHREADINFO threadinfo; @@ -91,7 +91,7 @@ index 170111e9c28..e437132a763 100644 TRACE( "setting foreground window to %p\n", hwnd ); SetForegroundWindow( hwnd ); -@@ -843,6 +846,8 @@ static void focus_out( Display *display , HWND hwnd ) +@@ -856,6 +859,8 @@ static void focus_out( Display *display , HWND hwnd ) if (!focus_win) { @@ -101,10 +101,10 @@ index 170111e9c28..e437132a763 100644 Foreground window, because in most cases the messages sent above must have already changed the foreground window, in which diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c -index c9bef8d46d2..f6fd11c43ac 100644 +index 7959ee46966..63cb0dad0f7 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c -@@ -409,6 +409,7 @@ static const struct user_driver_funcs x11drv_funcs = +@@ -412,6 +412,7 @@ static const struct user_driver_funcs x11drv_funcs = .pMsgWaitForMultipleObjectsEx = X11DRV_MsgWaitForMultipleObjectsEx, .pReleaseDC = X11DRV_ReleaseDC, .pScrollDC = X11DRV_ScrollDC, @@ -113,10 +113,10 @@ index c9bef8d46d2..f6fd11c43ac 100644 .pSetFocus = X11DRV_SetFocus, .pSetLayeredWindowAttributes = X11DRV_SetLayeredWindowAttributes, diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c -index bcb0b8044bc..5143ea6840b 100644 +index f249f48e26a..d89809f211e 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c -@@ -2232,6 +2232,54 @@ BOOL CDECL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update ) +@@ -2229,6 +2229,54 @@ BOOL CDECL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update ) } @@ -172,7 +172,7 @@ index bcb0b8044bc..5143ea6840b 100644 * SetCapture (X11DRV.@) */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h -index 182ca4dd857..d857f9a961a 100644 +index a7d7c1c5925..6dadf2ea6bd 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -217,6 +217,7 @@ extern void CDECL X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_re @@ -183,7 +183,7 @@ index 182ca4dd857..d857f9a961a 100644 extern void CDECL X11DRV_SetCapture( HWND hwnd, UINT flags ) DECLSPEC_HIDDEN; extern void CDECL X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags ) DECLSPEC_HIDDEN; -@@ -372,6 +373,7 @@ struct x11drv_thread_data +@@ -384,6 +385,7 @@ struct x11drv_thread_data Display *display; XEvent *current_event; /* event currently being processed */ HWND grab_hwnd; /* window that currently grabs the mouse */ @@ -191,7 +191,7 @@ index 182ca4dd857..d857f9a961a 100644 HWND last_focus; /* last window that had focus */ XIM xim; /* input method */ HWND last_xic_hwnd; /* last xic window */ -@@ -483,6 +485,7 @@ enum x11drv_atoms +@@ -493,6 +495,7 @@ enum x11drv_atoms XATOM_DndSelection, XATOM__ICC_PROFILE, XATOM__MOTIF_WM_HINTS, @@ -200,7 +200,7 @@ index 182ca4dd857..d857f9a961a 100644 XATOM__NET_STARTUP_INFO, XATOM__NET_SUPPORTED, diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c -index 4a8605fc668..0699e1199e4 100644 +index a38cc2b6139..09ca3d0c4bf 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -160,6 +160,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = diff --git a/staging/upstream-commit b/staging/upstream-commit index 74ee095a..3024ecc3 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -b65ef71fc0a7044557e0ba530e3b95497644867c +161d61481f5d5ab8ee0b6237853af830e992afb1