/* GLOBALS *******************************************************************/
-PVOID LdrpManifestProberRoutine;
+PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine;
ULONG LdrpNormalSnap;
/* FUNCTIONS *****************************************************************/
-VOID
-NTAPI
-AVrfPageHeapDllNotification(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
-{
- /* Check if page heap dll notification is turned on */
- if (!(RtlpDphGlobalFlags & DPH_FLAG_DLL_NOTIFY))
- return;
-
- /* We don't support this flag currently */
- UNIMPLEMENTED;
-}
NTSTATUS
NTAPI
/* We'll only do forwarders. Get the import name */
ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->Name);
- /* Get the list of forwaders */
+ /* Get the list of forwarders */
ForwarderChain = IatEntry->ForwarderChain;
/* Loop them */
/* Get the name's VA */
BoundImportName = (LPSTR)FirstEntry + BoundEntry->OffsetModuleName;
- /* Show debug mesage */
+ /* Show debug message */
if (ShowSnaps)
{
DPRINT1("LDR: %wZ bound to %s\n", &LdrEntry->BaseDllName, BoundImportName);
/* Load the module for this entry */
Status = LdrpLoadImportModule(DllPath,
BoundImportName,
- LdrEntry->DllBase,
&DllLdrEntry,
&AlreadyLoaded);
if (!NT_SUCCESS(Status))
{
/* Add it to our list */
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
- &DllLdrEntry->InInitializationOrderModuleList);
+ &DllLdrEntry->InInitializationOrderLinks);
}
/* Check if the Bound Entry is now invalid */
/* Load the module */
Status = LdrpLoadImportModule(DllPath,
ForwarderName,
- LdrEntry->DllBase,
&ForwarderLdrEntry,
&AlreadyLoaded);
if (NT_SUCCESS(Status))
{
/* Add it to our list */
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
- &ForwarderLdrEntry->InInitializationOrderModuleList);
+ &ForwarderLdrEntry->InInitializationOrderLinks);
}
}
/* Load the module associated to it */
Status = LdrpLoadImportModule(DllPath,
ImportName,
- LdrEntry->DllBase,
&DllLdrEntry,
&AlreadyLoaded);
if (!NT_SUCCESS(Status))
{
/* Add the DLL to our list */
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
- &DllLdrEntry->InInitializationOrderModuleList);
+ &DllLdrEntry->InInitializationOrderLinks);
}
/* Now snap the IAT Entry */
{
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;
- DPRINT("LdrpWalkImportDescriptor('%S' %p)\n", DllPath, LdrEntry);
+
+ DPRINT("LdrpWalkImportDescriptor - BEGIN (%wZ %p '%S')\n", &LdrEntry->BaseDllName, LdrEntry, DllPath);
/* Set up the Act Ctx */
RtlZeroMemory(&ActCtx, sizeof(ActCtx));
/* 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; // FIXME: Ignore that error for now
+ 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 */
if (!NT_SUCCESS(Status)) return Status;
/* Get the Active ActCtx */
- Status = RtlGetActiveActivationContext(&LdrEntry->EntryPointActivationContext);
- if (!NT_SUCCESS(Status))
+ if (!LdrEntry->EntryPointActivationContext)
{
- /* Exit */
- DbgPrintEx(DPFLTR_SXS_ID,
- DPFLTR_WARNING_LEVEL,
- "LDR: RtlGetActiveActivationContext() failed; ntstatus = "
- "0x%08lx\n",
- Status);
- return Status;
+ Status = RtlGetActiveActivationContext(&LdrEntry->EntryPointActivationContext);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* Exit */
+ DbgPrintEx(DPFLTR_SXS_ID,
+ DPFLTR_WARNING_LEVEL,
+ "LDR: RtlGetActiveActivationContext() failed; ntstatus = "
+ "0x%08lx\n",
+ Status);
+ return Status;
+ }
}
/* Activate the ActCtx */
}
/* Check if Application Verifier was enabled */
- if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAIL_CHECK)
+ if (Peb->NtGlobalFlag & FLG_APPLICATION_VERIFIER)
{
- /* FIXME */
- DPRINT1("We don't support Application Verifier yet!\n");
+ AVrfDllLoadNotification(LdrEntry);
}
/* Just to be safe */
/* Release the activation context */
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
+ DPRINT("LdrpWalkImportDescriptor - END (%wZ %p)\n", &LdrEntry->BaseDllName, LdrEntry);
+
/* Return status */
return Status;
}
-/* FIXME: This function is missing SxS support and has wrong prototype */
NTSTATUS
NTAPI
LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
IN LPSTR ImportName,
- IN PVOID DllBase,
OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry,
OUT PBOOLEAN Existing)
{
ANSI_STRING AnsiString;
PUNICODE_STRING ImpDescName;
+ const WCHAR *p;
+ BOOLEAN GotExtension;
+ WCHAR c;
NTSTATUS Status;
PPEB Peb = RtlGetCurrentPeb();
PTEB Teb = NtCurrentTeb();
+ UNICODE_STRING RedirectedImpDescName;
+ BOOLEAN RedirectedDll;
+
+ DPRINT("LdrpLoadImportModule('%S' '%s' %p %p)\n", DllPath, ImportName, DataTableEntry, Existing);
- DPRINT("LdrpLoadImportModule('%S' '%s' %p %p %p)\n", DllPath, ImportName, DllBase, DataTableEntry, Existing);
+ RedirectedDll = FALSE;
+ RtlInitEmptyUnicodeString(&RedirectedImpDescName, NULL, 0);
/* Convert import descriptor name to unicode string */
ImpDescName = &Teb->StaticUnicodeString;
Status = RtlAnsiStringToUnicodeString(ImpDescName, &AnsiString, FALSE);
if (!NT_SUCCESS(Status)) return Status;
+ /* Find the extension, if present */
+ p = ImpDescName->Buffer + ImpDescName->Length / sizeof(WCHAR) - 1;
+ GotExtension = FALSE;
+ while (p >= ImpDescName->Buffer)
+ {
+ c = *p--;
+ if (c == L'.')
+ {
+ GotExtension = TRUE;
+ break;
+ }
+ else if (c == L'\\')
+ {
+ break;
+ }
+ }
+
+ /* If no extension was found, add the default extension */
+ if (!GotExtension)
+ {
+ /* Check that we have space to add one */
+ if ((ImpDescName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL)) >=
+ sizeof(Teb->StaticUnicodeBuffer))
+ {
+ /* No space to add the extension */
+ DbgPrintEx(DPFLTR_LDR_ID,
+ DPFLTR_ERROR_LEVEL,
+ "LDR: %s - Dll name missing extension; with extension "
+ "added the name is too long\n"
+ " ImpDescName: (@ %p) \"%wZ\"\n"
+ " ImpDescName->Length: %u\n",
+ __FUNCTION__,
+ ImpDescName,
+ ImpDescName,
+ ImpDescName->Length);
+ return STATUS_NAME_TOO_LONG;
+ }
+
+ /* Add it. Needs to be null terminated, thus the length check above */
+ (VOID)RtlAppendUnicodeStringToString(ImpDescName,
+ &LdrApiDefaultExtension);
+ }
+
+ /* Check if the SxS Assemblies specify another file */
+ Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
+ ImpDescName,
+ &LdrApiDefaultExtension,
+ NULL,
+ &RedirectedImpDescName,
+ &ImpDescName,
+ NULL,
+ NULL,
+ NULL);
+
+ /* Check success */
+ if (NT_SUCCESS(Status))
+ {
+ /* Let Ldrp know */
+ RedirectedDll = TRUE;
+ }
+ else if (Status != STATUS_SXS_KEY_NOT_FOUND)
+ {
+ /* Unrecoverable SxS failure */
+ DPRINT1("LDR: RtlDosApplyFileIsolationRedirection_Ustr failed with status %x for dll %wZ\n", Status, ImpDescName);
+ goto done;
+ }
+
/* Check if it's loaded */
if (LdrpCheckForLoadedDll(DllPath,
ImpDescName,
TRUE,
- FALSE,
+ RedirectedDll,
DataTableEntry))
{
/* It's already existing in the list */
*Existing = TRUE;
- return STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
+ goto done;
}
/* We're loading it for the first time */
ImpDescName->Buffer,
NULL,
TRUE,
- FALSE,
+ RedirectedDll,
DataTableEntry);
-
- if (!NT_SUCCESS(Status)) return Status;
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName);
+ goto done;
+ }
/* Walk its import descriptor table */
Status = LdrpWalkImportDescriptor(DllPath,
{
/* Add it to the in-init-order list in case of failure */
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
- &(*DataTableEntry)->InInitializationOrderModuleList);
+ &(*DataTableEntry)->InInitializationOrderLinks);
}
+done:
+ RtlFreeUnicodeString(&RedirectedImpDescName);
+
return Status;
}
/* Is this a static snap? */
if (Static)
{
+ RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown");
/* Inform the debug log */
if (IsOrdinal)
- DPRINT1("Failed to snap ordinal 0x%x\n", OriginalOrdinal);
+ DPRINT1("Failed to snap ordinal %Z!0x%x\n", &TempString, OriginalOrdinal);
else
- DPRINT1("Failed to snap %s\n", ImportName);
+ DPRINT1("Failed to snap %Z!%s\n", &TempString, ImportName);
/* These are critical errors. Setup a string for the DLL name */
- RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown");
RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE);
/* Set it as the parameter */