[RTL] Add support for vectored continue handlers, complementing the vectored exceptio...
[reactos.git] / reactos / dll / ntdll / ldr / ldrinit.c
index 2c7094d..1d5468d 100644 (file)
@@ -11,9 +11,6 @@
 
 #include <ntdll.h>
 
-#include <wingdi.h>
-#include <callback.h>
-
 #define NDEBUG
 #include <debug.h>
 
@@ -80,7 +77,7 @@ ULONG LdrpActiveUnloadCount;
 
 //extern LIST_ENTRY RtlCriticalSectionList;
 
-VOID RtlpInitializeVectoredExceptionHandling(VOID);
+VOID NTAPI RtlpInitializeVectoredExceptionHandling(VOID);
 VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
 VOID NTAPI RtlInitializeHeapManager(VOID);
 extern BOOLEAN RtlpPageHeapEnabled;
@@ -90,6 +87,7 @@ ULONG RtlpShutdownProcessFlags; // TODO: Use it
 
 NTSTATUS LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase);
 void actctx_init(void);
+extern BOOLEAN RtlpUse16ByteSLists;
 
 #ifdef _WIN64
 #define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
@@ -397,7 +395,7 @@ LdrQueryImageFileExecutionOptions(IN PUNICODE_STRING SubKey,
 
 VOID
 NTAPI
-LdrpEnsureLoaderLockIsHeld()
+LdrpEnsureLoaderLockIsHeld(VOID)
 {
     // Ignored atm
 }
@@ -528,7 +526,7 @@ LdrpInitializeThread(IN PCONTEXT Context)
     while (NextEntry != ListHead)
     {
         /* Get the current entry */
-        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);
+        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
 
         /* Make sure it's not ourselves */
         if (Peb->ImageBaseAddress != LdrEntry->DllBase)
@@ -676,7 +674,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
     while (NextEntry != ListHead)
     {
         /* Get the Data Entry */
-        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
 
         /* Check if we have a Root Entry */
         if (LdrRootEntry)
@@ -842,7 +840,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
     while (NextEntry != ListHead)
     {
         /* Get the Data Entrry */
-        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
 
         /* FIXME: Verify NX Compat */
         // LdrpCheckNXCompatibility()
@@ -934,7 +932,7 @@ LdrShutdownProcess(VOID)
     while (NextEntry != ListHead)
     {
         /* Get the current entry */
-        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
         NextEntry = NextEntry->Blink;
 
         /* Make sure it's not ourselves */
@@ -1039,7 +1037,7 @@ LdrShutdownThread(VOID)
     while (NextEntry != ListHead)
     {
         /* Get the current entry */
-        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
         NextEntry = NextEntry->Blink;
 
         /* Make sure it's not ourselves */
@@ -1778,7 +1776,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     /* Check if we failed */
     if (!NT_SUCCESS(Status))
     {
-        /* Aassume System32 */
+        /* Assume System32 */
         LdrpKnownDllObjectDirectory = NULL;
         RtlInitUnicodeString(&LdrpKnownDllPath, StringBuffer);
         LdrpKnownDllPath.Length -= sizeof(WCHAR);
@@ -1846,24 +1844,24 @@ LdrpInitializeProcess(IN PCONTEXT Context,
     PebLdr.Initialized = TRUE;
 
     /* Allocate a data entry for the Image */
-    LdrpImageEntry = NtLdrEntry = LdrpAllocateDataTableEntry(Peb->ImageBaseAddress);
+    LdrpImageEntry = LdrpAllocateDataTableEntry(Peb->ImageBaseAddress);
 
     /* Set it up */
-    NtLdrEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(NtLdrEntry->DllBase);
-    NtLdrEntry->LoadCount = -1;
-    NtLdrEntry->EntryPointActivationContext = 0;
-    NtLdrEntry->FullDllName = ImageFileName;
+    LdrpImageEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrpImageEntry->DllBase);
+    LdrpImageEntry->LoadCount = -1;
+    LdrpImageEntry->EntryPointActivationContext = 0;
+    LdrpImageEntry->FullDllName = ImageFileName;
 
     if (IsDotNetImage)
-        NtLdrEntry->Flags = LDRP_COR_IMAGE;
+        LdrpImageEntry->Flags = LDRP_COR_IMAGE;
     else
-        NtLdrEntry->Flags = 0;
+        LdrpImageEntry->Flags = 0;
 
     /* Check if the name is empty */
     if (!ImageFileName.Buffer[0])
     {
         /* Use the same Base name */
-        NtLdrEntry->BaseDllName = NtLdrEntry->FullDllName;
+        LdrpImageEntry->BaseDllName = LdrpImageEntry->FullDllName;
     }
     else
     {
@@ -1882,21 +1880,21 @@ LdrpInitializeProcess(IN PCONTEXT Context,
         if (!NtDllName)
         {
             /* Use the same Base name */
-            NtLdrEntry->BaseDllName = NtLdrEntry->FullDllName;
+            LdrpImageEntry->BaseDllName = LdrpImageEntry->FullDllName;
         }
         else
         {
             /* Setup the name */
-            NtLdrEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
-            NtLdrEntry->BaseDllName.MaximumLength = NtLdrEntry->BaseDllName.Length + sizeof(WCHAR);
-            NtLdrEntry->BaseDllName.Buffer = (PWSTR)((ULONG_PTR)ImageFileName.Buffer +
-                                                     (ImageFileName.Length - NtLdrEntry->BaseDllName.Length));
+            LdrpImageEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)ImageFileName.Buffer + ImageFileName.Length - (ULONG_PTR)NtDllName);
+            LdrpImageEntry->BaseDllName.MaximumLength = LdrpImageEntry->BaseDllName.Length + sizeof(WCHAR);
+            LdrpImageEntry->BaseDllName.Buffer = (PWSTR)((ULONG_PTR)ImageFileName.Buffer +
+                                                     (ImageFileName.Length - LdrpImageEntry->BaseDllName.Length));
         }
     }
 
     /* Processing done, insert it */
-    LdrpInsertMemoryTableEntry(NtLdrEntry);
-    NtLdrEntry->Flags |= LDRP_ENTRY_PROCESSED;
+    LdrpInsertMemoryTableEntry(LdrpImageEntry);
+    LdrpImageEntry->Flags |= LDRP_ENTRY_PROCESSED;
 
     /* Now add an entry for NTDLL */
     NtLdrEntry = LdrpAllocateDataTableEntry(SystemArgument1);
@@ -1929,7 +1927,7 @@ LdrpInitializeProcess(IN PCONTEXT Context,
 
     /* Link the Init Order List */
     InsertHeadList(&Peb->Ldr->InInitializationOrderModuleList,
-                   &LdrpNtDllDataTableEntry->InInitializationOrderModuleList);
+                   &LdrpNtDllDataTableEntry->InInitializationOrderLinks);
 
     /* Initialize Wine's active context implementation for the current process */
     actctx_init();
@@ -2073,6 +2071,40 @@ LdrpInitializeProcess(IN PCONTEXT Context,
                             &ExecuteOptions,
                             sizeof(ULONG));
 
+    // FIXME: Should be done by Application Compatibility features,
+    // by reading the registry, etc...
+    // For now, this is the old code from ntdll!RtlGetVersion().
+    RtlInitEmptyUnicodeString(&Peb->CSDVersion, NULL, 0);
+    if (((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
+    {
+        WCHAR szCSDVersion[128];
+        LONG i;
+        ULONG Length = ARRAYSIZE(szCSDVersion) - 1;
+        i = _snwprintf(szCSDVersion, Length,
+                       L"Service Pack %d",
+                       ((Peb->OSCSDVersion >> 8) & 0xFF));
+        if (i < 0)
+        {
+            /* Null-terminate if it was overflowed */
+            szCSDVersion[Length] = UNICODE_NULL;
+        }
+
+        Length *= sizeof(WCHAR);
+        Peb->CSDVersion.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                                 0,
+                                                 Length + sizeof(UNICODE_NULL));
+        if (Peb->CSDVersion.Buffer)
+        {
+            Peb->CSDVersion.Length = Length;
+            Peb->CSDVersion.MaximumLength = Length + sizeof(UNICODE_NULL);
+
+            RtlCopyMemory(Peb->CSDVersion.Buffer,
+                          szCSDVersion,
+                          Peb->CSDVersion.MaximumLength);
+            Peb->CSDVersion.Buffer[Peb->CSDVersion.Length / sizeof(WCHAR)] = UNICODE_NULL;
+        }
+    }
+
     /* Check if we had Shim Data */
     if (OldShimData)
     {
@@ -2152,6 +2184,11 @@ LdrpInit(PCONTEXT Context,
         NtCurrentTeb()->RealClientId.UniqueProcess,
         NtCurrentTeb()->RealClientId.UniqueThread);
 
+#ifdef _WIN64
+    /* Set the SList header usage */
+    RtlpUse16ByteSLists = SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE128];
+#endif /* _WIN64 */
+
     /* Check if we have a deallocation stack */
     if (!Teb->DeallocationStack)
     {