Module: wine Branch: master Commit: 7ee9c19687beeb80474619cd611e08e84dfd82e8 URL: https://gitlab.winehq.org/wine/wine/-/commit/7ee9c19687beeb80474619cd611e08e...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Aug 25 12:09:12 2023 +0200
ntdll: Also store syscall id and names following the syscall dispatcher pointer.
---
dlls/ntdll/unix/loader.c | 19 +++++++++++++------ dlls/win32u/syscall.c | 2 +- include/wine/unixlib.h | 2 +- tools/winebuild/import.c | 7 +++++-- 4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 8d5fc79895c..a32d0e31544 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1233,24 +1233,31 @@ static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name, void * /*********************************************************************** * ntdll_init_syscalls */ -NTSTATUS ntdll_init_syscalls( ULONG id, SYSTEM_SERVICE_TABLE *table, void **dispatcher ) +NTSTATUS ntdll_init_syscalls( SYSTEM_SERVICE_TABLE *table, void **dispatcher ) { struct syscall_info { void *dispatcher; + UINT version; + USHORT id; USHORT limit; - BYTE args[1]; + /* USHORT names[limit]; */ + /* BYTE args[limit]; */ } *info = (struct syscall_info *)dispatcher;
- if (id > 3) return STATUS_INVALID_PARAMETER; + if (info->version != 0xca110001) + { + ERR( "invalid syscall table version %x\n", info->version ); + NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_PARAMETER ); + } if (info->limit != table->ServiceLimit) { ERR( "syscall count mismatch %u / %lu\n", info->limit, table->ServiceLimit ); NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_PARAMETER ); } info->dispatcher = __wine_syscall_dispatcher; - memcpy( table->ArgumentTable, info->args, table->ServiceLimit ); - KeServiceDescriptorTable[id] = *table; + memcpy( table->ArgumentTable, (USHORT *)(info + 1) + info->limit, table->ServiceLimit ); + KeServiceDescriptorTable[info->id] = *table; return STATUS_SUCCESS; }
@@ -2093,7 +2100,7 @@ static void start_main_thread(void) load_ntdll(); if (main_image_info.Machine != current_machine) load_wow64_ntdll( main_image_info.Machine ); load_apiset_dll(); - ntdll_init_syscalls( 0, &syscall_table, p__wine_syscall_dispatcher ); + ntdll_init_syscalls( &syscall_table, p__wine_syscall_dispatcher ); server_init_process_done(); }
diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 99fd7859250..b5fee3a12c7 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -461,7 +461,7 @@ static NTSTATUS init( void *dispatcher ) } #endif
- return ntdll_init_syscalls( 1, &syscall_table, dispatcher ); + return ntdll_init_syscalls( &syscall_table, dispatcher ); }
unixlib_entry_t __wine_unix_call_funcs[] = diff --git a/include/wine/unixlib.h b/include/wine/unixlib.h index f853f1c6a31..8a9522ec532 100644 --- a/include/wine/unixlib.h +++ b/include/wine/unixlib.h @@ -36,7 +36,7 @@ extern DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD d extern int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict ); extern int ntdll_wcsicmp( const WCHAR *str1, const WCHAR *str2 ); extern int ntdll_wcsnicmp( const WCHAR *str1, const WCHAR *str2, int n ); -extern NTSTATUS ntdll_init_syscalls( ULONG id, SYSTEM_SERVICE_TABLE *table, void **dispatcher ); +extern NTSTATUS ntdll_init_syscalls( SYSTEM_SERVICE_TABLE *table, void **dispatcher );
/* exception handling */
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index fcf93addb50..99258a94527 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1529,8 +1529,11 @@ void output_syscalls( DLLSPEC *spec ) output( "\t.data\n" ); output( "\t.align %d\n", get_alignment( get_ptr_size() ) ); output( "%s\n", asm_globl("__wine_syscall_dispatcher") ); - output( "\t%s 0\n", get_asm_ptr_keyword() ); - output( "\t.short %u\n", count ); + output( "\t%s 0\n", get_asm_ptr_keyword() ); /* dispatcher */ + output( "\t.long 0xca110001\n" ); /* version */ + output( "\t.short %u\n", spec->syscall_table ); /* id */ + output( "\t.short %u\n", count ); /* limit */ + for (i = 0; i < count; i++) output( "\t.short %u\n", syscalls[i]->hint ); for (i = 0; i < count; i++) output( "\t.byte %u\n", get_args_size( syscalls[i] )); }