mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 10:13:56 +00:00
ntdll: Add support for running IL-only .NET executables.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e1c2a87061
commit
39c8875ff8
8 changed files with 56 additions and 9 deletions
|
@ -886,6 +886,44 @@ static void free_tls_slot( LDR_MODULE *mod )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* fixup_imports_ilonly
|
||||||
|
*
|
||||||
|
* Fixup imports for an IL-only module. All we do is import mscoree.
|
||||||
|
* The loader_section must be locked while calling this function.
|
||||||
|
*/
|
||||||
|
static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void **entry )
|
||||||
|
{
|
||||||
|
static const WCHAR mscoreeW[] = {'m','s','c','o','r','e','e','.','d','l','l',0};
|
||||||
|
IMAGE_EXPORT_DIRECTORY *exports;
|
||||||
|
DWORD exp_size;
|
||||||
|
NTSTATUS status;
|
||||||
|
void *proc = NULL;
|
||||||
|
WINE_MODREF *prev, *imp;
|
||||||
|
|
||||||
|
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */
|
||||||
|
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
|
||||||
|
|
||||||
|
wm->nDeps = 1;
|
||||||
|
wm->deps = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(WINE_MODREF *) );
|
||||||
|
|
||||||
|
prev = current_modref;
|
||||||
|
current_modref = wm;
|
||||||
|
if (!(status = load_dll( load_path, mscoreeW, 0, &imp ))) wm->deps[0] = imp;
|
||||||
|
current_modref = prev;
|
||||||
|
if (status) return status;
|
||||||
|
|
||||||
|
TRACE( "loaded mscoree for %s\n", debugstr_w(wm->ldr.FullDllName.Buffer) );
|
||||||
|
|
||||||
|
if ((exports = RtlImageDirectoryEntryToData( imp->ldr.BaseAddress, TRUE,
|
||||||
|
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
|
||||||
|
proc = find_named_export( imp->ldr.BaseAddress, exports, exp_size, "_CorExeMain", -1, load_path );
|
||||||
|
if (!proc) return STATUS_PROCEDURE_NOT_FOUND;
|
||||||
|
*entry = proc;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* fixup_imports
|
* fixup_imports
|
||||||
*
|
*
|
||||||
|
@ -1837,6 +1875,9 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (image_info.loader_flags) wm->ldr.Flags |= LDR_COR_IMAGE;
|
||||||
|
if (image_info.image_flags & IMAGE_FLAGS_ComPlusILOnly) wm->ldr.Flags |= LDR_COR_ILONLY;
|
||||||
|
|
||||||
set_security_cookie( module, len );
|
set_security_cookie( module, len );
|
||||||
|
|
||||||
/* fixup imports */
|
/* fixup imports */
|
||||||
|
@ -2991,7 +3032,7 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
|
||||||
* Attach to all the loaded dlls.
|
* Attach to all the loaded dlls.
|
||||||
* If this is the first time, perform the full process initialization.
|
* If this is the first time, perform the full process initialization.
|
||||||
*/
|
*/
|
||||||
NTSTATUS attach_dlls( CONTEXT *context )
|
NTSTATUS attach_dlls( CONTEXT *context, void **entry )
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
|
@ -3009,7 +3050,12 @@ NTSTATUS attach_dlls( CONTEXT *context )
|
||||||
if (!imports_fixup_done)
|
if (!imports_fixup_done)
|
||||||
{
|
{
|
||||||
actctx_init();
|
actctx_init();
|
||||||
if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS)
|
if (wm->ldr.Flags & LDR_COR_ILONLY)
|
||||||
|
status = fixup_imports_ilonly( wm, load_path, entry );
|
||||||
|
else
|
||||||
|
status = fixup_imports( wm, load_path );
|
||||||
|
|
||||||
|
if (status)
|
||||||
{
|
{
|
||||||
ERR( "Importing dlls for %s failed, status %x\n",
|
ERR( "Importing dlls for %s failed, status %x\n",
|
||||||
debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
|
debugstr_w(NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer), status );
|
||||||
|
|
|
@ -106,7 +106,7 @@ extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr )
|
||||||
|
|
||||||
/* module handling */
|
/* module handling */
|
||||||
extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
|
extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS attach_dlls( CONTEXT *context ) DECLSPEC_HIDDEN;
|
extern NTSTATUS attach_dlls( CONTEXT *context, void **entry ) DECLSPEC_HIDDEN;
|
||||||
extern FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
|
extern FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
|
||||||
DWORD exp_size, FARPROC proc, DWORD ordinal, const WCHAR *user ) DECLSPEC_HIDDEN;
|
DWORD exp_size, FARPROC proc, DWORD ordinal, const WCHAR *user ) DECLSPEC_HIDDEN;
|
||||||
extern FARPROC SNOOP_GetProcAddress( HMODULE hmod, const IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
|
extern FARPROC SNOOP_GetProcAddress( HMODULE hmod, const IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
|
||||||
|
|
|
@ -1277,7 +1277,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
|
||||||
init_thread_context( ctx, entry, arg, relay );
|
init_thread_context( ctx, entry, arg, relay );
|
||||||
}
|
}
|
||||||
ctx->ContextFlags = CONTEXT_FULL;
|
ctx->ContextFlags = CONTEXT_FULL;
|
||||||
attach_dlls( ctx );
|
attach_dlls( ctx, (void **)&ctx->R0 );
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1009,7 +1009,7 @@ static void thread_startup( void *param )
|
||||||
context.Pc = (DWORD_PTR)info->start;
|
context.Pc = (DWORD_PTR)info->start;
|
||||||
|
|
||||||
if (info->suspend) wait_suspend( &context );
|
if (info->suspend) wait_suspend( &context );
|
||||||
attach_dlls( &context );
|
attach_dlls( &context, (void **)&context.u.s.X0 );
|
||||||
|
|
||||||
((thread_start_func)context.Pc)( (LPTHREAD_START_ROUTINE)context.u.s.X0, (void *)context.u.s.X1 );
|
((thread_start_func)context.Pc)( (LPTHREAD_START_ROUTINE)context.u.s.X0, (void *)context.u.s.X1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -2675,7 +2675,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
|
||||||
init_thread_context( ctx, entry, arg, relay );
|
init_thread_context( ctx, entry, arg, relay );
|
||||||
}
|
}
|
||||||
ctx->ContextFlags = CONTEXT_FULL;
|
ctx->ContextFlags = CONTEXT_FULL;
|
||||||
attach_dlls( ctx );
|
attach_dlls( ctx, (void **)&ctx->Eax );
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1171,7 +1171,7 @@ static void thread_startup( void *param )
|
||||||
context.Iar = (DWORD)info->start;
|
context.Iar = (DWORD)info->start;
|
||||||
|
|
||||||
if (info->suspend) wait_suspend( &context );
|
if (info->suspend) wait_suspend( &context );
|
||||||
attach_dlls( &context );
|
attach_dlls( &context, (void **)&context->Gpr3 );
|
||||||
|
|
||||||
((thread_start_func)context.Iar)( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 );
|
((thread_start_func)context.Iar)( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -4169,7 +4169,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
|
||||||
init_thread_context( ctx, entry, arg, relay );
|
init_thread_context( ctx, entry, arg, relay );
|
||||||
}
|
}
|
||||||
ctx->ContextFlags = CONTEXT_FULL;
|
ctx->ContextFlags = CONTEXT_FULL;
|
||||||
attach_dlls( ctx );
|
attach_dlls( ctx, (void **)&ctx->Rcx );
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2158,7 +2158,8 @@ typedef struct _LDR_MODULE
|
||||||
#define LDR_UNLOAD_IN_PROGRESS 0x00002000
|
#define LDR_UNLOAD_IN_PROGRESS 0x00002000
|
||||||
#define LDR_NO_DLL_CALLS 0x00040000
|
#define LDR_NO_DLL_CALLS 0x00040000
|
||||||
#define LDR_PROCESS_ATTACHED 0x00080000
|
#define LDR_PROCESS_ATTACHED 0x00080000
|
||||||
#define LDR_MODULE_REBASED 0x00200000
|
#define LDR_COR_IMAGE 0x00400000
|
||||||
|
#define LDR_COR_ILONLY 0x01000000
|
||||||
|
|
||||||
/* these ones is Wine specific */
|
/* these ones is Wine specific */
|
||||||
#define LDR_DONT_RESOLVE_REFS 0x40000000
|
#define LDR_DONT_RESOLVE_REFS 0x40000000
|
||||||
|
|
Loading…
Reference in a new issue