We display a revision number (prefix: 'r')
[reactos.git] / reactos / ntoskrnl / ex / init.c
index 75a0ce5..186584a 100644 (file)
 /* INCLUDES ******************************************************************/
 
 #include <ntoskrnl.h>
+#include <reactos/buildno.h>
 #define NDEBUG
 #include <debug.h>
-#include "ntstrsafe.h"
+
+/* Temporary hack */
+BOOLEAN
+NTAPI
+MmArmInitSystem(
+    IN ULONG Phase,
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
 
 typedef struct _INIT_BUFFER
 {
@@ -36,7 +44,7 @@ ULONG NtBuildNumber = VER_PRODUCTBUILD;
 #endif
 
 /* NT System Info */
-ULONG NtGlobalFlag;
+ULONG NtGlobalFlag = 0;
 ULONG ExSuiteMask;
 
 /* Cm Version Info */
@@ -79,6 +87,7 @@ BOOLEAN ExpRealTimeIsUniversal;
 
 NTSTATUS
 NTAPI
+INIT_FUNCTION
 ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     UNICODE_STRING LinkName;
@@ -190,6 +199,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
 ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     LARGE_INTEGER SectionSize;
@@ -201,7 +211,7 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     PLIST_ENTRY ListHead, NextEntry;
     PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
     ULONG NlsTablesEncountered = 0;
-    ULONG NlsTableSizes[3]; /* 3 NLS tables */
+    SIZE_T NlsTableSizes[3] = {0, 0, 0}; /* 3 NLS tables */
 
     /* Check if this is boot-time phase 0 initialization */
     if (!ExpInitializationPhase)
@@ -235,7 +245,7 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
         /* Allocate the a new buffer since loader memory will be freed */
         ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool,
                                                 ExpNlsTableSize,
-                                                'iltR');
+                                                TAG_RTLI);
         if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
 
         /* Copy the codepage data in its new location. */
@@ -288,7 +298,7 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                              NULL,
                              &SectionSize,
                              PAGE_READWRITE,
-                             SEC_COMMIT,
+                             SEC_COMMIT | 0x1,
                              NULL);
     if (!NT_SUCCESS(Status))
     {
@@ -321,10 +331,11 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     }
 
     /* Copy the codepage data in its new location. */
+    ASSERT(SectionBase >= MmSystemRangeStart);
     RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
 
     /* Free the previously allocated buffer and set the new location */
-    ExFreePoolWithTag(ExpNlsTableBase, 'iltR');
+    ExFreePoolWithTag(ExpNlsTableBase, TAG_RTLI);
     ExpNlsTableBase = SectionBase;
 
     /* Initialize the NLS Tables */
@@ -364,6 +375,7 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
 ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
                       OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
                       OUT PCHAR *ProcessEnvironment)
@@ -388,17 +400,16 @@ ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
                                      (PVOID*)&ProcessParams,
                                      0,
                                      &Size,
-                                     MEM_COMMIT,
+                                     MEM_RESERVE | MEM_COMMIT,
                                      PAGE_READWRITE);
     if (!NT_SUCCESS(Status))
     {
         /* Failed, display error */
-        p = InitBuffer->DebugBuffer;
-        _snwprintf(p,
-                   256 * sizeof(WCHAR),
+        _snwprintf(InitBuffer->DebugBuffer,
+                   sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR),
                    L"INIT: Unable to allocate Process Parameters. 0x%lx",
                    Status);
-        RtlInitUnicodeString(&DebugString, p);
+        RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer);
         ZwDisplayString(&DebugString);
 
         /* Bugcheck the system */
@@ -406,8 +417,8 @@ ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
     }
 
     /* Setup the basic header, and give the process the low 1MB to itself */
-    ProcessParams->Length = Size;
-    ProcessParams->MaximumLength = Size;
+    ProcessParams->Length = (ULONG)Size;
+    ProcessParams->MaximumLength = (ULONG)Size;
     ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |
                            RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
 
@@ -417,17 +428,16 @@ ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
                                      &EnvironmentPtr,
                                      0,
                                      &Size,
-                                     MEM_COMMIT,
+                                     MEM_RESERVE | MEM_COMMIT,
                                      PAGE_READWRITE);
     if (!NT_SUCCESS(Status))
     {
         /* Failed, display error */
-        p = InitBuffer->DebugBuffer;
-        _snwprintf(p,
-                   256 * sizeof(WCHAR),
+        _snwprintf(InitBuffer->DebugBuffer,
+                   sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR),
                    L"INIT: Unable to allocate Process Environment. 0x%lx",
                    Status);
-        RtlInitUnicodeString(&DebugString, p);
+        RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer);
         ZwDisplayString(&DebugString);
 
         /* Bugcheck the system */
@@ -548,12 +558,11 @@ ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
     if (!NT_SUCCESS(Status))
     {
         /* Failed, display error */
-        p = InitBuffer->DebugBuffer;
-        _snwprintf(p,
-                   256 * sizeof(WCHAR),
+        _snwprintf(InitBuffer->DebugBuffer,
+                   sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR),
                    L"INIT: Unable to create Session Manager. 0x%lx",
                    Status);
-        RtlInitUnicodeString(&DebugString, p);
+        RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer);
         ZwDisplayString(&DebugString);
 
         /* Bugcheck the system */
@@ -565,12 +574,11 @@ ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
     if (!NT_SUCCESS(Status))
     {
         /* Failed, display error */
-        p = InitBuffer->DebugBuffer;
-        _snwprintf(p,
-                   256 * sizeof(WCHAR),
+        _snwprintf(InitBuffer->DebugBuffer,
+                   sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR),
                    L"INIT: Unable to resume Session Manager. 0x%lx",
                    Status);
-        RtlInitUnicodeString(&DebugString, p);
+        RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer);
         ZwDisplayString(&DebugString);
 
         /* Bugcheck the system */
@@ -584,6 +592,7 @@ ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
 
 ULONG
 NTAPI
+INIT_FUNCTION
 ExComputeTickCountMultiplier(IN ULONG ClockIncrement)
 {
     ULONG MsRemainder = 0, MsIncrement;
@@ -616,6 +625,7 @@ ExComputeTickCountMultiplier(IN ULONG ClockIncrement)
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 ExpInitSystemPhase0(VOID)
 {
     /* Initialize EXRESOURCE Support */
@@ -638,6 +648,7 @@ ExpInitSystemPhase0(VOID)
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 ExpInitSystemPhase1(VOID)
 {
     /* Initialize worker threads */
@@ -647,34 +658,74 @@ ExpInitSystemPhase1(VOID)
     ExpInitializePushLocks();
 
     /* Initialize events and event pairs */
-    ExpInitializeEventImplementation();
-    ExpInitializeEventPairImplementation();
-
-    /* Initialize callbacks */
-    ExpInitializeCallbacks();
-
+    if (ExpInitializeEventImplementation() == FALSE)
+    {
+        DPRINT1("Executive: Event initialization failed\n");
+        return FALSE;
+    }
+    if (ExpInitializeEventPairImplementation() == FALSE)
+    {
+        DPRINT1("Executive: Event Pair initialization failed\n");
+        return FALSE;
+    }
+    
     /* Initialize mutants */
-    ExpInitializeMutantImplementation();
-
+    if (ExpInitializeMutantImplementation() == FALSE)
+    {
+        DPRINT1("Executive: Mutant initialization failed\n");
+        return FALSE;
+    }
+    
+    /* Initialize callbacks */
+    if (ExpInitializeCallbacks() == FALSE)
+    {
+        DPRINT1("Executive: Callback initialization failed\n");
+        return FALSE;
+    }
+    
     /* Initialize semaphores */
-    ExpInitializeSemaphoreImplementation();
-
+    if (ExpInitializeSemaphoreImplementation() == FALSE)
+    {
+        DPRINT1("Executive: Semaphore initialization failed\n");
+        return FALSE;
+    }
+    
     /* Initialize timers */
-    ExpInitializeTimerImplementation();
-
+    if (ExpInitializeTimerImplementation() == FALSE)
+    {
+        DPRINT1("Executive: Timer initialization failed\n");
+        return FALSE;
+    }
+    
     /* Initialize profiling */
-    ExpInitializeProfileImplementation();
-
+    if (ExpInitializeProfileImplementation() == FALSE)
+    {
+        DPRINT1("Executive: Profile initialization failed\n");
+        return FALSE;
+    }
+    
     /* Initialize UUIDs */
     ExpInitUuids();
-
+    
+    /* Initialize keyed events */
+    if (ExpInitializeKeyedEventImplementation() == FALSE)
+    {
+        DPRINT1("Executive: Keyed event initialization failed\n");
+        return FALSE;
+    }
+    
     /* Initialize Win32K */
-    ExpWin32kInit();
+    if (ExpWin32kInit() == FALSE)
+    {
+        DPRINT1("Executive: Win32 initialization failed\n");
+        return FALSE;
+    }
     return TRUE;
 }
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 ExInitSystem(VOID)
 {
     /* Check the initialization phase */
@@ -700,6 +751,7 @@ ExInitSystem(VOID)
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     PLOADER_PARAMETER_EXTENSION Extension;
@@ -725,6 +777,7 @@ ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
 ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     ULONG i = 0;
@@ -732,9 +785,9 @@ ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
     ULONG Count, Length;
     PWCHAR Name;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
-    BOOLEAN OverFlow = FALSE;
     CHAR NameBuffer[256];
     STRING SymbolString;
+    NTSTATUS Status;
 
     /* Loop the driver list */
     NextEntry = LoaderBlock->LoadOrderListHead.Flink;
@@ -757,7 +810,7 @@ ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
                 if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL))
                 {
                     /* It's too long */
-                    OverFlow = TRUE;
+                    Status = STATUS_BUFFER_OVERFLOW;
                 }
                 else
                 {
@@ -771,33 +824,21 @@ ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
                     /* Null-terminate */
                     NameBuffer[Count] = ANSI_NULL;
+                    Status = STATUS_SUCCESS;
                 }
             }
             else
             {
-                /* This should be a driver, check if it fits */
-                if (sizeof(NameBuffer) <
-                    (sizeof("\\System32\\Drivers\\") +
-                     NtSystemRoot.Length / sizeof(WCHAR) - sizeof(UNICODE_NULL) +
-                     LdrEntry->BaseDllName.Length / sizeof(WCHAR) +
-                     sizeof(ANSI_NULL)))
-                {
-                    /* Buffer too small */
-                    OverFlow = TRUE;
-                    while (TRUE);
-                }
-                else
-                {
-                    /* Otherwise build the name. HACKED for GCC :( */
-                    sprintf(NameBuffer,
-                            "%S\\System32\\Drivers\\%S",
-                            &SharedUserData->NtSystemRoot[2],
-                            LdrEntry->BaseDllName.Buffer);
-                }
+                /* Safely print the string into our buffer */
+                Status = RtlStringCbPrintfA(NameBuffer,
+                                            sizeof(NameBuffer),
+                                            "%S\\System32\\Drivers\\%wZ",
+                                            &SharedUserData->NtSystemRoot[2],
+                                            &LdrEntry->BaseDllName);
             }
 
             /* Check if the buffer was ok */
