- Don't hardcode PEB address
[reactos.git] / reactos / lib / ntdll / ldr / startup.c
index e7fbe96..15defad 100644 (file)
 
 /* INCLUDES *****************************************************************/
 
-#include <reactos/config.h>
-#include <ddk/ntddk.h>
-#include <windows.h>
-#include <ntdll/ldr.h>
-#include <ntdll/rtl.h>
-#include <csrss/csrss.h>
-#include <ntdll/csr.h>
-#include <user32/callback.h>
-#include <rosrtl/string.h>
-
+#include <ntdll.h>
 #define NDEBUG
-#include <ntdll/ntdll.h>
-
+#include <debug.h>
+#include <win32k/callback.h>
 
 VOID RtlInitializeHeapManager (VOID);
 VOID LdrpInitLoader(VOID);
+VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
 
 /* GLOBALS *******************************************************************/
 
 
 extern unsigned int _image_base__;
 
-static CRITICAL_SECTION PebLock;
-static CRITICAL_SECTION LoaderLock;
+static RTL_CRITICAL_SECTION PebLock;
+static RTL_CRITICAL_SECTION LoaderLock;
 static RTL_BITMAP TlsBitMap;
-PLDR_MODULE ExeModule;
-
-ULONG NtGlobalFlag = 0;
+PLDR_DATA_TABLE_ENTRY ExeModule;
 
 NTSTATUS LdrpAttachThread (VOID);
 
+VOID RtlpInitializeVectoredExceptionHandling(VOID);
+
 
 #define VALUE_BUFFER_SIZE 256
 
-BOOL FASTCALL
+BOOLEAN FASTCALL
 ReadCompatibilitySetting(HANDLE Key, LPWSTR Value, PKEY_VALUE_PARTIAL_INFORMATION ValueInfo, DWORD *Buffer)
 {
        UNICODE_STRING ValueName;
@@ -75,14 +67,35 @@ LoadImageFileExecutionOptions(PPEB Peb)
     NTSTATUS Status = STATUS_SUCCESS;
     ULONG Value = 0;
     UNICODE_STRING ValueString;
+    UNICODE_STRING ImageName;
+    UNICODE_STRING ImagePathName;
     WCHAR ValueBuffer[64];
     ULONG ValueSize;
 
     if (Peb->ProcessParameters &&
         Peb->ProcessParameters->ImagePathName.Length > 0)
       {
+        DPRINT("%wZ\n", &Peb->ProcessParameters->ImagePathName);
+
+        ImagePathName = Peb->ProcessParameters->ImagePathName;
+        ImageName.Buffer = ImagePathName.Buffer + ImagePathName.Length / sizeof(WCHAR);
+        ImageName.Length = 0;
+        while (ImagePathName.Buffer < ImageName.Buffer)
+        {
+            ImageName.Buffer--;
+            if (*ImageName.Buffer == L'\\')
+            {
+               ImageName.Buffer++;
+               break;
+            }
+        }
+        ImageName.Length = ImagePathName.Length - (ImageName.Buffer - ImagePathName.Buffer) * sizeof(WCHAR);
+        ImageName.MaximumLength = ImageName.Length + ImagePathName.MaximumLength - ImagePathName.Length;
+
+        DPRINT("%wZ\n", &ImageName);
+
         /* global flag */
-        Status = LdrQueryImageFileExecutionOptions (&Peb->ProcessParameters->ImagePathName,
+        Status = LdrQueryImageFileExecutionOptions (&ImageName,
                                                    L"GlobalFlag",
                                                    REG_SZ,
                                                    (PVOID)ValueBuffer,
@@ -90,25 +103,27 @@ LoadImageFileExecutionOptions(PPEB Peb)
                                                    &ValueSize);
         if (NT_SUCCESS(Status))
           {
-            ValueString.Buffer = ValueBuffer + 1;
-           ValueString.Length = ValueSize - 2 * sizeof(WCHAR);
+            ValueString.Buffer = ValueBuffer;
+           ValueString.Length = ValueSize - sizeof(WCHAR);
            ValueString.MaximumLength = sizeof(ValueBuffer);
-           RtlUnicodeStringToInteger(&ValueString, 16, &Value);
-            Peb->NtGlobalFlag |= Value;
-           DPRINT("GlobalFlag: Key='%S', Value=%08x\n", ValueBuffer, Value);
+           Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value);
+            if (NT_SUCCESS(Status))
+              {
+                Peb->NtGlobalFlag |= Value;
+               DPRINT("GlobalFlag: Key='%S', Value=%08x\n", ValueBuffer, Value);
+              }
          }
         /*
         * FIXME:
-        *   read more options 
+        *   read more options
          */
       }
-    NtGlobalFlag = Peb->NtGlobalFlag;
 }
 
 
