From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/loader.c | 25 ++++++++++++++++++------- dlls/win32u/syscall.c | 3 ++- 2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 3bb7f056b2a..cbfd1dacc90 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -364,6 +364,7 @@ static void * const syscalls[] = wine_unix_to_nt_file_name, };
+static ULONG_PTR syscall_flags[ARRAY_SIZE(syscalls)]; static BYTE syscall_args[ARRAY_SIZE(syscalls)];
SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4]; @@ -1335,20 +1336,30 @@ already_loaded: NTSTATUS ntdll_init_syscalls( ULONG id, SYSTEM_SERVICE_TABLE *table, void **dispatcher ) { struct syscall_info + { + BYTE syscall_args; + }; + struct syscall_table_info { void *dispatcher; USHORT limit; - BYTE args[1]; - } *info = (struct syscall_info *)dispatcher; + struct syscall_info info[1]; + } *table_info = (struct syscall_table_info *)dispatcher; + USHORT i;
if (id > 3) return STATUS_INVALID_PARAMETER; - if (info->limit != table->ServiceLimit) + if (table_info->limit != table->ServiceLimit) { - ERR( "syscall count mismatch %u / %lu\n", info->limit, table->ServiceLimit ); + ERR( "syscall count mismatch %u / %lu\n", table_info->limit, table->ServiceLimit ); NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_PARAMETER ); } - info->dispatcher = __wine_syscall_dispatcher; - memcpy( table->ArgumentTable, info->args, table->ServiceLimit ); + table_info->dispatcher = __wine_syscall_dispatcher; + + for (i = 0; i < table_info->limit; ++i) + { + table->ArgumentTable[i] = table_info->info[i].syscall_args; + } + KeServiceDescriptorTable[id] = *table; return STATUS_SUCCESS; } @@ -2174,7 +2185,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = */ static void start_main_thread(void) { - SYSTEM_SERVICE_TABLE syscall_table = { (ULONG_PTR *)syscalls, NULL, ARRAY_SIZE(syscalls), syscall_args }; + SYSTEM_SERVICE_TABLE syscall_table = { (ULONG_PTR *)syscalls, syscall_flags, ARRAY_SIZE(syscalls), syscall_args }; TEB *teb = virtual_alloc_first_teb();
signal_init_threading(); diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index ec6cd859ff6..e6e0de2f07c 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -306,12 +306,13 @@ static void * const syscalls[] = NtUserWindowFromPoint, };
+static ULONG_PTR syscall_flags[ARRAY_SIZE(syscalls)]; static BYTE arguments[ARRAY_SIZE(syscalls)];
static SYSTEM_SERVICE_TABLE syscall_table = { (ULONG_PTR *)syscalls, - 0, + syscall_flags, ARRAY_SIZE(syscalls), arguments };