mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
- Revert r52573
- Branch repair (part 1 of x) svn path=/branches/GSoC_2011/TcpIpDriver/; revision=53062
This commit is contained in:
@@ -10,6 +10,11 @@
|
||||
|
||||
#define LDR_HASH_TABLE_ENTRIES 32
|
||||
|
||||
/* LdrpUpdateLoadCount2 flags */
|
||||
#define LDRP_UPDATE_REFCOUNT 0x01
|
||||
#define LDRP_UPDATE_DEREFCOUNT 0x02
|
||||
#define LDRP_UPDATE_PIN 0x03
|
||||
|
||||
typedef struct _LDRP_TLS_DATA
|
||||
{
|
||||
LIST_ENTRY TlsLinks;
|
||||
@@ -27,10 +32,21 @@ extern BOOLEAN LdrpInLdrInit;
|
||||
extern LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
|
||||
extern BOOLEAN ShowSnaps;
|
||||
extern UNICODE_STRING LdrpDefaultPath;
|
||||
extern HANDLE LdrpKnownDllObjectDirectory;
|
||||
extern ULONG LdrpNumberOfProcessors;
|
||||
extern ULONG LdrpFatalHardErrorCount;
|
||||
extern PUNICODE_STRING LdrpTopLevelDllBeingLoaded;
|
||||
extern PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer;
|
||||
extern UNICODE_STRING LdrApiDefaultExtension;
|
||||
extern BOOLEAN LdrpLdrDatabaseIsSetup;
|
||||
extern ULONG LdrpActiveUnloadCount;
|
||||
extern BOOLEAN LdrpShutdownInProgress;
|
||||
extern UNICODE_STRING LdrpKnownDllPath;
|
||||
extern PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache;
|
||||
|
||||
/* ldrinit.c */
|
||||
NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL);
|
||||
NTSTATUS NTAPI LdrpInitializeThread(IN PCONTEXT Context);
|
||||
VOID NTAPI LdrpInitializeThread(IN PCONTEXT Context);
|
||||
NTSTATUS NTAPI LdrpInitializeTls(VOID);
|
||||
NTSTATUS NTAPI LdrpAllocateTls(VOID);
|
||||
VOID NTAPI LdrpFreeTls(VOID);
|
||||
@@ -38,7 +54,7 @@ VOID NTAPI LdrpTlsCallback(PVOID BaseAddress, ULONG Reason);
|
||||
BOOLEAN NTAPI LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context);
|
||||
NTSTATUS NTAPI LdrpInitializeProcess(PCONTEXT Context, PVOID SystemArgument1);
|
||||
VOID NTAPI LdrpInitFailure(NTSTATUS Status);
|
||||
|
||||
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry);
|
||||
|
||||
/* ldrpe.c */
|
||||
NTSTATUS
|
||||
@@ -79,6 +95,10 @@ LdrpLoadDll(IN BOOLEAN Redirected,
|
||||
OUT PVOID *BaseAddress,
|
||||
IN BOOLEAN CallInit);
|
||||
|
||||
VOID NTAPI
|
||||
LdrpUpdateLoadCount2(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
||||
IN ULONG Flags);
|
||||
|
||||
ULONG NTAPI
|
||||
LdrpClearLoadInProgress();
|
||||
|
||||
@@ -101,6 +121,9 @@ LdrpMapDll(IN PWSTR SearchPath OPTIONAL,
|
||||
PVOID NTAPI
|
||||
LdrpFetchAddressOfEntryPoint(PVOID ImageBase);
|
||||
|
||||
BOOLEAN NTAPI
|
||||
LdrpFreeUnicodeString(PUNICODE_STRING String);
|
||||
|
||||
|
||||
/* FIXME: Cleanup this mess */
|
||||
typedef NTSTATUS (NTAPI *PEPFUNC)(PPEB);
|
||||
@@ -110,13 +133,8 @@ NTSTATUS LdrMapSections(HANDLE ProcessHandle,
|
||||
PIMAGE_NT_HEADERS NTHeaders);
|
||||
NTSTATUS LdrMapNTDllForProcess(HANDLE ProcessHandle,
|
||||
PHANDLE NTDllSectionHandle);
|
||||
BOOLEAN LdrMappedAsDataFile(PVOID *BaseAddress);
|
||||
ULONG
|
||||
LdrpGetResidentSize(PIMAGE_NT_HEADERS NTHeaders);
|
||||
PEPFUNC LdrPEStartup (PVOID ImageBase,
|
||||
HANDLE SectionHandle,
|
||||
PLDR_DATA_TABLE_ENTRY* Module,
|
||||
PWSTR FullDosName);
|
||||
|
||||
extern HANDLE WindowsApiPort;
|
||||
|
||||
|
||||
+476
-15
@@ -16,6 +16,8 @@
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
LONG LdrpLoaderLockAcquisitonCount;
|
||||
BOOLEAN LdrpShowRecursiveLoads;
|
||||
UNICODE_STRING LdrApiDefaultExtension = RTL_CONSTANT_STRING(L".DLL");
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
@@ -242,6 +244,480 @@ Quickie:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrLoadDll(IN PWSTR SearchPath OPTIONAL,
|
||||
IN PULONG DllCharacteristics OPTIONAL,
|
||||
IN PUNICODE_STRING DllName,
|
||||
OUT PVOID *BaseAddress)
|
||||
{
|
||||
WCHAR StringBuffer[MAX_PATH];
|
||||
UNICODE_STRING DllString1, DllString2;
|
||||
BOOLEAN RedirectedDll = FALSE;
|
||||
NTSTATUS Status;
|
||||
ULONG Cookie;
|
||||
PUNICODE_STRING OldTldDll;
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
|
||||
/* Initialize the strings */
|
||||
RtlInitUnicodeString(&DllString2, NULL);
|
||||
DllString1.Buffer = StringBuffer;
|
||||
DllString1.Length = 0;
|
||||
DllString1.MaximumLength = sizeof(StringBuffer);
|
||||
|
||||
/* Check if the SxS Assemblies specify another file */
|
||||
Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
|
||||
DllName,
|
||||
&LdrApiDefaultExtension,
|
||||
&DllString1,
|
||||
&DllString2,
|
||||
&DllName,
|
||||
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; did we get a string? */
|
||||
if (DllString2.Buffer)
|
||||
{
|
||||
/* Free the string */
|
||||
RtlFreeUnicodeString(&DllString2);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Lock the loader lock */
|
||||
LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);
|
||||
|
||||
/* Check if there's a TLD DLL being loaded */
|
||||
if ((OldTldDll = LdrpTopLevelDllBeingLoaded))
|
||||
{
|
||||
/* This is a recursive load, do something about it? */
|
||||
if (ShowSnaps || LdrpShowRecursiveLoads)
|
||||
{
|
||||
/* Print out debug messages */
|
||||
DPRINT1("[%lx, %lx] LDR: Recursive DLL Load\n",
|
||||
Teb->RealClientId.UniqueProcess,
|
||||
Teb->RealClientId.UniqueThread);
|
||||
DPRINT1("[%lx, %lx] Previous DLL being loaded \"%wZ\"\n",
|
||||
Teb->RealClientId.UniqueProcess,
|
||||
Teb->RealClientId.UniqueThread,
|
||||
OldTldDll);
|
||||
DPRINT1("[%lx, %lx] DLL being requested \"%wZ\"\n",
|
||||
Teb->RealClientId.UniqueProcess,
|
||||
Teb->RealClientId.UniqueThread,
|
||||
DllName);
|
||||
|
||||
/* Was it initializing too? */
|
||||
if (!LdrpCurrentDllInitializer)
|
||||
{
|
||||
DPRINT1("[%lx, %lx] LDR: No DLL Initializer was running\n",
|
||||
Teb->RealClientId.UniqueProcess,
|
||||
Teb->RealClientId.UniqueThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("[%lx, %lx] DLL whose initializer was currently running \"%wZ\"\n",
|
||||
Teb->ClientId.UniqueProcess,
|
||||
Teb->ClientId.UniqueThread,
|
||||
&LdrpCurrentDllInitializer->BaseDllName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set this one as the TLD DLL being loaded*/
|
||||
LdrpTopLevelDllBeingLoaded = DllName;
|
||||
|
||||
/* Load the DLL */
|
||||
Status = LdrpLoadDll(RedirectedDll,
|
||||
SearchPath,
|
||||
DllCharacteristics,
|
||||
DllName,
|
||||
BaseAddress,
|
||||
TRUE);
|
||||
|
||||
/* Restore the old TLD DLL */
|
||||
LdrpTopLevelDllBeingLoaded = OldTldDll;
|
||||
|
||||
/* Release the lock */
|
||||
LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
|
||||
|
||||
/* Do we have a redirect string? */
|
||||
if (DllString2.Buffer) RtlFreeUnicodeString(&DllString2);
|
||||
|
||||
/* Return */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrFindEntryForAddress(PVOID Address,
|
||||
PLDR_DATA_TABLE_ENTRY *Module)
|
||||
{
|
||||
PLIST_ENTRY ListHead, NextEntry;
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PPEB_LDR_DATA Ldr = NtCurrentPeb()->Ldr;
|
||||
ULONG_PTR DllBase, DllEnd;
|
||||
|
||||
DPRINT("LdrFindEntryForAddress(Address %p)\n", Address);
|
||||
|
||||
/* Nothing to do */
|
||||
if (!Ldr) return STATUS_NO_MORE_ENTRIES;
|
||||
|
||||
/* Loop the module list */
|
||||
ListHead = &Ldr->InMemoryOrderModuleList;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
/* Get the entry and NT Headers */
|
||||
LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);
|
||||
if ((NtHeader = RtlImageNtHeader(LdrEntry->DllBase)))
|
||||
{
|
||||
/* Get the Image Base */
|
||||
DllBase = (ULONG_PTR)LdrEntry->DllBase;
|
||||
DllEnd = DllBase + NtHeader->OptionalHeader.SizeOfImage;
|
||||
|
||||
/* Check if they match */
|
||||
if (((ULONG_PTR)Address >= DllBase) &&
|
||||
((ULONG_PTR)Address < DllEnd))
|
||||
{
|
||||
/* Return it */
|
||||
*Module = LdrEntry;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Next Entry */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing found */
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrGetDllHandleEx(IN ULONG Flags,
|
||||
IN PWSTR DllPath OPTIONAL,
|
||||
IN PULONG DllCharacteristics OPTIONAL,
|
||||
IN PUNICODE_STRING DllName,
|
||||
OUT PVOID *DllHandle OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status = STATUS_DLL_NOT_FOUND;
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
UNICODE_STRING RedirectName, DllString1;
|
||||
UNICODE_STRING RawDllName;
|
||||
PUNICODE_STRING pRedirectName = &RedirectName;
|
||||
PUNICODE_STRING CompareName;
|
||||
PWCHAR p1, p2, p3;
|
||||
BOOLEAN Locked = FALSE;
|
||||
BOOLEAN RedirectedDll = FALSE;
|
||||
ULONG Cookie;
|
||||
ULONG LoadFlag;
|
||||
|
||||
/* Initialize the strings */
|
||||
RtlInitUnicodeString(&DllString1, NULL);
|
||||
RtlInitUnicodeString(&RawDllName, NULL);
|
||||
RedirectName = *DllName;
|
||||
|
||||
/* Clear the handle */
|
||||
if (DllHandle) *DllHandle = NULL;
|
||||
|
||||
/* Check for a valid flag */
|
||||
if ((Flags & ~3) || (!DllHandle && !(Flags & 2)))
|
||||
{
|
||||
DPRINT1("Flags are invalid or no DllHandle given\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* If not initializing */
|
||||
if (!LdrpInLdrInit)
|
||||
{
|
||||
/* Acquire the lock */
|
||||
Status = LdrLockLoaderLock(0, NULL, &Cookie);
|
||||
Locked = TRUE;
|
||||
}
|
||||
|
||||
/* Check if the SxS Assemblies specify another file */
|
||||
Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
|
||||
pRedirectName,
|
||||
&LdrApiDefaultExtension,
|
||||
NULL,
|
||||
&DllString1,
|
||||
&pRedirectName,
|
||||
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; */
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Use the cache if we can */
|
||||
if (LdrpGetModuleHandleCache)
|
||||
{
|
||||
/* Check if we were redirected */
|
||||
if (RedirectedDll)
|
||||
{
|
||||
/* Check the flag */
|
||||
if (LdrpGetModuleHandleCache->Flags & LDRP_REDIRECTED)
|
||||
{
|
||||
/* Use the right name */
|
||||
CompareName = &LdrpGetModuleHandleCache->FullDllName;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto DontCompare;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the flag */
|
||||
if (!(LdrpGetModuleHandleCache->Flags & LDRP_REDIRECTED))
|
||||
{
|
||||
/* Use the right name */
|
||||
CompareName = &LdrpGetModuleHandleCache->BaseDllName;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto DontCompare;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the name matches */
|
||||
if (RtlEqualUnicodeString(pRedirectName,
|
||||
CompareName,
|
||||
TRUE))
|
||||
{
|
||||
/* Skip the rest */
|
||||
LdrEntry = LdrpGetModuleHandleCache;
|
||||
|
||||
/* Return success */
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
goto FoundEntry;
|
||||
}
|
||||
}
|
||||
|
||||
DontCompare:
|
||||
/* Find the name without the extension */
|
||||
p1 = pRedirectName->Buffer;
|
||||
p3 = &p1[pRedirectName->Length / sizeof(WCHAR)];
|
||||
StartLoop:
|
||||
p2 = NULL;
|
||||
while (p1 != p3)
|
||||
{
|
||||
if (*p1++ == L'.')
|
||||
{
|
||||
p2 = p1;
|
||||
}
|
||||
else if (*p1 == L'\\')
|
||||
{
|
||||
goto StartLoop;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if no extension was found or if we got a slash */
|
||||
if (!p2 || *p2 == L'\\' || *p2 == L'/')
|
||||
{
|
||||
/* Check that we have space to add one */
|
||||
if (pRedirectName->Length + LdrApiDefaultExtension.Length >= MAXLONG)
|
||||
{
|
||||
/* No space to add the extension */
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Setup the string */
|
||||
RawDllName.MaximumLength = pRedirectName->Length + LdrApiDefaultExtension.Length + sizeof(UNICODE_NULL);
|
||||
RawDllName.Length = RawDllName.MaximumLength - sizeof(UNICODE_NULL);
|
||||
RawDllName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
RawDllName.MaximumLength);
|
||||
|
||||
/* Copy the buffer */
|
||||
RtlMoveMemory(RawDllName.Buffer,
|
||||
pRedirectName->Buffer,
|
||||
pRedirectName->Length);
|
||||
|
||||
/* Add extension */
|
||||
RtlMoveMemory((PVOID)((ULONG_PTR)RawDllName.Buffer + pRedirectName->Length),
|
||||
LdrApiDefaultExtension.Buffer,
|
||||
LdrApiDefaultExtension.Length);
|
||||
|
||||
/* Null terminate */
|
||||
RawDllName.Buffer[RawDllName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if there's something in the name */
|
||||
if (pRedirectName->Length)
|
||||
{
|
||||
/* Check and remove trailing period */
|
||||
if (pRedirectName->Buffer[(pRedirectName->Length - 2) /
|
||||
sizeof(WCHAR)] == '.')
|
||||
{
|
||||
/* Decrease the size */
|
||||
pRedirectName->Length -= sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the string */
|
||||
RawDllName.MaximumLength = pRedirectName->Length + sizeof(WCHAR);
|
||||
RawDllName.Length = pRedirectName->Length;
|
||||
RawDllName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
RawDllName.MaximumLength);
|
||||
|
||||
/* Copy the buffer */
|
||||
RtlMoveMemory(RawDllName.Buffer,
|
||||
pRedirectName->Buffer,
|
||||
pRedirectName->Length);
|
||||
|
||||
/* Null terminate */
|
||||
RawDllName.Buffer[RawDllName.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
}
|
||||
|
||||
/* Display debug string */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: LdrGetDllHandle, searching for %wZ from %ws\n",
|
||||
&RawDllName,
|
||||
DllPath ? ((ULONG_PTR)DllPath == 1 ? L"" : DllPath) : L"");
|
||||
}
|
||||
|
||||
/* Do the lookup */
|
||||
if (LdrpCheckForLoadedDll(DllPath,
|
||||
&RawDllName,
|
||||
((ULONG_PTR)DllPath == 1) ? TRUE : FALSE,
|
||||
RedirectedDll,
|
||||
&LdrEntry))
|
||||
{
|
||||
/* Update cached entry */
|
||||
LdrpGetModuleHandleCache = LdrEntry;
|
||||
|
||||
/* Return success */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make sure to NULL this */
|
||||
LdrEntry = NULL;
|
||||
}
|
||||
FoundEntry:
|
||||
DPRINT("Got LdrEntry->BaseDllName %wZ\n", LdrEntry ? &LdrEntry->BaseDllName : NULL);
|
||||
|
||||
/* Check if we got an entry */
|
||||
if (LdrEntry)
|
||||
{
|
||||
/* Check for success */
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Check if the DLL is locked */
|
||||
if (LdrEntry->LoadCount != -1)
|
||||
{
|
||||
/* Check what flag we got */
|
||||
if (!(Flags & 1))
|
||||
{
|
||||
/* Check what to do with the load count */
|
||||
if (Flags & 2)
|
||||
{
|
||||
/* Pin it */
|
||||
LdrEntry->LoadCount = -1;
|
||||
LoadFlag = LDRP_UPDATE_PIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increase the load count */
|
||||
LdrEntry->LoadCount++;
|
||||
LoadFlag = LDRP_UPDATE_REFCOUNT;
|
||||
}
|
||||
|
||||
/* Update the load count now */
|
||||
LdrpUpdateLoadCount2(LdrEntry, LoadFlag);
|
||||
LdrpClearLoadInProgress();
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the caller is requesting the handle */
|
||||
if (DllHandle) *DllHandle = LdrEntry->DllBase;
|
||||
}
|
||||
}
|
||||
Quickie:
|
||||
/* Free string if needed */
|
||||
if (DllString1.Buffer) RtlFreeUnicodeString(&DllString1);
|
||||
|
||||
/* Free the raw DLL Name if needed */
|
||||
if (RawDllName.Buffer)
|
||||
{
|
||||
/* Free the heap-allocated buffer */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, RawDllName.Buffer);
|
||||
RawDllName.Buffer = NULL;
|
||||
}
|
||||
|
||||
/* Release lock */
|
||||
if (Locked) LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
|
||||
|
||||
/* Return */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrGetDllHandle(IN PWSTR DllPath OPTIONAL,
|
||||
IN PULONG DllCharacteristics OPTIONAL,
|
||||
IN PUNICODE_STRING DllName,
|
||||
OUT PVOID *DllHandle)
|
||||
{
|
||||
/* Call the newer API */
|
||||
return LdrGetDllHandleEx(TRUE,
|
||||
DllPath,
|
||||
DllCharacteristics,
|
||||
DllName,
|
||||
DllHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrGetProcedureAddress(IN PVOID BaseAddress,
|
||||
IN PANSI_STRING Name,
|
||||
IN ULONG Ordinal,
|
||||
OUT PVOID *ProcedureAddress)
|
||||
{
|
||||
/* Call the internal routine and tell it to execute DllInit */
|
||||
return LdrpGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -374,21 +850,6 @@ LdrVerifyImageMatchesChecksum(IN HANDLE FileHandle,
|
||||
return !Result ? STATUS_IMAGE_CHECKSUM_MISMATCH : Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrGetProcedureAddress_(IN PVOID BaseAddress,
|
||||
IN PANSI_STRING Name,
|
||||
IN ULONG Ordinal,
|
||||
OUT PVOID *ProcedureAddress)
|
||||
{
|
||||
/* Call the internal routine and tell it to execute DllInit */
|
||||
return LdrpGetProcedureAddress(BaseAddress, Name, Ordinal, ProcedureAddress, TRUE);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrQueryProcessModuleInformationEx(IN ULONG ProcessId,
|
||||
|
||||
+481
-33
@@ -10,9 +10,12 @@
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntdll.h>
|
||||
#include <win32k/callback.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
HKEY ImageExecOptionsKey;
|
||||
@@ -25,11 +28,14 @@ BOOLEAN LdrpInLdrInit;
|
||||
LONG LdrpProcessInitialized;
|
||||
BOOLEAN LdrpLoaderLockInit;
|
||||
BOOLEAN LdrpLdrDatabaseIsSetup;
|
||||
BOOLEAN LdrpShutdownInProgress;
|
||||
HANDLE LdrpShutdownThreadId;
|
||||
|
||||
BOOLEAN LdrpDllValidation;
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY LdrpImageEntry;
|
||||
PUNICODE_STRING LdrpTopLevelDllBeingLoaded;
|
||||
WCHAR StringBuffer[156];
|
||||
extern PTEB LdrpTopLevelDllBeingLoadedTeb; // defined in rtlsupp.c!
|
||||
PLDR_DATA_TABLE_ENTRY LdrpCurrentDllInitializer;
|
||||
PLDR_DATA_TABLE_ENTRY LdrpNtDllDataTableEntry;
|
||||
@@ -68,6 +74,7 @@ RTL_CRITICAL_SECTION FastPebLock;
|
||||
BOOLEAN ShowSnaps;
|
||||
|
||||
ULONG LdrpFatalHardErrorCount;
|
||||
ULONG LdrpActiveUnloadCount;
|
||||
|
||||
//extern LIST_ENTRY RtlCriticalSectionList;
|
||||
|
||||
@@ -78,10 +85,12 @@ extern BOOLEAN RtlpPageHeapEnabled;
|
||||
extern ULONG RtlpDphGlobalFlags;
|
||||
|
||||
NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase);
|
||||
NTSTATUS NTAPI
|
||||
LdrpInitializeProcess_(PCONTEXT Context,
|
||||
PVOID SystemArgument1);
|
||||
|
||||
#ifdef _WIN64
|
||||
#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
|
||||
#else
|
||||
#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
|
||||
#endif
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
@@ -414,8 +423,7 @@ LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
|
||||
Cookie = (PVOID)ConfigDir->SecurityCookie;
|
||||
|
||||
/* Check this cookie */
|
||||
if (Cookie == NULL ||
|
||||
(PCHAR)Cookie <= (PCHAR)BaseAddress ||
|
||||
if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
|
||||
(PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
|
||||
{
|
||||
Cookie = NULL;
|
||||
@@ -429,20 +437,178 @@ PVOID
|
||||
NTAPI
|
||||
LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
|
||||
{
|
||||
PVOID Cookie;
|
||||
PULONG_PTR Cookie;
|
||||
LARGE_INTEGER Counter;
|
||||
//ULONG NewCookie;
|
||||
|
||||
/* Fetch address of the cookie */
|
||||
Cookie = LdrpFetchAddressOfSecurityCookie(LdrEntry->DllBase, LdrEntry->SizeOfImage);
|
||||
|
||||
if (Cookie)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
Cookie = NULL;
|
||||
/* Check if it's a default one */
|
||||
if (*Cookie == DEFAULT_SECURITY_COOKIE ||
|
||||
*Cookie == 0xBB40)
|
||||
{
|
||||
/* We need to initialize it */
|
||||
|
||||
NtQueryPerformanceCounter(&Counter, NULL);
|
||||
#if 0
|
||||
GetSystemTimeAsFileTime (&systime.ft_struct);
|
||||
#ifdef _WIN64
|
||||
cookie = systime.ft_scalar;
|
||||
#else
|
||||
cookie = systime.ft_struct.dwLowDateTime;
|
||||
cookie ^= systime.ft_struct.dwHighDateTime;
|
||||
#endif
|
||||
|
||||
cookie ^= GetCurrentProcessId ();
|
||||
cookie ^= GetCurrentThreadId ();
|
||||
cookie ^= GetTickCount ();
|
||||
|
||||
QueryPerformanceCounter (&perfctr);
|
||||
#ifdef _WIN64
|
||||
cookie ^= perfctr.QuadPart;
|
||||
#else
|
||||
cookie ^= perfctr.LowPart;
|
||||
cookie ^= perfctr.HighPart;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
cookie &= 0x0000ffffffffffffll;
|
||||
#endif
|
||||
#endif
|
||||
*Cookie = Counter.LowPart;
|
||||
|
||||
//Cookie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return Cookie;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LdrpInitializeThread(IN PCONTEXT Context)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
|
||||
NTSTATUS Status;
|
||||
PVOID EntryPoint;
|
||||
|
||||
DPRINT("LdrpInitializeThread() called for %wZ\n",
|
||||
&LdrpImageEntry->BaseDllName);
|
||||
|
||||
/* Allocate an Activation Context Stack */
|
||||
/* FIXME: This is a hack for Wine's actctx stuff */
|
||||
DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
|
||||
if (!(NtCurrentTeb()->ActivationContextStackPointer))
|
||||
{
|
||||
Status = RtlAllocateActivationContextStack((PVOID*)&NtCurrentTeb()->ActivationContextStackPointer);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ActivationContextStack %p\n", NtCurrentTeb()->ActivationContextStackPointer);
|
||||
DPRINT("ActiveFrame %p\n", ((PACTIVATION_CONTEXT_STACK)NtCurrentTeb()->ActivationContextStackPointer)->ActiveFrame);
|
||||
NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NULL;
|
||||
}
|
||||
else
|
||||
DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
|
||||
}
|
||||
|
||||
/* Make sure we are not shutting down */
|
||||
if (LdrpShutdownInProgress) return;
|
||||
|
||||
/* Allocate TLS */
|
||||
LdrpAllocateTls();
|
||||
|
||||
/* Start at the beginning */
|
||||
ListHead = &Peb->Ldr->InMemoryOrderModuleList;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
/* Get the current entry */
|
||||
LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);
|
||||
|
||||
/* Make sure it's not ourselves */
|
||||
if (Peb->ImageBaseAddress != LdrEntry->DllBase)
|
||||
{
|
||||
/* Check if we should call */
|
||||
if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS))
|
||||
{
|
||||
/* Get the entrypoint */
|
||||
EntryPoint = LdrEntry->EntryPoint;
|
||||
|
||||
/* Check if we are ready to call it */
|
||||
if ((EntryPoint) &&
|
||||
(LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
|
||||
(LdrEntry->Flags & LDRP_IMAGE_DLL))
|
||||
{
|
||||
/* Set up the Act Ctx */
|
||||
ActCtx.Size = sizeof(ActCtx);
|
||||
ActCtx.Format = 1;
|
||||
RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
|
||||
|
||||
/* Activate the ActCtx */
|
||||
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
||||
LdrEntry->EntryPointActivationContext);
|
||||
|
||||
/* Check if it has TLS */
|
||||
if (LdrEntry->TlsIndex)
|
||||
{
|
||||
/* Make sure we're not shutting down */
|
||||
if (!LdrpShutdownInProgress)
|
||||
{
|
||||
/* Call TLS */
|
||||
LdrpTlsCallback(LdrEntry->DllBase, DLL_THREAD_ATTACH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we're not shutting down */
|
||||
if (!LdrpShutdownInProgress)
|
||||
{
|
||||
/* Call the Entrypoint */
|
||||
DPRINT("%wZ - Calling entry point at %x for thread attaching\n",
|
||||
&LdrEntry->BaseDllName, LdrEntry->EntryPoint);
|
||||
LdrpCallDllEntry(LdrEntry->EntryPoint,
|
||||
LdrEntry->DllBase,
|
||||
DLL_THREAD_ATTACH,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Deactivate the ActCtx */
|
||||
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Next entry */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/* Check for TLS */
|
||||
if (LdrpImageHasTls && !LdrpShutdownInProgress)
|
||||
{
|
||||
/* Set up the Act Ctx */
|
||||
ActCtx.Size = sizeof(ActCtx);
|
||||
ActCtx.Format = 1;
|
||||
RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
|
||||
|
||||
/* Activate the ActCtx */
|
||||
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
||||
LdrpImageEntry->EntryPointActivationContext);
|
||||
|
||||
/* Do TLS callbacks */
|
||||
LdrpTlsCallback(Peb->ImageBaseAddress, DLL_THREAD_ATTACH);
|
||||
|
||||
/* Deactivate the ActCtx */
|
||||
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||
}
|
||||
|
||||
DPRINT("LdrpInitializeThread() done\n");
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
|
||||
@@ -715,6 +881,267 @@ Quickie:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrShutdownProcess(VOID)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
|
||||
PVOID EntryPoint;
|
||||
|
||||
DPRINT("LdrShutdownProcess() called for %wZ\n", &LdrpImageEntry->BaseDllName);
|
||||
if (LdrpShutdownInProgress) return STATUS_SUCCESS;
|
||||
|
||||
/* Tell the Shim Engine */
|
||||
//if (ShimsEnabled)
|
||||
//{
|
||||
/* FIXME */
|
||||
//}
|
||||
|
||||
/* Tell the world */
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("\n");
|
||||
}
|
||||
|
||||
/* Set the shutdown variables */
|
||||
LdrpShutdownThreadId = NtCurrentTeb()->RealClientId.UniqueThread;
|
||||
LdrpShutdownInProgress = TRUE;
|
||||
|
||||
/* Enter the Loader Lock */
|
||||
RtlEnterCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
/* Cleanup trace logging data (Etw) */
|
||||
if (SharedUserData->TraceLogging)
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("We don't support Etw yet.\n");
|
||||
}
|
||||
|
||||
/* Start at the end */
|
||||
ListHead = &Peb->Ldr->InInitializationOrderModuleList;
|
||||
NextEntry = ListHead->Blink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
/* Get the current entry */
|
||||
LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
|
||||
NextEntry = NextEntry->Blink;
|
||||
|
||||
/* Make sure it's not ourselves */
|
||||
if (Peb->ImageBaseAddress != LdrEntry->DllBase)
|
||||
{
|
||||
/* Get the entrypoint */
|
||||
EntryPoint = LdrEntry->EntryPoint;
|
||||
|
||||
/* Check if we are ready to call it */
|
||||
if (EntryPoint &&
|
||||
(LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
|
||||
LdrEntry->Flags)
|
||||
{
|
||||
/* Set up the Act Ctx */
|
||||
ActCtx.Size = sizeof(ActCtx);
|
||||
ActCtx.Format = 1;
|
||||
RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
|
||||
|
||||
/* Activate the ActCtx */
|
||||
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
||||
LdrEntry->EntryPointActivationContext);
|
||||
|
||||
/* Check if it has TLS */
|
||||
if (LdrEntry->TlsIndex)
|
||||
{
|
||||
/* Call TLS */
|
||||
LdrpTlsCallback(LdrEntry->DllBase, DLL_PROCESS_DETACH);
|
||||
}
|
||||
|
||||
/* Call the Entrypoint */
|
||||
DPRINT("%wZ - Calling entry point at %x for thread detaching\n",
|
||||
&LdrEntry->BaseDllName, LdrEntry->EntryPoint);
|
||||
LdrpCallDllEntry(EntryPoint,
|
||||
LdrEntry->DllBase,
|
||||
DLL_PROCESS_DETACH,
|
||||
(PVOID)1);
|
||||
|
||||
/* Deactivate the ActCtx */
|
||||
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for TLS */
|
||||
if (LdrpImageHasTls)
|
||||
{
|
||||
/* Set up the Act Ctx */
|
||||
ActCtx.Size = sizeof(ActCtx);
|
||||
ActCtx.Format = 1;
|
||||
RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
|
||||
|
||||
/* Activate the ActCtx */
|
||||
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
||||
LdrpImageEntry->EntryPointActivationContext);
|
||||
|
||||
/* Do TLS callbacks */
|
||||
LdrpTlsCallback(Peb->ImageBaseAddress, DLL_PROCESS_DETACH);
|
||||
|
||||
/* Deactivate the ActCtx */
|
||||
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||
}
|
||||
|
||||
/* FIXME: Do Heap detection and Etw final shutdown */
|
||||
|
||||
/* Release the lock */
|
||||
RtlLeaveCriticalSection(&LdrpLoaderLock);
|
||||
DPRINT("LdrpShutdownProcess() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrShutdownThread(VOID)
|
||||
{
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED ActCtx;
|
||||
PVOID EntryPoint;
|
||||
|
||||
DPRINT("LdrShutdownThread() called for %wZ\n",
|
||||
&LdrpImageEntry->BaseDllName);
|
||||
|
||||
/* Cleanup trace logging data (Etw) */
|
||||
if (SharedUserData->TraceLogging)
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("We don't support Etw yet.\n");
|
||||
}
|
||||
|
||||
/* Get the Ldr Lock */
|
||||
RtlEnterCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
/* Start at the end */
|
||||
ListHead = &Peb->Ldr->InInitializationOrderModuleList;
|
||||
NextEntry = ListHead->Blink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
/* Get the current entry */
|
||||
LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
|
||||
NextEntry = NextEntry->Blink;
|
||||
|
||||
/* Make sure it's not ourselves */
|
||||
if (Peb->ImageBaseAddress != LdrEntry->DllBase)
|
||||
{
|
||||
/* Check if we should call */
|
||||
if (!(LdrEntry->Flags & LDRP_DONT_CALL_FOR_THREADS) &&
|
||||
(LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
|
||||
(LdrEntry->Flags & LDRP_IMAGE_DLL))
|
||||
{
|
||||
/* Get the entrypoint */
|
||||
EntryPoint = LdrEntry->EntryPoint;
|
||||
|
||||
/* Check if we are ready to call it */
|
||||
if (EntryPoint)
|
||||
{
|
||||
/* Set up the Act Ctx */
|
||||
ActCtx.Size = sizeof(ActCtx);
|
||||
ActCtx.Format = 1;
|
||||
RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
|
||||
|
||||
/* Activate the ActCtx */
|
||||
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
||||
LdrEntry->EntryPointActivationContext);
|
||||
|
||||
/* Check if it has TLS */
|
||||
if (LdrEntry->TlsIndex)
|
||||
{
|
||||
/* Make sure we're not shutting down */
|
||||
if (!LdrpShutdownInProgress)
|
||||
{
|
||||
/* Call TLS */
|
||||
LdrpTlsCallback(LdrEntry->DllBase, DLL_THREAD_DETACH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we're not shutting down */
|
||||
if (!LdrpShutdownInProgress)
|
||||
{
|
||||
/* Call the Entrypoint */
|
||||
DPRINT("%wZ - Calling entry point at %x for thread detaching\n",
|
||||
&LdrEntry->BaseDllName, LdrEntry->EntryPoint);
|
||||
LdrpCallDllEntry(EntryPoint,
|
||||
LdrEntry->DllBase,
|
||||
DLL_THREAD_DETACH,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Deactivate the ActCtx */
|
||||
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for TLS */
|
||||
if (LdrpImageHasTls)
|
||||
{
|
||||
/* Set up the Act Ctx */
|
||||
ActCtx.Size = sizeof(ActCtx);
|
||||
ActCtx.Format = 1;
|
||||
RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
|
||||
|
||||
/* Activate the ActCtx */
|
||||
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
||||
LdrpImageEntry->EntryPointActivationContext);
|
||||
|
||||
/* Do TLS callbacks */
|
||||
LdrpTlsCallback(Peb->ImageBaseAddress, DLL_THREAD_DETACH);
|
||||
|
||||
/* Deactivate the ActCtx */
|
||||
RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||
}
|
||||
|
||||
/* Free TLS */
|
||||
LdrpFreeTls();
|
||||
RtlLeaveCriticalSection(&LdrpLoaderLock);
|
||||
|
||||
/* Check for expansion slots */
|
||||
if (Teb->TlsExpansionSlots)
|
||||
{
|
||||
/* Free expansion slots */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->TlsExpansionSlots);
|
||||
}
|
||||
|
||||
/* Check for FLS Data */
|
||||
if (Teb->FlsData)
|
||||
{
|
||||
/* FIXME */
|
||||
DPRINT1("We don't support FLS Data yet\n");
|
||||
}
|
||||
|
||||
/* Check for Fiber data */
|
||||
if (Teb->HasFiberData)
|
||||
{
|
||||
/* Free Fiber data*/
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Teb->NtTib.FiberData);
|
||||
Teb->NtTib.FiberData = NULL;
|
||||
}
|
||||
|
||||
/* Free the activation context stack */
|
||||
RtlFreeThreadActivationContextStack();
|
||||
DPRINT("LdrShutdownThread() done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpInitializeTls(VOID)
|
||||
@@ -879,10 +1306,10 @@ LdrpFreeTls(VOID)
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PULONG Options)
|
||||
LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHKEY OptionsKey)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
*Options = 0;
|
||||
*OptionsKey = NULL;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -915,7 +1342,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
//LPWSTR ImagePathBuffer;
|
||||
ULONG ConfigSize;
|
||||
UNICODE_STRING CurrentDirectory;
|
||||
ULONG ExecuteOptions;
|
||||
HKEY OptionsKey;
|
||||
ULONG HeapFlags;
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
LPWSTR NtDllName = NULL;
|
||||
@@ -928,9 +1355,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
ULONG i;
|
||||
PWSTR ImagePath;
|
||||
ULONG DebugProcessHeapOnly = 0;
|
||||
WCHAR FullNtDllPath[MAX_PATH];
|
||||
PLDR_DATA_TABLE_ENTRY NtLdrEntry;
|
||||
PWCHAR Current;
|
||||
ULONG ExecuteOptions = 0;
|
||||
|
||||
/* Set a NULL SEH Filter */
|
||||
RtlSetUnhandledExceptionFilter(NULL);
|
||||
@@ -954,7 +1381,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress);
|
||||
|
||||
/* Get the execution options */
|
||||
Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &ExecuteOptions);
|
||||
Status = LdrpInitializeExecutionOptions(&ImagePathName, Peb, &OptionsKey);
|
||||
|
||||
/* Check if this is a .NET executable */
|
||||
if (RtlImageDirectoryEntryToData(Peb->ImageBaseAddress,
|
||||
@@ -1040,7 +1467,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
}
|
||||
|
||||
/* Check if verbose debugging (ShowSnaps) was requested */
|
||||
ShowSnaps = TRUE;//Peb->NtGlobalFlag & FLG_SHOW_LDR_SNAPS;
|
||||
ShowSnaps = Peb->NtGlobalFlag & FLG_SHOW_LDR_SNAPS;
|
||||
|
||||
/* Start verbose debugging messages right now if they were requested */
|
||||
if (ShowSnaps)
|
||||
@@ -1091,9 +1518,11 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
}
|
||||
|
||||
/* Initialize the Loader Lock */
|
||||
// FIXME: What's the point of initing it manually, if two lines lower
|
||||
// a call to RtlInitializeCriticalSection() is being made anyway?
|
||||
//InsertTailList(&RtlCriticalSectionList, &LdrpLoaderLock.DebugInfo->ProcessLocksList);
|
||||
//LdrpLoaderLock.DebugInfo->CriticalSection = &LdrpLoaderLock;
|
||||
UNIMPLEMENTED;
|
||||
RtlInitializeCriticalSection(&LdrpLoaderLock);
|
||||
LdrpLoaderLockInit = TRUE;
|
||||
|
||||
/* Check if User Stack Trace Database support was requested */
|
||||
@@ -1134,19 +1563,30 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
// FIXME: Is it located properly?
|
||||
/* Initialize table of callbacks for the kernel. */
|
||||
Peb->KernelCallbackTable = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(PVOID) *
|
||||
(USER32_CALLBACK_MAXIMUM + 1));
|
||||
if (!Peb->KernelCallbackTable)
|
||||
{
|
||||
DPRINT1("Failed to create callback table\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
/* Allocate an Activation Context Stack */
|
||||
Status = RtlAllocateActivationContextStack((PVOID *)&Teb->ActivationContextStackPointer);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
// FIXME: Loader private heap is missing
|
||||
DPRINT1("Loader private heap is missing\n");
|
||||
//DPRINT1("Loader private heap is missing\n");
|
||||
|
||||
/* Check for Debug Heap */
|
||||
DPRINT1("Check for a debug heap is missing\n");
|
||||
if (FALSE)
|
||||
if (OptionsKey)
|
||||
{
|
||||
/* Query the setting */
|
||||
Status = LdrQueryImageFileKeyOption(NULL,//hKey
|
||||
Status = LdrQueryImageFileKeyOption(OptionsKey,
|
||||
L"DebugProcessHeapOnly",
|
||||
REG_DWORD,
|
||||
&DebugProcessHeapOnly,
|
||||
@@ -1165,9 +1605,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
}
|
||||
|
||||
/* Build the NTDLL Path */
|
||||
FullPath.Buffer = FullNtDllPath;
|
||||
FullPath.Buffer = StringBuffer;
|
||||
FullPath.Length = 0;
|
||||
FullPath.MaximumLength = sizeof(FullNtDllPath);
|
||||
FullPath.MaximumLength = sizeof(StringBuffer);
|
||||
RtlInitUnicodeString(&NtSystemRoot, SharedUserData->NtSystemRoot);
|
||||
RtlAppendUnicodeStringToString(&FullPath, &NtSystemRoot);
|
||||
RtlAppendUnicodeToString(&FullPath, L"\\System32\\");
|
||||
@@ -1188,7 +1628,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
{
|
||||
/* It doesn't, so assume System32 */
|
||||
LdrpKnownDllObjectDirectory = NULL;
|
||||
RtlInitUnicodeString(&LdrpKnownDllPath, FullPath.Buffer);
|
||||
RtlInitUnicodeString(&LdrpKnownDllPath, StringBuffer);
|
||||
LdrpKnownDllPath.Length -= sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
@@ -1230,6 +1670,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
else
|
||||
{
|
||||
/* We need a valid path */
|
||||
DPRINT1("No valid DllPath was given!\n");
|
||||
LdrpInitFailure(STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
@@ -1246,6 +1687,11 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
0,
|
||||
3 * sizeof(WCHAR) +
|
||||
sizeof(UNICODE_NULL));
|
||||
if (!CurrentDirectory.Buffer)
|
||||
{
|
||||
DPRINT1("LDR: LdrpInitializeProcess - unable to allocate current working directory buffer\n");
|
||||
// FIXME: And what?
|
||||
}
|
||||
|
||||
/* Copy the drive of the system root */
|
||||
RtlMoveMemory(CurrentDirectory.Buffer,
|
||||
@@ -1256,12 +1702,12 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
CurrentDirectory.MaximumLength = CurrentDirectory.Length + sizeof(WCHAR);
|
||||
|
||||
FreeCurDir = TRUE;
|
||||
DPRINT("Using dynamically allocd curdir\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the local buffer */
|
||||
CurrentDirectory.Length = NtSystemRoot.Length;
|
||||
CurrentDirectory.Buffer = NtSystemRoot.Buffer;
|
||||
DPRINT("Using local system root\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1280,8 +1726,8 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
|
||||
NtLdrEntry->LoadCount = -1;
|
||||
NtLdrEntry->EntryPointActivationContext = 0;
|
||||
NtLdrEntry->FullDllName.Length = ImageFileName.Length;
|
||||
NtLdrEntry->FullDllName.Buffer = ImageFileName.Buffer;
|
||||
NtLdrEntry->FullDllName = ImageFileName;
|
||||
|
||||
if (IsDotNetImage)
|
||||
NtLdrEntry->Flags = LDRP_COR_IMAGE;
|
||||
else
|
||||
@@ -1291,7 +1737,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
if (!ImageFileName.Buffer[0])
|
||||
{
|
||||
/* Use the same Base name */
|
||||
NtLdrEntry->BaseDllName = NtLdrEntry->BaseDllName;
|
||||
NtLdrEntry->BaseDllName = NtLdrEntry->FullDllName;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1332,14 +1778,16 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
|
||||
NtLdrEntry->LoadCount = -1;
|
||||
NtLdrEntry->EntryPointActivationContext = 0;
|
||||
//NtLdrEntry->BaseDllName.Length = NtSystemRoot.Length;
|
||||
//RtlAppendUnicodeStringToString(&NtSystemRoot, &NtDllString);
|
||||
|
||||
NtLdrEntry->FullDllName.Length = FullPath.Length;
|
||||
NtLdrEntry->FullDllName.MaximumLength = FullPath.MaximumLength;
|
||||
NtLdrEntry->FullDllName.Buffer = StringBuffer;
|
||||
RtlAppendUnicodeStringToString(&NtLdrEntry->FullDllName, &NtDllString);
|
||||
|
||||
NtLdrEntry->BaseDllName.Length = NtDllString.Length;
|
||||
NtLdrEntry->BaseDllName.MaximumLength = NtDllString.MaximumLength;
|
||||
NtLdrEntry->BaseDllName.Buffer = NtDllString.Buffer;
|
||||
|
||||
// FIXME: Full DLL name?!
|
||||
|
||||
/* Processing done, insert it */
|
||||
LdrpNtDllDataTableEntry = NtLdrEntry;
|
||||
LdrpInsertMemoryTableEntry(NtLdrEntry);
|
||||
@@ -1510,7 +1958,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||
|
||||
///* Close the key if we have one opened */
|
||||
//if (hKey) NtClose(hKey);
|
||||
DbgBreakPoint();
|
||||
|
||||
/* Return status */
|
||||
return Status;
|
||||
}
|
||||
@@ -1596,7 +2044,7 @@ LdrpInit(PCONTEXT Context,
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Initialize the Process */
|
||||
LoaderStatus = LdrpInitializeProcess_(Context,
|
||||
LoaderStatus = LdrpInitializeProcess(Context,
|
||||
SystemArgument1);
|
||||
|
||||
/* Check for success and if MinimumStackCommit was requested */
|
||||
|
||||
+66
-19
@@ -100,9 +100,7 @@ LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry,
|
||||
|
||||
/* Deal with Watcom and other retarded compilers */
|
||||
if (!IatSize)
|
||||
{
|
||||
IatSize = SectionHeader->SizeOfRawData;
|
||||
}
|
||||
|
||||
/* Found it, get out */
|
||||
break;
|
||||
@@ -255,7 +253,7 @@ NTSTATUS
|
||||
NTAPI
|
||||
LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
IN PLDR_DATA_TABLE_ENTRY LdrEntry,
|
||||
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry,
|
||||
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR *BoundEntryPtr,
|
||||
IN PIMAGE_BOUND_IMPORT_DESCRIPTOR FirstEntry)
|
||||
{
|
||||
LPSTR ImportName = NULL, BoundImportName, ForwarderName;
|
||||
@@ -264,11 +262,15 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
|
||||
PLDR_DATA_TABLE_ENTRY DllLdrEntry, ForwarderLdrEntry;
|
||||
PIMAGE_BOUND_FORWARDER_REF ForwarderEntry;
|
||||
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry;
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
ULONG i, IatSize;
|
||||
|
||||
/* Get the pointer to the bound entry */
|
||||
BoundEntry = *BoundEntryPtr;
|
||||
|
||||
/* Get the name's VA */
|
||||
BoundImportName = (LPSTR)(BoundEntry + BoundEntry->OffsetModuleName);
|
||||
BoundImportName = (LPSTR)FirstEntry + BoundEntry->OffsetModuleName;
|
||||
|
||||
/* Show debug mesage */
|
||||
if (ShowSnaps)
|
||||
@@ -311,7 +313,7 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: %wZ has stale binding to %s\n",
|
||||
&DllLdrEntry->BaseDllName,
|
||||
&LdrEntry->BaseDllName,
|
||||
BoundImportName);
|
||||
}
|
||||
|
||||
@@ -324,7 +326,7 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: %wZ has correct binding to %s\n",
|
||||
&DllLdrEntry->BaseDllName,
|
||||
&LdrEntry->BaseDllName,
|
||||
BoundImportName);
|
||||
}
|
||||
|
||||
@@ -339,7 +341,7 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
for (i = 0; i < BoundEntry->NumberOfModuleForwarderRefs; i++)
|
||||
{
|
||||
/* Get the name */
|
||||
ForwarderName = (LPSTR)(FirstEntry + ForwarderEntry->OffsetModuleName);
|
||||
ForwarderName = (LPSTR)FirstEntry + ForwarderEntry->OffsetModuleName;
|
||||
|
||||
/* Show debug message */
|
||||
if (ShowSnaps)
|
||||
@@ -376,7 +378,7 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: %wZ has stale binding to %s\n",
|
||||
&ForwarderLdrEntry->BaseDllName,
|
||||
&LdrEntry->BaseDllName,
|
||||
ForwarderName);
|
||||
}
|
||||
|
||||
@@ -389,7 +391,7 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
if (ShowSnaps)
|
||||
{
|
||||
DPRINT1("LDR: %wZ has correct binding to %s\n",
|
||||
&ForwarderLdrEntry->BaseDllName,
|
||||
&LdrEntry->BaseDllName,
|
||||
ForwarderName);
|
||||
}
|
||||
|
||||
@@ -423,7 +425,7 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
if (!_stricmp(ImportName, BoundImportName)) break;
|
||||
|
||||
/* Move to next entry */
|
||||
ImportEntry += 1;
|
||||
ImportEntry++;
|
||||
}
|
||||
|
||||
/* If we didn't find a name, fail */
|
||||
@@ -477,7 +479,7 @@ LdrpHandleOneNewFormatImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
|
||||
Quickie:
|
||||
/* Write where we are now and return */
|
||||
*BoundEntry = *FirstEntry;
|
||||
*BoundEntryPtr = FirstEntry;
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -496,7 +498,7 @@ LdrpHandleNewFormatImportDescriptors(IN LPWSTR DllPath OPTIONAL,
|
||||
/* Parse this descriptor */
|
||||
Status = LdrpHandleOneNewFormatImportDescriptor(DllPath,
|
||||
LdrEntry,
|
||||
BoundEntry,
|
||||
&BoundEntry,
|
||||
FirstEntry);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
@@ -642,8 +644,35 @@ LdrpNameToOrdinal(LPSTR ImportName,
|
||||
PULONG NameTable,
|
||||
PUSHORT OrdinalTable)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
ULONG Start, End, Next;
|
||||
LONG CmpResult;
|
||||
|
||||
/* Use classical binary search to find the ordinal */
|
||||
Start = 0;
|
||||
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)
|
||||
End = Next - 1;
|
||||
else if (CmpResult > 0)
|
||||
Start = Next + 1;
|
||||
}
|
||||
|
||||
/* If end is before start, then the search failed */
|
||||
if (End < Start) return -1;
|
||||
|
||||
/* Return found name */
|
||||
return OrdinalTable[Next];
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
@@ -657,10 +686,12 @@ LdrpWalkImportDescriptor(IN LPWSTR DllPath OPTIONAL,
|
||||
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundEntry = NULL;
|
||||
PIMAGE_IMPORT_DESCRIPTOR ImportEntry;
|
||||
ULONG BoundSize, IatSize;
|
||||
DPRINT1("LdrpWalkImportDescriptor('%S' %x)\n", DllPath, LdrEntry);
|
||||
|
||||
DPRINT("LdrpWalkImportDescriptor('%S' %x)\n", DllPath, LdrEntry);
|
||||
|
||||
/* Set up the Act Ctx */
|
||||
ActCtx.Size = sizeof(ActCtx);
|
||||
ActCtx.Frame.Flags = 1;
|
||||
ActCtx.Format = 1;
|
||||
RtlZeroMemory(&ActCtx.Frame, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME));
|
||||
|
||||
/* Check if we have a manifest prober routine */
|
||||
@@ -680,7 +711,7 @@ DPRINT1("LdrpWalkImportDescriptor('%S' %x)\n", DllPath, LdrEntry);
|
||||
RtlActivateActivationContextUnsafeFast(&ActCtx,
|
||||
LdrEntry->EntryPointActivationContext);
|
||||
|
||||
/* Check if we were directed */
|
||||
/* Check if we were redirected */
|
||||
if (!(LdrEntry->Flags & LDRP_REDIRECTED))
|
||||
{
|
||||
/* Get the Bound IAT */
|
||||
@@ -764,7 +795,9 @@ LdrpLoadImportModule(IN PWSTR DllPath OPTIONAL,
|
||||
NTSTATUS Status;
|
||||
PPEB Peb = RtlGetCurrentPeb();
|
||||
PTEB Teb = NtCurrentTeb();
|
||||
DPRINT1("LdrpLoadImportModule('%S' '%s' %p %p %p)\n", DllPath, ImportName, DllBase, DataTableEntry, Existing);
|
||||
|
||||
DPRINT("LdrpLoadImportModule('%S' '%s' %p %p %p)\n", DllPath, ImportName, DllBase, DataTableEntry, Existing);
|
||||
|
||||
/* Convert import descriptor name to unicode string */
|
||||
ImpDescName = &Teb->StaticUnicodeString;
|
||||
RtlInitAnsiString(&AnsiString, ImportName);
|
||||
@@ -788,8 +821,8 @@ DPRINT1("LdrpLoadImportModule('%S' '%s' %p %p %p)\n", DllPath, ImportName, DllBa
|
||||
|
||||
/* Map it */
|
||||
Status = LdrpMapDll(DllPath,
|
||||
ImpDescName->Buffer,
|
||||
NULL,
|
||||
ImpDescName->Buffer,
|
||||
NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
@@ -893,6 +926,12 @@ FailurePath:
|
||||
/* Is this a static snap? */
|
||||
if (Static)
|
||||
{
|
||||
/* Inform the debug log */
|
||||
if (IsOrdinal)
|
||||
DPRINT1("Failed to snap ordinal 0x%x\n", OriginalOrdinal);
|
||||
else
|
||||
DPRINT1("Failed to snap %s\n", ImportName);
|
||||
|
||||
/* These are critical errors. Setup a string for the DLL name */
|
||||
RtlInitAnsiString(&TempString, DllName ? DllName : "Unknown");
|
||||
RtlAnsiStringToUnicodeString(&HardErrorDllName, &TempString, TRUE);
|
||||
@@ -944,6 +983,14 @@ FailurePath:
|
||||
/* Return ordinal error */
|
||||
RtlRaiseStatus(STATUS_ORDINAL_NOT_FOUND);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* Set this as a bad DLL */
|
||||
Thunk->u1.Function = (ULONG_PTR)0xffbadd11;
|
||||
|
||||
+1765
-11
File diff suppressed because it is too large
Load Diff
+1
-278
@@ -10,12 +10,11 @@
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntdll.h>
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include <win32k/callback.h>
|
||||
|
||||
VOID RtlInitializeHeapManager(VOID);
|
||||
VOID LdrpInitLoader(VOID);
|
||||
extern PTEB LdrpTopLevelDllBeingLoadedTeb;
|
||||
VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
|
||||
VOID RtlpInitializeVectoredExceptionHandling(VOID);
|
||||
@@ -309,280 +308,4 @@ finish:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrpInitializeProcess_(PCONTEXT Context,
|
||||
PVOID SystemArgument1)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NTHeaders;
|
||||
PEPFUNC EntryPoint;
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
PVOID ImageBase;
|
||||
PPEB Peb = NtCurrentPeb();
|
||||
PLDR_DATA_TABLE_ENTRY NtModule; // ntdll
|
||||
NLSTABLEINFO NlsTable;
|
||||
WCHAR FullNtDllPath[MAX_PATH];
|
||||
SYSTEM_BASIC_INFORMATION SystemInformation;
|
||||
NTSTATUS Status;
|
||||
PVOID BaseAddress = SystemArgument1;
|
||||
|
||||
DPRINT("LdrpInit()\n");
|
||||
DPRINT("Peb %p\n", Peb);
|
||||
ImageBase = Peb->ImageBaseAddress;
|
||||
DPRINT("ImageBase %p\n", ImageBase);
|
||||
|
||||
if (ImageBase <= (PVOID) 0x1000)
|
||||
{
|
||||
DPRINT("ImageBase is null\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
|
||||
}
|
||||
|
||||
/* If MZ header exists */
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
|
||||
NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
|
||||
DPRINT("PEDosHeader %p\n", PEDosHeader);
|
||||
|
||||
if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
|
||||
PEDosHeader->e_lfanew == 0L ||
|
||||
NTHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
DPRINT1("Image has bad header\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
|
||||
}
|
||||
|
||||
/* normalize process parameters */
|
||||
RtlNormalizeProcessParams(Peb->ProcessParameters);
|
||||
|
||||
/* Initialize NLS data */
|
||||
RtlInitNlsTables(Peb->AnsiCodePageData,
|
||||
Peb->OemCodePageData,
|
||||
Peb->UnicodeCaseTableData,
|
||||
&NlsTable);
|
||||
RtlResetRtlTranslations(&NlsTable);
|
||||
|
||||
/* Get number of processors */
|
||||
DPRINT("Here\n");
|
||||
Status = ZwQuerySystemInformation(SystemBasicInformation,
|
||||
&SystemInformation,
|
||||
sizeof(SYSTEM_BASIC_INFORMATION),
|
||||
NULL);
|
||||
DPRINT("Here2\n");
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ZwTerminateProcess(NtCurrentProcess(), Status);
|
||||
}
|
||||
|
||||
Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors;
|
||||
|
||||
/* Initialize Critical Section Data */
|
||||
RtlpInitDeferedCriticalSection();
|
||||
|
||||
/* Load execution options */
|
||||
LoadImageFileExecutionOptions(Peb);
|
||||
|
||||
/* create process heap */
|
||||
RtlInitializeHeapManager();
|
||||
Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
|
||||
NULL,
|
||||
NTHeaders->OptionalHeader.SizeOfHeapReserve,
|
||||
NTHeaders->OptionalHeader.SizeOfHeapCommit,
|
||||
NULL,
|
||||
NULL);
|
||||
if (Peb->ProcessHeap == 0)
|
||||
{
|
||||
DPRINT1("Failed to create process heap\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
/* Check for correct machine type */
|
||||
if (NTHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE)
|
||||
{
|
||||
ULONG_PTR HardErrorParameters[1];
|
||||
UNICODE_STRING ImageNameU;
|
||||
ANSI_STRING ImageNameA;
|
||||
WCHAR *Ptr;
|
||||
ULONG ErrorResponse;
|
||||
|
||||
DPRINT1("Image %wZ is for a foreign architecture (0x%x).\n",
|
||||
&Peb->ProcessParameters->ImagePathName, NTHeaders->FileHeader.Machine);
|
||||
|
||||
/* Get the full image path name */
|
||||
ImageNameU = Peb->ProcessParameters->ImagePathName;
|
||||
|
||||
/* Get the file name */
|
||||
Ptr = Peb->ProcessParameters->ImagePathName.Buffer +
|
||||
(Peb->ProcessParameters->ImagePathName.Length / sizeof(WCHAR)) -1;
|
||||
while ((Ptr >= Peb->ProcessParameters->ImagePathName.Buffer) &&
|
||||
(*Ptr != L'\\')) Ptr--;
|
||||
ImageNameU.Buffer = Ptr + 1;
|
||||
ImageNameU.Length = Peb->ProcessParameters->ImagePathName.Length -
|
||||
(ImageNameU.Buffer - Peb->ProcessParameters->ImagePathName.Buffer) * sizeof(WCHAR);
|
||||
ImageNameU.MaximumLength = ImageNameU.Length;
|
||||
|
||||
/*`Convert to ANSI, harderror message needs that */
|
||||
RtlUnicodeStringToAnsiString(&ImageNameA, &ImageNameU, TRUE);
|
||||
|
||||
/* Raise harderror */
|
||||
HardErrorParameters[0] = (ULONG_PTR)&ImageNameA;
|
||||
NtRaiseHardError(STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE,
|
||||
1,
|
||||
1,
|
||||
HardErrorParameters,
|
||||
OptionOk,
|
||||
&ErrorResponse);
|
||||
|
||||
RtlFreeAnsiString(&ImageNameA);
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE);
|
||||
}
|
||||
|
||||
/* initialized vectored exception handling */
|
||||
RtlpInitializeVectoredExceptionHandling();
|
||||
|
||||
/* initalize peb lock support */
|
||||
RtlInitializeCriticalSection(&FastPebLock);
|
||||
Peb->FastPebLock = &FastPebLock;
|
||||
|
||||
/* initialize tls bitmaps */
|
||||
RtlInitializeBitMap(&TlsBitMap, Peb->TlsBitmapBits, TLS_MINIMUM_AVAILABLE);
|
||||
RtlInitializeBitMap(&TlsExpansionBitMap, Peb->TlsExpansionBitmapBits, TLS_EXPANSION_SLOTS);
|
||||
|
||||
Peb->TlsBitmap = &TlsBitMap;
|
||||
Peb->TlsExpansionBitmap = &TlsExpansionBitMap;
|
||||
Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE;
|
||||
|
||||
/* Initialize table of callbacks for the kernel. */
|
||||
Peb->KernelCallbackTable = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(PVOID) *
|
||||
(USER32_CALLBACK_MAXIMUM + 1));
|
||||
if (Peb->KernelCallbackTable == NULL)
|
||||
{
|
||||
DPRINT1("Failed to create callback table\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
/* initalize loader lock */
|
||||
RtlInitializeCriticalSection(&LdrpLoaderLock);
|
||||
Peb->LoaderLock = &LdrpLoaderLock;
|
||||
|
||||
/* create loader information */
|
||||
Peb->Ldr = (PPEB_LDR_DATA) RtlAllocateHeap(Peb->ProcessHeap,
|
||||
0,
|
||||
sizeof(PEB_LDR_DATA));
|
||||
if (Peb->Ldr == NULL)
|
||||
{
|
||||
DPRINT1("Failed to create loader data\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
|
||||
Peb->Ldr->Initialized = FALSE;
|
||||
Peb->Ldr->SsHandle = NULL;
|
||||
InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
|
||||
InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
|
||||
InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
|
||||
|
||||
/* Load compatibility settings */
|
||||
LoadCompatibilitySettings(Peb);
|
||||
|
||||
/* build full ntdll path */
|
||||
wcscpy(FullNtDllPath, SharedUserData->NtSystemRoot);
|
||||
wcscat(FullNtDllPath, L"\\system32\\ntdll.dll");
|
||||
|
||||
/* add entry for ntdll */
|
||||
NtModule = (PLDR_DATA_TABLE_ENTRY)
|
||||
RtlAllocateHeap(Peb->ProcessHeap,
|
||||
0,
|
||||
sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
if (NtModule == NULL)
|
||||
{
|
||||
DPRINT1("Failed to create loader module entry (NTDLL)\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
memset(NtModule, 0, sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
|
||||
NtModule->DllBase = BaseAddress;
|
||||
NtModule->EntryPoint = 0; /* no entry point */
|
||||
RtlCreateUnicodeString(&NtModule->FullDllName, FullNtDllPath);
|
||||
RtlCreateUnicodeString(&NtModule->BaseDllName, L"ntdll.dll");
|
||||
NtModule->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_PROCESSED;
|
||||
|
||||
NtModule->LoadCount = -1; /* don't unload */
|
||||
NtModule->TlsIndex = -1;
|
||||
NtModule->SectionPointer = NULL;
|
||||
NtModule->CheckSum = 0;
|
||||
|
||||
NTHeaders = RtlImageNtHeader(NtModule->DllBase);
|
||||
NtModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
|
||||
NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||
|
||||
InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
|
||||
&NtModule->InLoadOrderLinks);
|
||||
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
|
||||
&NtModule->InInitializationOrderModuleList);
|
||||
|
||||
/* add entry for executable (becomes first list entry) */
|
||||
LdrpImageEntry = (PLDR_DATA_TABLE_ENTRY)
|
||||
RtlAllocateHeap(Peb->ProcessHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
if (LdrpImageEntry == NULL)
|
||||
{
|
||||
DPRINT1("Failed to create loader module infomation\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
LdrpImageEntry->DllBase = Peb->ImageBaseAddress;
|
||||
|
||||
if ((Peb->ProcessParameters == NULL) ||
|
||||
(Peb->ProcessParameters->ImagePathName.Length == 0))
|
||||
{
|
||||
DPRINT1("Failed to access the process parameter block\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
RtlCreateUnicodeString(&LdrpImageEntry->FullDllName,
|
||||
Peb->ProcessParameters->ImagePathName.Buffer);
|
||||
RtlCreateUnicodeString(&LdrpImageEntry->BaseDllName,
|
||||
wcsrchr(LdrpImageEntry->FullDllName.Buffer, L'\\') + 1);
|
||||
|
||||
DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", &LdrpImageEntry->BaseDllName, &LdrpImageEntry->FullDllName);
|
||||
|
||||
LdrpImageEntry->Flags = LDRP_ENTRY_PROCESSED;
|
||||
LdrpImageEntry->LoadCount = -1; /* don't unload */
|
||||
LdrpImageEntry->TlsIndex = -1;
|
||||
LdrpImageEntry->SectionPointer = NULL;
|
||||
LdrpImageEntry->CheckSum = 0;
|
||||
|
||||
NTHeaders = RtlImageNtHeader(LdrpImageEntry->DllBase);
|
||||
LdrpImageEntry->SizeOfImage = LdrpGetResidentSize(NTHeaders);
|
||||
LdrpImageEntry->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||
|
||||
LdrpTopLevelDllBeingLoadedTeb = NtCurrentTeb();
|
||||
|
||||
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
|
||||
&LdrpImageEntry->InLoadOrderLinks);
|
||||
|
||||
LdrpInitLoader();
|
||||
|
||||
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
|
||||
LdrpImageEntry->EntryPoint = EntryPoint;
|
||||
|
||||
/* all required dlls are loaded now */
|
||||
Peb->Ldr->Initialized = TRUE;
|
||||
|
||||
/* Check before returning that we can run the image safely. */
|
||||
if (EntryPoint == NULL)
|
||||
{
|
||||
DPRINT1("Failed to initialize image\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
|
||||
}
|
||||
|
||||
/* Break into debugger */
|
||||
if (Peb->BeingDebugged)
|
||||
DbgBreakPoint();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+16
-2061
File diff suppressed because it is too large
Load Diff
@@ -443,20 +443,11 @@ LoadLibraryExW(LPCWSTR lpLibFileName,
|
||||
}
|
||||
}
|
||||
|
||||
/* HACK!!! FIXME */
|
||||
if (InWindows)
|
||||
{
|
||||
/* Call the API Properly */
|
||||
Status = LdrLoadDll(SearchPath,
|
||||
&DllCharacteristics,
|
||||
&DllName,
|
||||
(PVOID*)&hInst);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the ROS API. NOTE: Don't fix this, I have a patch to merge later. */
|
||||
Status = LdrLoadDll(SearchPath, &dwFlags, &DllName, (PVOID*)&hInst);
|
||||
}
|
||||
/* Call the API Properly */
|
||||
Status = LdrLoadDll(SearchPath,
|
||||
&DllCharacteristics,
|
||||
&DllName,
|
||||
(PVOID*)&hInst);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
||||
+14
-5
@@ -2736,6 +2736,10 @@ NTAPI
|
||||
RtlAllocateActivationContextStack(IN PVOID *Context)
|
||||
{
|
||||
PACTIVATION_CONTEXT_STACK ContextStack;
|
||||
|
||||
/* FIXME: Check if it's already allocated */
|
||||
//if (*Context) return STATUS_SUCCESS;
|
||||
|
||||
ContextStack = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (ACTIVATION_CONTEXT_STACK) );
|
||||
if (!ContextStack)
|
||||
{
|
||||
@@ -2798,7 +2802,16 @@ RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTE
|
||||
/* Return pointer to the activation frame */
|
||||
return &Frame->Frame;
|
||||
#else
|
||||
return NULL;
|
||||
|
||||
RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame = &Frame->Frame;
|
||||
|
||||
frame->Previous = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
|
||||
frame->ActivationContext = Context;
|
||||
frame->Flags = 0;
|
||||
|
||||
NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2806,7 +2819,6 @@ PRTL_ACTIVATION_CONTEXT_STACK_FRAME
|
||||
FASTCALL
|
||||
RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
|
||||
{
|
||||
#if NEW_NTDLL_LOADER
|
||||
RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame, *top;
|
||||
|
||||
/* find the right frame */
|
||||
@@ -2820,9 +2832,6 @@ RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CON
|
||||
NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame->Previous;
|
||||
|
||||
return frame;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user