Commit e5339ecb authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Add a Wine-specific class in NtQueryVirtualMemory to retrieve the init…

ntdll: Add a Wine-specific class in NtQueryVirtualMemory to retrieve the init functions of a module. Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent c6373abc
......@@ -1338,6 +1338,31 @@ static void call_tls_callbacks( HMODULE module, UINT reason )
}
}
/*************************************************************************
* init_builtin_dll
*/
static void init_builtin_dll( HMODULE module )
{
void *buffer[16];
void (**funcs)(int, char **, char **) = (void *)buffer;
SIZE_T i, size;
NTSTATUS status;
status = NtQueryVirtualMemory( GetCurrentProcess(), module, MemoryWineImageInitFuncs,
buffer, sizeof(buffer), &size );
if (status == STATUS_BUFFER_TOO_SMALL)
{
if (!(funcs = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return;
status = NtQueryVirtualMemory( GetCurrentProcess(), module, MemoryWineImageInitFuncs,
funcs, size, &size );
}
if (!status) for (i = 0; i < size / sizeof(*funcs); i++) funcs[i]( 0, NULL, NULL );
if ((void *)funcs != (void *)buffer) RtlFreeHeap( GetProcessHeap(), 0, funcs );
}
/*************************************************************************
* MODULE_InitDLL
*/
......@@ -1354,7 +1379,7 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return STATUS_SUCCESS;
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, reason );
if (wm->ldr.Flags & LDR_WINE_INTERNAL && reason == DLL_PROCESS_ATTACH)
unix_funcs->init_builtin_dll( wm->ldr.DllBase );
init_builtin_dll( wm->ldr.DllBase );
if (!entry) return STATUS_SUCCESS;
if (TRACE_ON(relay))
......@@ -3914,7 +3939,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
}
release_address_space();
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, DLL_PROCESS_ATTACH );
if (wm->ldr.Flags & LDR_WINE_INTERNAL) unix_funcs->init_builtin_dll( wm->ldr.DllBase );
if (wm->ldr.Flags & LDR_WINE_INTERNAL) init_builtin_dll( wm->ldr.DllBase );
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
process_breakpoint();
}
......
......@@ -1700,26 +1700,21 @@ static BOOL get_relocbase(caddr_t mapbase, caddr_t *relocbase)
#endif
/*************************************************************************
* init_builtin_dll
* get_builtin_init_funcs
*/
static void CDECL init_builtin_dll( void *module )
NTSTATUS get_builtin_init_funcs( void *handle, void **funcs, SIZE_T len, SIZE_T *retlen )
{
#ifdef HAVE_DLINFO
void *handle = NULL;
struct link_map *map;
void (*init_func)(int, char **, char **) = NULL;
void (**init_array)(int, char **, char **) = NULL;
ULONG_PTR i, init_arraysz = 0;
void *init_func = NULL, **init_array = NULL;
ULONG_PTR i, count, init_arraysz = 0;
#ifdef _WIN64
const Elf64_Dyn *dyn;
#else
const Elf32_Dyn *dyn;
#endif
if (!(handle = get_builtin_so_handle( module ))) return;
if (dlinfo( handle, RTLD_DI_LINKMAP, &map )) map = NULL;
release_builtin_module( module );
if (!map) return;
if (dlinfo( handle, RTLD_DI_LINKMAP, &map )) return STATUS_INVALID_IMAGE_FORMAT;
for (dyn = map->l_ld; dyn->d_tag; dyn++)
{
......@@ -1738,13 +1733,16 @@ static void CDECL init_builtin_dll( void *module )
}
}
TRACE( "%p: got init_func %p init_array %p %lu\n", module, init_func, init_array, init_arraysz );
TRACE( "%p: got init_func %p init_array %p %lu\n", handle, init_func, init_array, init_arraysz );
if (init_func) init_func( main_argc, main_argv, main_envp );
count = init_arraysz / sizeof(*init_array);
if (init_func) count++;
if (retlen) *retlen = count * sizeof(*funcs);
if (init_array)
for (i = 0; i < init_arraysz / sizeof(*init_array); i++)
init_array[i]( main_argc, main_argv, main_envp );
if (count > len / sizeof(*funcs)) return STATUS_BUFFER_TOO_SMALL;
if (init_func) *funcs++ = init_func;
for (i = 0; i < init_arraysz / sizeof(*init_array); i++) funcs[i] = init_array[i];
return STATUS_SUCCESS;
#endif
}
......@@ -1896,7 +1894,6 @@ static struct unix_funcs unix_funcs =
ntdll_sqrt,
ntdll_tan,
load_so_dll,
init_builtin_dll,
init_unix_lib,
unwind_builtin_dll,
};
......
......@@ -158,6 +158,7 @@ extern BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) DECLSPE
extern NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *curdir, WCHAR **image,
void **module ) DECLSPEC_HIDDEN;
extern NTSTATUS load_start_exe( WCHAR **image, void **module ) DECLSPEC_HIDDEN;
extern NTSTATUS get_builtin_init_funcs( void *handle, void **funcs, SIZE_T len, SIZE_T *retlen ) DECLSPEC_HIDDEN;
extern void start_server( BOOL debug ) DECLSPEC_HIDDEN;
extern unsigned int server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN;
......
......@@ -4281,6 +4281,21 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
case MemoryMappedFilenameInformation:
return get_memory_section_name( process, addr, buffer, len, res_len );
case MemoryWineImageInitFuncs:
if (process == GetCurrentProcess())
{
void *module = (void *)addr;
void *handle = get_builtin_so_handle( module );
if (handle)
{
NTSTATUS status = get_builtin_init_funcs( handle, buffer, len, res_len );
release_builtin_module( module );
return status;
}
}
return STATUS_INVALID_HANDLE;
default:
FIXME("(%p,%p,info_class=%d,%p,%ld,%p) Unknown information class\n",
process, addr, info_class, buffer, len, res_len);
......
......@@ -26,7 +26,7 @@
struct _DISPATCHER_CONTEXT;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 124
#define NTDLL_UNIXLIB_VERSION 125
struct unix_funcs
{
......@@ -71,7 +71,6 @@ struct unix_funcs
/* loader functions */
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, 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,
CONTEXT *context );
......
......@@ -363,6 +363,9 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
break;
}
case MemoryWineImageInitFuncs:
return STATUS_INVALID_INFO_CLASS;
default:
FIXME( "unsupported class %u\n", class );
return STATUS_INVALID_INFO_CLASS;
......
......@@ -1918,6 +1918,9 @@ typedef enum _MEMORY_INFORMATION_CLASS {
MemoryEnclaveImageInformation,
MemoryBasicInformationCapped,
MemoryPhysicalContiguityInformation,
#ifdef __WINESRC__
MemoryWineImageInitFuncs = 1000
#endif
} MEMORY_INFORMATION_CLASS;
typedef struct _MEMORY_SECTION_NAME
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment