diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 244ab3162ec..ab4710d3413 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -1132,6 +1132,9 @@ # Unix files @ stdcall wine_get_unix_file_name(str ptr long) +# Init code +@ cdecl __wine_kernel_init() + ################################################################ # Wine dll separation hacks, these will go away, don't use them # diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 67eddae3dc0..a0a8129306f 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -369,11 +369,11 @@ static BOOL build_initial_environment(void) /*********************************************************************** - * set_library_argv + * set_library_wargv * - * Set the Wine library argc/argv global variables. + * Set the Wine library Unicode argv global variables. */ -static void set_library_argv( char **argv ) +static void set_library_wargv( char **argv ) { int argc; WCHAR *p; @@ -394,9 +394,6 @@ static void set_library_argv( char **argv ) total -= reslen; } wargv[argc] = NULL; - - __wine_main_argc = argc; - __wine_main_argv = argv; __wine_main_wargv = wargv; } @@ -618,9 +615,6 @@ static BOOL process_init( char *argv[] ) setbuf(stderr,NULL); setlocale(LC_CTYPE,""); - /* Setup the server connection */ - wine_server_init_thread(); - /* Retrieve startup info from the server */ SERVER_START_REQ( init_process ) { @@ -639,9 +633,6 @@ static BOOL process_init( char *argv[] ) SERVER_END_REQ; if (!ret) return FALSE; - /* Create the process heap */ - peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL ); - if (info_size == 0) { params = peb->ProcessParameters; @@ -729,7 +720,7 @@ static void start_process( void *arg ) { __TRY { - LdrInitializeThunk( main_exe_file, 0, 0, 0 ); + LdrInitializeThunk( main_exe_file, CreateFileW, 0, 0 ); } __EXCEPT(UnhandledExceptionFilter) { @@ -740,11 +731,11 @@ static void start_process( void *arg ) /*********************************************************************** - * __wine_process_init + * __wine_kernel_init * * Wine initialisation: load and start the main exe file. */ -void __wine_process_init( int argc, char *argv[] ) +void __wine_kernel_init(void) { WCHAR *main_exe_name, *p; char error[1024]; @@ -753,22 +744,23 @@ void __wine_process_init( int argc, char *argv[] ) PEB *peb = NtCurrentTeb()->Peb; /* Initialize everything */ - if (!process_init( argv )) exit(1); + if (!process_init( __wine_main_argv )) exit(1); - argv++; /* remove argv[0] (wine itself) */ + __wine_main_argv++; /* remove argv[0] (wine itself) */ + __wine_main_argc--; if (!(main_exe_name = peb->ProcessParameters->ImagePathName.Buffer)) { WCHAR buffer[MAX_PATH]; WCHAR exe_nameW[MAX_PATH]; - if (!argv[0]) OPTIONS_Usage(); + if (!__wine_main_argv[0]) OPTIONS_Usage(); /* FIXME: locale info not loaded yet */ - MultiByteToWideChar( CP_UNIXCP, 0, argv[0], -1, exe_nameW, MAX_PATH ); + MultiByteToWideChar( CP_UNIXCP, 0, __wine_main_argv[0], -1, exe_nameW, MAX_PATH ); if (!find_exe_file( exe_nameW, buffer, MAX_PATH, &main_exe_file )) { - MESSAGE( "wine: cannot find '%s'\n", argv[0] ); + MESSAGE( "wine: cannot find '%s'\n", __wine_main_argv[0] ); ExitProcess(1); } if (main_exe_file == INVALID_HANDLE_VALUE) @@ -781,7 +773,7 @@ void __wine_process_init( int argc, char *argv[] ) } TRACE( "starting process name=%s file=%p argv[0]=%s\n", - debugstr_w(main_exe_name), main_exe_file, debugstr_a(argv[0]) ); + debugstr_w(main_exe_name), main_exe_file, debugstr_a(__wine_main_argv[0]) ); MODULE_InitLoadPath(); VERSION_Init( main_exe_name ); @@ -821,8 +813,9 @@ void __wine_process_init( int argc, char *argv[] ) TRACE( "starting Win16/DOS binary %s\n", debugstr_w(main_exe_name) ); CloseHandle( main_exe_file ); main_exe_file = 0; - argv--; - argv[0] = "winevdm.exe"; + __wine_main_argv--; + __wine_main_argc++; + __wine_main_argv[0] = "winevdm.exe"; if (open_builtin_exe_file( winevdmW, error, sizeof(error), 0, &file_exists )) goto found; MESSAGE( "wine: trying to run %s, cannot open builtin library for 'winevdm.exe': %s\n", @@ -860,12 +853,9 @@ void __wine_process_init( int argc, char *argv[] ) found: /* build command line */ - set_library_argv( argv ); + set_library_wargv( __wine_main_argv ); if (!build_command_line( __wine_main_wargv )) goto error; - /* create 32-bit module for main exe */ - if (!(peb->ImageBaseAddress = BUILTIN32_LoadExeModule( peb->ImageBaseAddress, CreateFileW ))) - goto error; stack_size = RtlImageNtHeader(peb->ImageBaseAddress)->OptionalHeader.SizeOfStackReserve; /* allocate main thread stack */ diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index b45ace8884a..3c6eae02aee 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -138,13 +138,6 @@ inline static void set_status( NTSTATUS status ) NtCurrentTeb()->last_error = RtlNtStatusToDosError( status ); } -/* set the process main heap */ -static void set_process_heap( HANDLE heap ) -{ - NtCurrentTeb()->Peb->ProcessHeap = heap; - processHeap = heap; -} - /* mark a block of memory as free for debugging purposes */ static inline void mark_block_free( void *ptr, size_t size ) { @@ -1035,10 +1028,8 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, ULONG totalSize, ULONG com firstHeap = heapPtr; RtlUnlockHeap( processHeap ); } - else /* assume the first heap we create is the process main heap */ - { - set_process_heap( (HANDLE)subheap->heap ); - } + else processHeap = subheap->heap; /* assume the first heap we create is the process main heap */ + return (HANDLE)subheap; } diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index ad69abf4747..200f23bf295 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -82,7 +82,8 @@ struct builtin_load_info WINE_MODREF *wm; }; -static struct builtin_load_info *builtin_load_info; +static struct builtin_load_info default_load_info; +static struct builtin_load_info *builtin_load_info = &default_load_info; static UINT tls_module_count; /* number of modules with TLS directory */ static UINT tls_total_size; /* total size of TLS storage */ @@ -1029,9 +1030,11 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name, */ static void load_builtin_callback( void *module, const char *filename ) { + static const WCHAR emptyW[1]; IMAGE_NT_HEADERS *nt; WINE_MODREF *wm; WCHAR *fullname, *p; + const WCHAR *load_path; if (!module) { @@ -1078,7 +1081,10 @@ static void load_builtin_callback( void *module, const char *filename ) /* fixup imports */ - if (fixup_imports( wm, builtin_load_info->load_path ) != STATUS_SUCCESS) + load_path = builtin_load_info->load_path; + if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; + if (!load_path) load_path = emptyW; + if (fixup_imports( wm, load_path ) != STATUS_SUCCESS) { /* the module has only be inserted in the load & memory order lists */ RemoveEntryList(&wm->ldr.InLoadOrderModuleList); @@ -1738,9 +1744,9 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule) /****************************************************************** * LdrInitializeThunk (NTDLL.@) * - * FIXME: the arguments are not correct, main_file is a Wine invention. + * FIXME: the arguments are not correct, main_file and CreateFileW_ptr are Wine inventions. */ -void WINAPI LdrInitializeThunk( HANDLE main_file, ULONG unknown2, ULONG unknown3, ULONG unknown4 ) +void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG unknown3, ULONG unknown4 ) { NTSTATUS status; WINE_MODREF *wm; @@ -1750,6 +1756,13 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, ULONG unknown2, ULONG unknown3 UNICODE_STRING *main_exe_name = &peb->ProcessParameters->ImagePathName; IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress ); + pCreateFileW = CreateFileW_ptr; + if (!MODULE_GetSystemDirectory( &system_dir )) + { + ERR( "Couldn't get system dir\n"); + exit(1); + } + /* allocate the modref for the main exe */ if (!(wm = alloc_module( peb->ImageBaseAddress, main_exe_name->Buffer ))) { @@ -1874,28 +1887,42 @@ PVOID WINAPI RtlImageRvaToVa( const IMAGE_NT_HEADERS *nt, HMODULE module, /*********************************************************************** - * BUILTIN32_Init - * - * Initialize loading callbacks and return HMODULE of main exe. - * 'main' is the main exe in case it was already loaded from a PE file. - * - * FIXME: this should be done differently once kernel is properly separated. + * __wine_process_init */ -HMODULE BUILTIN32_LoadExeModule( HMODULE main, void *CreateFileW_ptr ) +void __wine_process_init( int argc, char *argv[] ) { - static struct builtin_load_info default_info; + static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0}; - pCreateFileW = CreateFileW_ptr; - if (!MODULE_GetSystemDirectory( &system_dir )) - MESSAGE( "Couldn't get system dir in process init\n"); - NtCurrentTeb()->Peb->ImageBaseAddress = main; - default_info.status = STATUS_SUCCESS; - default_info.load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; - builtin_load_info = &default_info; + WINE_MODREF *wm; + NTSTATUS status; + ANSI_STRING func_name; + void (DECLSPEC_NORETURN *init_func)(); + + /* setup the server connection */ + wine_server_init_process(); + wine_server_init_thread(); + + /* create the process heap */ + if (!(NtCurrentTeb()->Peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL ))) + { + MESSAGE( "wine: failed to create the process heap\n" ); + exit(1); + } + + /* setup the load callback and create ntdll modref */ wine_dll_set_callback( load_builtin_callback ); - if (!NtCurrentTeb()->Peb->ImageBaseAddress) - MESSAGE( "No built-in EXE module loaded! Did you create a .spec file?\n" ); - if (default_info.status != STATUS_SUCCESS) - MESSAGE( "Error while processing initial modules\n"); - return NtCurrentTeb()->Peb->ImageBaseAddress; + + if ((status = load_builtin_dll( NULL, kernel32W, 0, &wm )) != STATUS_SUCCESS) + { + MESSAGE( "wine: could not load kernel32.dll, status %lx\n", status ); + exit(1); + } + RtlInitAnsiString( &func_name, "__wine_kernel_init" ); + if ((status = LdrGetProcedureAddress( wm->ldr.BaseAddress, &func_name, + 0, (void **)&init_func )) != STATUS_SUCCESS) + { + MESSAGE( "wine: could not find __wine_kernel_init in kernel32.dll, status %lx\n", status ); + exit(1); + } + init_func(); } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 109ef7ded62..3713208bfb2 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -38,6 +38,7 @@ extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes); extern void NTDLL_get_server_timeout( abs_time_t *when, const LARGE_INTEGER *timeout ); extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags, const LARGE_INTEGER *timeout ); +extern void wine_server_init_process(void); /* module handling */ extern BOOL MODULE_GetSystemDirectory( UNICODE_STRING *sysdir ); diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 4f74307e3f9..54f6966077d 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -600,11 +600,11 @@ static int server_connect( const char *oldcwd, const char *serverdir ) /*********************************************************************** - * server_init + * wine_server_init_process * * Start the server and create the initial socket pair. */ -static void server_init(void) +void wine_server_init_process(void) { int size; char *oldcwd; @@ -657,8 +657,6 @@ void wine_server_init_thread(void) int reply_pipe[2]; struct sigaction sig_act; - if (fd_socket == -1) server_init(); - sig_act.sa_handler = SIG_IGN; sig_act.sa_flags = 0; sigemptyset( &sig_act.sa_mask ); diff --git a/include/module.h b/include/module.h index 0f8839f4c7d..c5138c322c0 100644 --- a/include/module.h +++ b/include/module.h @@ -203,7 +203,4 @@ extern void MODULE_GetLoadOrderW( enum loadorder_type plo[], const WCHAR *app_na extern void MODULE_GetLoadOrderA( enum loadorder_type plo[], const WCHAR *app_name, const char *path, BOOL win32 ); -/* relay32/builtin.c */ -extern HMODULE BUILTIN32_LoadExeModule( HMODULE main, void *CreateFileW_ptr ); - #endif /* __WINE_MODULE_H */ diff --git a/include/winternl.h b/include/winternl.h index 97ce5fea81f..e7d976cd462 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -957,7 +957,7 @@ NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULO NTSTATUS WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**); NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, const UNICODE_STRING*, HMODULE*); NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**); -void WINAPI LdrInitializeThunk(HANDLE,ULONG,ULONG,ULONG); +void WINAPI LdrInitializeThunk(HANDLE,LPVOID,ULONG,ULONG); NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*); void WINAPI LdrShutdownProcess(void); void WINAPI LdrShutdownThread(void); diff --git a/libs/wine/loader.c b/libs/wine/loader.c index ed2a8260cad..fe725e6a786 100644 --- a/libs/wine/loader.c +++ b/libs/wine/loader.c @@ -415,16 +415,17 @@ void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, void wine_init( int argc, char *argv[], char *error, int error_size ) { int file_exists; - void *kernel; - void (*init_func)(int, char **); + void *ntdll; + void (*init_func)(void); build_dll_path(); init_argv0_path( argv[0] ); - if (!dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists )) return; - /* make sure kernel32 is loaded too */ - if (!(kernel = dlopen_dll( "kernel32.dll", error, error_size, 0, &file_exists ))) return; - if (!(init_func = wine_dlsym( kernel, "__wine_process_init", error, error_size ))) return; - init_func( argc, argv ); + __wine_main_argc = argc; + __wine_main_argv = argv; + + if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists ))) return; + if (!(init_func = wine_dlsym( ntdll, "__wine_process_init", error, error_size ))) return; + init_func(); }