mirror of
https://github.com/reactos/wine.git
synced 2025-02-16 10:59:45 +00:00
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;
|
||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
|
||||
PLIST_ENTRY entry, mark;
|
||||
BOOLEAN linked = FALSE;
|
||||
DWORD len;
|
||||
|
||||
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->ldr.BaseAddress = hModule;
|
||||
wm->ldr.EntryPoint = (nt->OptionalHeader.AddressOfEntryPoint) ?
|
||||
((char *)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
|
||||
wm->ldr.EntryPoint = NULL;
|
||||
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
|
||||
wm->ldr.Flags = 0;
|
||||
wm->ldr.LoadCount = 0;
|
||||
@ -522,27 +520,15 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
||||
else p = wm->ldr.FullDllName.Buffer;
|
||||
RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
|
||||
|
||||
/* this is a bit ugly, but we need to have app module first in LoadOrder
|
||||
* 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))
|
||||
if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)
|
||||
{
|
||||
/* is first loaded module a DLL or an exec ? */
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||
if (mark->Flink == mark ||
|
||||
(CONTAINING_RECORD(mark->Flink, LDR_MODULE, InLoadOrderModuleList)->Flags & LDR_IMAGE_IS_DLL))
|
||||
{
|
||||
InsertHeadList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
linked = TRUE;
|
||||
}
|
||||
wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
||||
if (nt->OptionalHeader.AddressOfEntryPoint)
|
||||
wm->ldr.EntryPoint = (char *)hModule + nt->OptionalHeader.AddressOfEntryPoint;
|
||||
}
|
||||
else wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
||||
|
||||
if (!linked)
|
||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
|
||||
/* insert module in MemoryList, sorted in increasing base addresses */
|
||||
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.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))
|
||||
{
|
||||
@ -1078,8 +1064,10 @@ static void load_builtin_callback( void *module, const char *filename )
|
||||
{
|
||||
/* if we already have an executable, ignore this one */
|
||||
if (!NtCurrentTeb()->Peb->ImageBaseAddress)
|
||||
{
|
||||
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 */
|
||||
@ -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.@)
|
||||
*
|
||||
@ -1786,11 +1811,7 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG u
|
||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
||||
|
||||
pCreateFileW = CreateFileW_ptr;
|
||||
if (!MODULE_GetSystemDirectory( &system_dir ))
|
||||
{
|
||||
ERR( "Couldn't get system dir\n");
|
||||
exit(1);
|
||||
}
|
||||
init_system_dir();
|
||||
|
||||
/* allocate the modref for the main exe */
|
||||
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 */
|
||||
|
||||
/* 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
|
||||
* send exceptions to the debugger before the create process event that
|
||||
* 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_size = wm->ldr.SizeOfImage;
|
||||
req->entry = wm->ldr.EntryPoint;
|
||||
req->entry = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
|
||||
/* API requires a double indirection */
|
||||
req->name = &main_exe_name->Buffer;
|
||||
req->exe_file = main_file;
|
||||
|
Loading…
x
Reference in New Issue
Block a user