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:
parent
3da1e24643
commit
410e6b7b39
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue