2011-03-16 14:22:15 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: lib/ntdll/ldr/ldrpe.c
|
|
|
|
* PURPOSE: Loader Functions dealing low-level PE Format structures
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#include <ntdll.h>
|
2014-01-20 12:59:27 +00:00
|
|
|
|
2011-03-16 14:22:15 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* GLOBALS *******************************************************************/
|
2011-07-10 02:14:29 +00:00
|
|
|
|
2015-03-01 15:34:06 +00:00
|
|
|
PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine;
|
2011-07-10 02:14:29 +00:00
|
|
|
ULONG LdrpNormalSnap;
|
2011-03-16 14:22:15 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2011-08-21 22:15:08 +00:00
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry,
|
|
|
|
IN PLDR_DATA_TABLE_ENTRY ImportLdrEntry,
|
|
|
|
IN PIMAGE_IMPORT_DESCRIPTOR IatEntry,
|
|
|
|
IN BOOLEAN EntriesValid)
|
|
|
|
{
|
|
|
|
PVOID Iat;
|
|
|
|
NTSTATUS Status;
|
2011-03-23 12:25:53 +00:00
|
|
|
PIMAGE_THUNK_DATA OriginalThunk, FirstThunk;
|
2011-03-22 12:41:52 +00:00
|
|
|
PIMAGE_NT_HEADERS NtHeader;
|
|
|
|
PIMAGE_SECTION_HEADER SectionHeader;
|
2011-07-10 13:23:19 +00:00
|
|
|
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
|
|
|
|
LPSTR ImportName;
|
|
|
|
ULONG ForwarderChain, i, Rva, OldProtect, IatSize, ExportSize;
|
|
|
|
SIZE_T ImportSize;
|
2013-08-29 21:12:40 +00:00
|
|
|
DPRINT("LdrpSnapIAT(%wZ %wZ %p %u)\n", &ExportLdrEntry->BaseDllName, &ImportLdrEntry->BaseDllName, IatEntry, EntriesValid);
|
2011-03-23 12:25:53 +00:00
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
/* Get export directory */
|
|
|
|
ExportDirectory = RtlImageDirectoryEntryToData(ExportLdrEntry->DllBase,
|
|
|
|
TRUE,
|
|
|
|
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
|
|
|
&ExportSize);
|
|
|
|
|
|
|
|
/* Make sure it has one */
|
2011-07-10 13:23:19 +00:00
|
|
|
if (!ExportDirectory)
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
DbgPrint("LDR: %wZ doesn't contain an EXPORT table\n",
|
|
|
|
&ExportLdrEntry->BaseDllName);
|
|
|
|
return STATUS_INVALID_IMAGE_FORMAT;
|
|
|
|
}
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Get the IAT */
|
|
|
|
Iat = RtlImageDirectoryEntryToData(ImportLdrEntry->DllBase,
|
|
|
|
TRUE,
|
|
|
|
IMAGE_DIRECTORY_ENTRY_IAT,
|
|
|
|
&IatSize);
|
|
|
|
ImportSize = IatSize;
|
|
|
|
|
|
|
|
/* Check if we don't have one */
|
|
|
|
if (!Iat)
|
|
|
|
{
|
|
|
|
/* Get the NT Header and the first section */
|
|
|
|
NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase);
|
2011-07-10 13:23:19 +00:00
|
|
|
if (!NtHeader) return STATUS_INVALID_IMAGE_FORMAT;
|
2011-03-22 12:41:52 +00:00
|
|
|
SectionHeader = IMAGE_FIRST_SECTION(NtHeader);
|
|
|
|
|
|
|
|
/* Get the RVA of the import directory */
|
|
|
|
Rva = NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
|
|
|
|
|
|
|
/* Make sure we got one */
|
|
|
|
if (Rva)
|
|
|
|
{
|
|
|
|
/* Loop all the sections */
|
|
|
|
for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
|
|
|
|
{
|
|
|
|
/* Check if we are inside this section */
|
|
|
|
if ((Rva >= SectionHeader->VirtualAddress) &&
|
|
|
|
(Rva < (SectionHeader->VirtualAddress +
|
|
|
|
SectionHeader->SizeOfRawData)))
|
|
|
|
{
|
|
|
|
/* We are, so set the IAT here */
|
|
|
|
Iat = (PVOID)((ULONG_PTR)(ImportLdrEntry->DllBase) +
|
|
|
|
SectionHeader->VirtualAddress);
|
|
|
|
|
|
|
|
/* Set the size */
|
|
|
|
IatSize = SectionHeader->Misc.VirtualSize;
|
|
|
|
|
|
|
|
/* Deal with Watcom and other retarded compilers */
|
2011-07-10 13:23:19 +00:00
|
|
|
if (!IatSize) IatSize = SectionHeader->SizeOfRawData;
|
2011-03-23 12:25:53 +00:00
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
/* Found it, get out */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No match, move to the next section */
|
2011-03-23 12:25:53 +00:00
|
|
|
SectionHeader++;
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we still don't have an IAT, that's bad */
|
2011-07-10 13:23:19 +00:00
|
|
|
if (!Iat)
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
DbgPrint("LDR: Unable to unprotect IAT for %wZ (Image Base %p)\n",
|
|
|
|
&ImportLdrEntry->BaseDllName,
|
|
|
|
ImportLdrEntry->DllBase);
|
|
|
|
return STATUS_INVALID_IMAGE_FORMAT;
|
|
|
|
}
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Set the right size */
|
|
|
|
ImportSize = IatSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unprotect the IAT */
|
|
|
|
Status = NtProtectVirtualMemory(NtCurrentProcess(),
|
|
|
|
&Iat,
|
|
|
|
&ImportSize,
|
|
|
|
PAGE_READWRITE,
|
|
|
|
&OldProtect);
|
2011-07-10 13:23:19 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
DbgPrint("LDR: Unable to unprotect IAT for %wZ (Status %x)\n",
|
|
|
|
&ImportLdrEntry->BaseDllName,
|
|
|
|
Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Check if the Thunks are already valid */
|
|
|
|
if (EntriesValid)
|
|
|
|
{
|
|
|
|
/* We'll only do forwarders. Get the import name */
|
|
|
|
ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->Name);
|
|
|
|
|
2016-11-12 21:53:33 +00:00
|
|
|
/* Get the list of forwarders */
|
2011-03-22 12:41:52 +00:00
|
|
|
ForwarderChain = IatEntry->ForwarderChain;
|
|
|
|
|
|
|
|
/* Loop them */
|
|
|
|
while (ForwarderChain != -1)
|
|
|
|
{
|
|
|
|
/* Get the cached thunk VA*/
|
|
|
|
OriginalThunk = (PIMAGE_THUNK_DATA)
|
|
|
|
((ULONG_PTR)ImportLdrEntry->DllBase +
|
|
|
|
IatEntry->OriginalFirstThunk +
|
|
|
|
(ForwarderChain * sizeof(IMAGE_THUNK_DATA)));
|
|
|
|
|
|
|
|
/* Get the first thunk */
|
|
|
|
FirstThunk = (PIMAGE_THUNK_DATA)
|
|
|
|
((ULONG_PTR)ImportLdrEntry->DllBase +
|
|
|
|
IatEntry->FirstThunk +
|
|
|
|
(ForwarderChain * sizeof(IMAGE_THUNK_DATA)));
|
|
|
|
|
|
|
|
/* Get the Forwarder from the thunk */
|
|
|
|
ForwarderChain = (ULONG)FirstThunk->u1.Ordinal;
|
|
|
|
|
|
|
|
/* Snap the thunk */
|
2011-03-23 12:25:53 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
Status = LdrpSnapThunk(ExportLdrEntry->DllBase,
|
|
|
|
ImportLdrEntry->DllBase,
|
|
|
|
OriginalThunk,
|
|
|
|
FirstThunk,
|
|
|
|
ExportDirectory,
|
|
|
|
ExportSize,
|
|
|
|
TRUE,
|
|
|
|
ImportName);
|
|
|
|
|
|
|
|
/* Move to the next thunk */
|
|
|
|
FirstThunk++;
|
|
|
|
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
/* Fail with the SEH error */
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
} _SEH2_END;
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* If we messed up, exit */
|
|
|
|
if (!NT_SUCCESS(Status)) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (IatEntry->FirstThunk)
|
|
|
|
{
|
|
|
|
/* Full snapping. Get the First thunk */
|
|
|
|
FirstThunk = (PIMAGE_THUNK_DATA)
|
|
|
|
((ULONG_PTR)ImportLdrEntry->DllBase +
|
|
|
|
IatEntry->FirstThunk);
|
|
|
|
|
|
|
|
/* Get the NT Header */
|
|
|
|
NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase);
|
|
|
|
|
|
|
|
/* Get the Original thunk VA, watch out for weird images */
|
|
|
|
if ((IatEntry->Characteristics < NtHeader->OptionalHeader.SizeOfHeaders) ||
|
|
|
|
(IatEntry->Characteristics >= NtHeader->OptionalHeader.SizeOfImage))
|
|
|
|
{
|
2011-03-23 12:25:53 +00:00
|
|
|
/* Refuse it, this is a strange linked file */
|
2011-03-22 12:41:52 +00:00
|
|
|
OriginalThunk = FirstThunk;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Get the address from the field and convert to VA */
|
|
|
|
OriginalThunk = (PIMAGE_THUNK_DATA)
|
|
|
|
((ULONG_PTR)ImportLdrEntry->DllBase +
|
|
|
|
IatEntry->OriginalFirstThunk);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the Import name VA */
|
|
|
|
ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase +
|
|
|
|
IatEntry->Name);
|
|
|
|
|
|
|
|
/* Loop while it's valid */
|
|
|
|
while (OriginalThunk->u1.AddressOfData)
|
|
|
|
{
|
|
|
|
/* Snap the Thunk */
|
2011-03-23 12:25:53 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
Status = LdrpSnapThunk(ExportLdrEntry->DllBase,
|
|
|
|
ImportLdrEntry->DllBase,
|
|
|
|
OriginalThunk,
|
|
|
|
FirstThunk,
|
|
|
|
ExportDirectory,
|
|
|
|
ExportSize,
|
|
|
|
TRUE,
|
|
|
|
ImportName);
|
|
|
|
|
|
|
|
/* Next thunks */
|
|
|
|
OriginalThunk++;
|
|
|
|
FirstThunk++;
|
|
|
|
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
/* Fail with the SEH error */
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
} _SEH2_END;
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* If we failed the snap, break out */
|
|
|
|
if (!NT_SUCCESS(Status)) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Protect the IAT again */
|
|
|
|
NtProtectVirtualMemory(NtCurrentProcess(),
|
|
|
|
&Iat,
|
|
|
|
&ImportSize,
|
|
|
|
OldProtect,
|
|
|
|
&OldProtect);
|
|
|
|
|
|
|
|
/* Also flush out the cache */
|
|
|
|
NtFlushInstructionCache(NtCurrentProcess(), Iat, IatSize);
|
|
|
|
|
|
|
|
/* Return to Caller */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
|
|
|
IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR *BoundEntryPtr,
|
2011-03-22 12:41:52 +00:00
|
|
|
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry)
|
|
|
|
{
|
|
|
|
LPSTR ImportName = NULL, BoundImportName, ForwarderName;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN AlreadyLoaded = FALSE, Stale;
|
|
|
|
PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
|
|
|
|
PLDR_DATA_TABLE_ENTRY DllLdrEntry, ForwarderLdrEntry;
|
|
|
|
PIMAGE_BOUND_FORWARDER_REF ForwarderEntry;
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry;
|
2011-03-22 12:41:52 +00:00
|
|
|
PPEB Peb = NtCurrentPeb();
|
|
|
|
ULONG i, IatSize;
|
|
|
|
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
/* Get the pointer to the bound entry */
|
|
|
|
BoundEntry = *BoundEntryPtr;
|
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
/* Get the name's VA */
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
BoundImportName = (LPSTR)FirstEntry + BoundEntry->OffsetModuleName;
|
2011-03-22 12:41:52 +00:00
|
|
|
|
2016-11-12 21:53:33 +00:00
|
|
|
/* Show debug message */
|
2011-03-22 12:41:52 +00:00
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ bound to %s\n", &LdrEntry->BaseDllName, BoundImportName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Load the module for this entry */
|
|
|
|
Status = LdrpLoadImportModule(DllPath,
|
|
|
|
BoundImportName,
|
|
|
|
&DllLdrEntry,
|
|
|
|
&AlreadyLoaded);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n",
|
|
|
|
&LdrEntry->BaseDllName,
|
|
|
|
BoundImportName,
|
|
|
|
Status);
|
|
|
|
}
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if it wasn't already loaded */
|
|
|
|
if (!AlreadyLoaded)
|
|
|
|
{
|
|
|
|
/* Add it to our list */
|
|
|
|
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
|
2015-06-15 18:38:57 +00:00
|
|
|
&DllLdrEntry->InInitializationOrderLinks);
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the Bound Entry is now invalid */
|
|
|
|
if ((BoundEntry->TimeDateStamp != DllLdrEntry->TimeDateStamp) ||
|
|
|
|
(DllLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE))
|
|
|
|
{
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ has stale binding to %s\n",
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
&LdrEntry->BaseDllName,
|
2011-03-22 12:41:52 +00:00
|
|
|
BoundImportName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remember it's become stale */
|
|
|
|
Stale = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ has correct binding to %s\n",
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
&LdrEntry->BaseDllName,
|
2011-03-22 12:41:52 +00:00
|
|
|
BoundImportName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remember it's valid */
|
|
|
|
Stale = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the forwarders */
|
|
|
|
ForwarderEntry = (PIMAGE_BOUND_FORWARDER_REF)(BoundEntry + 1);
|
|
|
|
|
|
|
|
/* Loop them */
|
|
|
|
for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++)
|
|
|
|
{
|
|
|
|
/* Get the name */
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
ForwarderName = (LPSTR)FirstEntry + ForwarderEntry->OffsetModuleName;
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ bound to %s via forwarder(s) from %wZ\n",
|
|
|
|
&LdrEntry->BaseDllName,
|
|
|
|
ForwarderName,
|
|
|
|
&DllLdrEntry->BaseDllName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Load the module */
|
|
|
|
Status = LdrpLoadImportModule(DllPath,
|
|
|
|
ForwarderName,
|
|
|
|
&ForwarderLdrEntry,
|
|
|
|
&AlreadyLoaded);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Loaded it, was it already loaded? */
|
|
|
|
if (!AlreadyLoaded)
|
|
|
|
{
|
|
|
|
/* Add it to our list */
|
|
|
|
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
|
2015-06-15 18:38:57 +00:00
|
|
|
&ForwarderLdrEntry->InInitializationOrderLinks);
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the Bound Entry is now invalid */
|
|
|
|
if (!(NT_SUCCESS(Status)) ||
|
|
|
|
(ForwarderEntry->TimeDateStamp != ForwarderLdrEntry->TimeDateStamp) ||
|
|
|
|
(ForwarderLdrEntry->Flags & LDRP_IMAGE_NOT_AT_BASE))
|
|
|
|
{
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ has stale binding to %s\n",
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
&LdrEntry->BaseDllName,
|
2011-03-22 12:41:52 +00:00
|
|
|
ForwarderName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remember it's become stale */
|
|
|
|
Stale = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ has correct binding to %s\n",
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
&LdrEntry->BaseDllName,
|
2011-03-22 12:41:52 +00:00
|
|
|
ForwarderName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remember it's valid */
|
|
|
|
Stale = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move to the next one */
|
|
|
|
ForwarderEntry++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the next bound entry to the forwarder */
|
|
|
|
FirstEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)ForwarderEntry;
|
|
|
|
|
|
|
|
/* Check if the binding was stale */
|
|
|
|
if (Stale)
|
|
|
|
{
|
|
|
|
/* It was, so find the IAT entry for it */
|
2011-07-10 13:23:19 +00:00
|
|
|
++LdrpNormalSnap;
|
2011-03-22 12:41:52 +00:00
|
|
|
ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
|
|
|
|
TRUE,
|
|
|
|
IMAGE_DIRECTORY_ENTRY_IMPORT,
|
|
|
|
&IatSize);
|
|
|
|
|
|
|
|
/* Make sure it has a name */
|
|
|
|
while (ImportEntry->Name)
|
|
|
|
{
|
|
|
|
/* Get the name */
|
|
|
|
ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + ImportEntry->Name);
|
|
|
|
|
|
|
|
/* Compare it */
|
|
|
|
if (!_stricmp(ImportName, BoundImportName)) break;
|
|
|
|
|
|
|
|
/* Move to next entry */
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
ImportEntry++;
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If we didn't find a name, fail */
|
|
|
|
if (!ImportEntry->Name)
|
|
|
|
{
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: LdrpWalkImportTable - failing with"
|
|
|
|
"STATUS_OBJECT_NAME_INVALID due to no import descriptor name\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return error */
|
|
|
|
Status = STATUS_OBJECT_NAME_INVALID;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: Stale Bind %s from %wZ\n",
|
|
|
|
ImportName,
|
|
|
|
&LdrEntry->BaseDllName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Snap the IAT Entry*/
|
|
|
|
Status = LdrpSnapIAT(DllLdrEntry,
|
|
|
|
LdrEntry,
|
|
|
|
ImportEntry,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
/* Make sure we didn't fail */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %wZ failed to load import module %s; status = %x\n",
|
|
|
|
&LdrEntry->BaseDllName,
|
|
|
|
BoundImportName,
|
|
|
|
Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All done */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* Write where we are now and return */
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
*BoundEntryPtr = FirstEntry;
|
2011-03-22 12:41:52 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpHandleNewFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL,
|
|
|
|
IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
|
|
|
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry)
|
|
|
|
{
|
|
|
|
PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry = BoundEntry;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Make sure we have a name */
|
|
|
|
while (BoundEntry->OffsetModuleName)
|
|
|
|
{
|
|
|
|
/* Parse this descriptor */
|
|
|
|
Status = LdrpHandleOneNewFormatImportDescriptor(DllPath,
|
|
|
|
LdrEntry,
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
&BoundEntry,
|
2011-03-22 12:41:52 +00:00
|
|
|
FirstEntry);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Done */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpHandleOneOldFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
|
|
|
IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
2011-07-10 02:14:29 +00:00
|
|
|
IN PIMAGE_IMPORT_DESCRIPTOR *ImportEntry)
|
2011-03-22 12:41:52 +00:00
|
|
|
{
|
|
|
|
LPSTR ImportName;
|
|
|
|
NTSTATUS Status;
|
2011-07-10 02:14:29 +00:00
|
|
|
BOOLEAN AlreadyLoaded = FALSE;
|
2011-03-22 12:41:52 +00:00
|
|
|
PLDR_DATA_TABLE_ENTRY DllLdrEntry;
|
|
|
|
PIMAGE_THUNK_DATA FirstThunk;
|
|
|
|
PPEB Peb = NtCurrentPeb();
|
|
|
|
|
|
|
|
/* Get the import name's VA */
|
2011-07-10 02:14:29 +00:00
|
|
|
ImportName = (LPSTR)((ULONG_PTR)LdrEntry->DllBase + (*ImportEntry)->Name);
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Get the first thunk */
|
|
|
|
FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrEntry->DllBase +
|
2011-07-10 02:14:29 +00:00
|
|
|
(*ImportEntry)->FirstThunk);
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Make sure it's valid */
|
|
|
|
if (!FirstThunk->u1.Function) goto SkipEntry;
|
|
|
|
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: %s used by %wZ\n",
|
|
|
|
ImportName,
|
|
|
|
&LdrEntry->BaseDllName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Load the module associated to it */
|
|
|
|
Status = LdrpLoadImportModule(DllPath,
|
|
|
|
ImportName,
|
|
|
|
&DllLdrEntry,
|
|
|
|
&AlreadyLoaded);
|
2011-07-10 02:14:29 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Fail */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DbgPrint("LDR: LdrpWalkImportTable - LdrpLoadImportModule failed "
|
|
|
|
"on import %s with status %x\n",
|
|
|
|
ImportName,
|
|
|
|
Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
return Status;
|
|
|
|
}
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Show debug message */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: Snapping imports for %wZ from %s\n",
|
|
|
|
&LdrEntry->BaseDllName,
|
|
|
|
ImportName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if it wasn't already loaded */
|
2011-07-10 02:14:29 +00:00
|
|
|
++LdrpNormalSnap;
|
2011-03-22 12:41:52 +00:00
|
|
|
if (!AlreadyLoaded)
|
|
|
|
{
|
|
|
|
/* Add the DLL to our list */
|
|
|
|
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
|
2015-06-15 18:38:57 +00:00
|
|
|
&DllLdrEntry->InInitializationOrderLinks);
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
2011-07-10 02:14:29 +00:00
|
|
|
/* Now snap the IAT Entry */
|
|
|
|
Status = LdrpSnapIAT(DllLdrEntry, LdrEntry, *ImportEntry, FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2011-03-22 12:41:52 +00:00
|
|
|
{
|
2011-07-10 02:14:29 +00:00
|
|
|
/* Fail */
|
|
|
|
if (ShowSnaps)
|
|
|
|
{
|
|
|
|
DbgPrint("LDR: LdrpWalkImportTable - LdrpSnapIAT #2 failed with "
|
|
|
|
"status %x\n",
|
|
|
|
Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return */
|
|
|
|
return Status;
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SkipEntry:
|
2011-07-10 02:14:29 +00:00
|
|
|
/* Move on */
|
2011-07-10 13:44:19 +00:00
|
|
|
(*ImportEntry)++;
|
2011-03-22 12:41:52 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpHandleOldFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL,
|
|
|
|
IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
|
|
|
IN PIMAGE_IMPORT_DESCRIPTOR ImportEntry)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Check for Name and Thunk */
|
2011-07-10 02:14:29 +00:00
|
|
|
while ((ImportEntry->Name) && (ImportEntry->FirstThunk))
|
2011-03-22 12:41:52 +00:00
|
|
|
{
|
|
|
|
/* Parse this descriptor */
|
|
|
|
Status = LdrpHandleOneOldFormatImportDescriptor(DllPath,
|
|
|
|
LdrEntry,
|
2011-07-10 02:14:29 +00:00
|
|
|
&ImportEntry);
|
2011-03-22 12:41:52 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Done */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-07-10 02:14:29 +00:00
|
|
|
USHORT
|
|
|
|
NTAPI
|
|
|
|
LdrpNameToOrdinal(IN LPSTR ImportName,
|
|
|
|
IN ULONG NumberOfNames,
|
|
|
|
IN PVOID ExportBase,
|
|
|
|
IN PULONG NameTable,
|
|
|
|
IN PUSHORT OrdinalTable)
|
2011-03-16 14:22:15 +00:00
|
|
|
{
|
2011-07-10 02:14:29 +00:00
|
|
|
LONG Start, End, Next, CmpResult;
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
|
|
|
|
/* Use classical binary search to find the ordinal */
|
2011-07-10 02:14:29 +00:00
|
|
|
Start = Next = 0;
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
End = NumberOfNames - 1;
|
|
|
|
while (End >= Start)
|
|
|
|
{
|
|
|
|
/* Next will be exactly between Start and End */
|
|
|
|
Next = (Start + End) >> 1;
|
|
|
|
|
|
|
|
/* Compare this name with the one we need to find */
|
|
|
|
CmpResult = strcmp(ImportName, (PCHAR)((ULONG_PTR)ExportBase + NameTable[Next]));
|
|
|
|
|
|
|
|
/* We found our entry if result is 0 */
|
|
|
|
if (!CmpResult) break;
|
|
|
|
|
|
|
|
/* We didn't find, update our range then */
|
|
|
|
if (CmpResult < 0)
|
2011-07-10 02:14:29 +00:00
|
|
|
{
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
End = Next - 1;
|
2011-07-10 02:14:29 +00:00
|
|
|
}
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
else if (CmpResult > 0)
|
2011-07-10 02:14:29 +00:00
|
|
|
{
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
Start = Next + 1;
|
2011-07-10 02:14:29 +00:00
|
|
|
}
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If end is before start, then the search failed */
|
|
|
|
if (End < Start) return -1;
|
|
|
|
|
|
|
|
/* Return found name */
|
|
|
|
return OrdinalTable[Next];
|
2011-03-16 14:22:15 +00:00
|
|
|
}
|
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
|
|
|
IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
|
|
|
{
|
|
|
|
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
|
|
|
|
PPEB Peb = NtCurrentPeb();
|
2016-01-07 12:09:03 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS, Status2;
|
2011-03-22 12:41:52 +00:00
|
|
|
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry = NULL;
|
|
|
|
PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
|
|
|
|
ULONG BoundSize, IatSize;
|
2016-01-27 15:02:28 +00:00
|
|
|
|
|
|
|
DPRINT("LdrpWalkImportDescriptor - BEGIN (%wZ %p '%S')\n", &LdrEntry->BaseDllName, LdrEntry, DllPath);
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
/* Set up the Act Ctx */
|
2011-07-12 12:55:03 +00:00
|
|
|
RtlZeroMemory(&ActCtx, sizeof(ActCtx));
|
2011-03-22 12:41:52 +00:00
|
|
|
ActCtx.Size = sizeof(ActCtx);
|
2011-07-10 02:14:29 +00:00
|
|
|
ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER;
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Check if we have a manifest prober routine */
|
|
|
|
if (LdrpManifestProberRoutine)
|
|
|
|
{
|
2016-01-07 12:09:03 +00:00
|
|
|
/* 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 */
|
2016-01-27 15:02:28 +00:00
|
|
|
//Status = Status2; // FIXME: Ignore that error for now
|
2016-01-07 12:09:03 +00:00
|
|
|
DbgPrintEx(DPFLTR_SXS_ID,
|
|
|
|
DPFLTR_WARNING_LEVEL,
|
|
|
|
"LDR: LdrpWalkImportDescriptor() failed to probe %wZ for its "
|
|
|
|
"manifest, ntstatus = 0x%08lx\n",
|
|
|
|
&LdrEntry->FullDllName, Status);
|
|
|
|
}
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we failed above */
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
|
|
|
/* Get the Active ActCtx */
|
2016-01-27 15:02:28 +00:00
|
|
|
if (!LdrEntry->EntryPointActivationContext)
|
2011-07-10 02:14:29 +00:00
|
|
|
{
|
2016-01-27 15:02:28 +00:00
|
|
|
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;
|
|
|
|
}
|
2011-07-10 02:14:29 +00:00
|
|
|
}
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Activate the ActCtx */
|
|
|
|
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
|
|
|
LdrEntry->EntryPointActivationContext);
|
|
|
|
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
/* Check if we were redirected */
|
2011-03-22 12:41:52 +00:00
|
|
|
if (!(LdrEntry->Flags & LDRP_REDIRECTED))
|
|
|
|
{
|
|
|
|
/* Get the Bound IAT */
|
|
|
|
BoundEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
|
|
|
|
TRUE,
|
|
|
|
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
|
|
|
|
&BoundSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the regular IAT, for fallback */
|
|
|
|
ImportEntry = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
|
|
|
|
TRUE,
|
|
|
|
IMAGE_DIRECTORY_ENTRY_IMPORT,
|
|
|
|
&IatSize);
|
|
|
|
|
|
|
|
/* Check if we got at least one */
|
2011-07-10 02:14:29 +00:00
|
|
|
if ((BoundEntry) || (ImportEntry))
|
2011-03-22 12:41:52 +00:00
|
|
|
{
|
|
|
|
/* Do we have a Bound IAT */
|
|
|
|
if (BoundEntry)
|
|
|
|
{
|
|
|
|
/* Handle the descriptor */
|
|
|
|
Status = LdrpHandleNewFormatImportDescriptors(DllPath,
|
|
|
|
LdrEntry,
|
|
|
|
BoundEntry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Handle the descriptor */
|
|
|
|
Status = LdrpHandleOldFormatImportDescriptors(DllPath,
|
|
|
|
LdrEntry,
|
|
|
|
ImportEntry);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the status of the handlers */
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Check for Per-DLL Heap Tagging */
|
|
|
|
if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAG_BY_DLL)
|
|
|
|
{
|
|
|
|
/* FIXME */
|
|
|
|
DPRINT1("We don't support Per-DLL Heap Tagging yet!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if Page Heap was enabled */
|
|
|
|
if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS)
|
|
|
|
{
|
2011-08-21 22:15:08 +00:00
|
|
|
/* Initialize target DLL */
|
|
|
|
AVrfPageHeapDllNotification(LdrEntry);
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if Application Verifier was enabled */
|
2018-04-27 20:43:45 +00:00
|
|
|
if (Peb->NtGlobalFlag & FLG_APPLICATION_VERIFIER)
|
2011-03-22 12:41:52 +00:00
|
|
|
{
|
2018-04-27 20:43:45 +00:00
|
|
|
AVrfDllLoadNotification(LdrEntry);
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Just to be safe */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Release the activation context */
|
|
|
|
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
|
|
|
|
2016-01-27 15:02:28 +00:00
|
|
|
DPRINT("LdrpWalkImportDescriptor - END (%wZ %p)\n", &LdrEntry->BaseDllName, LdrEntry);
|
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
/* Return status */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
|
|
|
|
IN LPSTR ImportName,
|
|
|
|
OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry,
|
|
|
|
OUT PBOOLEAN Existing)
|
|
|
|
{
|
|
|
|
ANSI_STRING AnsiString;
|
|
|
|
PUNICODE_STRING ImpDescName;
|
2016-06-03 19:02:46 +00:00
|
|
|
const WCHAR *p;
|
|
|
|
BOOLEAN GotExtension;
|
|
|
|
WCHAR c;
|
2011-03-22 12:41:52 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PPEB Peb = RtlGetCurrentPeb();
|
|
|
|
PTEB Teb = NtCurrentTeb();
|
2017-10-03 19:11:47 +00:00
|
|
|
UNICODE_STRING RedirectedImpDescName;
|
|
|
|
BOOLEAN RedirectedDll;
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
|
2016-06-03 19:02:46 +00:00
|
|
|
DPRINT("LdrpLoadImportModule('%S' '%s' %p %p)\n", DllPath, ImportName, DataTableEntry, Existing);
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
|
2017-10-03 19:11:47 +00:00
|
|
|
RedirectedDll = FALSE;
|
|
|
|
RtlInitEmptyUnicodeString(&RedirectedImpDescName, NULL, 0);
|
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
/* Convert import descriptor name to unicode string */
|
|
|
|
ImpDescName = &Teb->StaticUnicodeString;
|
|
|
|
RtlInitAnsiString(&AnsiString, ImportName);
|
|
|
|
Status = RtlAnsiStringToUnicodeString(ImpDescName, &AnsiString, FALSE);
|
|
|
|
if (!NT_SUCCESS(Status)) return Status;
|
|
|
|
|
2016-06-03 19:02:46 +00:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2017-10-03 19:11:47 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
/* Check if it's loaded */
|
|
|
|
if (LdrpCheckForLoadedDll(DllPath,
|
|
|
|
ImpDescName,
|
|
|
|
TRUE,
|
2017-10-03 19:11:47 +00:00
|
|
|
RedirectedDll,
|
2011-03-22 12:41:52 +00:00
|
|
|
DataTableEntry))
|
|
|
|
{
|
|
|
|
/* It's already existing in the list */
|
|
|
|
*Existing = TRUE;
|
2017-10-03 19:11:47 +00:00
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
goto done;
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We're loading it for the first time */
|
|
|
|
*Existing = FALSE;
|
|
|
|
|
|
|
|
/* Map it */
|
|
|
|
Status = LdrpMapDll(DllPath,
|
|
|
|
NULL,
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
ImpDescName->Buffer,
|
2011-03-22 12:41:52 +00:00
|
|
|
NULL,
|
|
|
|
TRUE,
|
2017-10-03 19:11:47 +00:00
|
|
|
RedirectedDll,
|
2011-03-22 12:41:52 +00:00
|
|
|
DataTableEntry);
|
2017-10-03 19:11:47 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("LDR: LdrpMapDll failed with status %x for dll %wZ\n", Status, ImpDescName);
|
|
|
|
goto done;
|
|
|
|
}
|
2011-03-22 12:41:52 +00:00
|
|
|
|
|
|
|
/* Walk its import descriptor table */
|
|
|
|
Status = LdrpWalkImportDescriptor(DllPath,
|
|
|
|
*DataTableEntry);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Add it to the in-init-order list in case of failure */
|
|
|
|
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
|
2015-06-15 18:38:57 +00:00
|
|
|
&(*DataTableEntry)->InInitializationOrderLinks);
|
2011-03-22 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
2017-10-03 19:11:47 +00:00
|
|
|
done:
|
|
|
|
RtlFreeUnicodeString(&RedirectedImpDescName);
|
|
|
|
|
2011-03-22 12:41:52 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2011-03-16 14:22:15 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
LdrpSnapThunk(IN PVOID ExportBase,
|
|
|
|
IN PVOID ImportBase,
|
|
|
|
IN PIMAGE_THUNK_DATA OriginalThunk,
|
|
|
|
IN OUT PIMAGE_THUNK_DATA Thunk,
|
|
|
|
IN PIMAGE_EXPORT_DIRECTORY ExportEntry,
|
|
|
|
IN ULONG ExportSize,
|
|
|
|
IN BOOLEAN Static,
|
|
|
|
IN LPSTR DllName)
|
|
|
|
{
|
|
|
|
BOOLEAN IsOrdinal;
|
|
|
|
USHORT Ordinal;
|
|
|
|
ULONG OriginalOrdinal = 0;
|
|
|
|
PIMAGE_IMPORT_BY_NAME AddressOfData;
|
|
|
|
PULONG NameTable;
|
|
|
|
PUSHORT OrdinalTable;
|
2011-03-17 10:59:54 +00:00
|
|
|
LPSTR ImportName = NULL;
|
2011-03-16 14:22:15 +00:00
|
|
|
USHORT Hint;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG_PTR HardErrorParameters[3];
|
|
|
|
UNICODE_STRING HardErrorDllName, HardErrorEntryPointName;
|
|
|
|
ANSI_STRING TempString;
|
|
|
|
ULONG Mask;
|
|
|
|
ULONG Response;
|
|
|
|
PULONG AddressOfFunctions;
|
|
|
|
UNICODE_STRING TempUString;
|
|
|
|
ANSI_STRING ForwarderName;
|
|
|
|
PANSI_STRING ForwardName;
|
|
|
|
PVOID ForwarderHandle;
|
|
|
|
ULONG ForwardOrdinal;
|
|
|
|
|
|
|
|
/* Check if the snap is by ordinal */
|
|
|
|
if ((IsOrdinal = IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)))
|
|
|
|
{
|
|
|
|
/* Get the ordinal number, and its normalized version */
|
|
|
|
OriginalOrdinal = IMAGE_ORDINAL(OriginalThunk->u1.Ordinal);
|
|
|
|
Ordinal = (USHORT)(OriginalOrdinal - ExportEntry->Base);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* First get the data VA */
|
|
|
|
AddressOfData = (PIMAGE_IMPORT_BY_NAME)
|
|
|
|
((ULONG_PTR)ImportBase +
|
|
|
|
((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff));
|
|
|
|
|
|
|
|
/* Get the name */
|
|
|
|
ImportName = (LPSTR)AddressOfData->Name;
|
|
|
|
|
|
|
|
/* Now get the VA of the Name and Ordinal Tables */
|
|
|
|
NameTable = (PULONG)((ULONG_PTR)ExportBase +
|
|
|
|
(ULONG_PTR)ExportEntry->AddressOfNames);
|
|
|
|
OrdinalTable = (PUSHORT)((ULONG_PTR)ExportBase +
|
|
|
|
(ULONG_PTR)ExportEntry->AddressOfNameOrdinals);
|
|
|
|
|
|
|
|
/* Get the hint */
|
|
|
|
Hint = AddressOfData->Hint;
|
|
|
|
|
|
|
|
/* Try to get a match by using the hint */
|
|
|
|
if (((ULONG)Hint < ExportEntry->NumberOfNames) &&
|
|
|
|
(!strcmp(ImportName, ((LPSTR)((ULONG_PTR)ExportBase + NameTable[Hint])))))
|
|
|
|
{
|
|
|
|
/* We got a match, get the Ordinal from the hint */
|
|
|
|
Ordinal = OrdinalTable[Hint];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Well bummer, hint didn't work, do it the long way */
|
|
|
|
Ordinal = LdrpNameToOrdinal(ImportName,
|
|
|
|
ExportEntry->NumberOfNames,
|
|
|
|
ExportBase,
|
|
|
|
NameTable,
|
|
|
|
OrdinalTable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the ordinal is invalid */
|
|
|
|
if ((ULONG)Ordinal >= ExportEntry->NumberOfFunctions)
|
|
|
|
{
|
|
|
|
FailurePath:
|
|
|
|
/* Is this a static snap? */
|
|
|
|
if (Static)
|
|
|
|
{
|
2018-10-03 17:34:14 +00:00
|
|
|
RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown");
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
/* Inform the debug log */
|
|
|
|
if (IsOrdinal)
|
2018-10-03 17:34:14 +00:00
|
|
|
DPRINT1("Failed to snap ordinal %Z!0x%x\n", &TempString, OriginalOrdinal);
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
else
|
2018-10-03 17:34:14 +00:00
|
|
|
DPRINT1("Failed to snap %Z!%s\n", &TempString, ImportName);
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
|
2011-03-16 14:22:15 +00:00
|
|
|
/* These are critical errors. Setup a string for the DLL name */
|
|
|
|
RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE);
|
|
|
|
|
|
|
|
/* Set it as the parameter */
|
|
|
|
HardErrorParameters[1] = (ULONG_PTR)&HardErrorDllName;
|
|
|
|
Mask = 2;
|
|
|
|
|
|
|
|
/* Check if we have an ordinal */
|
|
|
|
if (IsOrdinal)
|
|
|
|
{
|
|
|
|
/* Then set the ordinal as the 1st parameter */
|
|
|
|
HardErrorParameters[0] = OriginalOrdinal;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We don't, use the entrypoint. Set up a string for it */
|
|
|
|
RtlInitAnsiString(&TempString, ImportName);
|
|
|
|
RtlAnsiStringToUnicodeString(&HardErrorEntryPointName,
|
|
|
|
&TempString,
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
/* Set it as the parameter */
|
|
|
|
HardErrorParameters[0] = (ULONG_PTR)&HardErrorEntryPointName;
|
|
|
|
Mask = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Raise the error */
|
|
|
|
NtRaiseHardError(IsOrdinal ? STATUS_ORDINAL_NOT_FOUND :
|
|
|
|
STATUS_ENTRYPOINT_NOT_FOUND,
|
|
|
|
2,
|
|
|
|
Mask,
|
|
|
|
HardErrorParameters,
|
|
|
|
OptionOk,
|
|
|
|
&Response);
|
|
|
|
|
|
|
|
/* Increase the error count */
|
|
|
|
if (LdrpInLdrInit) LdrpFatalHardErrorCount++;
|
|
|
|
|
|
|
|
/* Free our string */
|
|
|
|
RtlFreeUnicodeString(&HardErrorDllName);
|
|
|
|
if (!IsOrdinal)
|
|
|
|
{
|
|
|
|
/* Free our second string. Return entrypoint error */
|
|
|
|
RtlFreeUnicodeString(&HardErrorEntryPointName);
|
|
|
|
RtlRaiseStatus(STATUS_ENTRYPOINT_NOT_FOUND);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return ordinal error */
|
|
|
|
RtlRaiseStatus(STATUS_ORDINAL_NOT_FOUND);
|
|
|
|
}
|
[NTDLL/LDR]
- The long awaited LDR rewrite, a commit for testing the new implementation. In case of serious problems it may be reverted (revert should be approved by me).
- Its features include:
* A proper ...everything. Process, thread initialization codes, DLL loading (including compatible path lookup, and compatible/proper loading order of the dependent DLLs, including their initialization) and mapping and section creation, reference counting, relocations, good and understandable PE code for walking import descriptor, snapping, etc etc. Hacks--; GoodCode++;
* Activation contexts operations are now being performed compatible to how Windows performs them (though the actual actctx implementation is still Wine's, it was modified to be compatible). Previously, actctx stuff was added to the ldr code like a pepper is added to the soup: in different places until it starts to work.
* Partial DLL redirection implementation.
* Possibility to support Shim engine and app compat stuff in future.
* More cool stuff, just browse the code.
- I fixed all regressions I could find but one (hang during shutdown of the 3rd stage). The purpose of this commit is to seek and destroy the regressions I couldn't find (if there are any).
- Some of the old rarely called ldr code still remains in startup.c and utils.c. They are subject to be rewritten/removed soon, and every remaining old function is marked with a respective DPRINT1 to see when it's being called.
svn path=/trunk/; revision=52446
2011-06-24 21:30:09 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Inform the debug log */
|
|
|
|
if (IsOrdinal)
|
|
|
|
DPRINT("Non-fatal: Failed to snap ordinal 0x%x\n", OriginalOrdinal);
|
|
|
|
else
|
|
|
|
DPRINT("Non-fatal: Failed to snap %s\n", ImportName);
|
|
|
|
}
|
2011-03-16 14:22:15 +00:00
|
|
|
|
|
|
|
/* Set this as a bad DLL */
|
|
|
|
Thunk->u1.Function = (ULONG_PTR)0xffbadd11;
|
|
|
|
|
|
|
|
/* Return the right error code */
|
|
|
|
Status = IsOrdinal ? STATUS_ORDINAL_NOT_FOUND :
|
|
|
|
STATUS_ENTRYPOINT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* The ordinal seems correct, get the AddressOfFunctions VA */
|
|
|
|
AddressOfFunctions = (PULONG)
|
|
|
|
((ULONG_PTR)ExportBase +
|
|
|
|
(ULONG_PTR)ExportEntry->AddressOfFunctions);
|
|
|
|
|
|
|
|
/* Write the function pointer*/
|
|
|
|
Thunk->u1.Function = (ULONG_PTR)ExportBase + AddressOfFunctions[Ordinal];
|
|
|
|
|
|
|
|
/* Make sure it's within the exports */
|
|
|
|
if ((Thunk->u1.Function > (ULONG_PTR)ExportEntry) &&
|
|
|
|
(Thunk->u1.Function < ((ULONG_PTR)ExportEntry + ExportSize)))
|
|
|
|
{
|
|
|
|
/* Get the Import and Forwarder Names */
|
|
|
|
ImportName = (LPSTR)Thunk->u1.Function;
|
|
|
|
ForwarderName.Buffer = ImportName;
|
|
|
|
ForwarderName.Length = (USHORT)(strchr(ImportName, '.') - ImportName);
|
|
|
|
ForwarderName.MaximumLength = ForwarderName.Length;
|
|
|
|
Status = RtlAnsiStringToUnicodeString(&TempUString,
|
|
|
|
&ForwarderName,
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
/* Make sure the conversion was OK */
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Load the forwarder, free the temp string */
|
|
|
|
Status = LdrpLoadDll(FALSE,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&TempUString,
|
|
|
|
&ForwarderHandle,
|
|
|
|
FALSE);
|
|
|
|
RtlFreeUnicodeString(&TempUString);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the load or conversion failed, use the failure path */
|
|
|
|
if (!NT_SUCCESS(Status)) goto FailurePath;
|
|
|
|
|
|
|
|
/* Now set up a name for the actual forwarder dll */
|
|
|
|
RtlInitAnsiString(&ForwarderName,
|
|
|
|
ImportName + ForwarderName.Length + sizeof(CHAR));
|
|
|
|
|
|
|
|
/* Check if it's an ordinal forward */
|
|
|
|
if ((ForwarderName.Length > 1) && (*ForwarderName.Buffer == '#'))
|
|
|
|
{
|
|
|
|
/* We don't have an actual function name */
|
|
|
|
ForwardName = NULL;
|
|
|
|
|
|
|
|
/* Convert the string into an ordinal */
|
|
|
|
Status = RtlCharToInteger(ForwarderName.Buffer + sizeof(CHAR),
|
|
|
|
0,
|
|
|
|
&ForwardOrdinal);
|
|
|
|
|
|
|
|
/* If this fails, then error out */
|
|
|
|
if (!NT_SUCCESS(Status)) goto FailurePath;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Import by name */
|
|
|
|
ForwardName = &ForwarderName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the pointer */
|
|
|
|
Status = LdrpGetProcedureAddress(ForwarderHandle,
|
|
|
|
ForwardName,
|
|
|
|
ForwardOrdinal,
|
|
|
|
(PVOID*)&Thunk->u1.Function,
|
|
|
|
FALSE);
|
|
|
|
/* If this fails, then error out */
|
|
|
|
if (!NT_SUCCESS(Status)) goto FailurePath;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* It's not within the exports, let's hope it's valid */
|
|
|
|
if (!AddressOfFunctions[Ordinal]) goto FailurePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we got here, then it's success */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return status */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|