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.
This commit is contained in:
Alexandre Julliard 2003-10-10 00:12:17 +00:00
parent 3da1e24643
commit 410e6b7b39
9 changed files with 85 additions and 77 deletions

View File

@ -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
#

View File

@ -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 */

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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 */

View File

@ -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);

View File

@ -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();
}