Commit 410e6b7b authored by Alexandre Julliard's avatar Alexandre Julliard

Changed the init code to make libwine load only ntdll and transfer

control to it, and then have ntdll load kernel32 using the normal loader mechanisms. Get rid of BUILTIN32_LoadExeModule.
parent 3da1e246
......@@ -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
#
......
......@@ -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 */
......
......@@ -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;
}
......
......@@ -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();
}
......@@ -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 );
......
......@@ -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 );
......
......@@ -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 */
......@@ -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);
......
......@@ -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();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment