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
|
# Unix files
|
||||||
@ stdcall wine_get_unix_file_name(str ptr long)
|
@ 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
|
# 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;
|
int argc;
|
||||||
WCHAR *p;
|
WCHAR *p;
|
||||||
|
@ -394,9 +394,6 @@ static void set_library_argv( char **argv )
|
||||||
total -= reslen;
|
total -= reslen;
|
||||||
}
|
}
|
||||||
wargv[argc] = NULL;
|
wargv[argc] = NULL;
|
||||||
|
|
||||||
__wine_main_argc = argc;
|
|
||||||
__wine_main_argv = argv;
|
|
||||||
__wine_main_wargv = wargv;
|
__wine_main_wargv = wargv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,9 +615,6 @@ static BOOL process_init( char *argv[] )
|
||||||
setbuf(stderr,NULL);
|
setbuf(stderr,NULL);
|
||||||
setlocale(LC_CTYPE,"");
|
setlocale(LC_CTYPE,"");
|
||||||
|
|
||||||
/* Setup the server connection */
|
|
||||||
wine_server_init_thread();
|
|
||||||
|
|
||||||
/* Retrieve startup info from the server */
|
/* Retrieve startup info from the server */
|
||||||
SERVER_START_REQ( init_process )
|
SERVER_START_REQ( init_process )
|
||||||
{
|
{
|
||||||
|
@ -639,9 +633,6 @@ static BOOL process_init( char *argv[] )
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
if (!ret) return FALSE;
|
if (!ret) return FALSE;
|
||||||
|
|
||||||
/* Create the process heap */
|
|
||||||
peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL );
|
|
||||||
|
|
||||||
if (info_size == 0)
|
if (info_size == 0)
|
||||||
{
|
{
|
||||||
params = peb->ProcessParameters;
|
params = peb->ProcessParameters;
|
||||||
|
@ -729,7 +720,7 @@ static void start_process( void *arg )
|
||||||
{
|
{
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
LdrInitializeThunk( main_exe_file, 0, 0, 0 );
|
LdrInitializeThunk( main_exe_file, CreateFileW, 0, 0 );
|
||||||
}
|
}
|
||||||
__EXCEPT(UnhandledExceptionFilter)
|
__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.
|
* 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;
|
WCHAR *main_exe_name, *p;
|
||||||
char error[1024];
|
char error[1024];
|
||||||
|
@ -753,22 +744,23 @@ void __wine_process_init( int argc, char *argv[] )
|
||||||
PEB *peb = NtCurrentTeb()->Peb;
|
PEB *peb = NtCurrentTeb()->Peb;
|
||||||
|
|
||||||
/* Initialize everything */
|
/* 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))
|
if (!(main_exe_name = peb->ProcessParameters->ImagePathName.Buffer))
|
||||||
{
|
{
|
||||||
WCHAR buffer[MAX_PATH];
|
WCHAR buffer[MAX_PATH];
|
||||||
WCHAR exe_nameW[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 */
|
/* 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 ))
|
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);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
if (main_exe_file == INVALID_HANDLE_VALUE)
|
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",
|
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();
|
MODULE_InitLoadPath();
|
||||||
VERSION_Init( main_exe_name );
|
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) );
|
TRACE( "starting Win16/DOS binary %s\n", debugstr_w(main_exe_name) );
|
||||||
CloseHandle( main_exe_file );
|
CloseHandle( main_exe_file );
|
||||||
main_exe_file = 0;
|
main_exe_file = 0;
|
||||||
argv--;
|
__wine_main_argv--;
|
||||||
argv[0] = "winevdm.exe";
|
__wine_main_argc++;
|
||||||
|
__wine_main_argv[0] = "winevdm.exe";
|
||||||
if (open_builtin_exe_file( winevdmW, error, sizeof(error), 0, &file_exists ))
|
if (open_builtin_exe_file( winevdmW, error, sizeof(error), 0, &file_exists ))
|
||||||
goto found;
|
goto found;
|
||||||
MESSAGE( "wine: trying to run %s, cannot open builtin library for 'winevdm.exe': %s\n",
|
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:
|
found:
|
||||||
/* build command line */
|
/* build command line */
|
||||||
set_library_argv( argv );
|
set_library_wargv( __wine_main_argv );
|
||||||
if (!build_command_line( __wine_main_wargv )) goto error;
|
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;
|
stack_size = RtlImageNtHeader(peb->ImageBaseAddress)->OptionalHeader.SizeOfStackReserve;
|
||||||
|
|
||||||
/* allocate main thread stack */
|
/* allocate main thread stack */
|
||||||
|
|
|
@ -138,13 +138,6 @@ inline static void set_status( NTSTATUS status )
|
||||||
NtCurrentTeb()->last_error = RtlNtStatusToDosError( 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 */
|
/* mark a block of memory as free for debugging purposes */
|
||||||
static inline void mark_block_free( void *ptr, size_t size )
|
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;
|
firstHeap = heapPtr;
|
||||||
RtlUnlockHeap( processHeap );
|
RtlUnlockHeap( processHeap );
|
||||||
}
|
}
|
||||||
else /* assume the first heap we create is the process main heap */
|
else processHeap = subheap->heap; /* assume the first heap we create is the process main heap */
|
||||||
{
|
|
||||||
set_process_heap( (HANDLE)subheap->heap );
|
|
||||||
}
|
|
||||||
return (HANDLE)subheap;
|
return (HANDLE)subheap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,8 @@ struct builtin_load_info
|
||||||
WINE_MODREF *wm;
|
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_module_count; /* number of modules with TLS directory */
|
||||||
static UINT tls_total_size; /* total size of TLS storage */
|
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 void load_builtin_callback( void *module, const char *filename )
|
||||||
{
|
{
|
||||||
|
static const WCHAR emptyW[1];
|
||||||
IMAGE_NT_HEADERS *nt;
|
IMAGE_NT_HEADERS *nt;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
WCHAR *fullname, *p;
|
WCHAR *fullname, *p;
|
||||||
|
const WCHAR *load_path;
|
||||||
|
|
||||||
if (!module)
|
if (!module)
|
||||||
{
|
{
|
||||||
|
@ -1078,7 +1081,10 @@ static void load_builtin_callback( void *module, const char *filename )
|
||||||
|
|
||||||
/* fixup imports */
|
/* 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 */
|
/* the module has only be inserted in the load & memory order lists */
|
||||||
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
||||||
|
@ -1738,9 +1744,9 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* LdrInitializeThunk (NTDLL.@)
|
* 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;
|
NTSTATUS status;
|
||||||
WINE_MODREF *wm;
|
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;
|
UNICODE_STRING *main_exe_name = &peb->ProcessParameters->ImagePathName;
|
||||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
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 */
|
/* allocate the modref for the main exe */
|
||||||
if (!(wm = alloc_module( peb->ImageBaseAddress, main_exe_name->Buffer )))
|
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
|
* __wine_process_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.
|
|
||||||
*/
|
*/
|
||||||
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;
|
WINE_MODREF *wm;
|
||||||
if (!MODULE_GetSystemDirectory( &system_dir ))
|
NTSTATUS status;
|
||||||
MESSAGE( "Couldn't get system dir in process init\n");
|
ANSI_STRING func_name;
|
||||||
NtCurrentTeb()->Peb->ImageBaseAddress = main;
|
void (DECLSPEC_NORETURN *init_func)();
|
||||||
default_info.status = STATUS_SUCCESS;
|
|
||||||
default_info.load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
|
/* setup the server connection */
|
||||||
builtin_load_info = &default_info;
|
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 );
|
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 ((status = load_builtin_dll( NULL, kernel32W, 0, &wm )) != STATUS_SUCCESS)
|
||||||
if (default_info.status != STATUS_SUCCESS)
|
{
|
||||||
MESSAGE( "Error while processing initial modules\n");
|
MESSAGE( "wine: could not load kernel32.dll, status %lx\n", status );
|
||||||
return NtCurrentTeb()->Peb->ImageBaseAddress;
|
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 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,
|
extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
|
||||||
const LARGE_INTEGER *timeout );
|
const LARGE_INTEGER *timeout );
|
||||||
|
extern void wine_server_init_process(void);
|
||||||
|
|
||||||
/* module handling */
|
/* module handling */
|
||||||
extern BOOL MODULE_GetSystemDirectory( UNICODE_STRING *sysdir );
|
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.
|
* Start the server and create the initial socket pair.
|
||||||
*/
|
*/
|
||||||
static void server_init(void)
|
void wine_server_init_process(void)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
char *oldcwd;
|
char *oldcwd;
|
||||||
|
@ -657,8 +657,6 @@ void wine_server_init_thread(void)
|
||||||
int reply_pipe[2];
|
int reply_pipe[2];
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
|
||||||
if (fd_socket == -1) server_init();
|
|
||||||
|
|
||||||
sig_act.sa_handler = SIG_IGN;
|
sig_act.sa_handler = SIG_IGN;
|
||||||
sig_act.sa_flags = 0;
|
sig_act.sa_flags = 0;
|
||||||
sigemptyset( &sig_act.sa_mask );
|
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,
|
extern void MODULE_GetLoadOrderA( enum loadorder_type plo[], const WCHAR *app_name,
|
||||||
const char *path, BOOL win32 );
|
const char *path, BOOL win32 );
|
||||||
|
|
||||||
/* relay32/builtin.c */
|
|
||||||
extern HMODULE BUILTIN32_LoadExeModule( HMODULE main, void *CreateFileW_ptr );
|
|
||||||
|
|
||||||
#endif /* __WINE_MODULE_H */
|
#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 LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**);
|
||||||
NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, const UNICODE_STRING*, HMODULE*);
|
NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, const UNICODE_STRING*, HMODULE*);
|
||||||
NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**);
|
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*);
|
NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
|
||||||
void WINAPI LdrShutdownProcess(void);
|
void WINAPI LdrShutdownProcess(void);
|
||||||
void WINAPI LdrShutdownThread(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 )
|
void wine_init( int argc, char *argv[], char *error, int error_size )
|
||||||
{
|
{
|
||||||
int file_exists;
|
int file_exists;
|
||||||
void *kernel;
|
void *ntdll;
|
||||||
void (*init_func)(int, char **);
|
void (*init_func)(void);
|
||||||
|
|
||||||
build_dll_path();
|
build_dll_path();
|
||||||
init_argv0_path( argv[0] );
|
init_argv0_path( argv[0] );
|
||||||
if (!dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists )) return;
|
__wine_main_argc = argc;
|
||||||
/* make sure kernel32 is loaded too */
|
__wine_main_argv = argv;
|
||||||
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;
|
if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists ))) return;
|
||||||
init_func( argc, argv );
|
if (!(init_func = wine_dlsym( ntdll, "__wine_process_init", error, error_size ))) return;
|
||||||
|
init_func();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue