- Revert r52573

- Branch repair (part 1 of x)

svn path=/branches/GSoC_2011/TcpIpDriver/; revision=53062
This commit is contained in:
Cameron Gutman
2011-08-04 17:16:20 +00:00
parent 8a7764ca2d
commit 8b36c2fed5
9 changed files with 2849 additions and 2443 deletions
+25 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1 -278
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+5 -14
View File
@@ -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
View File
@@ -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
}