diff --git a/patches/cmd-launch-association/0001-cmd-Support-for-launching-programs-based-on-file-ass.patch b/patches/cmd-launch-association/0001-cmd-Support-for-launching-programs-based-on-file-ass.patch index f04119b2..1e4b7388 100644 --- a/patches/cmd-launch-association/0001-cmd-Support-for-launching-programs-based-on-file-ass.patch +++ b/patches/cmd-launch-association/0001-cmd-Support-for-launching-programs-based-on-file-ass.patch @@ -1,4 +1,4 @@ -From 1e7b6a812b248a8344076a402fc97bd60da495d1 Mon Sep 17 00:00:00 2001 +From 0173ca4b3352506b76801619ae5a05f338d6ff6e Mon Sep 17 00:00:00 2001 From: Jason Edmeades Date: Tue, 16 Jul 2019 13:49:18 +1000 Subject: [PATCH] cmd: Support for launching programs based on file association @@ -15,10 +15,10 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=36646 1 file changed, 102 insertions(+), 37 deletions(-) diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c -index 12d3db1b012..0f222f3640b 100644 +index ce48b16d7ec..2d20ee299fa 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c -@@ -1494,8 +1494,10 @@ void WCMD_run_program (WCHAR *command, BOOL called) +@@ -1541,8 +1541,10 @@ void WCMD_run_program (WCHAR *command, BOOL called) /* 1. If extension supplied, see if that file exists */ if (extensionsupplied) { @@ -30,7 +30,7 @@ index 12d3db1b012..0f222f3640b 100644 } } -@@ -1525,6 +1527,7 @@ void WCMD_run_program (WCHAR *command, BOOL called) +@@ -1572,6 +1574,7 @@ void WCMD_run_program (WCHAR *command, BOOL called) } if (GetFileAttributesW(thisDir) != INVALID_FILE_ATTRIBUTES) { @@ -38,17 +38,17 @@ index 12d3db1b012..0f222f3640b 100644 found = TRUE; thisExt = NULL; } -@@ -1546,6 +1549,7 @@ void WCMD_run_program (WCHAR *command, BOOL called) - /* Special case BAT and CMD */ - if (ext && (!wcsicmp(ext, L".bat") || !wcsicmp(ext, L".cmd"))) { +@@ -1595,6 +1598,7 @@ void WCMD_run_program (WCHAR *command, BOOL called) + RETURN_CODE return_code; BOOL oldinteractive = interactive; + + WINE_TRACE("Calling batch program\n"); interactive = FALSE; - WCMD_batch(thisDir, command, NULL, INVALID_HANDLE_VALUE); + return_code = WCMD_batch(thisDir, command, NULL, INVALID_HANDLE_VALUE); interactive = oldinteractive; -@@ -1554,48 +1558,109 @@ void WCMD_run_program (WCHAR *command, BOOL called) - context->skip_rest = TRUE; - } +@@ -1605,48 +1609,109 @@ void WCMD_run_program (WCHAR *command, BOOL called) + if (return_code != RETURN_CODE_ABORTED && return_code != RETURN_CODE_OLD_CHAINING) + errorlevel = return_code; return; - } else { - DWORD exit_code; @@ -193,5 +193,5 @@ index 12d3db1b012..0f222f3640b 100644 } -- -2.43.0 +2.45.2 diff --git a/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch b/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch index 9686446f..98d6f227 100644 --- a/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch +++ b/patches/d3dx9_36-DDS/0002-d3dx9_36-Improve-D3DXSaveTextureToFile-to-save-simpl.patch @@ -1,4 +1,4 @@ -From f6d47bb4eb5747fde7059271a560268080756791 Mon Sep 17 00:00:00 2001 +From 96af775034dae1c0b133b315c45b7172090d3498 Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Sun, 11 Jan 2015 16:29:30 +0100 Subject: [PATCH] d3dx9_36: Improve D3DXSaveTextureToFile to save simple @@ -6,15 +6,15 @@ Subject: [PATCH] d3dx9_36: Improve D3DXSaveTextureToFile to save simple --- dlls/d3dx9_36/d3dx9_private.h | 2 ++ - dlls/d3dx9_36/surface.c | 62 +++++++++++++++++++++++++++++++++++ + dlls/d3dx9_36/surface.c | 63 +++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/texture.c | 5 +-- - 3 files changed, 65 insertions(+), 4 deletions(-) + 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h -index 001a7f26f4f..b322765d164 100644 +index 34a9f6eec7f..878dff3fc01 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h -@@ -182,6 +182,8 @@ HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLO +@@ -178,6 +178,8 @@ HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLO IDirect3DSurface9 **temp_surface, BOOL write); HRESULT unlock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, IDirect3DSurface9 *temp_surface, BOOL update); @@ -24,10 +24,10 @@ index 001a7f26f4f..b322765d164 100644 const PALETTEENTRY *palette, D3DFORMAT format, uint32_t left, uint32_t top, uint32_t right, uint32_t bottom, uint32_t front, uint32_t back, struct d3dx_pixels *pixels); diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c -index fb49ca5665a..2a8bd97fe2d 100644 +index 31bce97bbab..212d452c654 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c -@@ -560,6 +560,68 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur +@@ -574,6 +574,69 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur return D3D_OK; } @@ -93,14 +93,15 @@ index fb49ca5665a..2a8bd97fe2d 100644 + + return hr; +} - HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, - const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key, - const D3DXIMAGE_INFO *src_info) ++ + HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data, + const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) + { diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c -index 52cfb1e8c34..ccbe1fcef20 100644 +index b42c9db3f2d..d84bac25cfe 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c -@@ -1858,10 +1858,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE +@@ -1847,10 +1847,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL; if (file_format == D3DXIFF_DDS) @@ -113,5 +114,5 @@ index 52cfb1e8c34..ccbe1fcef20 100644 type = IDirect3DBaseTexture9_GetType(src_texture); switch (type) -- -2.43.0 +2.45.2 diff --git a/patches/server-Shared_Memory/0001-ntdll-Implement-virtual_map_shared_memory.patch b/patches/server-Shared_Memory/0001-ntdll-Implement-virtual_map_shared_memory.patch deleted file mode 100644 index 42670589..00000000 --- a/patches/server-Shared_Memory/0001-ntdll-Implement-virtual_map_shared_memory.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 702145ee9253eb9c92225118830e3d9d999a803a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 18 Mar 2015 23:03:01 +0100 -Subject: [PATCH] ntdll: Implement virtual_map_shared_memory. - -Preparation for shared memory wineserver communication. ---- - dlls/ntdll/ntdll_misc.h | 1 + - dlls/ntdll/virtual.c | 51 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 52 insertions(+) - -diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index 76e8ec284e8..7e7ce5413dd 100644 ---- a/dlls/ntdll/ntdll_misc.h -+++ b/dlls/ntdll/ntdll_misc.h -@@ -204,6 +204,7 @@ extern NTSTATUS virtual_alloc_teb( TEB **teb ) DECLSPEC_HIDDEN; - extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN; - extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, - SIZE_T commit_size, SIZE_T *pthread_size ) DECLSPEC_HIDDEN; -+extern NTSTATUS virtual_map_shared_memory( int fd, PVOID *addr_ptr, ULONG zero_bits, SIZE_T *size_ptr, ULONG protect ) DECLSPEC_HIDDEN; - extern void virtual_clear_thread_stack( void *stack_end ) DECLSPEC_HIDDEN; - extern int virtual_handle_stack_fault( void *addr ) DECLSPEC_HIDDEN; - extern BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size ) DECLSPEC_HIDDEN; -diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index 7700385eb7b..cf08937cb14 100644 ---- a/dlls/ntdll/virtual.c -+++ b/dlls/ntdll/virtual.c -@@ -3551,6 +3551,57 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p - } - - -+/*********************************************************************** -+ * virtual_map_shared_memory -+ */ -+NTSTATUS virtual_map_shared_memory( int fd, PVOID *addr_ptr, ULONG zero_bits, -+ SIZE_T *size_ptr, ULONG protect ) -+{ -+ SIZE_T size; -+ struct file_view *view; -+ unsigned int vprot; -+ sigset_t sigset; -+ NTSTATUS res; -+ int prot; -+ -+ size = ROUND_SIZE( 0, *size_ptr ); -+ if (size < *size_ptr) -+ return STATUS_INVALID_PARAMETER; -+ -+ server_enter_uninterrupted_section( &csVirtual, &sigset ); -+ -+ get_vprot_flags( protect, &vprot, FALSE ); -+ vprot |= VPROT_COMMITTED; -+ res = map_view( &view, *addr_ptr, size, FALSE, vprot, 0 ); -+ if (!res) -+ { -+ /* Map the shared memory */ -+ -+ prot = VIRTUAL_GetUnixProt( vprot ); -+ if (force_exec_prot && (vprot & VPROT_READ)) -+ { -+ TRACE( "forcing exec permission on mapping %p-%p\n", -+ (char *)view->base, (char *)view->base + size - 1 ); -+ prot |= PROT_EXEC; -+ } -+ -+ if (mmap( view->base, size, prot, MAP_FIXED | MAP_SHARED, fd, 0 ) != (void *)-1) -+ { -+ *addr_ptr = view->base; -+ *size_ptr = size; -+ } -+ else -+ { -+ ERR( "virtual_map_shared_memory %p %lx failed\n", view->base, size ); -+ delete_view( view ); -+ } -+ } -+ -+ server_leave_uninterrupted_section( &csVirtual, &sigset ); -+ return res; -+} -+ -+ - /*********************************************************************** - * NtUnmapViewOfSection (NTDLL.@) - * ZwUnmapViewOfSection (NTDLL.@) --- -2.26.2 - diff --git a/patches/server-Shared_Memory/0002-server-Implement-support-for-global-and-local-shared.patch b/patches/server-Shared_Memory/0002-server-Implement-support-for-global-and-local-shared.patch deleted file mode 100644 index 95269bac..00000000 --- a/patches/server-Shared_Memory/0002-server-Implement-support-for-global-and-local-shared.patch +++ /dev/null @@ -1,424 +0,0 @@ -From 0329ba2101bf6667bdfaa66bd70253b57ca4fdd1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Thu, 19 Mar 2015 01:22:34 +0100 -Subject: [PATCH] server: Implement support for global and local shared memory - blocks based on memfd. - ---- - dlls/ntdll/ntdll_misc.h | 1 + - dlls/ntdll/server.c | 64 +++++++++++++++++++++++++++++++++++ - dlls/ntdll/thread.c | 4 +++ - include/wine/server.h | 11 ++++++ - include/winternl.h | 2 +- - server/fd.c | 27 +++++++++++++++ - server/file.h | 8 +++++ - server/main.c | 1 + - server/mapping.c | 74 +++++++++++++++++++++++++++++++++++++++++ - server/protocol.def | 15 +++++++++ - server/thread.c | 7 ++++ - server/thread.h | 2 ++ - 12 files changed, 215 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index d83166a0ffc9..f57189112a0c 100644 ---- a/dlls/ntdll/ntdll_misc.h -+++ b/dlls/ntdll/ntdll_misc.h -@@ -140,6 +140,7 @@ extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN; - extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret, - data_size_t *ret_len ) DECLSPEC_HIDDEN; - extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN; -+extern void *server_get_shared_memory( HANDLE thread ) DECLSPEC_HIDDEN; - - /* module handling */ - extern LIST_ENTRY tls_links DECLSPEC_HIDDEN; -diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c -index 2ebc39e03e25..f004ed07d27e 100644 ---- a/dlls/ntdll/server.c -+++ b/dlls/ntdll/server.c -@@ -1149,6 +1149,66 @@ done: - } - - -+/*********************************************************************** -+ * server_get_shared_memory_fd -+ * -+ * Receive a file descriptor to a server shared memory block. -+ */ -+static int server_get_shared_memory_fd( HANDLE thread, int *unix_fd ) -+{ -+ obj_handle_t dummy; -+ sigset_t sigset; -+ int ret; -+ -+ server_enter_uninterrupted_section( &fd_cache_section, &sigset ); -+ -+ SERVER_START_REQ( get_shared_memory ) -+ { -+ req->tid = HandleToULong(thread); -+ if (!(ret = wine_server_call( req ))) -+ { -+ *unix_fd = receive_fd( &dummy ); -+ if (*unix_fd == -1) ret = STATUS_NOT_SUPPORTED; -+ } -+ } -+ SERVER_END_REQ; -+ -+ server_leave_uninterrupted_section( &fd_cache_section, &sigset ); -+ return ret; -+} -+ -+ -+/*********************************************************************** -+ * server_get_shared_memory -+ * -+ * Get address of a shared memory block. -+ */ -+void *server_get_shared_memory( HANDLE thread ) -+{ -+ static shmglobal_t *shmglobal = (void *)-1; -+ void *mem = NULL; -+ int fd = -1; -+ -+ /* The global memory block is only requested once. No locking is -+ * required because this function is called very early during the -+ * process initialization for the first time. */ -+ if (!thread && shmglobal != (void *)-1) -+ return shmglobal; -+ -+ if (!server_get_shared_memory_fd( thread, &fd )) -+ { -+ SIZE_T size = thread ? sizeof(shmlocal_t) : sizeof(shmglobal_t); -+ virtual_map_shared_memory( fd, &mem, 0, &size, PAGE_READONLY ); -+ close( fd ); -+ } -+ -+ if (!thread) -+ shmglobal = mem; -+ -+ return mem; -+} -+ -+ - /*********************************************************************** - * wine_server_fd_to_handle (NTDLL.@) - * -@@ -2011,6 +2071,10 @@ size_t server_init_thread( void *entry_point, BOOL *suspend ) - } - SERVER_END_REQ; - -+ /* initialize thread shared memory pointers */ -+ NtCurrentTeb()->Reserved5[1] = server_get_shared_memory( 0 ); -+ NtCurrentTeb()->Reserved5[2] = server_get_shared_memory( NtCurrentTeb()->ClientId.UniqueThread ); -+ - is_wow64 = !is_win64 && (server_cpus & ((1 << CPU_x86_64) | (1 << CPU_ARM64))) != 0; - ntdll_get_thread_data()->wow64_redir = is_wow64; - -diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c -index 8a0b612b39a4..464e01b1e305 100644 ---- a/dlls/ntdll/thread.c -+++ b/dlls/ntdll/thread.c -@@ -429,6 +429,7 @@ void exit_thread( int status ) - void WINAPI RtlExitUserThread( ULONG status ) - { - static void *prev_teb; -+ shmlocal_t *shmlocal; - sigset_t sigset; - TEB *teb; - -@@ -453,6 +454,9 @@ void WINAPI RtlExitUserThread( ULONG status ) - LdrShutdownThread(); - RtlFreeThreadActivationContextStack(); - -+ shmlocal = InterlockedExchangePointer( &NtCurrentTeb()->Reserved5[2], NULL ); -+ if (shmlocal) NtUnmapViewOfSection( NtCurrentProcess(), shmlocal ); -+ - pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); - - if ((teb = InterlockedExchangePointer( &prev_teb, NtCurrentTeb() ))) -diff --git a/include/wine/server.h b/include/wine/server.h -index ac5dcc6f8bcd..5a845f424c28 100644 ---- a/include/wine/server.h -+++ b/include/wine/server.h -@@ -120,6 +120,17 @@ static inline void *wine_server_get_ptr( client_ptr_t ptr ) - return (void *)(ULONG_PTR)ptr; - } - -+/* returns a pointer to the wineserver global shared memory block */ -+static inline shmglobal_t *wine_get_shmglobal(void) -+{ -+ return (shmglobal_t *)NtCurrentTeb()->Reserved5[1]; -+} -+ -+/* returns a pointer to the wineserver local shared memory block */ -+static inline shmlocal_t *wine_get_shmlocal(void) -+{ -+ return (shmlocal_t *)NtCurrentTeb()->Reserved5[2]; -+} - - /* macros for server requests */ - -diff --git a/include/winternl.h b/include/winternl.h -index 1d2d49414448..39c269d29163 100644 ---- a/include/winternl.h -+++ b/include/winternl.h -@@ -403,7 +403,7 @@ typedef struct _TEB - PVOID ReservedForPerf; /* f7c/1750 */ - PVOID ReservedForOle; /* f80/1758 */ - ULONG WaitingOnLoaderLock; /* f84/1760 */ -- PVOID Reserved5[3]; /* f88/1768 */ -+ PVOID Reserved5[3]; /* f88/1768 used for x86_64 OSX and wineserver shared memory */ - PVOID *TlsExpansionSlots; /* f94/1780 */ - #ifdef _WIN64 - PVOID DeallocationBStore; /* /1788 */ -diff --git a/server/fd.c b/server/fd.c -index 405240e14d84..cc8df828a653 100644 ---- a/server/fd.c -+++ b/server/fd.c -@@ -2704,6 +2704,33 @@ DECL_HANDLER(write) - release_object( fd ); - } - -+/* get file descriptor to shared memory block */ -+DECL_HANDLER(get_shared_memory) -+{ -+ if (req->tid) -+ { -+ struct thread *thread = get_thread_from_id( req->tid ); -+ if (thread) -+ { -+ if (thread->shm_fd != -1 || allocate_shared_memory( &thread->shm_fd, -+ (void **)&thread->shm, sizeof(*thread->shm) )) -+ { -+ send_client_fd( current->process, thread->shm_fd, 0 ); -+ } -+ else -+ set_error( STATUS_NOT_SUPPORTED ); -+ release_object( thread ); -+ } -+ } -+ else -+ { -+ if (shmglobal_fd != -1) -+ send_client_fd( current->process, shmglobal_fd, 0 ); -+ else -+ set_error( STATUS_NOT_SUPPORTED ); -+ } -+} -+ - /* perform an ioctl on a file */ - DECL_HANDLER(ioctl) - { -diff --git a/server/file.h b/server/file.h -index d577aaed3cfa..399f512cf49e 100644 ---- a/server/file.h -+++ b/server/file.h -@@ -182,6 +182,14 @@ extern struct object *create_mailslot_device( struct object *root, const struct - extern struct object *create_unix_device( struct object *root, const struct unicode_str *name, - const char *unix_path ); - -+/* shared memory functions */ -+ -+extern int allocate_shared_memory( int *fd, void **memory, size_t size ); -+extern void release_shared_memory( int fd, void *memory, size_t size ); -+extern void init_shared_memory( void ); -+extern shmglobal_t *shmglobal; -+extern int shmglobal_fd; -+ - /* change notification functions */ - - extern void do_change_notify( int unix_fd ); -diff --git a/server/main.c b/server/main.c -index 2b5065e18526..483a0c855808 100644 ---- a/server/main.c -+++ b/server/main.c -@@ -146,6 +146,7 @@ int main( int argc, char *argv[] ) - init_signals(); - init_directories(); - init_registry(); -+ init_shared_memory(); - main_loop(); - return 0; - } -diff --git a/server/mapping.c b/server/mapping.c -index d73d8de9c283..6c79f7d18a6f 100644 ---- a/server/mapping.c -+++ b/server/mapping.c -@@ -29,8 +29,32 @@ - #ifdef HAVE_SYS_MMAN_H - # include - #endif -+#ifdef HAVE_SYS_SYSCALL_H -+# include -+#endif - #include - -+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) -+ -+/* __NR_memfd_create might not yet be available when buildservers use an old kernel */ -+#ifndef __NR_memfd_create -+#ifdef __x86_64__ -+#define __NR_memfd_create 319 -+#else -+#define __NR_memfd_create 356 -+#endif -+#endif -+ -+/* the following declarations are only available in linux/fcntl.h, but not fcntl.h */ -+#define F_LINUX_SPECIFIC_BASE 1024 -+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) -+#define MFD_ALLOW_SEALING 0x0002U -+#define F_SEAL_SEAL 0x0001 -+#define F_SEAL_SHRINK 0x0002 -+#define F_SEAL_GROW 0x0004 -+ -+#endif -+ - #include "ntstatus.h" - #define WIN32_NO_STATUS - #include "windef.h" -@@ -191,6 +215,10 @@ static const struct fd_ops mapping_fd_ops = - - static size_t page_mask; - -+/* global shared memory */ -+shmglobal_t *shmglobal; -+int shmglobal_fd; -+ - #define ROUND_SIZE(size) (((size) + page_mask) & ~page_mask) - - -@@ -262,6 +290,52 @@ static int check_current_dir_for_exec(void) - return (ret != MAP_FAILED); - } - -+/* allocates a block of shared memory */ -+int allocate_shared_memory( int *fd, void **memory, size_t size ) -+{ -+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) -+ void *shm_mem; -+ int shm_fd; -+ -+ shm_fd = syscall( __NR_memfd_create, "wineserver_shm", MFD_ALLOW_SEALING ); -+ if (shm_fd == -1) goto err; -+ if (grow_file( shm_fd, size )) -+ { -+ if (fcntl( shm_fd, F_ADD_SEALS, F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW ) >= 0) -+ { -+ shm_mem = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0 ); -+ if (shm_mem != MAP_FAILED) -+ { -+ memset( shm_mem, 0, size ); -+ *fd = shm_fd; -+ *memory = shm_mem; -+ return 1; -+ } -+ } -+ } -+ close( shm_fd ); -+err: -+#endif -+ *memory = NULL; -+ *fd = -1; -+ return 0; -+} -+ -+/* releases a block of shared memory */ -+void release_shared_memory( int fd, void *memory, size_t size ) -+{ -+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) -+ if (memory) munmap( memory, size ); -+ if (fd != -1) close( fd ); -+#endif -+} -+ -+/* intialize shared memory management */ -+void init_shared_memory( void ) -+{ -+ allocate_shared_memory( &shmglobal_fd, (void **)&shmglobal, sizeof(*shmglobal) ); -+} -+ - /* create a temp file for anonymous mappings */ - static int create_temp_file( file_pos_t size ) - { -diff --git a/server/protocol.def b/server/protocol.def -index 197a48592e0a..99651c9ed534 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -69,6 +69,15 @@ struct request_max_size - #define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */ - #define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */ - -+typedef struct -+{ -+ int dummy; -+} shmglobal_t; -+ -+typedef struct -+{ -+ int dummy; -+} shmlocal_t; - - /* debug event data */ - typedef union -@@ -1335,6 +1344,12 @@ enum server_fd_type - @END - - -+/* Get file descriptor for shared memory */ -+@REQ(get_shared_memory) -+ thread_id_t tid; /* thread id or 0 */ -+@END -+ -+ - /* Flush a file buffers */ - @REQ(flush) - async_data_t async; /* async I/O parameters */ -diff --git a/server/thread.c b/server/thread.c -index 987da2f7c4ff..233320c78ad5 100644 ---- a/server/thread.c -+++ b/server/thread.c -@@ -239,6 +239,8 @@ static inline void init_thread_structure( struct thread *thread ) - thread->desc = NULL; - thread->desc_len = 0; - thread->exit_poll = NULL; -+ thread->shm_fd = -1; -+ thread->shm = NULL; - - thread->creation_time = current_time; - thread->exit_time = 0; -@@ -409,7 +411,10 @@ static void cleanup_thread( struct thread *thread ) - thread->inflight[i].client = thread->inflight[i].server = -1; - } - } -+ - free( thread->desc ); -+ release_shared_memory( thread->shm_fd, thread->shm, sizeof(*thread->shm) ); -+ - thread->req_data = NULL; - thread->reply_data = NULL; - thread->request_fd = NULL; -@@ -418,6 +423,8 @@ static void cleanup_thread( struct thread *thread ) - thread->desktop = 0; - thread->desc = NULL; - thread->desc_len = 0; -+ thread->shm_fd = -1; -+ thread->shm = NULL; - } - - /* destroy a thread when its refcount is 0 */ -diff --git a/server/thread.h b/server/thread.h -index 912df68eaf63..00f6f7c64a93 100644 ---- a/server/thread.h -+++ b/server/thread.h -@@ -91,6 +91,8 @@ struct thread - data_size_t desc_len; /* thread description length in bytes */ - WCHAR *desc; /* thread description string */ - struct timeout_user *exit_poll; /* poll if the thread/process has exited already */ -+ int shm_fd; /* file descriptor for thread local shared memory */ -+ shmlocal_t *shm; /* thread local shared memory pointer */ - }; - - struct thread_snapshot --- -2.26.2 - diff --git a/patches/server-Shared_Memory/0003-user32-Get-rid-of-wineserver-call-for-GetInputState.patch b/patches/server-Shared_Memory/0003-user32-Get-rid-of-wineserver-call-for-GetInputState.patch deleted file mode 100644 index 93f699ce..00000000 --- a/patches/server-Shared_Memory/0003-user32-Get-rid-of-wineserver-call-for-GetInputState.patch +++ /dev/null @@ -1,120 +0,0 @@ -From dc483d01e1493b319aecd409ce4e65223c18b5bd Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 19 Mar 2015 01:32:51 +0100 -Subject: user32: Get rid of wineserver call for GetInputState. - ---- - dlls/user32/input.c | 14 +++++++++++++- - server/protocol.def | 2 +- - server/queue.c | 14 ++++++++++++++ - 3 files changed, 28 insertions(+), 2 deletions(-) - -diff --git a/dlls/user32/input.c b/dlls/user32/input.c -index 130aacc..4cf6b61 100644 ---- a/dlls/user32/input.c -+++ b/dlls/user32/input.c -@@ -454,17 +454,29 @@ DWORD WINAPI GetQueueStatus( UINT flags ) - */ - BOOL WINAPI GetInputState(void) - { -+ shmlocal_t *shm = wine_get_shmlocal(); - DWORD ret; - - check_for_events( QS_INPUT ); - -+ /* req->clear is not set, so we can safely get the -+ * wineserver status without an additional call. */ -+ if (shm) -+ { -+ ret = shm->queue_bits; -+ goto done; -+ } -+ - SERVER_START_REQ( get_queue_status ) - { - req->clear_bits = 0; - wine_server_call( req ); -- ret = reply->wake_bits & (QS_KEY | QS_MOUSEBUTTON); -+ ret = reply->wake_bits; - } - SERVER_END_REQ; -+ -+done: -+ ret &= (QS_KEY | QS_MOUSEBUTTON); - return ret; - } - -diff --git a/server/protocol.def b/server/protocol.def -index ea2e231..4872251 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -76,7 +76,7 @@ typedef struct - - typedef struct - { -- int dummy; -+ int queue_bits; /* queue wake bits */ - } shmlocal_t; - - /* debug event data */ -diff --git a/server/queue.c b/server/queue.c -index c318fc3..3a1d2b7 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -118,6 +118,7 @@ struct thread_input - struct msg_queue - { - struct object obj; /* object header */ -+ struct thread *thread; /* reference to the thread owning the queue */ - struct fd *fd; /* optional file descriptor to poll */ - unsigned int wake_bits; /* wakeup bits */ - unsigned int wake_mask; /* wakeup mask */ -@@ -282,6 +283,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ - if ((queue = alloc_object( &msg_queue_ops ))) - { - queue->fd = NULL; -+ queue->thread = thread; - queue->wake_bits = 0; - queue->wake_mask = 0; - queue->changed_bits = 0; -@@ -315,6 +317,7 @@ void free_msg_queue( struct thread *thread ) - { - remove_thread_hooks( thread ); - if (!thread->queue) return; -+ thread->queue->thread = NULL; - release_object( thread->queue ); - thread->queue = NULL; - } -@@ -427,11 +430,21 @@ static inline int is_signaled( struct msg_queue *queue ) - return ((queue->wake_bits & queue->wake_mask) || (queue->changed_bits & queue->changed_mask)); - } - -+/* synchronize the queue state with the shared memory */ -+static inline void update_shm_queue_bits( struct msg_queue *queue ) -+{ -+ shmlocal_t *shm; -+ if (!queue->thread) return; -+ if ((shm = queue->thread->shm)) -+ shm->queue_bits = queue->wake_bits; -+} -+ - /* set some queue bits */ - static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits ) - { - queue->wake_bits |= bits; - queue->changed_bits |= bits; -+ update_shm_queue_bits( queue ); - if (is_signaled( queue )) wake_up( &queue->obj, 0 ); - } - -@@ -440,6 +453,7 @@ static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits - { - queue->wake_bits &= ~bits; - queue->changed_bits &= ~bits; -+ update_shm_queue_bits( queue ); - } - - /* check whether msg is a keyboard message */ --- -2.3.5 - diff --git a/patches/server-Shared_Memory/0006-ntdll-Only-enable-wineserver-shared-memory-communica.patch b/patches/server-Shared_Memory/0006-ntdll-Only-enable-wineserver-shared-memory-communica.patch deleted file mode 100644 index 27d91376..00000000 --- a/patches/server-Shared_Memory/0006-ntdll-Only-enable-wineserver-shared-memory-communica.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 3225fc5b602f25a2d17ee68b732ec2a59fb29c0f Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 19 Mar 2015 02:55:36 +0100 -Subject: [PATCH] ntdll: Only enable wineserver shared memory communication - when a special environment variable is set. - ---- - dlls/ntdll/server.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c -index 749e753ae5a..c3f9d11c760 100644 ---- a/dlls/ntdll/server.c -+++ b/dlls/ntdll/server.c -@@ -100,6 +100,7 @@ - #include "ddk/wdm.h" - - WINE_DEFAULT_DEBUG_CHANNEL(server); -+WINE_DECLARE_DEBUG_CHANNEL(winediag); - - /* just in case... */ - #undef EXT2_IOC_GETFLAGS -@@ -1177,6 +1178,21 @@ static int server_get_shared_memory_fd( HANDLE thread, int *unix_fd ) - return ret; - } - -+/* The shared memory wineserver communication is still highly experimental -+ * and might cause unexpected results when the client/server status gets -+ * out of synchronization. The feature will be disabled by default until it -+ * is tested a bit more. */ -+static inline BOOL experimental_SHARED_MEMORY( void ) -+{ -+ static int enabled = -1; -+ if (enabled == -1) -+ { -+ const char *str = getenv( "STAGING_SHARED_MEMORY" ); -+ enabled = str && (atoi(str) != 0); -+ } -+ return enabled; -+} -+ - - /*********************************************************************** - * server_get_shared_memory -@@ -1189,6 +1205,9 @@ void *server_get_shared_memory( HANDLE thread ) - void *mem = NULL; - int fd = -1; - -+ if (!experimental_SHARED_MEMORY()) -+ return NULL; -+ - /* The global memory block is only requested once. No locking is - * required because this function is called very early during the - * process initialization for the first time. */ -@@ -1203,7 +1222,10 @@ void *server_get_shared_memory( HANDLE thread ) - } - - if (!thread) -+ { -+ if (mem) WARN_(winediag)("Using shared memory wineserver communication\n"); - shmglobal = mem; -+ } - - return mem; - } --- -2.26.2 - diff --git a/patches/server-Shared_Memory/0007-server-Store-a-list-of-associated-queues-for-each-th.patch b/patches/server-Shared_Memory/0007-server-Store-a-list-of-associated-queues-for-each-th.patch deleted file mode 100644 index dd3ecf0a..00000000 --- a/patches/server-Shared_Memory/0007-server-Store-a-list-of-associated-queues-for-each-th.patch +++ /dev/null @@ -1,79 +0,0 @@ -From cb18df88215aa555e89a877ee5ede75706c170f9 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 21 Mar 2015 09:00:17 +0100 -Subject: server: Store a list of associated queues for each thread input. - -Required by the following patches, splitted as a separate patch for easier -reviewing. ---- - server/queue.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/server/queue.c b/server/queue.c -index 418a2b1..1b80348 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -99,6 +99,7 @@ struct thread_input - { - struct object obj; /* object header */ - struct desktop *desktop; /* desktop that this thread input belongs to */ -+ struct list queues; /* list of all queues this input belongs to */ - user_handle_t focus; /* focus window */ - user_handle_t capture; /* capture window */ - user_handle_t active; /* active window */ -@@ -139,6 +140,7 @@ struct msg_queue - lparam_t next_timer_id; /* id for the next timer with a 0 window */ - struct timeout_user *timeout; /* timeout for next timer to expire */ - struct thread_input *input; /* thread input descriptor */ -+ struct list input_entry; /* entry in input->queues */ - struct hook_table *hooks; /* hook table */ - timeout_t last_get_msg; /* time of last get message call */ - unsigned int ignore_post_msg; /* ignore post messages newer than this unique id */ -@@ -254,6 +256,7 @@ static struct thread_input *create_thread_input( struct thread *thread ) - input->cursor = 0; - input->cursor_count = 0; - input->lock_count = 0; -+ list_init( &input->queues ); - list_init( &input->msg_list ); - set_caret_window( input, 0 ); - memset( input->keystate, 0, sizeof(input->keystate) ); -@@ -297,6 +300,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ - queue->next_timer_id = 0x7fff; - queue->timeout = NULL; - queue->input = (struct thread_input *)grab_object( input ); -+ list_add_tail( &input->queues, &queue->input_entry ); - queue->hooks = NULL; - queue->last_get_msg = current_time; - queue->ignore_post_msg = 0; -@@ -336,10 +340,12 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_ - { - if (queue->keystate_locked) queue->input->lock_count--; - queue->input->cursor_count -= queue->cursor_count; -+ list_remove( &queue->input_entry ); - release_object( queue->input ); - queue->keystate_locked = 0; - } - queue->input = (struct thread_input *)grab_object( new_input ); -+ list_add_tail( &new_input->queues, &queue->input_entry ); - new_input->cursor_count += queue->cursor_count; - return 1; - } -@@ -1003,6 +1009,7 @@ static void msg_queue_destroy( struct object *obj ) - if (queue->timeout) remove_timeout_user( queue->timeout ); - if (queue->keystate_locked) queue->input->lock_count--; - queue->input->cursor_count -= queue->cursor_count; -+ list_remove( &queue->input_entry ); - release_object( queue->input ); - if (queue->hooks) release_object( queue->hooks ); - if (queue->fd) release_object( queue->fd ); -@@ -1029,6 +1036,7 @@ static void thread_input_destroy( struct object *obj ) - { - struct thread_input *input = (struct thread_input *)obj; - -+ assert( list_empty(&input->queues) ); - empty_msg_list( &input->msg_list ); - if (input->desktop) - { --- -2.3.5 - diff --git a/patches/server-Shared_Memory/0008-user32-Get-rid-of-wineserver-call-for-GetActiveWindo.patch b/patches/server-Shared_Memory/0008-user32-Get-rid-of-wineserver-call-for-GetActiveWindo.patch deleted file mode 100644 index 57d8d280..00000000 --- a/patches/server-Shared_Memory/0008-user32-Get-rid-of-wineserver-call-for-GetActiveWindo.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 452f8d47d7cd63f0fe5270d8ec6a7062544d3903 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 21 Mar 2015 09:45:54 +0100 -Subject: user32: Get rid of wineserver call for GetActiveWindow, GetFocus, - GetCapture. - ---- - dlls/user32/focus.c | 4 ++++ - dlls/user32/input.c | 2 ++ - server/protocol.def | 5 ++++- - server/queue.c | 30 +++++++++++++++++++++++++++++- - 4 files changed, 39 insertions(+), 2 deletions(-) - -diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c -index c47a82d..35fe89b 100644 ---- a/dlls/user32/focus.c -+++ b/dlls/user32/focus.c -@@ -329,8 +329,10 @@ BOOL WINAPI SetForegroundWindow( HWND hwnd ) - */ - HWND WINAPI GetActiveWindow(void) - { -+ shmlocal_t *shm = wine_get_shmlocal(); - HWND ret = 0; - -+ if (shm) return wine_server_ptr_handle( shm->input_active ); - SERVER_START_REQ( get_thread_input ) - { - req->tid = GetCurrentThreadId(); -@@ -346,8 +348,10 @@ HWND WINAPI GetActiveWindow(void) - */ - HWND WINAPI GetFocus(void) - { -+ shmlocal_t *shm = wine_get_shmlocal(); - HWND ret = 0; - -+ if (shm) return wine_server_ptr_handle( shm->input_focus ); - SERVER_START_REQ( get_thread_input ) - { - req->tid = GetCurrentThreadId(); -diff --git a/dlls/user32/input.c b/dlls/user32/input.c -index e63c8cf..0943d01 100644 ---- a/dlls/user32/input.c -+++ b/dlls/user32/input.c -@@ -342,8 +342,10 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReleaseCapture(void) - */ - HWND WINAPI GetCapture(void) - { -+ shmlocal_t *shm = wine_get_shmlocal(); - HWND ret = 0; - -+ if (shm) return wine_server_ptr_handle( shm->input_capture ); - SERVER_START_REQ( get_thread_input ) - { - req->tid = GetCurrentThreadId(); -diff --git a/server/protocol.def b/server/protocol.def -index f12109f..5ec2485 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -76,7 +76,10 @@ typedef struct - - typedef struct - { -- int queue_bits; /* queue wake bits */ -+ int queue_bits; /* queue wake bits */ -+ user_handle_t input_focus; /* focus window */ -+ user_handle_t input_capture; /* capture window */ -+ user_handle_t input_active; /* active window */ - } shmlocal_t; - - /* debug event data */ -diff --git a/server/queue.c b/server/queue.c -index 3f52656..33c2758 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -270,6 +270,25 @@ static struct thread_input *create_thread_input( struct thread *thread ) - return input; - } - -+/* synchronize the input state with the shared memory */ -+static void update_shm_thread_input( struct thread_input *input ) -+{ -+ struct msg_queue *queue; -+ -+ /* the loop doesn't matter, usually it should only have one or a few entries */ -+ LIST_FOR_EACH_ENTRY( queue, &input->queues, struct msg_queue, input_entry ) -+ { -+ shmlocal_t *shm; -+ if (!queue->thread) continue; -+ if ((shm = queue->thread->shm)) -+ { -+ shm->input_active = input->active; -+ shm->input_focus = input->focus; -+ shm->input_capture = input->capture; -+ } -+ } -+} -+ - /* create a message queue object */ - static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_input *input ) - { -@@ -312,7 +331,11 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ - - thread->queue = queue; - } -- if (new_input) release_object( new_input ); -+ if (new_input) -+ { -+ update_shm_thread_input( new_input ); -+ release_object( new_input ); -+ } - return queue; - } - -@@ -347,6 +370,7 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_ - queue->input = (struct thread_input *)grab_object( new_input ); - list_add_tail( &new_input->queues, &queue->input_entry ); - new_input->cursor_count += queue->cursor_count; -+ update_shm_thread_input( new_input ); - return 1; - } - -@@ -1056,6 +1080,7 @@ static inline void thread_input_cleanup_window( struct msg_queue *queue, user_ha - if (window == input->menu_owner) input->menu_owner = 0; - if (window == input->move_size) input->move_size = 0; - if (window == input->caret) set_caret_window( input, 0 ); -+ update_shm_thread_input( input ); - } - - /* check if the specified window can be set in the input data of a given queue */ -@@ -2985,6 +3010,7 @@ DECL_HANDLER(set_focus_window) - { - reply->previous = queue->input->focus; - queue->input->focus = get_user_full_handle( req->handle ); -+ update_shm_thread_input( queue->input ); - } - } - -@@ -3001,6 +3027,7 @@ DECL_HANDLER(set_active_window) - { - reply->previous = queue->input->active; - queue->input->active = get_user_full_handle( req->handle ); -+ update_shm_thread_input( queue->input ); - } - else set_error( STATUS_INVALID_HANDLE ); - } -@@ -3027,6 +3054,7 @@ DECL_HANDLER(set_capture_window) - input->capture = get_user_full_handle( req->handle ); - input->menu_owner = (req->flags & CAPTURE_MENU) ? input->capture : 0; - input->move_size = (req->flags & CAPTURE_MOVESIZE) ? input->capture : 0; -+ update_shm_thread_input( input ); - reply->full_handle = input->capture; - } - } --- -2.3.5 - diff --git a/staging/upstream-commit b/staging/upstream-commit index c672db64..be8a6b55 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -17f052c36a414a05fcb6a6e67bd3aac824fbed3e +797df8df394d81a165328f9ac6b4039253a78718