[NTDLL/LDR]
[reactos.git] / reactos / dll / ntdll / ldr / startup.c
index f6550ab..fb814c4 100644 (file)
@@ -25,7 +25,6 @@ extern PTEB LdrpTopLevelDllBeingLoadedTeb;
 
 PLDR_DATA_TABLE_ENTRY ExeModule;
 static RTL_CRITICAL_SECTION PebLock;
-static RTL_CRITICAL_SECTION LoaderLock;
 static RTL_BITMAP TlsBitMap;
 static RTL_BITMAP TlsExpansionBitMap;
 static volatile BOOLEAN LdrpInitialized = FALSE;
@@ -74,9 +73,9 @@ LoadImageFileExecutionOptions(PPEB Peb)
     UNICODE_STRING ImageName;
     UNICODE_STRING ImagePathName;
     ULONG ValueSize;
-    extern ULONG RtlpPageHeapGlobalFlags, RtlpPageHeapSizeRangeStart, RtlpPageHeapSizeRangeEnd;
+    extern ULONG RtlpDphGlobalFlags, RtlpPageHeapSizeRangeStart, RtlpPageHeapSizeRangeEnd;
     extern ULONG RtlpPageHeapDllRangeStart, RtlpPageHeapDllRangeEnd;
-    extern WCHAR RtlpPageHeapTargetDlls[512];
+    extern WCHAR RtlpDphTargetDlls[512];
     extern BOOLEAN RtlpPageHeapEnabled;
 
     if (Peb->ProcessParameters &&
@@ -144,8 +143,8 @@ LoadImageFileExecutionOptions(PPEB Peb)
             LdrQueryImageFileExecutionOptions(&ImageName,
                                               L"PageHeapFlags",
                                               REG_DWORD,
-                                              (PVOID)&RtlpPageHeapGlobalFlags,
-                                              sizeof(RtlpPageHeapGlobalFlags),
+                                              (PVOID)&RtlpDphGlobalFlags,
+                                              sizeof(RtlpDphGlobalFlags),
                                               &ValueSize);
 
             LdrQueryImageFileExecutionOptions(&ImageName,
@@ -179,8 +178,8 @@ LoadImageFileExecutionOptions(PPEB Peb)
             LdrQueryImageFileExecutionOptions(&ImageName,
                                               L"PageHeapTargetDlls",
                                               REG_SZ,
-                                              (PVOID)RtlpPageHeapTargetDlls,
-                                              sizeof(RtlpPageHeapTargetDlls),
+                                              (PVOID)RtlpDphTargetDlls,
+                                              sizeof(RtlpDphTargetDlls),
                                               &ValueSize);
 
             /* Now when all parameters are read, enable page heap */
@@ -344,11 +343,12 @@ LdrpInit2(PCONTEXT Context,
 
     /*  If MZ header exists  */
     PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
+    NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
     DPRINT("PEDosHeader %p\n", PEDosHeader);
 
     if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
         PEDosHeader->e_lfanew == 0L ||
-        *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE)
+        NTHeaders->Signature != IMAGE_NT_SIGNATURE)
     {
         DPRINT1("Image has bad header\n");
         ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
@@ -364,8 +364,6 @@ LdrpInit2(PCONTEXT Context,
                      &NlsTable);
     RtlResetRtlTranslations(&NlsTable);
 
-    NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
-
     /* Get number of processors */
     DPRINT("Here\n");
     Status = ZwQuerySystemInformation(SystemBasicInformation,
@@ -383,6 +381,9 @@ LdrpInit2(PCONTEXT Context,
     /* Initialize Critical Section Data */
     RtlpInitDeferedCriticalSection();
 
+    /* Load execution options */
+    LoadImageFileExecutionOptions(Peb);
+
     /* create process heap */
     RtlInitializeHeapManager();
     Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
@@ -397,6 +398,47 @@ LdrpInit2(PCONTEXT Context,
         ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
     }
 
+    /* Check for correct machine type */
+    if (NTHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE)
+    {
+        ULONG_PTR HardErrorParameters[1];
+        UNICODE_STRING ImageNameU;
+        ANSI_STRING ImageNameA;
+        WCHAR *Ptr;
+        ULONG ErrorResponse;
+
+        DPRINT1("Image %wZ is for a foreign architecture (0x%x).\n",
+                &Peb->ProcessParameters->ImagePathName, NTHeaders->FileHeader.Machine);
+
+        /* Get the full image path name */
+        ImageNameU = Peb->ProcessParameters->ImagePathName;
+
+        /* Get the file name */
+        Ptr = Peb->ProcessParameters->ImagePathName.Buffer +
+              (Peb->ProcessParameters->ImagePathName.Length / sizeof(WCHAR)) -1;
+        while ((Ptr >= Peb->ProcessParameters->ImagePathName.Buffer) &&
+               (*Ptr != L'\\')) Ptr--;
+        ImageNameU.Buffer = Ptr + 1;
+        ImageNameU.Length = Peb->ProcessParameters->ImagePathName.Length -
+            (ImageNameU.Buffer - Peb->ProcessParameters->ImagePathName.Buffer) * sizeof(WCHAR);
+        ImageNameU.MaximumLength = ImageNameU.Length;
+
+        /*`Convert to ANSI, harderror message needs that */
+        RtlUnicodeStringToAnsiString(&ImageNameA, &ImageNameU, TRUE);
+
+        /* Raise harderror */
+        HardErrorParameters[0] = (ULONG_PTR)&ImageNameA;
+        NtRaiseHardError(STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE,
+                         1,
+                         1,
+                         HardErrorParameters,
+                         OptionOk,
+                         &ErrorResponse);
+
+        RtlFreeAnsiString(&ImageNameA);
+        ZwTerminateProcess(NtCurrentProcess(), STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE);
+    }
+
     /* initialized vectored exception handling */
     RtlpInitializeVectoredExceptionHandling();
 
@@ -424,8 +466,8 @@ LdrpInit2(PCONTEXT Context,
     }
 
     /* initalize loader lock */
-    RtlInitializeCriticalSection(&LoaderLock);
-    Peb->LoaderLock = &LoaderLock;
+    RtlInitializeCriticalSection(&LdrpLoaderLock);
+    Peb->LoaderLock = &LdrpLoaderLock;
 
     /* create loader information */
     Peb->Ldr = (PPEB_LDR_DATA) RtlAllocateHeap(Peb->ProcessHeap,
@@ -447,9 +489,6 @@ LdrpInit2(PCONTEXT Context,
     /* Load compatibility settings */
     LoadCompatibilitySettings(Peb);
 
-    /* Load execution options */
-    LoadImageFileExecutionOptions(Peb);
-
     /* build full ntdll path */
     wcscpy(FullNtDllPath, SharedUserData->NtSystemRoot);
     wcscat(FullNtDllPath, L"\\system32\\ntdll.dll");
@@ -489,7 +528,7 @@ LdrpInit2(PCONTEXT Context,
     /* add entry for executable (becomes first list entry) */
     ExeModule = (PLDR_DATA_TABLE_ENTRY)
                  RtlAllocateHeap(Peb->ProcessHeap,
-                                 0,
+                                 HEAP_ZERO_MEMORY,
                                  sizeof(LDR_DATA_TABLE_ENTRY));
     if (ExeModule == NULL)
     {