-           
-       
-BOOL FASTCALL
+
+
+BOOLEAN FASTCALL
 LoadCompatibilitySettings(PPEB Peb)
 {
        NTSTATUS Status;
@@ -116,7 +131,8 @@ LoadCompatibilitySettings(PPEB Peb)
        HANDLE KeyHandle;
        HANDLE SubKeyHandle;
        OBJECT_ATTRIBUTES ObjectAttributes;
-       UNICODE_STRING KeyName;
+       UNICODE_STRING KeyName = RTL_CONSTANT_STRING(
+    L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
        UNICODE_STRING ValueName;
        UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
        PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
@@ -134,9 +150,6 @@ LoadCompatibilitySettings(PPEB Peb)
                        return FALSE;
                }
 
-               RtlRosInitUnicodeStringFromLiteral(&KeyName, 
-                       L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
-
                InitializeObjectAttributes(&ObjectAttributes,
                        &KeyName,
                        OBJ_CASE_INSENSITIVE,
@@ -210,10 +223,9 @@ LoadCompatibilitySettings(PPEB Peb)
                Peb->OSPlatformId = (ULONG)PlatformId;
 
                /* optional service pack version numbers */
-               if(ReadCompatibilitySetting(SubKeyHandle, L"SPMajorVersion", ValueInfo, &SPMajorVersion))
-                       Peb->SPMajorVersion = (UCHAR)SPMajorVersion;
-               if(ReadCompatibilitySetting(SubKeyHandle, L"SPMinorVersion", ValueInfo, &SPMinorVersion))
-                       Peb->SPMinorVersion = (UCHAR)SPMinorVersion;
+               if(ReadCompatibilitySetting(SubKeyHandle, L"SPMajorVersion", ValueInfo, &SPMajorVersion) &&
+                  ReadCompatibilitySetting(SubKeyHandle, L"SPMinorVersion", ValueInfo, &SPMinorVersion))
+                       Peb->OSCSDVersion = ((SPMajorVersion & 0xFF) << 8) | (SPMinorVersion & 0xFF);
 
 finish:
                /* we're finished */
@@ -225,28 +237,29 @@ finish:
        return FALSE;
 }
 
-
 /* FUNCTIONS *****************************************************************/
 
-VOID STDCALL
-__true_LdrInitializeThunk (ULONG Unknown1,
-                    ULONG Unknown2,
-                    ULONG Unknown3,
-                    ULONG Unknown4)
+VOID
+NTAPI
+LdrpInit(PCONTEXT Context,
+         PVOID SystemArgument1,
+         PVOID SystemArgument2)
 {
    PIMAGE_NT_HEADERS NTHeaders;
    PEPFUNC EntryPoint;
    PIMAGE_DOS_HEADER PEDosHeader;
    PVOID ImageBase;
    PPEB Peb;
-   PLDR_MODULE NtModule;  // ntdll
+   PLDR_DATA_TABLE_ENTRY NtModule;  // ntdll
    NLSTABLEINFO NlsTable;
    WCHAR FullNtDllPath[MAX_PATH];
+   SYSTEM_BASIC_INFORMATION SystemInformation;
+   NTSTATUS Status;
 
-   DPRINT("LdrInitializeThunk()\n");
+   DPRINT("LdrpInit()\n");
    if (NtCurrentPeb()->Ldr == NULL || NtCurrentPeb()->Ldr->Initialized == FALSE)
      {
-       Peb = (PPEB)(PEB_BASE);
+       Peb = NtCurrentPeb();
        DPRINT("Peb %x\n", Peb);
        ImageBase = Peb->ImageBaseAddress;
        DPRINT("ImageBase %x\n", ImageBase);
@@ -259,9 +272,10 @@ __true_LdrInitializeThunk (ULONG Unknown1,
        /*  If MZ header exists  */
        PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
        DPRINT("PEDosHeader %x\n", PEDosHeader);
-       if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
+
+       if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
            PEDosHeader->e_lfanew == 0L ||
-           *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC)
+           *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE)
          {
            DPRINT1("Image has bad header\n");
            ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
@@ -277,7 +291,24 @@ __true_LdrInitializeThunk (ULONG Unknown1,
                          &NlsTable);
        RtlResetRtlTranslations (&NlsTable);
 
-       NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
+       NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
+
+       /* 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();
 
        /* create process heap */
        RtlInitializeHeapManager();
@@ -293,6 +324,9 @@ __true_LdrInitializeThunk (ULONG Unknown1,
            ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
          }
 
+       /* initialized vectored exception handling */
+       RtlpInitializeVectoredExceptionHandling();
+
        /* initalize peb lock support */
        RtlInitializeCriticalSection (&PebLock);
        Peb->FastPebLock = &PebLock;
@@ -307,7 +341,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
        Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE;
 
        /* Initialize table of callbacks for the kernel. */
-       Peb->KernelCallbackTable = 
+       Peb->KernelCallbackTable =
          RtlAllocateHeap(RtlGetProcessHeap(),
                          0,
                          sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1));
@@ -343,31 +377,31 @@ __true_LdrInitializeThunk (ULONG Unknown1,
        wcscat (FullNtDllPath, L"\\system32\\ntdll.dll");
 
        /* add entry for ntdll */
-       NtModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
+       NtModule = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap (Peb->ProcessHeap,
                                                 0,
-                                                sizeof(LDR_MODULE));
+                                                sizeof(LDR_DATA_TABLE_ENTRY));
        if (NtModule == NULL)
          {
            DPRINT1("Failed to create loader module entry (NTDLL)\n");
            ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
         }
-       memset(NtModule, 0, sizeof(LDR_MODULE));
+       memset(NtModule, 0, sizeof(LDR_DATA_TABLE_ENTRY));
 
-       NtModule->BaseAddress = (PVOID)&_image_base__;
+       NtModule->DllBase = (PVOID)&_image_base__;
        NtModule->EntryPoint = 0; /* no entry point */
        RtlCreateUnicodeString (&NtModule->FullDllName,
                                FullNtDllPath);
        RtlCreateUnicodeString (&NtModule->BaseDllName,
                                L"ntdll.dll");
-       NtModule->Flags = IMAGE_DLL|ENTRY_PROCESSED;
+       NtModule->Flags = LDRP_IMAGE_DLL|LDRP_ENTRY_PROCESSED;
 
        NtModule->LoadCount = -1; /* don't unload */
        NtModule->TlsIndex = -1;
-       NtModule->SectionHandle = NULL;
+       NtModule->SectionPointer = NULL;
        NtModule->CheckSum = 0;
 
-       NTHeaders = RtlImageNtHeader (NtModule->BaseAddress);
-       NtModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
+       NTHeaders = RtlImageNtHeader (NtModule->DllBase);
+       NtModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
        NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
 
        InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
@@ -382,15 +416,15 @@ __true_LdrInitializeThunk (ULONG Unknown1,
 #endif /* DBG || KDBG */
 
        /* add entry for executable (becomes first list entry) */
-       ExeModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
+       ExeModule = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap (Peb->ProcessHeap,
                                                  0,
-                                                 sizeof(LDR_MODULE));
+                                                 sizeof(LDR_DATA_TABLE_ENTRY));
        if (ExeModule == NULL)
          {
            DPRINT1("Failed to create loader module infomation\n");
            ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
          }
-       ExeModule->BaseAddress = Peb->ImageBaseAddress;
+       ExeModule->DllBase = Peb->ImageBaseAddress;
 
        if ((Peb->ProcessParameters == NULL) ||
            (Peb->ProcessParameters->ImagePathName.Length == 0))
@@ -408,14 +442,14 @@ __true_LdrInitializeThunk (ULONG Unknown1,
               &ExeModule->BaseDllName,
               &ExeModule->FullDllName);
 
-       ExeModule->Flags = ENTRY_PROCESSED;
+       ExeModule->Flags = LDRP_ENTRY_PROCESSED;
        ExeModule->LoadCount = -1; /* don't unload */
        ExeModule->TlsIndex = -1;
-       ExeModule->SectionHandle = NULL;
+       ExeModule->SectionPointer = NULL;
        ExeModule->CheckSum = 0;
 
-       NTHeaders = RtlImageNtHeader (ExeModule->BaseAddress);
-       ExeModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
+       NTHeaders = RtlImageNtHeader (ExeModule->DllBase);
+       ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
        ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
 
        InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
@@ -430,7 +464,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
 #endif /* DBG || KDBG */
 
        EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
-       ExeModule->EntryPoint = (ULONG)EntryPoint;
+       ExeModule->EntryPoint = EntryPoint;
 
        /* all required dlls are loaded now */
        Peb->Ldr->Initialized = TRUE;