Better support for loading exe files as libraries.
Make sure kernel32 and ntdll have a full path name even though they are loaded before we know the system dir.
This commit is contained in:
parent
9e8ce63e2e
commit
cba157e998
@ -496,7 +496,6 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
|||||||
WCHAR *p;
|
WCHAR *p;
|
||||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
|
||||||
PLIST_ENTRY entry, mark;
|
PLIST_ENTRY entry, mark;
|
||||||
BOOLEAN linked = FALSE;
|
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
RtlUnicodeToMultiByteSize( &len, filename, (strlenW(filename) + 1) * sizeof(WCHAR) );
|
RtlUnicodeToMultiByteSize( &len, filename, (strlenW(filename) + 1) * sizeof(WCHAR) );
|
||||||
@ -507,8 +506,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
|||||||
wm->deps = NULL;
|
wm->deps = NULL;
|
||||||
|
|
||||||
wm->ldr.BaseAddress = hModule;
|
wm->ldr.BaseAddress = hModule;
|
||||||
wm->ldr.EntryPoint = (nt->OptionalHeader.AddressOfEntryPoint) ?
|
wm->ldr.EntryPoint = NULL;
|
||||||
((char *)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
|
|
||||||
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
|
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
|
||||||
wm->ldr.Flags = 0;
|
wm->ldr.Flags = 0;
|
||||||
wm->ldr.LoadCount = 0;
|
wm->ldr.LoadCount = 0;
|
||||||
@ -522,27 +520,15 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
|||||||
else p = wm->ldr.FullDllName.Buffer;
|
else p = wm->ldr.FullDllName.Buffer;
|
||||||
RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
|
RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
|
||||||
|
|
||||||
/* this is a bit ugly, but we need to have app module first in LoadOrder
|
if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)
|
||||||
* list, But in wine, ntdll is loaded first, so by inserting DLLs at the tail
|
|
||||||
* and app module at the head we insure that order
|
|
||||||
*/
|
|
||||||
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
|
||||||
{
|
{
|
||||||
/* is first loaded module a DLL or an exec ? */
|
wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
||||||
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
if (nt->OptionalHeader.AddressOfEntryPoint)
|
||||||
if (mark->Flink == mark ||
|
wm->ldr.EntryPoint = (char *)hModule + nt->OptionalHeader.AddressOfEntryPoint;
|
||||||
(CONTAINING_RECORD(mark->Flink, LDR_MODULE, InLoadOrderModuleList)->Flags & LDR_IMAGE_IS_DLL))
|
|
||||||
{
|
|
||||||
InsertHeadList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
|
||||||
&wm->ldr.InLoadOrderModuleList);
|
|
||||||
linked = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
|
||||||
|
|
||||||
if (!linked)
|
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
&wm->ldr.InLoadOrderModuleList);
|
||||||
&wm->ldr.InLoadOrderModuleList);
|
|
||||||
|
|
||||||
/* insert module in MemoryList, sorted in increasing base addresses */
|
/* insert module in MemoryList, sorted in increasing base addresses */
|
||||||
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
||||||
@ -692,7 +678,7 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
|
|||||||
|
|
||||||
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return TRUE;
|
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return TRUE;
|
||||||
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
|
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
|
||||||
if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return TRUE;
|
if (!entry) return TRUE;
|
||||||
|
|
||||||
if (TRACE_ON(relay))
|
if (TRACE_ON(relay))
|
||||||
{
|
{
|
||||||
@ -1078,8 +1064,10 @@ static void load_builtin_callback( void *module, const char *filename )
|
|||||||
{
|
{
|
||||||
/* if we already have an executable, ignore this one */
|
/* if we already have an executable, ignore this one */
|
||||||
if (!NtCurrentTeb()->Peb->ImageBaseAddress)
|
if (!NtCurrentTeb()->Peb->ImageBaseAddress)
|
||||||
|
{
|
||||||
NtCurrentTeb()->Peb->ImageBaseAddress = module;
|
NtCurrentTeb()->Peb->ImageBaseAddress = module;
|
||||||
return; /* don't create the modref here, will be done later on */
|
return; /* don't create the modref here, will be done later on */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the MODREF */
|
/* create the MODREF */
|
||||||
@ -1771,6 +1759,43 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* init_system_dir
|
||||||
|
*
|
||||||
|
* System dir initialization once kernel32 has been loaded.
|
||||||
|
*/
|
||||||
|
static inline void init_system_dir(void)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY mark, entry;
|
||||||
|
LPWSTR buffer, p;
|
||||||
|
|
||||||
|
if (!MODULE_GetSystemDirectory( &system_dir ))
|
||||||
|
{
|
||||||
|
ERR( "Couldn't get system dir\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepend the system dir to the name of the already created modules */
|
||||||
|
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
|
{
|
||||||
|
LDR_MODULE *mod = CONTAINING_RECORD( entry, LDR_MODULE, InLoadOrderModuleList );
|
||||||
|
|
||||||
|
assert( mod->Flags & LDR_WINE_INTERNAL );
|
||||||
|
|
||||||
|
buffer = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||||
|
system_dir.Length + mod->FullDllName.Length + 2*sizeof(WCHAR) );
|
||||||
|
if (!buffer) continue;
|
||||||
|
strcpyW( buffer, system_dir.Buffer );
|
||||||
|
p = buffer + strlenW( buffer );
|
||||||
|
if (p > buffer && p[-1] != '\\') *p++ = '\\';
|
||||||
|
strcpyW( p, mod->FullDllName.Buffer );
|
||||||
|
RtlInitUnicodeString( &mod->FullDllName, buffer );
|
||||||
|
RtlInitUnicodeString( &mod->BaseDllName, p );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* LdrInitializeThunk (NTDLL.@)
|
* LdrInitializeThunk (NTDLL.@)
|
||||||
*
|
*
|
||||||
@ -1786,11 +1811,7 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG u
|
|||||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
||||||
|
|
||||||
pCreateFileW = CreateFileW_ptr;
|
pCreateFileW = CreateFileW_ptr;
|
||||||
if (!MODULE_GetSystemDirectory( &system_dir ))
|
init_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 )))
|
||||||
@ -1800,6 +1821,10 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG u
|
|||||||
}
|
}
|
||||||
wm->ldr.LoadCount = -1; /* can't unload main exe */
|
wm->ldr.LoadCount = -1; /* can't unload main exe */
|
||||||
|
|
||||||
|
/* the main exe needs to be the first in the load order list */
|
||||||
|
RemoveEntryList( &wm->ldr.InLoadOrderModuleList );
|
||||||
|
InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList );
|
||||||
|
|
||||||
/* Install signal handlers; this cannot be done before, since we cannot
|
/* Install signal handlers; this cannot be done before, since we cannot
|
||||||
* send exceptions to the debugger before the create process event that
|
* send exceptions to the debugger before the create process event that
|
||||||
* is sent by REQ_INIT_PROCESS_DONE.
|
* is sent by REQ_INIT_PROCESS_DONE.
|
||||||
@ -1813,7 +1838,7 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG u
|
|||||||
{
|
{
|
||||||
req->module = peb->ImageBaseAddress;
|
req->module = peb->ImageBaseAddress;
|
||||||
req->module_size = wm->ldr.SizeOfImage;
|
req->module_size = wm->ldr.SizeOfImage;
|
||||||
req->entry = wm->ldr.EntryPoint;
|
req->entry = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
|
||||||
/* API requires a double indirection */
|
/* API requires a double indirection */
|
||||||
req->name = &main_exe_name->Buffer;
|
req->name = &main_exe_name->Buffer;
|
||||||
req->exe_file = main_file;
|
req->exe_file = main_file;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user