- 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

svn path=/trunk/; revision=70522
This commit is contained in:
Aleksey Bragin
2016-01-07 12:09:03 +00:00
parent b835d33a8c
commit d3d56d9cbc
6 changed files with 89 additions and 28 deletions
+19 -2
View File
@@ -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 */
+1 -23
View File
@@ -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','\\'};
@@ -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 **********************************************************/
/*
@@ -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);
@@ -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
+14 -3
View File
@@ -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;