-            if (!OverFlow)
+            if (NT_SUCCESS(Status))
             {
                 /* Initialize the STRING for the debugger */
                 RtlInitString(&SymbolString, NameBuffer);
@@ -817,6 +858,53 @@ ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
 VOID
 NTAPI
+INIT_FUNCTION
+ExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+             IN ULONG_PTR PagesToDestroy,
+             IN TYPE_OF_MEMORY MemoryType)
+{
+    PLIST_ENTRY ListEntry;
+    PMEMORY_ALLOCATION_DESCRIPTOR MemDescriptor;
+
+    DPRINT1("Burn RAM amount: %d pages\n", PagesToDestroy);
+
+    /* Loop the memory descriptors, beginning at the end */
+    for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Blink;
+         ListEntry != &LoaderBlock->MemoryDescriptorListHead;
+         ListEntry = ListEntry->Blink)
+    {
+        /* Get the memory descriptor structure */
+        MemDescriptor = CONTAINING_RECORD(ListEntry,
+                                          MEMORY_ALLOCATION_DESCRIPTOR,
+                                          ListEntry);
+
+        /* Is memory free there or is it temporary? */
+        if (MemDescriptor->MemoryType == LoaderFree ||
+            MemDescriptor->MemoryType == LoaderFirmwareTemporary)
+        {
+            /* Check if the descriptor has more pages than we want */
+            if (MemDescriptor->PageCount > PagesToDestroy)
+            {
+                /* Change block's page count, ntoskrnl doesn't care much */
+                MemDescriptor->PageCount -= PagesToDestroy;
+                break;
+            }
+            else
+            {
+                /* Change block type */
+                MemDescriptor->MemoryType = MemoryType;
+                PagesToDestroy -= MemDescriptor->PageCount;
+
+                /* Check if we are done */
+                if (PagesToDestroy == 0) break;
+            }
+        }
+    }
+}
+
+VOID
+NTAPI
+INIT_FUNCTION
 ExpInitializeExecutive(IN ULONG Cpu,
                        IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
@@ -829,7 +917,7 @@ ExpInitializeExecutive(IN ULONG Cpu,
     PLDR_DATA_TABLE_ENTRY NtosEntry;
     PMESSAGE_RESOURCE_ENTRY MsgEntry;
     ANSI_STRING CsdString;
-    SIZE_T Remaining = 0;
+    size_t Remaining = 0;
     PCHAR RcEnd = NULL;
     CHAR VersionBuffer [65];
 
@@ -919,12 +1007,7 @@ ExpInitializeExecutive(IN ULONG Cpu,
             {
                 /* Read the number of pages we'll use */
                 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE);
-                if (PerfMem)
-                {
-                    /* FIXME: TODO */
-                    DPRINT1("Burnable memory support not yet present."
-                            "/BURNMEM option ignored.\n");
-                }
+                if (PerfMemUsed) ExBurnMemory(LoaderBlock, PerfMemUsed, LoaderBad);
             }
         }
     }
