mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
[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 svn path=/trunk/; revision=70522
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user