Module: wine Branch: master Commit: f6dbcccab9e33f05b4df9ba3824a849b172b97c3 URL: https://gitlab.winehq.org/wine/wine/-/commit/f6dbcccab9e33f05b4df9ba3824a849...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Aug 28 13:47:14 2023 +0200
wow64: Send cross-process notifications.
---
dlls/wow64/process.c | 16 ------- dlls/wow64/syscall.c | 2 +- dlls/wow64/virtual.c | 116 +++++++++++++++++++++++++++++++++++++++------ dlls/wow64/wow64_private.h | 2 +- 4 files changed, 103 insertions(+), 33 deletions(-)
diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index 2b6674ccf1b..880b7623b10 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -426,22 +426,6 @@ NTSTATUS WINAPI wow64_NtDebugActiveProcess( UINT *args ) }
-/********************************************************************** - * wow64_NtFlushInstructionCache - */ -NTSTATUS WINAPI wow64_NtFlushInstructionCache( UINT *args ) -{ - HANDLE process = get_handle( &args ); - const void *addr = get_ptr( &args ); - SIZE_T size = get_ulong( &args ); - - if (pBTCpuNotifyFlushInstructionCache2 && RtlIsCurrentProcess( process )) - pBTCpuNotifyFlushInstructionCache2( addr, size ); - - return NtFlushInstructionCache( process, addr, size ); -} - - /********************************************************************** * wow64_NtFlushProcessWriteBuffers */ diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index 70c63535ae6..f5a020bac0a 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -115,7 +115,7 @@ void (WINAPI *pBTCpuNotifyFlushInstructionCache2)( const void *, SIZE_T ) = NULL void (WINAPI *pBTCpuNotifyMapViewOfSection)( void * ) = NULL; void (WINAPI *pBTCpuNotifyMemoryAlloc)( void *, SIZE_T, ULONG, ULONG ) = NULL; void (WINAPI *pBTCpuNotifyMemoryDirty)( void *, SIZE_T ) = NULL; -void (WINAPI *pBTCpuNotifyMemoryFree)( void *, SIZE_T ) = NULL; +void (WINAPI *pBTCpuNotifyMemoryFree)( void *, SIZE_T, ULONG ) = NULL; void (WINAPI *pBTCpuNotifyMemoryProtect)( void *, SIZE_T, ULONG ) = NULL; void (WINAPI *pBTCpuNotifyUnmapViewOfSection)( void * ) = NULL; void (WINAPI *pBTCpuUpdateProcessorInformation)( SYSTEM_CPU_INFORMATION * ) = NULL; diff --git a/dlls/wow64/virtual.c b/dlls/wow64/virtual.c index 6a63f3793bb..79b4e9c2288 100644 --- a/dlls/wow64/virtual.c +++ b/dlls/wow64/virtual.c @@ -32,6 +32,36 @@
WINE_DEFAULT_DEBUG_CHANNEL(wow);
+static BOOL WINAPIV send_cross_process_notification( HANDLE process, UINT id, const void *addr, SIZE_T size, + int nb_args, ... ) +{ + CROSS_PROCESS_WORK_LIST *list; + CROSS_PROCESS_WORK_ENTRY *entry; + void *unused; + HANDLE section; + va_list args; + int i; + + RtlOpenCrossProcessEmulatorWorkConnection( process, §ion, (void **)&list ); + if (!list) return FALSE; + if ((entry = RtlWow64PopCrossProcessWorkFromFreeList( &list->free_list ))) + { + entry->id = id; + entry->addr = (ULONG_PTR)addr; + entry->size = size; + if (nb_args) + { + va_start( args, nb_args ); + for (i = 0; i < nb_args; i++) entry->args[i] = va_arg( args, int ); + va_end( args ); + } + RtlWow64PushCrossProcessWorkOntoWorkList( &list->work_list, entry, &unused ); + } + NtUnmapViewOfSection( GetCurrentProcess(), list ); + NtClose( section ); + return TRUE; +} +
static MEMORY_RANGE_ENTRY *memory_range_entry_array_32to64( const MEMORY_RANGE_ENTRY32 *addresses32, ULONG count ) @@ -118,16 +148,27 @@ NTSTATUS WINAPI wow64_NtAllocateVirtualMemory( UINT *args ) ULONG type = get_ulong( &args ); ULONG protect = get_ulong( &args );
- void *addr; - SIZE_T size; + void *addr = ULongToPtr( *addr32 ); + SIZE_T size = *size32; + BOOL is_current = RtlIsCurrentProcess( process ); NTSTATUS status;
- status = NtAllocateVirtualMemory( process, addr_32to64( &addr, addr32 ), get_zero_bits( zero_bits ), - size_32to64( &size, size32 ), type, protect ); + if (!addr) type |= MEM_RESERVE; + + if (!is_current) + send_cross_process_notification( process, CrossProcessPreVirtualAlloc, + addr, size, 3, type, protect, 0 ); + + status = NtAllocateVirtualMemory( process, &addr, get_zero_bits( zero_bits ), &size, type, protect ); if (!status) { - if (pBTCpuNotifyMemoryAlloc && RtlIsCurrentProcess(process)) - pBTCpuNotifyMemoryAlloc( addr, size, type, protect ); + if (is_current) + { + if (pBTCpuNotifyMemoryAlloc) pBTCpuNotifyMemoryAlloc( addr, size, type, protect ); + } + else send_cross_process_notification( process, CrossProcessPostVirtualAlloc, + addr, size, 3, type, protect, 0 ); + put_addr( addr32, addr ); put_size( size32, size ); } @@ -148,20 +189,30 @@ NTSTATUS WINAPI wow64_NtAllocateVirtualMemoryEx( UINT *args ) MEM_EXTENDED_PARAMETER32 *params32 = get_ptr( &args ); ULONG count = get_ulong( &args );
- void *addr; - SIZE_T size; + void *addr = ULongToPtr( *addr32 ); + SIZE_T size = *size32; NTSTATUS status; MEM_EXTENDED_PARAMETER *params64; BOOL is_current = RtlIsCurrentProcess( process ); BOOL set_limit = (!*addr32 && is_current);
+ if (!addr) type |= MEM_RESERVE; + if ((status = mem_extended_parameters_32to64( ¶ms64, params32, &count, set_limit ))) return status;
- status = NtAllocateVirtualMemoryEx( process, addr_32to64( &addr, addr32 ), size_32to64( &size, size32 ), - type, protect, params64, count ); + if (!is_current) send_cross_process_notification( process, CrossProcessPreVirtualAlloc, + addr, size, 3, type, protect, 0 ); + + status = NtAllocateVirtualMemoryEx( process, &addr, &size, type, protect, params64, count ); if (!status) { - if (pBTCpuNotifyMemoryAlloc && is_current) pBTCpuNotifyMemoryAlloc( addr, size, type, protect ); + if (is_current) + { + if (pBTCpuNotifyMemoryAlloc) pBTCpuNotifyMemoryAlloc( addr, size, type, protect ); + } + else send_cross_process_notification( process, CrossProcessPostVirtualAlloc, + addr, size, 3, type, protect, 0 ); + put_addr( addr32, addr ); put_size( size32, size ); } @@ -181,6 +232,25 @@ NTSTATUS WINAPI wow64_NtAreMappedFilesTheSame( UINT *args ) }
+/********************************************************************** + * wow64_NtFlushInstructionCache + */ +NTSTATUS WINAPI wow64_NtFlushInstructionCache( UINT *args ) +{ + HANDLE process = get_handle( &args ); + const void *addr = get_ptr( &args ); + SIZE_T size = get_ulong( &args ); + + if (RtlIsCurrentProcess( process )) + { + if (pBTCpuNotifyFlushInstructionCache2) pBTCpuNotifyFlushInstructionCache2( addr, size ); + } + else send_cross_process_notification( process, CrossProcessFlushCache, addr, size, 0 ); + + return NtFlushInstructionCache( process, addr, size ); +} + + /********************************************************************** * wow64_NtFlushVirtualMemory */ @@ -218,14 +288,22 @@ NTSTATUS WINAPI wow64_NtFreeVirtualMemory( UINT *args )
void *addr = ULongToPtr( *addr32 ); SIZE_T size = *size32; + BOOL is_current = RtlIsCurrentProcess( process ); NTSTATUS status;
- if (pBTCpuNotifyMemoryFree && RtlIsCurrentProcess( process )) - pBTCpuNotifyMemoryFree( addr, size ); + if (is_current) + { + if (pBTCpuNotifyMemoryFree) pBTCpuNotifyMemoryFree( addr, size, type ); + } + else send_cross_process_notification( process, CrossProcessPreVirtualFree, + addr, size, 2, type, 0 );
status = NtFreeVirtualMemory( process, &addr, &size, type ); if (!status) { + if (!is_current) + send_cross_process_notification( process, CrossProcessPostVirtualFree, + addr, size, 2, type, 0 ); put_addr( addr32, addr ); put_size( size32, size ); } @@ -428,14 +506,22 @@ NTSTATUS WINAPI wow64_NtProtectVirtualMemory( UINT *args )
void *addr = ULongToPtr( *addr32 ); SIZE_T size = *size32; + BOOL is_current = RtlIsCurrentProcess( process ); NTSTATUS status;
- if (pBTCpuNotifyMemoryProtect && RtlIsCurrentProcess(process)) - pBTCpuNotifyMemoryProtect( addr, size, new_prot ); + if (is_current) + { + if (pBTCpuNotifyMemoryProtect) pBTCpuNotifyMemoryProtect( addr, size, new_prot ); + } + else send_cross_process_notification( process, CrossProcessPreVirtualProtect, + addr, size, 2, new_prot, 0 );
status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot ); if (!status) { + if (!is_current) + send_cross_process_notification( process, CrossProcessPostVirtualProtect, + addr, size, 2, new_prot, 0 ); put_addr( addr32, addr ); put_size( size32, size ); } diff --git a/dlls/wow64/wow64_private.h b/dlls/wow64/wow64_private.h index 5b09d16c9d9..6f98a5f7a57 100644 --- a/dlls/wow64/wow64_private.h +++ b/dlls/wow64/wow64_private.h @@ -43,7 +43,7 @@ extern void (WINAPI *pBTCpuNotifyFlushInstructionCache2)( const void *, SIZE_T ) extern void (WINAPI *pBTCpuNotifyMapViewOfSection)( void * ); extern void (WINAPI *pBTCpuNotifyMemoryAlloc)( void *, SIZE_T, ULONG, ULONG ); extern void (WINAPI *pBTCpuNotifyMemoryDirty)( void *, SIZE_T ); -extern void (WINAPI *pBTCpuNotifyMemoryFree)( void *, SIZE_T ); +extern void (WINAPI *pBTCpuNotifyMemoryFree)( void *, SIZE_T, ULONG ); extern void (WINAPI *pBTCpuNotifyMemoryProtect)( void *, SIZE_T, ULONG ); extern void (WINAPI *pBTCpuNotifyUnmapViewOfSection)( void * ); extern void (WINAPI *pBTCpuUpdateProcessorInformation)( SYSTEM_CPU_INFORMATION * );