@@ -933,10 +1016,10 @@ ExpInitializeExecutive(IN ULONG Cpu,
     NlsData = LoaderBlock->NlsData;
     ExpNlsTableBase = NlsData->AnsiCodePageData;
     ExpAnsiCodePageDataOffset = 0;
-    ExpOemCodePageDataOffset = ((ULONG_PTR)NlsData->OemCodePageData -
-                                (ULONG_PTR)NlsData->AnsiCodePageData);
-    ExpUnicodeCaseTableDataOffset = ((ULONG_PTR)NlsData->UnicodeCodePageData -
-                                     (ULONG_PTR)NlsData->AnsiCodePageData);
+    ExpOemCodePageDataOffset = (ULONG)((ULONG_PTR)NlsData->OemCodePageData -
+                                       (ULONG_PTR)NlsData->AnsiCodePageData);
+    ExpUnicodeCaseTableDataOffset = (ULONG)((ULONG_PTR)NlsData->UnicodeCodePageData -
+                                            (ULONG_PTR)NlsData->AnsiCodePageData);
 
     /* Initialize the NLS Tables */
     RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
@@ -990,22 +1073,26 @@ ExpInitializeExecutive(IN ULONG Cpu,
     CmGetSystemControlValues(LoaderBlock->RegistryBase, CmControlVector);
 
     /* Load static defaults for Service Pack 1 and add our SVN revision */
+    /* Format of CSD : SPMajor - SPMinor */
     CmNtCSDVersion = 0x100 | (KERNEL_VERSION_BUILD_HEX << 16);
     CmNtCSDReleaseType = 0;
 
     /* Set Service Pack data for Service Pack 1 */
-    CmNtSpBuildNumber = 1830;
+    CmNtSpBuildNumber = VER_PRODUCTBUILD_QFE;
     if (!(CmNtCSDVersion & 0xFFFF0000))
     {
         /* Check the release type */
-        if (CmNtCSDReleaseType == 1) CmNtSpBuildNumber |= 1830 << 16;
+        if (CmNtCSDReleaseType == 1) CmNtSpBuildNumber |= VER_PRODUCTBUILD_QFE << 16;
     }
 
+    /* Add loaded CmNtGlobalFlag value */
+    NtGlobalFlag |= CmNtGlobalFlag;
+
     /* Initialize the executive at phase 0 */
     if (!ExInitSystem()) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
 
     /* Initialize the memory manager at phase 0 */
-    if (!MmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
+    if (!MmArmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
 
     /* Load boot symbols */
     ExpLoadBootSymbols(LoaderBlock);
@@ -1021,8 +1108,13 @@ ExpInitializeExecutive(IN ULONG Cpu,
     }
 
     /* Set system ranges */
+#ifdef _M_AMD64
+    SharedUserData->Reserved1 = MM_HIGHEST_USER_ADDRESS_WOW64;
+    SharedUserData->Reserved3 = MM_SYSTEM_RANGE_START_WOW64;
+#else
     SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress;
     SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart;
+#endif
 
     /* Make a copy of the NLS Tables */
     ExpInitNls(LoaderBlock);
@@ -1129,7 +1221,7 @@ ExpInitializeExecutive(IN ULONG Cpu,
         /* Add the version format string */
         Status = RtlStringCbPrintfA(RcEnd,
                                     Remaining,
-                                    "v. %u",
+                                    "r%u",
                                     (CmNtCSDVersion & 0xFFFF0000) >> 16);
         if (!NT_SUCCESS(Status))
         {
@@ -1226,14 +1318,17 @@ ExpInitializeExecutive(IN ULONG Cpu,
     SharedUserData->NtMinorVersion = NtMinorVersion;
 
     /* Set the machine type */
-    SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_ARCHITECTURE;
-    SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_ARCHITECTURE;
+    SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_NATIVE;
+    SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_NATIVE;
 }
 
-extern BOOLEAN AllowPagedPool;
+VOID
+NTAPI
+MmFreeLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
 
 VOID
 NTAPI
+INIT_FUNCTION
 Phase1InitializationDiscard(IN PVOID Context)
 {
     PLOADER_PARAMETER_BLOCK LoaderBlock = Context;
@@ -1249,9 +1344,10 @@ Phase1InitializationDiscard(IN PVOID Context)
     ANSI_STRING TempString;
     ULONG LastTzBias, Length, YearHack = 0, Disposition, MessageCode = 0;
     SIZE_T Size;
+    size_t Remaining;
     PRTL_USER_PROCESS_INFORMATION ProcessInfo;
     KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo;
-    UNICODE_STRING KeyName, DebugString;
+    UNICODE_STRING KeyName;
     OBJECT_ATTRIBUTES ObjectAttributes;
     HANDLE KeyHandle, OptionHandle;
     PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
@@ -1259,7 +1355,7 @@ Phase1InitializationDiscard(IN PVOID Context)
     /* Allocate the initialization buffer */
     InitBuffer = ExAllocatePoolWithTag(NonPagedPool,
                                        sizeof(INIT_BUFFER),
-                                       'tinI');
+                                       TAG_INIT);
     if (!InitBuffer)
     {
         /* Bugcheck */
@@ -1328,14 +1424,14 @@ Phase1InitializationDiscard(IN PVOID Context)
     StringBuffer = InitBuffer->VersionBuffer;
     BeginBuffer = StringBuffer;
     EndBuffer = StringBuffer;
-    Size = 256;
+    Remaining = sizeof(InitBuffer->VersionBuffer);
     if (CmCSDVersionString.Length)
     {
         /* Print the version string */
         Status = RtlStringCbPrintfExA(StringBuffer,
-                                      255,
+                                      Remaining,
                                       &EndBuffer,
-                                      &Size,
+                                      &Remaining,
                                       0,
                                       ": %wZ",
                                       &CmCSDVersionString);
@@ -1348,16 +1444,17 @@ Phase1InitializationDiscard(IN PVOID Context)
     else
     {
         /* No version */
-        Size = 255;
+        *EndBuffer = ANSI_NULL; /* Null-terminate the string */
     }
 
-    /* Null-terminate the string */
-    *EndBuffer++ = ANSI_NULL;
+    /* Skip over the null-terminator to start a new string */
+    ++EndBuffer;
+    --Remaining;
 
     /* Build the version number */
     StringBuffer = InitBuffer->VersionNumber;
     Status = RtlStringCbPrintfA(StringBuffer,
-                                24,
+                                sizeof(InitBuffer->VersionNumber),
                                 "%u.%u",
                                 VER_PRODUCTMAJORVERSION,
                                 VER_PRODUCTMINORVERSION);
@@ -1372,7 +1469,7 @@ Phase1InitializationDiscard(IN PVOID Context)
     {
         /* Create the banner message */
         Status = RtlStringCbPrintfA(EndBuffer,
-                                    Size,
+                                    Remaining,
                                     (PCHAR)MsgEntry->Text,
                                     StringBuffer,
                                     NtBuildNumber & 0xFFFF,
@@ -1386,7 +1483,7 @@ Phase1InitializationDiscard(IN PVOID Context)
     else
     {
         /* Use hard-coded banner message */
-        Status = RtlStringCbCopyA(EndBuffer, Size, "REACTOS (R)\n");
+        Status = RtlStringCbCopyA(EndBuffer, Remaining, "REACTOS (R)\n");
         if (!NT_SUCCESS(Status))
         {
             /* Bugcheck */
@@ -1486,7 +1583,7 @@ Phase1InitializationDiscard(IN PVOID Context)
     /* Create the string */
     StringBuffer = InitBuffer->VersionBuffer;
     Status = RtlStringCbPrintfA(StringBuffer,
-                                256,
+                                sizeof(InitBuffer->VersionBuffer),
                                 NT_SUCCESS(MsgStatus) ?
                                 (PCHAR)MsgEntry->Text :
                                 "%u System Processor [%u MB Memory] %Z\n",
@@ -1539,7 +1636,7 @@ Phase1InitializationDiscard(IN PVOID Context)
     if (!MmInitSystem(1, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED);
 
     /* Create NLS section */
-    ExpInitNls(KeLoaderBlock);
+    ExpInitNls(LoaderBlock);
 
     /* Initialize Cache Views */
     if (!CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED);
@@ -1729,7 +1826,10 @@ Phase1InitializationDiscard(IN PVOID Context)
                                          &KeyPartialInfo,
                                          sizeof(KeyPartialInfo),
                                          &Length);
-                if (!NT_SUCCESS(Status)) AlternateShell = FALSE;
+                if (!(NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW))
+                {
+                    AlternateShell = FALSE;
+                }
             }
 
             /* Create the option key */
@@ -1824,8 +1924,8 @@ Phase1InitializationDiscard(IN PVOID Context)
         NtClose(OptionHandle);
     }
 
-    /* Unmap Low memory, and initialize the MPW and Balancer Thread */
-    MmInitSystem(2, LoaderBlock);
+    /* FIXME: This doesn't do anything for now */
+    MmArmInitSystem(2, LoaderBlock);
 
     /* Update progress bar */
     InbvUpdateProgressBar(80);
@@ -1838,41 +1938,35 @@ Phase1InitializationDiscard(IN PVOID Context)
     /* Initialize Power Subsystem in Phase 1*/
     if (!PoInitSystem(1)) KeBugCheck(INTERNAL_POWER_ERROR);
 
+    /* Update progress bar */
+    InbvUpdateProgressBar(90);
+
     /* Initialize the Process Manager at Phase 1 */
     if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
 
-    /* Update progress bar */
-    InbvUpdateProgressBar(85);
-
     /* Make sure nobody touches the loader block again */
     if (LoaderBlock == KeLoaderBlock) KeLoaderBlock = NULL;
+    MmFreeLoaderBlock(LoaderBlock);
     LoaderBlock = Context = NULL;
 
-    /* Update progress bar */
-    InbvUpdateProgressBar(90);
-
-    /* Launch initial process */
-    ProcessInfo = &InitBuffer->ProcessInfo;
-    ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);
-
     /* Update progress bar */
     InbvUpdateProgressBar(100);
 
     /* Allow strings to be displayed */
     InbvEnableDisplayString(TRUE);
 
-    /* Enough fun for now */
-    AllowPagedPool = FALSE;
+    /* Launch initial process */
+    DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
+    ProcessInfo = &InitBuffer->ProcessInfo;
+    ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);
 
-    /* Wait 5 seconds for it to initialize */
+    /* Wait 5 seconds for initial process to initialize */
     Timeout.QuadPart = Int32x32To64(5, -10000000);
     Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout);
-    if (InbvBootDriverInstalled) FinalizeBootLogo();
     if (Status == STATUS_SUCCESS)
     {
         /* Failed, display error */
-        RtlInitUnicodeString(&DebugString, L"INIT: Session Manager terminated.");
-        ZwDisplayString(&DebugString);
+        DPRINT1("INIT: Session Manager terminated.\n");
 
         /* Bugcheck the system if SMSS couldn't initialize */
         KeBugCheck(SESSION5_INITIALIZATION_FAILED);
@@ -1896,11 +1990,15 @@ Phase1InitializationDiscard(IN PVOID Context)
                         &Size,
                         MEM_RELEASE);
 
+    /* Clean the screen */
+    if (InbvBootDriverInstalled) FinalizeBootLogo();
+
     /* Increase init phase */
     ExpInitializationPhase++;
 
     /* Free the boot buffer */
-    ExFreePool(InitBuffer);
+    ExFreePoolWithTag(InitBuffer, TAG_INIT);
+    DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
 }
 
 VOID
@@ -1911,5 +2009,5 @@ Phase1Initialization(IN PVOID Context)
     Phase1InitializationDiscard(Context);
 
     /* Jump into zero page thread */
-    MmZeroPageThreadMain(NULL);
+    MmZeroPageThread();
 }