Check for failed allocations. Spotted by Martin Bealby.
[reactos.git] / reactos / lib / ntdll / ldr / startup.c
index e775fab..7cfcbb4 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;
+PLDR_DATA_TABLE_ENTRY ExeModule;
 
 NTSTATUS LdrpAttachThread (VOID);
 
+VOID RtlpInitializeVectoredExceptionHandling(VOID);
+
 
 #define VALUE_BUFFER_SIZE 256
 
@@ -73,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,
@@ -88,23 +103,26 @@ 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=0x%lx\n", ValueBuffer, Value);
+              }
          }
         /*
         * FIXME:
-        *   read more options 
+        *   read more options
          */
       }
 }
 
 
-           
-       
+
+
 BOOLEAN FASTCALL
 LoadCompatibilitySettings(PPEB Peb)
 {
@@ -113,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;
@@ -131,9 +150,6 @@ LoadCompatibilitySettings(PPEB Peb)
                        return FALSE;
                }
 
-               RtlRosInitUnicodeStringFromLiteral(&KeyName, 
-                       L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
-
                InitializeObjectAttributes(&ObjectAttributes,
                        &KeyName,
                        OBJ_CASE_INSENSITIVE,
@@ -223,46 +239,46 @@ finish:
 
 /* 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);
-       DPRINT("Peb %x\n", Peb);
+       Peb = NtCurrentPeb();
+       DPRINT("Peb %p\n", Peb);
        ImageBase = Peb->ImageBaseAddress;
-       DPRINT("ImageBase %x\n", ImageBase);
+       DPRINT("ImageBase %p\n", ImageBase);
        if (ImageBase <= (PVOID)0x1000)
          {
            DPRINT("ImageBase is null\n");
-           ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
+           ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
          }
 
        /*  If MZ header exists  */
        PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
-       DPRINT("PEDosHeader %x\n", PEDosHeader);
+       DPRINT("PEDosHeader %p\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);
+           ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
          }
 
        /* normalize process parameters */
@@ -275,19 +291,21 @@ __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.NumberProcessors;
+       Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors;
 
        /* Initialize Critical Section Data */
        RtlpInitDeferedCriticalSection();
@@ -303,9 +321,12 @@ __true_LdrInitializeThunk (ULONG Unknown1,
        if (Peb->ProcessHeap == 0)
          {
            DPRINT1("Failed to create process heap\n");
-           ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
+           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
          }
-            
+
+       /* initialized vectored exception handling */
+       RtlpInitializeVectoredExceptionHandling();
+
        /* initalize peb lock support */
        RtlInitializeCriticalSection (&PebLock);
        Peb->FastPebLock = &PebLock;
@@ -320,11 +341,16 @@ __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));
-       
+       if (Peb->KernelCallbackTable == NULL)
+         {
+           DPRINT1("Failed to create callback table\n");
+           ZwTerminateProcess(NtCurrentProcess(),STATUS_INSUFFICIENT_RESOURCES);
+         }
+
        /* initalize loader lock */
        RtlInitializeCriticalSection (&LoaderLock);
        Peb->LoaderLock = &LoaderLock;
@@ -336,7 +362,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
        if (Peb->Ldr == NULL)
          {
            DPRINT1("Failed to create loader data\n");
-           ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
+           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
          }
        Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
        Peb->Ldr->Initialized = FALSE;
@@ -356,31 +382,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);
+           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
         }
-       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->ResidentSize = LdrpGetResidentSize(NTHeaders);
+       NTHeaders = RtlImageNtHeader (NtModule->DllBase);
+       NtModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
        NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
 
        InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
@@ -395,15 +421,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);
+           ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
          }
-       ExeModule->BaseAddress = Peb->ImageBaseAddress;
+       ExeModule->DllBase = Peb->ImageBaseAddress;
 
        if ((Peb->ProcessParameters == NULL) ||
            (Peb->ProcessParameters->ImagePathName.Length == 0))
@@ -421,14 +447,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->ResidentSize = LdrpGetResidentSize(NTHeaders);
+       NTHeaders = RtlImageNtHeader (ExeModule->DllBase);
+       ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
        ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
 
        InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
@@ -443,7 +469,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;
@@ -452,7 +478,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
        if (EntryPoint == NULL)
          {
            DPRINT1("Failed to initialize image\n");
-           ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
+           ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
          }
      }
    /* attach the thread */