[AVIFIL32]
[reactos.git] / reactos / dll / ntdll / ldr / ldrinit.c
index dca2b29..8aa9e74 100644 (file)
@@ -10,7 +10,7 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntdll.h>
-#include <win32k/callback.h>
+#include <callback.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -18,8 +18,8 @@
 
 /* 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");
@@ -48,7 +48,7 @@ LIST_ENTRY LdrpTlsList;
 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;
@@ -80,13 +80,14 @@ ULONG LdrpActiveUnloadCount;
 
 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
@@ -103,9 +104,9 @@ NTSTATUS
 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;
@@ -123,7 +124,7 @@ LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey,
 
     /* Setup the object attributes */
     InitializeObjectAttributes(&ObjectAttributes,
-                               Wow64 ? 
+                               Wow64 ?
                                &Wow64OptionsString : &ImageExecOptionsString,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
@@ -173,7 +174,7 @@ LdrOpenImageFileOptionsKey(IN PUNICODE_STRING SubKey,
  */
 NTSTATUS
 NTAPI
-LdrQueryImageFileKeyOption(IN HKEY KeyHandle,
+LdrQueryImageFileKeyOption(IN HANDLE KeyHandle,
                            IN PCWSTR ValueName,
                            IN ULONG Type,
                            OUT PVOID Buffer,
@@ -206,20 +207,22 @@ LdrQueryImageFileKeyOption(IN HKEY KeyHandle,
         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 */
@@ -344,7 +347,7 @@ LdrQueryImageFileExecutionOptionsEx(IN PUNICODE_STRING SubKey,
                                     IN BOOLEAN Wow64)
 {
     NTSTATUS Status;
-    HKEY KeyHandle;
+    HANDLE KeyHandle;
 
     /* Open a handle to the key */
     Status = LdrOpenImageFileOptionsKey(SubKey, Wow64, &KeyHandle);
@@ -440,7 +443,7 @@ LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
 {
     PULONG_PTR Cookie;
     LARGE_INTEGER Counter;
-    //ULONG NewCookie;
+    ULONG_PTR NewCookie;
 
     /* Fetch address of the cookie */
     Cookie = LdrpFetchAddressOfSecurityCookie(LdrEntry->DllBase, LdrEntry->SizeOfImage);
@@ -448,40 +451,39 @@ LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
     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;
         }
     }
 
@@ -499,25 +501,17 @@ LdrpInitializeThread(IN PCONTEXT Context)
     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 */
@@ -544,7 +538,7 @@ LdrpInitializeThread(IN PCONTEXT Context)
                 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))
                 {
@@ -572,7 +566,7 @@ LdrpInitializeThread(IN PCONTEXT Context)
                     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);
@@ -632,7 +626,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
     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);
@@ -649,7 +643,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
             /* Allocate space for all the entries */
             LdrRootEntry = RtlAllocateHeap(RtlGetProcessHeap(),
                                            0,
-                                           Count * sizeof(LdrRootEntry));
+                                           Count * sizeof(*LdrRootEntry));
             if (!LdrRootEntry) return STATUS_NO_MEMORY;
         }
         else
@@ -667,7 +661,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
     /* 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);
@@ -695,12 +689,13 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
                 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,
@@ -728,7 +723,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
 
         /* Clear it */
         //Kernel32ProcessInitPostImportfunction = NULL;
-        UNIMPLEMENTED;
+        //UNIMPLEMENTED;
     }
 
     /* No root entry? return */
@@ -947,7 +942,7 @@ LdrShutdownProcess(VOID)
             EntryPoint = LdrEntry->EntryPoint;
 
             /* Check if we are ready to call it */
-            if (EntryPoint && 
+            if (EntryPoint &&
                 (LdrEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) &&
                 LdrEntry->Flags)
             {
@@ -968,7 +963,7 @@ LdrShutdownProcess(VOID)
                 }
 
                 /* 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,
@@ -1083,7 +1078,7 @@ LdrShutdownThread(VOID)
                     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,
@@ -1220,7 +1215,7 @@ LdrpAllocateTls(VOID)
     PTEB Teb = NtCurrentTeb();
     PLIST_ENTRY NextEntry, ListHead;
     PLDRP_TLS_DATA TlsData;
-    ULONG TlsDataSize;
+    SIZE_T TlsDataSize;
     PVOID *TlsVector;
 
     /* Check if we have any entries */
@@ -1244,7 +1239,7 @@ LdrpAllocateTls(VOID)
         NextEntry = NextEntry->Flink;
 
         /* Allocate this vector */
-        TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData - 
+        TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData -
                       TlsData->TlsDirectory.StartAddressOfRawData;
         TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(),
                                                                            0,
@@ -1258,7 +1253,7 @@ LdrpAllocateTls(VOID)
         /* 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],
@@ -1334,10 +1329,10 @@ LdrpInitializeApplicationVerifierPackage(PUNICODE_STRING ImagePathName, PPEB Peb
 
 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 */
@@ -1475,16 +1470,16 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     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();
@@ -1554,7 +1549,6 @@ LdrpInitializeProcess(IN PCONTEXT Context,
 
     /* Normalize the parameters */
     ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
-    ProcessParameters = Peb->ProcessParameters;
     if (ProcessParameters)
     {
         /* Save the Image and Command Line Names */
@@ -1611,7 +1605,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     /* 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);
     }
@@ -1702,20 +1696,8 @@ 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);
+    Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
     if (!NT_SUCCESS(Status)) return Status;
 
     // FIXME: Loader private heap is missing
@@ -1947,6 +1929,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     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))
@@ -1988,17 +1973,17 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     if (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
     {
         /* Load kernel32 and call BasePostImportInit... */
-        DPRINT1("Unimplemented codepath!\n");
+        DPRINT("Unimplemented codepath!\n");
     }
 
     /* 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);
@@ -2016,7 +2001,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
             DPRINT1("LdrRelocateImageWithBias() failed\n");
             return Status;
         }
-        
+
         /* Check if a start context was provided */
         if (Context)
         {
@@ -2024,7 +2009,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
             UNIMPLEMENTED; // We should support this
             return STATUS_INVALID_IMAGE_FORMAT;
         }
-        
+
         /* Restore the protection */
         Status = LdrpSetProtection(ViewBase, TRUE);
         if (!NT_SUCCESS(Status)) return Status;
@@ -2043,6 +2028,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     /* 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))
@@ -2095,7 +2083,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     {
         /* Check for Application Compatibility Goo */
         //LdrQueryApplicationCompatibilityGoo(hKey);
-        DPRINT1("Querying app compat hacks is missing!\n");
+        DPRINT("Querying app compat hacks is missing!\n");
     }
 
     /*
@@ -2158,7 +2146,7 @@ LdrpInit(PCONTEXT Context,
     MEMORY_BASIC_INFORMATION MemoryBasicInfo;
     PPEB Peb = NtCurrentPeb();
 
-    DPRINT("LdrpInit() %lx/%lx\n",
+    DPRINT("LdrpInit() %p/%p\n",
         NtCurrentTeb()->RealClientId.UniqueProcess,
         NtCurrentTeb()->RealClientId.UniqueThread);