Rebase against 797df8df394d81a165328f9ac6b4039253a78718.

This commit is contained in:
Elizabeth Figura 2024-07-04 18:08:56 -05:00
parent 0d4b9f2f62
commit 0e802db66f
9 changed files with 27 additions and 961 deletions

View File

@ -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 <us@edmeades.me.uk>
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

View File

@ -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 <titan.costa@gmail.com>
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

View File

@ -1,88 +0,0 @@
From 702145ee9253eb9c92225118830e3d9d999a803a Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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

View File

@ -1,424 +0,0 @@
From 0329ba2101bf6667bdfaa66bd70253b57ca4fdd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
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 <sys/mman.h>
#endif
+#ifdef HAVE_SYS_SYSCALL_H
+# include <sys/syscall.h>
+#endif
#include <unistd.h>
+#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

View File

@ -1,120 +0,0 @@
From dc483d01e1493b319aecd409ce4e65223c18b5bd Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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

View File

@ -1,68 +0,0 @@
From 3225fc5b602f25a2d17ee68b732ec2a59fb29c0f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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

View File

@ -1,79 +0,0 @@
From cb18df88215aa555e89a877ee5ede75706c170f9 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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

View File

@ -1,156 +0,0 @@
From 452f8d47d7cd63f0fe5270d8ec6a7062544d3903 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
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

View File

@ -1 +1 @@
17f052c36a414a05fcb6a6e67bd3aac824fbed3e
797df8df394d81a165328f9ac6b4039253a78718