ntdll: Call the Unix entry point from the Unix side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
22da5bd757
commit
e0fc8d7acb
|
@ -117,7 +117,6 @@ typedef struct _wine_modref
|
|||
{
|
||||
LDR_DATA_TABLE_ENTRY ldr;
|
||||
struct file_id id;
|
||||
void *unix_entry;
|
||||
int alloc_deps;
|
||||
int nDeps;
|
||||
struct _wine_modref **deps;
|
||||
|
@ -2340,12 +2339,12 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name,
|
|||
DWORD flags, WINE_MODREF** pwm, BOOL prefer_native )
|
||||
{
|
||||
NTSTATUS status;
|
||||
void *module, *unix_entry = NULL;
|
||||
void *module;
|
||||
SECTION_IMAGE_INFORMATION image_info;
|
||||
|
||||
TRACE("Trying built-in %s\n", debugstr_us(nt_name));
|
||||
|
||||
status = unix_funcs->load_builtin_dll( nt_name, &module, &unix_entry, &image_info, prefer_native );
|
||||
status = unix_funcs->load_builtin_dll( nt_name, &module, &image_info, prefer_native );
|
||||
if (status) return status;
|
||||
|
||||
if ((*pwm = get_modref( module ))) /* already loaded */
|
||||
|
@ -2359,8 +2358,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name,
|
|||
|
||||
TRACE( "loading %s\n", debugstr_us(nt_name) );
|
||||
status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm );
|
||||
if (!status) (*pwm)->unix_entry = unix_entry;
|
||||
else if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
|
||||
if (status && module) NtUnmapViewOfSection( NtCurrentProcess(), module );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -2730,15 +2728,11 @@ done:
|
|||
NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
NTSTATUS ret = STATUS_DLL_NOT_FOUND;
|
||||
NTSTATUS ret;
|
||||
|
||||
RtlEnterCriticalSection( &loader_section );
|
||||
|
||||
if ((wm = get_modref( module )))
|
||||
{
|
||||
NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = wm->unix_entry;
|
||||
if (init_func) ret = init_func( module, reason, ptr_in, ptr_out );
|
||||
}
|
||||
if ((wm = get_modref( module ))) ret = unix_funcs->init_unix_lib( module, reason, ptr_in, ptr_out );
|
||||
else ret = STATUS_INVALID_HANDLE;
|
||||
|
||||
RtlLeaveCriticalSection( &loader_section );
|
||||
|
|
|
@ -1107,7 +1107,7 @@ already_loaded:
|
|||
/***********************************************************************
|
||||
* dlopen_unix_dll
|
||||
*/
|
||||
static NTSTATUS dlopen_unix_dll( void *module, const char *name, void **unix_entry )
|
||||
static NTSTATUS dlopen_unix_dll( void *module, const char *name )
|
||||
{
|
||||
void *unix_module, *handle, *entry;
|
||||
const IMAGE_NT_HEADERS *nt;
|
||||
|
@ -1119,25 +1119,12 @@ static NTSTATUS dlopen_unix_dll( void *module, const char *name, void **unix_ent
|
|||
if (!(entry = dlsym( handle, "__wine_init_unix_lib" ))) goto done;
|
||||
|
||||
unix_module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
|
||||
switch (set_builtin_unix_handle( module, handle ))
|
||||
status = set_builtin_unix_handle( module, handle, entry );
|
||||
if (!status)
|
||||
{
|
||||
case STATUS_IMAGE_ALREADY_LOADED:
|
||||
*unix_entry = entry;
|
||||
return STATUS_SUCCESS;
|
||||
case STATUS_SUCCESS:
|
||||
map_so_dll( nt, unix_module );
|
||||
fixup_ntdll_imports( name, unix_module );
|
||||
*unix_entry = entry;
|
||||
return STATUS_SUCCESS;
|
||||
case STATUS_OBJECT_NAME_COLLISION:
|
||||
ERR( "module %p already has a Unix module that's not %s\n", module, debugstr_a(name) );
|
||||
break;
|
||||
case STATUS_DUPLICATE_NAME:
|
||||
ERR( "%s already loaded for module %p\n", debugstr_a(name), module );
|
||||
break;
|
||||
case STATUS_DLL_NOT_FOUND:
|
||||
ERR( "builtin module not found for %s\n", debugstr_a(name) );
|
||||
break;
|
||||
return status;
|
||||
}
|
||||
done:
|
||||
dlclose( handle );
|
||||
|
@ -1326,7 +1313,7 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **m
|
|||
/***********************************************************************
|
||||
* load_builtin_dll
|
||||
*/
|
||||
static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module, void **unix_entry,
|
||||
static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native )
|
||||
{
|
||||
unsigned int i, pos, namepos, namelen, maxlen = 0;
|
||||
|
@ -1400,7 +1387,7 @@ done:
|
|||
if (!status && ext)
|
||||
{
|
||||
strcpy( ext, ".so" );
|
||||
dlopen_unix_dll( *module, ptr, unix_entry );
|
||||
dlopen_unix_dll( *module, ptr );
|
||||
}
|
||||
free( file );
|
||||
return status;
|
||||
|
@ -1591,6 +1578,7 @@ static struct unix_funcs unix_funcs =
|
|||
load_so_dll,
|
||||
load_builtin_dll,
|
||||
init_builtin_dll,
|
||||
init_unix_lib,
|
||||
unwind_builtin_dll,
|
||||
get_load_order,
|
||||
__wine_dbg_get_channel_flags,
|
||||
|
|
|
@ -198,7 +198,8 @@ extern void virtual_set_large_address_space(void) DECLSPEC_HIDDEN;
|
|||
extern void virtual_fill_image_information( const pe_image_info_t *pe_info,
|
||||
SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||
extern void *get_builtin_so_handle( void *module ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS set_builtin_unix_handle( void *module, void *unix_handle ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL init_unix_lib( void *module, DWORD reason, const void *ptr_in, void *ptr_out ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern NTSTATUS get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_len ) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_thread_times( int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time,
|
||||
|
|
|
@ -91,6 +91,7 @@ struct builtin_module
|
|||
void *handle;
|
||||
void *module;
|
||||
void *unix_handle;
|
||||
void *unix_entry;
|
||||
};
|
||||
|
||||
static struct list builtin_modules = LIST_INIT( builtin_modules );
|
||||
|
@ -570,6 +571,7 @@ static void add_builtin_module( void *module, void *handle, const struct stat *s
|
|||
builtin->handle = handle;
|
||||
builtin->module = module;
|
||||
builtin->unix_handle = NULL;
|
||||
builtin->unix_entry = NULL;
|
||||
if (st)
|
||||
{
|
||||
builtin->dev = st->st_dev;
|
||||
|
@ -641,7 +643,7 @@ void *get_builtin_so_handle( void *module )
|
|||
/***********************************************************************
|
||||
* set_builtin_unix_handle
|
||||
*/
|
||||
NTSTATUS set_builtin_unix_handle( void *module, void *handle )
|
||||
NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry )
|
||||
{
|
||||
sigset_t sigset;
|
||||
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
||||
|
@ -650,25 +652,43 @@ NTSTATUS set_builtin_unix_handle( void *module, void *handle )
|
|||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
{
|
||||
if (builtin->module == module)
|
||||
if (builtin->module != module) continue;
|
||||
if (!builtin->unix_handle)
|
||||
{
|
||||
if (builtin->unix_handle == handle) status = STATUS_IMAGE_ALREADY_LOADED;
|
||||
else if (builtin->unix_handle) status = STATUS_OBJECT_NAME_COLLISION;
|
||||
else status = STATUS_SUCCESS;
|
||||
builtin->unix_handle = handle;
|
||||
builtin->unix_entry = entry;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else status = STATUS_IMAGE_ALREADY_LOADED;
|
||||
break;
|
||||
}
|
||||
if (builtin->unix_handle == handle)
|
||||
{
|
||||
status = STATUS_DUPLICATE_NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!status) builtin->unix_handle = handle;
|
||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* init_unix_lib
|
||||
*/
|
||||
NTSTATUS CDECL init_unix_lib( void *module, DWORD reason, const void *ptr_in, void *ptr_out )
|
||||
{
|
||||
sigset_t sigset;
|
||||
NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = NULL;
|
||||
struct builtin_module *builtin;
|
||||
|
||||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
{
|
||||
if (builtin->module != module) continue;
|
||||
init_func = builtin->unix_entry;
|
||||
break;
|
||||
}
|
||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
if (!init_func) return STATUS_DLL_NOT_FOUND;
|
||||
return init_func( module, reason, ptr_in, ptr_out );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* free_ranges_lower_bound
|
||||
*
|
||||
|
|
|
@ -37,7 +37,7 @@ enum loadorder
|
|||
};
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 117
|
||||
#define NTDLL_UNIXLIB_VERSION 118
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -85,9 +85,10 @@ struct unix_funcs
|
|||
|
||||
/* loader functions */
|
||||
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
|
||||
NTSTATUS (CDECL *load_builtin_dll)( UNICODE_STRING *name, void **module, void **unix_entry,
|
||||
NTSTATUS (CDECL *load_builtin_dll)( UNICODE_STRING *name, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native );
|
||||
void (CDECL *init_builtin_dll)( void *module );
|
||||
NTSTATUS (CDECL *init_unix_lib)( void *module, DWORD reason, const void *ptr_in, void *ptr_out );
|
||||
NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||
CONTEXT *context );
|
||||
enum loadorder (CDECL *get_load_order)( const WCHAR *app_name, const UNICODE_STRING *nt_name );
|
||||
|
|
Loading…
Reference in New Issue