/* INCLUDES *****************************************************************/
#include <ntdll.h>
-#include <win32k/callback.h>
+#include <callback.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
-HKEY ImageExecOptionsKey;
-HKEY Wow64ExecOptionsKey;
+HANDLE ImageExecOptionsKey;
+HANDLE Wow64ExecOptionsKey;
UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options");
UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L"");
UNICODE_STRING NtDllString = RTL_CONSTANT_STRING(L"ntdll.dll");
ULONG LdrpNumberOfTlsEntries;
ULONG LdrpNumberOfProcessors;
PVOID NtDllBase;
-LARGE_INTEGER RtlpTimeout;
+extern LARGE_INTEGER RtlpTimeout;
BOOLEAN RtlpTimeoutDisable;
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
LIST_ENTRY LdrpDllNotificationList;
VOID RtlpInitializeVectoredExceptionHandling(VOID);
VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
-VOID RtlInitializeHeapManager(VOID);
+VOID NTAPI RtlInitializeHeapManager(VOID);
extern BOOLEAN RtlpPageHeapEnabled;
ULONG RtlpDisableHeapLookaside; // TODO: Move to heap.c
ULONG RtlpShutdownProcessFlags; // TODO: Use it
NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase);
+void actctx_init(void);
#ifdef _WIN64
#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
NTAPI
LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey,
IN BOOLEAN Wow64,
- OUT PHKEY NewKeyHandle)
+ OUT PHANDLE NewKeyHandle)
{
- PHKEY RootKeyLocation;
+ PHANDLE RootKeyLocation;
HANDLE RootKey;
UNICODE_STRING SubKeyString;
OBJECT_ATTRIBUTES ObjectAttributes;
/* Setup the object attributes */
InitializeObjectAttributes(&ObjectAttributes,
- Wow64 ?
+ Wow64 ?
&Wow64OptionsString : &ImageExecOptionsString,
OBJ_CASE_INSENSITIVE,
NULL,
*/
NTSTATUS
NTAPI
-LdrQueryImageFileKeyOption(IN HKEY KeyHandle,
+LdrQueryImageFileKeyOption(IN HANDLE KeyHandle,
IN PCWSTR ValueName,
IN ULONG Type,
OUT PVOID Buffer,
KeyValueInformation = RtlAllocateHeap(RtlGetProcessHeap(),
0,
KeyInfoSize);
- if (KeyInfo == NULL)
+ if (KeyValueInformation != NULL)
+ {
+ /* Try again */
+ Status = ZwQueryValueKey(KeyHandle,
+ &ValueNameString,
+ KeyValuePartialInformation,
+ KeyValueInformation,
+ KeyInfoSize,
+ &ResultSize);
+ FreeHeap = TRUE;
+ }
+ else
{
/* Give up this time */
Status = STATUS_NO_MEMORY;
}
-
- /* Try again */
- Status = ZwQueryValueKey(KeyHandle,
- &ValueNameString,
- KeyValuePartialInformation,
- KeyValueInformation,
- KeyInfoSize,
- &ResultSize);
- FreeHeap = TRUE;
}
/* Check for success */
IN BOOLEAN Wow64)
{
NTSTATUS Status;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
/* Open a handle to the key */
Status = LdrOpenImageFileOptionsKey(SubKey, Wow64, &KeyHandle);
{
PULONG_PTR Cookie;
LARGE_INTEGER Counter;
- //ULONG NewCookie;
+ ULONG_PTR NewCookie;
/* Fetch address of the cookie */
Cookie = LdrpFetchAddressOfSecurityCookie(LdrEntry->DllBase, LdrEntry->SizeOfImage);
if (Cookie)
{
/* Check if it's a default one */
- if (*Cookie == DEFAULT_SECURITY_COOKIE ||
- *Cookie == 0xBB40)
+ if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
+ (*Cookie == 0xBB40))
{
- /* We need to initialize it */
-
+ /* Make up a cookie from a bunch of values which may uniquely represent
+ current moment of time, environment, etc */
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 ();
+ NewCookie = Counter.LowPart ^ Counter.HighPart;
+ NewCookie ^= (ULONG)NtCurrentTeb()->ClientId.UniqueProcess;
+ NewCookie ^= (ULONG)NtCurrentTeb()->ClientId.UniqueThread;
- QueryPerformanceCounter (&perfctr);
-#ifdef _WIN64
- cookie ^= perfctr.QuadPart;
-#else
- cookie ^= perfctr.LowPart;
- cookie ^= perfctr.HighPart;
-#endif
+ /* Loop like it's done in KeQueryTickCount(). We don't want to call it directly. */
+ while (SharedUserData->SystemTime.High1Time != SharedUserData->SystemTime.High2Time)
+ {
+ YieldProcessor();
+ };
-#ifdef _WIN64
- cookie &= 0x0000ffffffffffffll;
-#endif
-#endif
- *Cookie = Counter.LowPart;
+ /* Calculate the milliseconds value and xor it to the cookie */
+ NewCookie ^= Int64ShrlMod32(UInt32x32To64(SharedUserData->TickCountMultiplier, SharedUserData->TickCount.LowPart), 24) +
+ (SharedUserData->TickCountMultiplier * (SharedUserData->TickCount.High1Time << 8));
- //Cookie = NULL;
+ /* Make the cookie 16bit if necessary */
+ if (*Cookie == 0xBB40) NewCookie &= 0xFFFF;
+
+ /* If the result is 0 or the same as we got, just subtract one from the existing value
+ and that's it */
+ if ((NewCookie == 0) || (NewCookie == *Cookie))
+ {
+ NewCookie = *Cookie - 1;
+ }
+
+ /* Set the new cookie value */
+ *Cookie = NewCookie;
}
}
NTSTATUS Status;
PVOID EntryPoint;
- DPRINT("LdrpInitializeThread() called for %wZ (%lx/%lx)\n",
+ DPRINT("LdrpInitializeThread() called for %wZ (%p/%p)\n",
&LdrpImageEntry->BaseDllName,
NtCurrentTeb()->RealClientId.UniqueProcess,
NtCurrentTeb()->RealClientId.UniqueThread);
/* 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(&NtCurrentTeb()->ActivationContextStackPointer);
+ if (!NT_SUCCESS(Status))
{
- 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");
+ DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
}
/* Make sure we are not shutting down */
EntryPoint = LdrEntry->EntryPoint;
/* Check if we are ready to call it */
- if ((EntryPoint) &&
+ if ((EntryPoint) &&
(LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
(LdrEntry->Flags & LDRP_IMAGE_DLL))
{
if (!LdrpShutdownInProgress)
{
/* Call the Entrypoint */
- DPRINT("%wZ - Calling entry point at %p for thread attaching, %lx/%lx\n",
+ DPRINT("%wZ - Calling entry point at %p for thread attaching, %p/%p\n",
&LdrEntry->BaseDllName, LdrEntry->EntryPoint,
NtCurrentTeb()->RealClientId.UniqueProcess,
NtCurrentTeb()->RealClientId.UniqueThread);
PTEB OldTldTeb;
BOOLEAN DllStatus;
- DPRINT("LdrpRunInitializeRoutines() called for %wZ (%lx/%lx)\n",
+ DPRINT("LdrpRunInitializeRoutines() called for %wZ (%p/%p)\n",
&LdrpImageEntry->BaseDllName,
NtCurrentTeb()->RealClientId.UniqueProcess,
NtCurrentTeb()->RealClientId.UniqueThread);
/* Allocate space for all the entries */
LdrRootEntry = RtlAllocateHeap(RtlGetProcessHeap(),
0,
- Count * sizeof(LdrRootEntry));
+ Count * sizeof(*LdrRootEntry));
if (!LdrRootEntry) return STATUS_NO_MEMORY;
}
else
/* Show debug message */
if (ShowSnaps)
{
- DPRINT1("[%x,%x] LDR: Real INIT LIST for Process %wZ\n",
+ DPRINT1("[%p,%p] LDR: Real INIT LIST for Process %wZ\n",
NtCurrentTeb()->RealClientId.UniqueThread,
NtCurrentTeb()->RealClientId.UniqueProcess,
&Peb->ProcessParameters->ImagePathName);
if (LdrEntry->EntryPoint)
{
/* Write in array */
+ ASSERT(i < Count);
LdrRootEntry[i] = LdrEntry;
/* Display debug message */
if (ShowSnaps)
{
- DPRINT1("[%x,%x] LDR: %wZ init routine %p\n",
+ DPRINT1("[%p,%p] LDR: %wZ init routine %p\n",
NtCurrentTeb()->RealClientId.UniqueThread,
NtCurrentTeb()->RealClientId.UniqueProcess,
&LdrEntry->FullDllName,
EntryPoint = LdrEntry->EntryPoint;
/* Check if we are ready to call it */
- if (EntryPoint &&
+ if (EntryPoint &&
(LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
LdrEntry->Flags)
{
}
/* Call the Entrypoint */
- DPRINT("%wZ - Calling entry point at %x for thread detaching\n",
+ DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
&LdrEntry->BaseDllName, LdrEntry->EntryPoint);
LdrpCallInitRoutine(EntryPoint,
LdrEntry->DllBase,
if (!LdrpShutdownInProgress)
{
/* Call the Entrypoint */
- DPRINT("%wZ - Calling entry point at %x for thread detaching\n",
+ DPRINT("%wZ - Calling entry point at %p for thread detaching\n",
&LdrEntry->BaseDllName, LdrEntry->EntryPoint);
LdrpCallInitRoutine(EntryPoint,
LdrEntry->DllBase,
PTEB Teb = NtCurrentTeb();
PLIST_ENTRY NextEntry, ListHead;
PLDRP_TLS_DATA TlsData;
- ULONG TlsDataSize;
+ SIZE_T TlsDataSize;
PVOID *TlsVector;
/* Check if we have any entries */
NextEntry = NextEntry->Flink;
/* Allocate this vector */
- TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
+ TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
TlsData->TlsDirectory.StartAddressOfRawData;
TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
0,
/* Show debug message */
if (ShowSnaps)
{
- DPRINT1("LDR: TlsVector %x Index %d = %x copied from %x to %x\n",
+ DPRINT1("LDR: TlsVector %p Index %lu = %p copied from %x to %p\n",
TlsVector,
TlsData->TlsDirectory.Characteristics,
&TlsVector[TlsData->TlsDirectory.Characteristics],
NTSTATUS
NTAPI
-LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHKEY OptionsKey)
+LdrpInitializeExecutionOptions(PUNICODE_STRING ImagePathName, PPEB Peb, PHANDLE OptionsKey)
{
NTSTATUS Status;
- HKEY KeyHandle;
+ HANDLE KeyHandle;
ULONG ExecuteOptions, MinimumStackCommit = 0, GlobalFlag;
/* Return error if we were not provided a pointer where to save the options key handle */
PPEB Peb = NtCurrentPeb();
BOOLEAN IsDotNetImage = FALSE;
BOOLEAN FreeCurDir = FALSE;
- //HKEY CompatKey;
+ //HANDLE CompatKey;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
//LPWSTR ImagePathBuffer;
ULONG ConfigSize;
UNICODE_STRING CurrentDirectory;
- HKEY OptionsKey;
+ HANDLE OptionsKey;
ULONG HeapFlags;
PIMAGE_NT_HEADERS NtHeader;
LPWSTR NtDllName = NULL;
- NTSTATUS Status;
+ NTSTATUS Status, ImportStatus;
NLSTABLEINFO NlsTable;
PIMAGE_LOAD_CONFIG_DIRECTORY LoadConfig;
PTEB Teb = NtCurrentTeb();
/* Normalize the parameters */
ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
- ProcessParameters = Peb->ProcessParameters;
if (ProcessParameters)
{
/* Save the Image and Command Line Names */
/* Start verbose debugging messages right now if they were requested */
if (ShowSnaps)
{
- DPRINT1("LDR: PID: 0x%x started - '%wZ'\n",
+ DPRINT1("LDR: PID: 0x%p started - '%wZ'\n",
Teb->ClientId.UniqueProcess,
&CommandLine);
}
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);
+ Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
if (!NT_SUCCESS(Status)) return Status;
// FIXME: Loader private heap is missing
InsertHeadList(&Peb->Ldr->InInitializationOrderModuleList,
&LdrpNtDllDataTableEntry->InInitializationOrderModuleList);
+ /* Initialize Wine's active context implementation for the current process */
+ actctx_init();
+
/* Set the current directory */
Status = RtlSetCurrentDirectory_U(&CurrentDirectory);
if (!NT_SUCCESS(Status))
}
/* Walk the IAT and load all the DLLs */
- LdrpWalkImportDescriptor(LdrpDefaultPath.Buffer, LdrpImageEntry);
+ ImportStatus = LdrpWalkImportDescriptor(LdrpDefaultPath.Buffer, LdrpImageEntry);
/* Check if relocation is needed */
if (Peb->ImageBaseAddress != (PVOID)NtHeader->OptionalHeader.ImageBase)
{
DPRINT1("LDR: Performing EXE relocation\n");
-
+
/* Change the protection to prepare for relocation */
ViewBase = Peb->ImageBaseAddress;
Status = LdrpSetProtection(ViewBase, FALSE);
DPRINT1("LdrRelocateImageWithBias() failed\n");
return Status;
}
-
+
/* Check if a start context was provided */
if (Context)
{
UNIMPLEMENTED; // We should support this
return STATUS_INVALID_IMAGE_FORMAT;
}
-
+
/* Restore the protection */
Status = LdrpSetProtection(ViewBase, TRUE);
if (!NT_SUCCESS(Status)) return Status;
/* Phase 0 is done */
LdrpLdrDatabaseIsSetup = TRUE;
+ /* Check whether all static imports were properly loaded and return here */
+ if (!NT_SUCCESS(ImportStatus)) return ImportStatus;
+
/* Initialize TLS */
Status = LdrpInitializeTls();
if (!NT_SUCCESS(Status))
MEMORY_BASIC_INFORMATION MemoryBasicInfo;
PPEB Peb = NtCurrentPeb();
- DPRINT("LdrpInit() %lx/%lx\n",
+ DPRINT("LdrpInit() %p/%p\n",
NtCurrentTeb()->RealClientId.UniqueProcess,
NtCurrentTeb()->RealClientId.UniqueThread);