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;
|
LDR_DATA_TABLE_ENTRY ldr;
|
||||||
struct file_id id;
|
struct file_id id;
|
||||||
void *unix_entry;
|
|
||||||
int alloc_deps;
|
int alloc_deps;
|
||||||
int nDeps;
|
int nDeps;
|
||||||
struct _wine_modref **deps;
|
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 )
|
DWORD flags, WINE_MODREF** pwm, BOOL prefer_native )
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
void *module, *unix_entry = NULL;
|
void *module;
|
||||||
SECTION_IMAGE_INFORMATION image_info;
|
SECTION_IMAGE_INFORMATION image_info;
|
||||||
|
|
||||||
TRACE("Trying built-in %s\n", debugstr_us(nt_name));
|
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 (status) return status;
|
||||||
|
|
||||||
if ((*pwm = get_modref( module ))) /* already loaded */
|
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) );
|
TRACE( "loading %s\n", debugstr_us(nt_name) );
|
||||||
status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm );
|
status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm );
|
||||||
if (!status) (*pwm)->unix_entry = unix_entry;
|
if (status && module) NtUnmapViewOfSection( NtCurrentProcess(), module );
|
||||||
else if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2730,15 +2728,11 @@ done:
|
||||||
NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
|
NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
NTSTATUS ret = STATUS_DLL_NOT_FOUND;
|
NTSTATUS ret;
|
||||||
|
|
||||||
RtlEnterCriticalSection( &loader_section );
|
RtlEnterCriticalSection( &loader_section );
|
||||||
|
|
||||||
if ((wm = get_modref( module )))
|
if ((wm = get_modref( module ))) ret = unix_funcs->init_unix_lib( module, reason, ptr_in, ptr_out );
|
||||||
{
|
|
||||||
NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = wm->unix_entry;
|
|
||||||
if (init_func) ret = init_func( module, reason, ptr_in, ptr_out );
|
|
||||||
}
|
|
||||||
else ret = STATUS_INVALID_HANDLE;
|
else ret = STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &loader_section );
|
RtlLeaveCriticalSection( &loader_section );
|
||||||
|
|
|
@ -1107,7 +1107,7 @@ already_loaded:
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* dlopen_unix_dll
|
* 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;
|
void *unix_module, *handle, *entry;
|
||||||
const IMAGE_NT_HEADERS *nt;
|
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;
|
if (!(entry = dlsym( handle, "__wine_init_unix_lib" ))) goto done;
|
||||||
|
|
||||||
unix_module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
|
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 );
|
map_so_dll( nt, unix_module );
|
||||||
fixup_ntdll_imports( name, unix_module );
|
fixup_ntdll_imports( name, unix_module );
|
||||||
*unix_entry = entry;
|
return status;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
dlclose( handle );
|
dlclose( handle );
|
||||||
|
@ -1326,7 +1313,7 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **m
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* load_builtin_dll
|
* 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 )
|
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native )
|
||||||
{
|
{
|
||||||
unsigned int i, pos, namepos, namelen, maxlen = 0;
|
unsigned int i, pos, namepos, namelen, maxlen = 0;
|
||||||
|
@ -1400,7 +1387,7 @@ done:
|
||||||
if (!status && ext)
|
if (!status && ext)
|
||||||
{
|
{
|
||||||
strcpy( ext, ".so" );
|
strcpy( ext, ".so" );
|
||||||
dlopen_unix_dll( *module, ptr, unix_entry );
|
dlopen_unix_dll( *module, ptr );
|
||||||
}
|
}
|
||||||
free( file );
|
free( file );
|
||||||
return status;
|
return status;
|
||||||
|
@ -1591,6 +1578,7 @@ static struct unix_funcs unix_funcs =
|
||||||
load_so_dll,
|
load_so_dll,
|
||||||
load_builtin_dll,
|
load_builtin_dll,
|
||||||
init_builtin_dll,
|
init_builtin_dll,
|
||||||
|
init_unix_lib,
|
||||||
unwind_builtin_dll,
|
unwind_builtin_dll,
|
||||||
get_load_order,
|
get_load_order,
|
||||||
__wine_dbg_get_channel_flags,
|
__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,
|
extern void virtual_fill_image_information( const pe_image_info_t *pe_info,
|
||||||
SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN;
|
SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||||
extern void *get_builtin_so_handle( void *module ) 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 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,
|
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 *handle;
|
||||||
void *module;
|
void *module;
|
||||||
void *unix_handle;
|
void *unix_handle;
|
||||||
|
void *unix_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct list builtin_modules = LIST_INIT( builtin_modules );
|
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->handle = handle;
|
||||||
builtin->module = module;
|
builtin->module = module;
|
||||||
builtin->unix_handle = NULL;
|
builtin->unix_handle = NULL;
|
||||||
|
builtin->unix_entry = NULL;
|
||||||
if (st)
|
if (st)
|
||||||
{
|
{
|
||||||
builtin->dev = st->st_dev;
|
builtin->dev = st->st_dev;
|
||||||
|
@ -641,7 +643,7 @@ void *get_builtin_so_handle( void *module )
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* set_builtin_unix_handle
|
* 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;
|
sigset_t sigset;
|
||||||
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
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 );
|
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
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;
|
builtin->unix_handle = handle;
|
||||||
else if (builtin->unix_handle) status = STATUS_OBJECT_NAME_COLLISION;
|
builtin->unix_entry = entry;
|
||||||
else status = STATUS_SUCCESS;
|
status = STATUS_SUCCESS;
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (builtin->unix_handle == handle)
|
|
||||||
{
|
|
||||||
status = STATUS_DUPLICATE_NAME;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else status = STATUS_IMAGE_ALREADY_LOADED;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!status) builtin->unix_handle = handle;
|
|
||||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||||
return status;
|
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
|
* free_ranges_lower_bound
|
||||||
*
|
*
|
||||||
|
|
|
@ -37,7 +37,7 @@ enum loadorder
|
||||||
};
|
};
|
||||||
|
|
||||||
/* increment this when you change the function table */
|
/* increment this when you change the function table */
|
||||||
#define NTDLL_UNIXLIB_VERSION 117
|
#define NTDLL_UNIXLIB_VERSION 118
|
||||||
|
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
|
@ -85,9 +85,10 @@ struct unix_funcs
|
||||||
|
|
||||||
/* loader functions */
|
/* loader functions */
|
||||||
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
|
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 );
|
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native );
|
||||||
void (CDECL *init_builtin_dll)( void *module );
|
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,
|
NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||||
CONTEXT *context );
|
CONTEXT *context );
|
||||||
enum loadorder (CDECL *get_load_order)( const WCHAR *app_name, const UNICODE_STRING *nt_name );
|
enum loadorder (CDECL *get_load_order)( const WCHAR *app_name, const UNICODE_STRING *nt_name );
|
||||||
|
|
Loading…
Reference in New Issue