diff --git a/reactos/dll/ntdll/ldr/ldrpe.c b/reactos/dll/ntdll/ldr/ldrpe.c index 260c5bd7100..da32ab2c810 100644 --- a/reactos/dll/ntdll/ldr/ldrpe.c +++ b/reactos/dll/ntdll/ldr/ldrpe.c @@ -686,7 +686,7 @@ LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, { RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx; PPEB Peb = NtCurrentPeb(); - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status = STATUS_SUCCESS, Status2; PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry = NULL; PIMAGE_IMPORT_DESCRIPTOR ImportEntry; ULONG BoundSize, IatSize; @@ -700,7 +700,24 @@ LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL, /* Check if we have a manifest prober routine */ if (LdrpManifestProberRoutine) { - DPRINT1("We don't support manifests yet, much less prober routines\n"); + /* Probe the DLL for its manifest. Some details are omitted */ + Status2 = LdrpManifestProberRoutine(LdrEntry->DllBase, LdrEntry->FullDllName.Buffer, &LdrEntry->EntryPointActivationContext); + + if (!NT_SUCCESS(Status2) && + Status2 != STATUS_NO_SUCH_FILE && + Status2 != STATUS_RESOURCE_DATA_NOT_FOUND && + Status2 != STATUS_RESOURCE_TYPE_NOT_FOUND && + Status2 != STATUS_RESOURCE_NAME_NOT_FOUND && + Status2 != STATUS_RESOURCE_LANG_NOT_FOUND) + { + /* Some serious issue */ + Status = Status2; + DbgPrintEx(DPFLTR_SXS_ID, + DPFLTR_WARNING_LEVEL, + "LDR: LdrpWalkImportDescriptor() failed to probe %wZ for its " + "manifest, ntstatus = 0x%08lx\n", + &LdrEntry->FullDllName, Status); + } } /* Check if we failed above */ diff --git a/reactos/dll/ntdll/ldr/ldrutils.c b/reactos/dll/ntdll/ldr/ldrutils.c index 44dde719da0..840932db2d3 100644 --- a/reactos/dll/ntdll/ldr/ldrutils.c +++ b/reactos/dll/ntdll/ldr/ldrutils.c @@ -21,29 +21,7 @@ BOOLEAN g_ShimsEnabled; /* FUNCTIONS *****************************************************************/ -/* NOTE: Remove those two once our actctx support becomes better */ -NTSTATUS create_module_activation_context( LDR_DATA_TABLE_ENTRY *module ) -{ - NTSTATUS status; - LDR_RESOURCE_INFO info; - IMAGE_RESOURCE_DATA_ENTRY *entry; - - info.Type = (ULONG)RT_MANIFEST; - info.Name = (ULONG)ISOLATIONAWARE_MANIFEST_RESOURCE_ID; - info.Language = 0; - if (!(status = LdrFindResource_U( module->DllBase, &info, 3, &entry ))) - { - ACTCTXW ctx; - ctx.cbSize = sizeof(ctx); - ctx.lpSource = NULL; - ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; - ctx.hModule = module->DllBase; - ctx.lpResourceName = (LPCWSTR)ISOLATIONAWARE_MANIFEST_RESOURCE_ID; - status = RtlCreateActivationContext(0, (PVOID)&ctx, 0, NULL, NULL, &module->EntryPointActivationContext); - } - return status; -} - +/* NOTE: Remove thise one once our actctx support becomes better */ NTSTATUS find_actctx_dll( LPCWSTR libname, WCHAR *fullname ) { static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\'}; diff --git a/reactos/dll/win32/kernel32/client/actctx.c b/reactos/dll/win32/kernel32/client/actctx.c index d026c5b6a51..12ab09062de 100644 --- a/reactos/dll/win32/kernel32/client/actctx.c +++ b/reactos/dll/win32/kernel32/client/actctx.c @@ -131,6 +131,50 @@ Quickie: return Status; } +NTSTATUS +NTAPI +BasepProbeForDllManifest(IN PVOID DllHandle, + IN PCWSTR FullDllName, + OUT PVOID *ActCtx) +{ + NTSTATUS Status = STATUS_SUCCESS; + LDR_RESOURCE_INFO Info; + IMAGE_RESOURCE_DATA_ENTRY *Entry; + ACTCTXW Context; + HANDLE Result; + + /* Check if activation context parameter is provided */ + if (!ActCtx) + { + ASSERT(FALSE); + return STATUS_INVALID_PARAMETER; + } + + /* Zero it out */ + *ActCtx = NULL; + + /* Check whether the image has manifest resource associated with it */ + Info.Type = (ULONG)RT_MANIFEST; + Info.Name = (ULONG)ISOLATIONAWARE_MANIFEST_RESOURCE_ID; + Info.Language = 0; + if (!(Status = LdrFindResource_U(DllHandle, &Info, 2, &Entry))) + { + /* Create the activation context */ + Context.cbSize = sizeof(Context); + Context.lpSource = FullDllName; + Context.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; + Context.hModule = DllHandle; + Context.lpResourceName = (LPCWSTR)ISOLATIONAWARE_MANIFEST_RESOURCE_ID; + + Status = RtlCreateActivationContext(0, (PVOID)&Context, 0, NULL, NULL, &Result); + + /* Store activation context pointer if it was created successfully */ + if (NT_SUCCESS(Status)) *ActCtx = Result; + } + + return Status; +} + /* PUBLIC FUNCTIONS **********************************************************/ /* diff --git a/reactos/dll/win32/kernel32/client/dllmain.c b/reactos/dll/win32/kernel32/client/dllmain.c index abb06625acc..112b79f62c1 100644 --- a/reactos/dll/win32/kernel32/client/dllmain.c +++ b/reactos/dll/win32/kernel32/client/dllmain.c @@ -110,6 +110,9 @@ DllMain(HANDLE hDll, /* Enable the Rtl thread pool and timer queue to use proper Win32 thread */ RtlSetThreadPoolStartFunc(BaseCreateThreadPoolThread, BaseExitThreadPoolThread); + /* Register the manifest prober routine */ + LdrSetDllManifestProber(BasepProbeForDllManifest); + /* Don't bother us for each thread */ LdrDisableThreadCalloutsForDll((PVOID)hDll); diff --git a/reactos/dll/win32/kernel32/include/kernel32.h b/reactos/dll/win32/kernel32/include/kernel32.h index 73642de88b1..203310fa3e7 100644 --- a/reactos/dll/win32/kernel32/include/kernel32.h +++ b/reactos/dll/win32/kernel32/include/kernel32.h @@ -217,6 +217,14 @@ BasepAllocateActivationContextActivationBlock( OUT PBASEP_ACTCTX_BLOCK *ActivationBlock ); +NTSTATUS +NTAPI +BasepProbeForDllManifest( + IN PVOID DllHandle, + IN PCWSTR FullDllName, + OUT PVOID *ActCtx +); + __declspec(noreturn) VOID WINAPI diff --git a/reactos/lib/rtl/actctx.c b/reactos/lib/rtl/actctx.c index 5e0d410caa3..88794aa3828 100644 --- a/reactos/lib/rtl/actctx.c +++ b/reactos/lib/rtl/actctx.c @@ -2615,6 +2615,7 @@ static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assemb //DPRINT( "looking for res %s in module %p %s\n", resname, // hModule, filename ); + DPRINT("get_manifest_in_module %p\n", hModule); #if 0 if (TRACE_ON(actctx)) @@ -3139,7 +3140,7 @@ static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT* actctx, struct str total_len += sizeof(*data); total_len += aligned_string_len((strlenW(dll->name)+1)*sizeof(WCHAR)); - DPRINT("assembly %d, dll %d: dll name %S\n", i, j, dll->name); + DPRINT("assembly %d (%p), dll %d: dll name %S\n", i, assembly, j, dll->name); } dll_count += assembly->num_dlls; @@ -4922,6 +4923,10 @@ NTAPI RtlActivateActivationContextEx( ULONG flags, PTEB tebAddress, HANDLE handl frame->ActivationContext = handle; frame->Flags = 0; + DPRINT("ActiveSP %p: ACTIVATE (ActiveFrame %p -> NewFrame %p, Context %p)\n", + tebAddress->ActivationContextStackPointer, tebAddress->ActivationContextStackPointer->ActiveFrame, + frame, handle); + tebAddress->ActivationContextStackPointer->ActiveFrame = frame; RtlAddRefActivationContext( handle ); @@ -4958,6 +4963,11 @@ NTSTATUS NTAPI RtlDeactivateActivationContext( ULONG flags, ULONG_PTR cookie ) if (frame != top && !(flags & RTL_DEACTIVATE_ACTIVATION_CONTEXT_FLAG_FORCE_EARLY_DEACTIVATION)) RtlRaiseStatus( STATUS_SXS_EARLY_DEACTIVATION ); + DPRINT("ActiveSP %p: DEACTIVATE (ActiveFrame %p -> PreviousFrame %p)\n", + NtCurrentTeb()->ActivationContextStackPointer, + NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame, + frame->Previous); + /* pop everything up to and including frame */ NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame->Previous; @@ -5422,7 +5432,7 @@ RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTE /* Get the current active frame */ ActiveFrame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; - DPRINT("ActiveSP %p, ActiveFrame %p, &Frame->Frame %p, Context %p\n", + DPRINT("ActiveSP %p: ACTIVATE (ActiveFrame %p -> NewFrame %p, Context %p)\n", NtCurrentTeb()->ActivationContextStackPointer, ActiveFrame, &Frame->Frame, Context); @@ -5533,7 +5543,8 @@ RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CON DPRINT1("Deactivating wrong active frame: %p != %p\n", ActiveFrame, NewFrame); } - DPRINT("Deactivated actctx %p, active frame %p, new active frame %p\n", NtCurrentTeb()->ActivationContextStackPointer, NewFrame, NewFrame->Previous); + DPRINT("ActiveSP %p: DEACTIVATE (ActiveFrame %p -> PreviousFrame %p)\n", + NtCurrentTeb()->ActivationContextStackPointer, NewFrame, NewFrame->Previous); /* Pop everything up to and including frame */ NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NewFrame->Previous;