Author: fireball Date: Thu Jan 7 12:09:03 2016 New Revision: 70522
URL: http://svn.reactos.org/svn/reactos?rev=70522&view=rev Log: [LDR] - Implement support for manifest prober routine in LdrpWalkImportDescriptor, in its simplest way - Implement such routine in kernel32 (that's mostly a copy of Wine's create_module_activation_context which seems to nicely correspond to what Windows does). - As create_module_activation_context is moved into kernel32, delete it from ntdll - Improve debug output in RTL's Activation Context implementation to ease debugging - Now, ReactOS indeed looks for and actually loads manifests when loading modules. Thanks to http://blog.tombowles.me.uk/2009/10/05/winsxs/ for a really good description of how activation contexts work CORE-7313
Modified: trunk/reactos/dll/ntdll/ldr/ldrpe.c trunk/reactos/dll/ntdll/ldr/ldrutils.c trunk/reactos/dll/win32/kernel32/client/actctx.c trunk/reactos/dll/win32/kernel32/client/dllmain.c trunk/reactos/dll/win32/kernel32/include/kernel32.h trunk/reactos/lib/rtl/actctx.c
Modified: trunk/reactos/dll/ntdll/ldr/ldrpe.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrpe.c?rev=7... ============================================================================== --- trunk/reactos/dll/ntdll/ldr/ldrpe.c [iso-8859-1] (original) +++ trunk/reactos/dll/ntdll/ldr/ldrpe.c [iso-8859-1] Thu Jan 7 12:09:03 2016 @@ -686,7 +686,7 @@ { 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 @@ /* 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 */
Modified: trunk/reactos/dll/ntdll/ldr/ldrutils.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrutils.c?re... ============================================================================== --- trunk/reactos/dll/ntdll/ldr/ldrutils.c [iso-8859-1] (original) +++ trunk/reactos/dll/ntdll/ldr/ldrutils.c [iso-8859-1] Thu Jan 7 12:09:03 2016 @@ -21,29 +21,7 @@
/* 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','\'};
Modified: trunk/reactos/dll/win32/kernel32/client/actctx.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/a... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/actctx.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/actctx.c [iso-8859-1] Thu Jan 7 12:09:03 2016 @@ -128,6 +128,50 @@ Quickie: /* Failure or success path, return to caller and free on failure */ if (ContextInfo.hActCtx) RtlReleaseActivationContext(ContextInfo.hActCtx); + 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; }
Modified: trunk/reactos/dll/win32/kernel32/client/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/d... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/dllmain.c [iso-8859-1] Thu Jan 7 12:09:03 2016 @@ -110,6 +110,9 @@ /* 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);
Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include/... ============================================================================== --- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Thu Jan 7 12:09:03 2016 @@ -217,6 +217,14 @@ OUT PBASEP_ACTCTX_BLOCK *ActivationBlock );
+NTSTATUS +NTAPI +BasepProbeForDllManifest( + IN PVOID DllHandle, + IN PCWSTR FullDllName, + OUT PVOID *ActCtx +); + __declspec(noreturn) VOID WINAPI
Modified: trunk/reactos/lib/rtl/actctx.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/actctx.c?rev=70522&... ============================================================================== --- trunk/reactos/lib/rtl/actctx.c [iso-8859-1] (original) +++ trunk/reactos/lib/rtl/actctx.c [iso-8859-1] Thu Jan 7 12:09:03 2016 @@ -2615,6 +2615,7 @@
//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 @@ 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 @@ 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 );
@@ -4957,6 +4962,11 @@
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 @@ /* 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 @@ 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;