Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/loader.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 35a474a93e..782e1d28af 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -821,10 +821,11 @@ static NTSTATUS create_module_activation_context( LDR_MODULE *module ) * Some dlls (corpol.dll from IE6 for instance) are incorrectly marked as native * while being perfectly normal DLLs. This heuristic should catch such breakages. */ -static BOOL is_dll_native_subsystem( HMODULE module, const IMAGE_NT_HEADERS *nt, LPCWSTR filename ) +static BOOL is_dll_native_subsystem( WINE_MODREF *wm ) { static const WCHAR ntdllW[] = {'n','t','d','l','l','.','d','l','l',0}; static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0}; + const IMAGE_NT_HEADERS *nt = RtlImageNtHeader( wm->ldr.BaseAddress ); const IMAGE_IMPORT_DESCRIPTOR *imports; DWORD i, size; WCHAR buffer[16]; @@ -832,18 +833,19 @@ static BOOL is_dll_native_subsystem( HMODULE module, const IMAGE_NT_HEADERS *nt, if (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_NATIVE) return FALSE; if (nt->OptionalHeader.SectionAlignment < page_size) return TRUE;
- if ((imports = RtlImageDirectoryEntryToData( module, TRUE, + if ((imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size ))) { for (i = 0; imports[i].Name; i++) { - const char *name = get_rva( module, imports[i].Name ); + const char *name = get_rva( wm->ldr.BaseAddress, imports[i].Name ); DWORD len = strlen(name); if (len * sizeof(WCHAR) >= sizeof(buffer)) continue; ascii_to_unicode( buffer, name, len + 1 ); if (!strcmpiW( buffer, ntdllW ) || !strcmpiW( buffer, kernel32W )) { - TRACE( "%s imports %s, assuming not native\n", debugstr_w(filename), debugstr_w(buffer) ); + TRACE( "%s imports %s, assuming not native\n", + debugstr_us(&wm->ldr.BaseDllName), debugstr_w(buffer) ); return FALSE; } } @@ -1083,7 +1085,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename ) else p = wm->ldr.FullDllName.Buffer; RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
- if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL) || !is_dll_native_subsystem( hModule, nt, p )) + if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL) || !is_dll_native_subsystem( wm )) { if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/loader.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 782e1d28af..abff126832 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1242,6 +1242,38 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved return status; }
+static NTSTATUS attach_native_subsystem_dll( WINE_MODREF *wm ) +{ + static const WCHAR key_base[] = {'\','R','E','G','I','S','T','R','Y', + '\','M','A','C','H','I','N','E', + '\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', + '\','S','e','r','v','i','c','e','s','\',0}; + NTSTATUS (WINAPI *initfunc)(UNICODE_STRING *); + UNICODE_STRING keyname; + ANSI_STRING procname; + WCHAR *buffer; + NTSTATUS ret; + + RtlInitAnsiString( &procname, "DllInitialize" ); + if (LdrGetProcedureAddress( wm->ldr.BaseAddress, &procname, 0, (void **)&initfunc)) + return STATUS_SUCCESS; + + buffer = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(key_base) + wm->ldr.BaseDllName.Length ); + if (!buffer) + return STATUS_NO_MEMORY; + + strcpyW( buffer, key_base ); + strcatW( buffer, wm->ldr.BaseDllName.Buffer ); + RtlInitUnicodeString( &keyname, buffer ); + TRACE_(relay)( "\1Call DllInitialize %p (%s)\n", + initfunc, debugstr_us(&keyname) ); + ret = initfunc( &keyname ); + TRACE_(relay)( "\1Ret DllInitialize %p (%s) retval=%08x\n", + initfunc, debugstr_us(&keyname), ret ); + RtlFreeHeap( GetProcessHeap(), 0, buffer ); + + return ret; +}
/************************************************************************* * process_attach @@ -1312,7 +1344,10 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved ) current_modref = wm;
call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_LOADED, &wm->ldr ); - status = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved ); + if (is_dll_native_subsystem( wm )) + status = attach_native_subsystem_dll( wm ); + else + status = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved ); if (status == STATUS_SUCCESS) { wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
dlls/ntdll/loader.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-)
This would have to be done in ntoskrnl, after relocations have been applied. It may be possible to use dll notifications for this, now that they are implemented.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/loader.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index abff126832..5c877c2e47 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1275,6 +1275,21 @@ static NTSTATUS attach_native_subsystem_dll( WINE_MODREF *wm ) return ret; }
+static void detach_native_subsystem_dll( WINE_MODREF *wm ) +{ + NTSTATUS (WINAPI *unloadfunc)(void); + ANSI_STRING procname; + NTSTATUS ret; + + RtlInitAnsiString( &procname, "DllUnload" ); + if (!LdrGetProcedureAddress( wm->ldr.BaseAddress, &procname, 0, (void **)&unloadfunc)) + { + TRACE_(relay)( "\1Call DllUnload %p\n", unloadfunc ); + ret = unloadfunc(); + TRACE_(relay)( "\1Ret DllUnload %p retval=%08x\n", unloadfunc, ret ); + } +} + /************************************************************************* * process_attach * @@ -1411,6 +1426,7 @@ static void process_detach(void) { PLIST_ENTRY mark, entry; PLDR_MODULE mod; + WINE_MODREF *wm;
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList; do @@ -1419,6 +1435,8 @@ static void process_detach(void) { mod = CONTAINING_RECORD(entry, LDR_MODULE, InInitializationOrderModuleList); + wm = CONTAINING_RECORD( mod, WINE_MODREF, ldr ); + /* Check whether to detach this DLL */ if ( !(mod->Flags & LDR_PROCESS_ATTACHED) ) continue; @@ -1427,8 +1445,10 @@ static void process_detach(void)
/* Call detach notification */ mod->Flags &= ~LDR_PROCESS_ATTACHED; - MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr), - DLL_PROCESS_DETACH, ULongToPtr(process_detaching) ); + if (is_dll_native_subsystem( wm )) + detach_native_subsystem_dll( wm ); + else + MODULE_InitDLL( wm, DLL_PROCESS_DETACH, ULongToPtr(process_detaching) ); call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, mod );
/* Restart at head of WINE_MODREF list, as entries might have