/* 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 (KeyValueInformation == 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);
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);