[ros-diffs] [ion] 26659: - Added more improvements/fixes to the Executive Initialization code: - We now print out error messages at each SESSIONX_INITIALIZATION_FAILURE directly on the screen. - Build CmNtCSDVersion to include SP1 and our SVN Revision number. - Build CmNtSpBuildNumber with the actual SP1 build number. - Detect Headless Terminal usage. - Build and create the CmVersionString. - Display a startup banner similar to Windows based on the CmVersionString, also indicating the SVN revision. - Fix some bugs in the timezone code. - Display a second startup banner like Windows's, displaying memory and CPU counts. - Add calls to initialize RANGE_LISTs, the Prefetecher, XIP Support and Phase 2 Executive Initialization. - Parse the command line to detect /SAFEBOOT: switch and which type of safe mode boot this is. - Display an optional third startup banner showing which safemode boot type this is. - Detect /BOOTLOG switch and display a fourth startup banner if it's enabled, but don't initialize boot logging yet. - Don't allow driver loading to push the progress bar beyond 75%. - Write safe-boot type to registry, detect AlternateShell mode and validate that one is configured. - Write MININT key to registry if booting in WinPE (LiveCD) mode. - Don't leak smss environment and parameters anymore. - Cleanup and reformat some code, use VER_ constants instead of magic numbers.

ion at svn.reactos.org ion at svn.reactos.org
Wed May 9 02:44:45 CEST 2007


Author: ion
Date: Wed May  9 04:44:45 2007
New Revision: 26659

URL: http://svn.reactos.org/svn/reactos?rev=26659&view=rev
Log:
- Added more improvements/fixes to the Executive Initialization code:
  - We now print out error messages at each SESSIONX_INITIALIZATION_FAILURE directly on the screen.
  - Build CmNtCSDVersion to include SP1 and our SVN Revision number.
  - Build CmNtSpBuildNumber with the actual SP1 build number.
  - Detect Headless Terminal usage.
  - Build and create the CmVersionString.
  - Display a startup banner similar to Windows based on the CmVersionString, also indicating the SVN revision.
  - Fix some bugs in the timezone code.
  - Display a second startup banner like Windows's, displaying memory and CPU counts.
  - Add calls to initialize RANGE_LISTs, the Prefetecher, XIP Support and Phase 2 Executive Initialization.
  - Parse the command line to detect /SAFEBOOT: switch and which type of safe mode boot this is.
  - Display an optional third startup banner showing which safemode boot type this is.
  - Detect /BOOTLOG switch and display a fourth startup banner if it's enabled, but don't initialize boot logging yet.
  - Don't allow driver loading to push the progress bar beyond 75%.
  - Write safe-boot type to registry, detect AlternateShell mode and validate that one is configured.
  - Write MININT key to registry if booting in WinPE (LiveCD) mode.
  - Don't leak smss environment and parameters anymore.
  - Cleanup and reformat some code, use VER_ constants instead of magic numbers.

Modified:
    trunk/reactos/ntoskrnl/ex/init.c
    trunk/reactos/ntoskrnl/include/internal/rtl.h
    trunk/reactos/ntoskrnl/rtl/libsupp.c

Modified: trunk/reactos/ntoskrnl/ex/init.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=26659&r1=26658&r2=26659&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ex/init.c (original)
+++ trunk/reactos/ntoskrnl/ex/init.c Wed May  9 04:44:45 2007
@@ -14,7 +14,18 @@
 #include <debug.h>
 //#include <ntoskrnl/cm/newcm.h>
 #include "ntoskrnl/cm/cm.h"
-#include <ntverp.h>
+#include "ntverp.h"
+#include "ntstrsafe.h"
+
+typedef struct _INIT_BUFFER
+{
+    WCHAR DebugBuffer[256];
+    CHAR VersionBuffer[256];
+    CHAR BootlogHeader[256];
+    CHAR VersionNumber[24];
+    RTL_USER_PROCESS_INFORMATION ProcessInfo;
+    WCHAR RegistryBuffer[256];
+} INIT_BUFFER, *PINIT_BUFFER;
 
 /* DATA **********************************************************************/
 
@@ -65,6 +76,7 @@
 
 /* CMOS Timer Sanity */
 BOOLEAN ExCmosClockIsSane = TRUE;
+BOOLEAN ExpRealTimeIsUniversal;
 
 /* FUNCTIONS ****************************************************************/
 
@@ -347,38 +359,52 @@
     ExpNlsTableBase = SectionBase;
 }
 
-NTSTATUS
+VOID
 NTAPI
-ExpLoadInitialProcess(IN OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation)
+ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
+                      OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
+                      OUT PCHAR *ProcessEnvironment)
 {
-    PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
     NTSTATUS Status;
     ULONG Size;
     PWSTR p;
     UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
-    UNICODE_STRING SmssName, Environment, SystemDriveString;
+    UNICODE_STRING SmssName, Environment, SystemDriveString, DebugString;
     PVOID EnvironmentPtr = NULL;
+    PRTL_USER_PROCESS_INFORMATION ProcessInformation;
+    PRTL_USER_PROCESS_PARAMETERS ProcessParams = NULL;
+
+    /* Use the initial buffer, after the strings */
+    ProcessInformation = &InitBuffer->ProcessInfo;
 
     /* Allocate memory for the process parameters */
-    Size = sizeof(RTL_USER_PROCESS_PARAMETERS) +
-           ((MAX_PATH * 6) * sizeof(WCHAR));
+    Size = sizeof(*ProcessParams) + ((MAX_PATH * 6) * sizeof(WCHAR));
     Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
-                                     (PVOID)&ProcessParameters,
+                                     (PVOID*)&ProcessParams,
                                      0,
                                      &Size,
                                      MEM_COMMIT,
                                      PAGE_READWRITE);
     if (!NT_SUCCESS(Status))
     {
-        /* Failed */
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to allocate Process Parameters. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
         KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0);
     }
 
     /* Setup the basic header, and give the process the low 1MB to itself */
-    ProcessParameters->Length = Size;
-    ProcessParameters->MaximumLength = Size;
-    ProcessParameters->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |
-                               RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
+    ProcessParams->Length = Size;
+    ProcessParams->MaximumLength = Size;
+    ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |
+                           RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
 
     /* Allocate a page for the environment */
     Size = PAGE_SIZE;
@@ -390,39 +416,48 @@
                                      PAGE_READWRITE);
     if (!NT_SUCCESS(Status))
     {
-        /* Failed */
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to allocate Process Environment. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
         KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);
     }
 
     /* Write the pointer */
-    ProcessParameters->Environment = EnvironmentPtr;
+    ProcessParams->Environment = EnvironmentPtr;
 
     /* Make a buffer for the DOS path */
-    p = (PWSTR)(ProcessParameters + 1);
-    ProcessParameters->CurrentDirectory.DosPath.Buffer = p;
-    ProcessParameters->
-        CurrentDirectory.DosPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+    p = (PWSTR)(ProcessParams + 1);
+    ProcessParams->CurrentDirectory.DosPath.Buffer = p;
+    ProcessParams->CurrentDirectory.DosPath.MaximumLength = MAX_PATH *
+                                                            sizeof(WCHAR);
 
     /* Copy the DOS path */
-    RtlCopyUnicodeString(&ProcessParameters->CurrentDirectory.DosPath,
+    RtlCopyUnicodeString(&ProcessParams->CurrentDirectory.DosPath,
                          &NtSystemRoot);
 
     /* Make a buffer for the DLL Path */
-    p = (PWSTR)((PCHAR)ProcessParameters->CurrentDirectory.DosPath.Buffer +
-                ProcessParameters->CurrentDirectory.DosPath.MaximumLength);
-    ProcessParameters->DllPath.Buffer = p;
-    ProcessParameters->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+    p = (PWSTR)((PCHAR)ProcessParams->CurrentDirectory.DosPath.Buffer +
+                ProcessParams->CurrentDirectory.DosPath.MaximumLength);
+    ProcessParams->DllPath.Buffer = p;
+    ProcessParams->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
 
     /* Copy the DLL path and append the system32 directory */
-    RtlCopyUnicodeString(&ProcessParameters->DllPath,
-                         &ProcessParameters->CurrentDirectory.DosPath);
-    RtlAppendUnicodeToString(&ProcessParameters->DllPath, L"\\System32");
+    RtlCopyUnicodeString(&ProcessParams->DllPath,
+                         &ProcessParams->CurrentDirectory.DosPath);
+    RtlAppendUnicodeToString(&ProcessParams->DllPath, L"\\System32");
 
     /* Make a buffer for the image name */
-    p = (PWSTR)((PCHAR)ProcessParameters->DllPath.Buffer +
-                ProcessParameters->DllPath.MaximumLength);
-    ProcessParameters->ImagePathName.Buffer = p;
-    ProcessParameters->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
+    p = (PWSTR)((PCHAR)ProcessParams->DllPath.Buffer +
+                ProcessParams->DllPath.MaximumLength);
+    ProcessParams->ImagePathName.Buffer = p;
+    ProcessParams->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
 
     /* Make sure the buffer is a valid string which within the given length */
     if ((NtInitialUserProcessBufferType != REG_SZ) ||
@@ -433,7 +468,7 @@
     {
         /* Invalid initial process string, bugcheck */
         KeBugCheckEx(SESSION2_INITIALIZATION_FAILED,
-                     (ULONG_PTR)STATUS_INVALID_PARAMETER,
+                     STATUS_INVALID_PARAMETER,
                      NtInitialUserProcessBufferType,
                      NtInitialUserProcessBufferLength,
                      sizeof(NtInitialUserProcessBuffer));
@@ -441,41 +476,40 @@
 
     /* Cut out anything after a space */
     p = NtInitialUserProcessBuffer;
-    while (*p && *p != L' ') p++;
+    while ((*p) && (*p != L' ')) p++;
 
     /* Set the image path length */
-    ProcessParameters->ImagePathName.Length =
+    ProcessParams->ImagePathName.Length =
         (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer);
 
     /* Copy the actual buffer */
-    RtlCopyMemory(ProcessParameters->ImagePathName.Buffer,
+    RtlCopyMemory(ProcessParams->ImagePathName.Buffer,
                   NtInitialUserProcessBuffer,
-                  ProcessParameters->ImagePathName.Length);
+                  ProcessParams->ImagePathName.Length);
 
     /* Null-terminate it */
-    ProcessParameters->
-        ImagePathName.Buffer[ProcessParameters->ImagePathName.Length /
-                             sizeof(WCHAR)] = UNICODE_NULL;
+    ProcessParams->ImagePathName.Buffer[ProcessParams->ImagePathName.Length /
+                                        sizeof(WCHAR)] = UNICODE_NULL;
 
     /* Make a buffer for the command line */
-    p = (PWSTR)((PCHAR)ProcessParameters->ImagePathName.Buffer +
-                ProcessParameters->ImagePathName.MaximumLength);
-    ProcessParameters->CommandLine.Buffer = p;
-    ProcessParameters->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR);
+    p = (PWSTR)((PCHAR)ProcessParams->ImagePathName.Buffer +
+                ProcessParams->ImagePathName.MaximumLength);
+    ProcessParams->CommandLine.Buffer = p;
+    ProcessParams->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR);
 
     /* Add the image name to the command line */
-    RtlAppendUnicodeToString(&ProcessParameters->CommandLine,
+    RtlAppendUnicodeToString(&ProcessParams->CommandLine,
                              NtInitialUserProcessBuffer);
 
     /* Create the environment string */
     RtlInitEmptyUnicodeString(&Environment,
-                              ProcessParameters->Environment,
+                              ProcessParams->Environment,
                               (USHORT)Size);
 
     /* Append the DLL path to it */
     RtlAppendUnicodeToString(&Environment, L"Path=" );
-    RtlAppendUnicodeStringToString(&Environment, &ProcessParameters->DllPath);
-    RtlAppendUnicodeStringToString(&Environment, &NullString );
+    RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath);
+    RtlAppendUnicodeStringToString(&Environment, &NullString);
 
     /* Create the system drive string */
     SystemDriveString = NtSystemRoot;
@@ -491,12 +525,14 @@
     RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
     RtlAppendUnicodeStringToString(&Environment, &NullString);
 
+    /* Prepare the prefetcher */
+    //CcPfBeginBootPhase(150);
+
     /* Create SMSS process */
-    SmssName = ProcessParameters->ImagePathName;
+    SmssName = ProcessParams->ImagePathName;
     Status = RtlCreateUserProcess(&SmssName,
                                   OBJ_CASE_INSENSITIVE,
-                                  RtlDeNormalizeProcessParams(
-                                  ProcessParameters),
+                                  RtlDeNormalizeProcessParams(ProcessParams),
                                   NULL,
                                   NULL,
                                   NULL,
@@ -506,7 +542,16 @@
                                   ProcessInformation);
     if (!NT_SUCCESS(Status))
     {
-        /* Failed */
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to create Session Manager. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
         KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0);
     }
 
@@ -514,12 +559,22 @@
     Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL);
     if (!NT_SUCCESS(Status))
     {
-        /* Failed */
+        /* Failed, display error */
+        p = InitBuffer->DebugBuffer;
+        _snwprintf(p,
+                   256 * sizeof(WCHAR),
+                   L"INIT: Unable to resume Session Manager. 0x%lx",
+                   Status);
+        RtlInitUnicodeString(&DebugString, p);
+        ZwDisplayString(&DebugString);
+
+        /* Bugcheck the system */
         KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
     }
 
     /* Return success */
-    return STATUS_SUCCESS;
+    *ProcessParameters = ProcessParams;
+    *ProcessEnvironment = EnvironmentPtr;
 }
 
 ULONG
@@ -651,13 +706,13 @@
     if (Extension->Size < sizeof(LOADER_PARAMETER_EXTENSION)) return FALSE;
 
     /* Don't validate upper versions */
-    if (Extension->MajorVersion > 5) return TRUE;
+    if (Extension->MajorVersion > VER_PRODUCTMAJORVERSION) return TRUE;
 
     /* Fail if this is NT 4 */
-    if (Extension->MajorVersion < 5) return FALSE;
+    if (Extension->MajorVersion < VER_PRODUCTMAJORVERSION) return FALSE;
 
     /* Fail if this is XP */
-    if (Extension->MinorVersion < 2) return FALSE;
+    if (Extension->MinorVersion < VER_PRODUCTMINORVERSION) return FALSE;
 
     /* This is 2003 or newer, approve it */
     return TRUE;
@@ -766,6 +821,12 @@
     NTSTATUS Status;
     PCHAR CommandLine, PerfMem;
     ULONG PerfMemUsed;
+    PLDR_DATA_TABLE_ENTRY NtosEntry;
+    PRTL_MESSAGE_RESOURCE_ENTRY MsgEntry;
+    ANSI_STRING CsdString;
+    ULONG Remaining = 0;
+    PCHAR RcEnd = NULL;
+    CHAR VersionBuffer [65];
 
     /* Validate Loader */
     if (!ExpIsLoaderValid(LoaderBlock))
@@ -905,7 +966,7 @@
     sprintf(Buffer, "C:%s", LoaderBlock->NtBootPathName);
 
     /* Convert to ANSI_STRING and null-terminate it */
-    RtlInitString(&AnsiPath, Buffer );
+    RtlInitString(&AnsiPath, Buffer);
     Buffer[--AnsiPath.Length] = ANSI_NULL;
 
     /* Get the string from KUSER_SHARED_DATA's buffer */
@@ -923,17 +984,36 @@
     /* Setup initial system settings (FIXME: Needs Cm Rewrite) */
     CmGetSystemControlValues(LoaderBlock->RegistryBase, CmControlVector);
 
+    /* Load static defaults for Service Pack 1 and add our SVN revision */
+    CmNtCSDVersion = 0x100 | (KERNEL_VERSION_BUILD_HEX << 16);
+    CmNtCSDReleaseType = 0;
+
+    /* Set Service Pack data for Service Pack 1 */
+    CmNtSpBuildNumber = 1830;
+    if (!(CmNtCSDVersion & 0xFFFF0000))
+    {
+        /* Check the release type */
+        if (CmNtCSDReleaseType == 1) CmNtSpBuildNumber |= 1830 << 16;
+    }
+
     /* Initialize the executive at phase 0 */
     if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED);
 
     /* Initialize the memory manager at phase 0 */
-    if (!MmInitSystem(0, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED);
+    if (!MmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
 
     /* Load boot symbols */
     ExpLoadBootSymbols(LoaderBlock);
 
     /* Check if we should break after symbol load */
     if (KdBreakAfterSymbolLoad) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
+
+    /* Check if this loader is compatible with NT 5.2 */
+    if (LoaderBlock->Extension->Size >= sizeof(LOADER_PARAMETER_EXTENSION))
+    {
+        /* Setup headless terminal settings */
+        HeadlessInit(LoaderBlock);
+    }
 
     /* Set system ranges */
     SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress;
@@ -941,6 +1021,133 @@
 
     /* Make a copy of the NLS Tables */
     ExpInitNls(LoaderBlock);
+
+    /* Get the kernel's load entry */
+    NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink,
+                                  LDR_DATA_TABLE_ENTRY,
+                                  InLoadOrderLinks);
+
+    /* Check if this is a service pack */
+    if (CmNtCSDVersion & 0xFFFF)
+    {
+        /* Get the service pack string */
+        Status = RtlFindMessage(NtosEntry->DllBase,
+                                11,
+                                0,
+                                WINDOWS_NT_CSD_STRING,
+                                &MsgEntry);
+        if (NT_SUCCESS(Status))
+        {
+            /* Setup the string */
+            RtlInitAnsiString(&CsdString, MsgEntry->Text);
+            CsdString.Length -= sizeof(UNICODE_NULL);
+            Status = RtlStringCbPrintfA(Buffer,
+                                        sizeof(Buffer),
+                                        "%Z %u%c",
+                                        &CsdString,
+                                        (CmNtCSDVersion & 0xFF00) >> 8,
+                                        (CmNtCSDVersion & 0xFF) ?
+                                        'A' + (CmNtCSDVersion & 0xFF) - 1 :
+                                        ANSI_NULL);
+        }
+        else
+        {
+            /* Build default string */
+            Status = RtlStringCbPrintfA(Buffer,
+                                        sizeof(Buffer),
+                                        "CSD %04x",
+                                        CmNtCSDVersion);
+        }
+
+        /* Check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* Fail */
+            KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        }
+    }
+    else
+    {
+        /* Then this is a beta */
+        Status = RtlStringCbCopyExA(Buffer,
+                                    sizeof(Buffer),
+                                    VER_PRODUCTBETA_STR,
+                                    NULL,
+                                    &Remaining,
+                                    0);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Fail */
+            KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        }
+
+        /* Update length */
+        CmCSDVersionString.MaximumLength = sizeof(Buffer) - Remaining;
+    }
+
+    /* Check if we have an RC number */
+    if (CmNtCSDVersion & 0xFFFF0000)
+    {
+        /* Check if we have no version data yet */
+        if (!(*Buffer))
+        {
+            /* Set defaults */
+            Remaining = sizeof(Buffer);
+            RcEnd = Buffer;
+        }
+        else
+        {
+            /* Add comma and space */
+            Status = RtlStringCbCatExA(Buffer,
+                                       sizeof(Buffer),
+                                       ", ",
+                                       &RcEnd,
+                                       &Remaining,
+                                       0);
+            if (!NT_SUCCESS(Status))
+            {
+                /* Fail */
+                KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0);
+            }
+        }
+
+        /* Add the version format string */
+        Status = RtlStringCbPrintfA(RcEnd,
+                                    Remaining,
+                                    "v. %u",
+                                    (CmNtCSDVersion & 0xFFFF0000) >> 16);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Fail */
+            KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        }
+    }
+
+    /* Now setup the final string */
+    RtlInitAnsiString(&CsdString, Buffer);
+    Status = RtlAnsiStringToUnicodeString(&CmCSDVersionString,
+                                          &CsdString,
+                                          TRUE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    /* Add our version */
+    Status = RtlStringCbPrintfA(VersionBuffer,
+                                sizeof(VersionBuffer),
+                                "%u.%u",
+                                VER_PRODUCTMAJORVERSION,
+                                VER_PRODUCTMINORVERSION);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    /* Build the final version string */
+    RtlCreateUnicodeStringFromAsciiz(&CmVersionString, VersionBuffer);
 
     /* Check if the user wants a kernel stack trace database */
     if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB)
@@ -1020,23 +1227,32 @@
 
 VOID
 NTAPI
-Phase1InitializationDiscard(PVOID Context)
+Phase1InitializationDiscard(IN PVOID Context)
 {
     PLOADER_PARAMETER_BLOCK LoaderBlock = Context;
-    PCHAR CommandLine, Y2KHackRequired;
-    LARGE_INTEGER Timeout;
-    NTSTATUS Status;
+    NTSTATUS Status, MsgStatus;
     TIME_FIELDS TimeFields;
-    LARGE_INTEGER SystemBootTime, UniversalBootTime, OldTime;
+    LARGE_INTEGER SystemBootTime, UniversalBootTime, OldTime, Timeout;
+    BOOLEAN SosEnabled, NoGuiBoot, ResetBias = FALSE, AlternateShell = FALSE;
+    PLDR_DATA_TABLE_ENTRY NtosEntry;
+    PRTL_MESSAGE_RESOURCE_ENTRY MsgEntry;
+    PCHAR CommandLine, Y2KHackRequired, SafeBoot, Environment;
+    PCHAR StringBuffer, EndBuffer, BeginBuffer, MpString = "";
+    PINIT_BUFFER InitBuffer;
+    ANSI_STRING TempString;
+    ULONG LastTzBias, Size, Length, YearHack = 0, Disposition, MessageCode = 0;
     PRTL_USER_PROCESS_INFORMATION ProcessInfo;
-    BOOLEAN SosEnabled, NoGuiBoot;
-    ULONG YearHack = 0;
-
-    /* Allocate initial process information */
-    ProcessInfo = ExAllocatePoolWithTag(NonPagedPool,
-                                        sizeof(RTL_USER_PROCESS_INFORMATION),
-                                        TAG('I', 'n', 'i', 't'));
-    if (!ProcessInfo)
+    KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo;
+    UNICODE_STRING KeyName, DebugString;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE KeyHandle, OptionHandle;
+    PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
+
+    /* Allocate the initialization buffer */
+    InitBuffer = ExAllocatePoolWithTag(NonPagedPool,
+                                       sizeof(INIT_BUFFER),
+                                       TAG('I', 'n', 'i', 't'));
+    if (!InitBuffer)
     {
         /* Bugcheck */
         KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 8, 0, 0);
@@ -1088,7 +1304,90 @@
         InitWinPEModeType |= (strstr(CommandLine, "INRAM")) ? 0x80000000 : 1;
     }
 
-    /* FIXME: Print product name, version, and build */
+    /* Get the kernel's load entry */
+    NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink,
+                                  LDR_DATA_TABLE_ENTRY,
+                                  InLoadOrderLinks);
+
+    /* Find the banner message */
+    MsgStatus = RtlFindMessage(NtosEntry->DllBase,
+                               11,
+                               0,
+                               WINDOWS_NT_BANNER,
+                               &MsgEntry);
+
+    /* Setup defaults and check if we have a version string */
+    StringBuffer = InitBuffer->VersionBuffer;
+    BeginBuffer = StringBuffer;
+    EndBuffer = StringBuffer;
+    Length = 256;
+    if (CmCSDVersionString.Length)
+    {
+        /* Print the version string */
+        Status = RtlStringCbPrintfExA(StringBuffer,
+                                      255,
+                                      &EndBuffer,
+                                      &Length,
+                                      0,
+                                      ": %wZ",
+                                      &CmCSDVersionString);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Bugcheck */
+            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0);
+        }
+    }
+    else
+    {
+        /* No version */
+        Length = 255;
+    }
+
+    /* Null-terminate the string */
+    *EndBuffer++ = ANSI_NULL;
+
+    /* Build the version number */
+    StringBuffer = InitBuffer->VersionNumber;
+    Status = RtlStringCbPrintfA(StringBuffer,
+                                24,
+                                "%u.%u",
+                                VER_PRODUCTMAJORVERSION,
+                                VER_PRODUCTMINORVERSION);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0);
+    }
+
+    /* Check if we had found a banner message */
+    if (NT_SUCCESS(MsgStatus))
+    {
+        /* Create the banner message */
+        Status = RtlStringCbPrintfA(EndBuffer,
+                                    Length,
+                                    MsgEntry->Text,
+                                    StringBuffer,
+                                    NtBuildNumber & 0xFFFF,
+                                    BeginBuffer);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Bugcheck */
+            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0);
+        }
+    }
+    else
+    {
+        /* Use hard-coded banner message */
+        Status = RtlStringCbCopyA(EndBuffer, Length, "REACTOS (R)\n");
+        if (!NT_SUCCESS(Status))
+        {
+            /* Bugcheck */
+            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0);
+        }
+    }
+
+    /* Display the version string on-screen */
+    InbvDisplayString(EndBuffer);
 
     /* Initialize Power Subsystem in Phase 0 */
     if (!PoInitSystem(0, AcpiTableDetected)) KeBugCheck(INTERNAL_POWER_ERROR);
@@ -1108,23 +1407,36 @@
         RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
         UniversalBootTime = SystemBootTime;
 
-#if 0 // FIXME: Won't work until we can read registry data here
-        /* FIXME: This assumes that the RTC is not already in GMT */
-        ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60,
-                                                10000000);
-
-        /* Set the boot time-zone bias */
-        SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart;
-        SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart;
-        SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart;
-
-        /* Convert the boot time to local time, and set it */
-        UniversalBootTime.QuadPart = SystemBootTime.QuadPart +
-                                     ExpTimeZoneBias.QuadPart;
-#endif
+        /* Check if real time is GMT */
+        if (!ExpRealTimeIsUniversal)
+        {
+            /* Check if we don't have a valid bias */
+            if (ExpLastTimeZoneBias == -1)
+            {
+                /* Reset */
+                ResetBias = TRUE;
+                ExpLastTimeZoneBias = ExpAltTimeZoneBias;
+            }
+
+            /* Calculate the bias in seconds */
+            ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60,
+                                                    10000000);
+
+            /* Set the boot time-zone bias */
+            SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart;
+            SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart;
+            SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart;
+
+            /* Convert the boot time to local time, and set it */
+            UniversalBootTime.QuadPart = SystemBootTime.QuadPart +
+                                         ExpTimeZoneBias.QuadPart;
+        }
 
         /* Update the system time */
         KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL);
+
+        /* Do system callback */
+        PoNotifySystemTimeSet();
 
         /* Remember this as the boot time */
         KeBootTime = UniversalBootTime;
@@ -1134,7 +1446,47 @@
     /* Initialize all processors */
     if (!HalAllProcessorsStarted()) KeBugCheck(HAL1_INITIALIZATION_FAILED);
 
-    /* FIXME: Print CPU and Memory */
+#ifdef CONFIG_SMP
+    /* HACK: We should use RtlFindMessage and not only fallback to this */
+    MpString = "MultiProcessor Kernel\r\n";
+#endif
+
+    /* Setup the "MP" String */
+    RtlInitAnsiString(&TempString, MpString);
+
+    /* Make sure to remove the \r\n if we actually have a string */
+    if (TempString.Length >= 2) TempString.Length -= sizeof(UNICODE_NULL);
+
+    /* Get the information string from our resource file */
+    MsgStatus = RtlFindMessage(NtosEntry->DllBase,
+                               11,
+                               0,
+                               KeNumberProcessors > 1 ?
+                               WINDOWS_NT_INFO_STRING_PLURAL :
+                               WINDOWS_NT_INFO_STRING,
+                               &MsgEntry);
+
+    /* Get total RAM size */
+    Size = MmStats.NrTotalPages * PAGE_SIZE / 1024 / 1024;
+
+    /* Create the string */
+    StringBuffer = InitBuffer->VersionBuffer;
+    Status = RtlStringCbPrintfA(StringBuffer,
+                                256,
+                                NT_SUCCESS(MsgStatus) ?
+                                MsgEntry->Text :
+                                "%u System Processor [%u MB Memory] %Z\n",
+                                KeNumberProcessors,
+                                Size,
+                                &TempString);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Bugcheck */
+        KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 4, 0, 0);
+    }
+
+    /* Display RAM and CPU count */
+    InbvDisplayString(StringBuffer);
 
     /* Update the progress bar */
     InbvUpdateProgressBar(5);
@@ -1181,19 +1533,43 @@
     /* Initialize the Registry */
     if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED);
 
+    /* Initialize Prefetcher */
+    CcPfInitializePrefetcher();
+
     /* Update progress bar */
     InbvUpdateProgressBar(15);
 
     /* Update timezone information */
+    LastTzBias = ExpLastTimeZoneBias;
     ExRefreshTimeZoneInformation(&SystemBootTime);
+
+    /* Check if we're resetting timezone data */
+    if (ResetBias)
+    {
+        /* Convert the local time to system time */
+        ExLocalTimeToSystemTime(&SystemBootTime, &UniversalBootTime);
+        KeBootTime = UniversalBootTime;
+        KeBootTimeBias = 0;
+
+        /* Set the new time */
+        KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL);
+    }
+    else
+    {
+        /* Check if the timezone switched and update the time */
+        if (LastTzBias != ExpLastTimeZoneBias) ZwSetSystemTime(NULL, NULL);
+    }
 
     /* Initialize the File System Runtime Library */
     if (!FsRtlInitSystem()) KeBugCheck(FILE_INITIALIZATION_FAILED);
 
+    /* Initialize range lists */
+    RtlInitializeRangeListPackage();
+
     /* Report all resources used by HAL */
     HalReportResourceUsage();
 
-    /* Call the debugger DLL once we have KD64 6.0 support */
+    /* Call the debugger DLL */
     KdDebuggerInitialize1(LoaderBlock);
 
     /* Setup PnP Manager in phase 1 */
@@ -1205,8 +1581,234 @@
     /* Initialize LPC */
     if (!LpcInitSystem()) KeBugCheck(LPC_INITIALIZATION_FAILED);
 
+    /* Make sure we have a command line */
+    if (CommandLine)
+    {
+        /* Check if this is a safe mode boot */
+        SafeBoot = strstr(CommandLine, "SAFEBOOT:");
+        if (SafeBoot)
+        {
+            /* Check what kind of boot this is */
+            SafeBoot += 9;
+            if (!strncmp(SafeBoot, "MINIMAL", 7))
+            {
+                /* Minimal mode */
+                InitSafeBootMode = 1;
+                SafeBoot += 7;
+                MessageCode = BOOTING_IN_SAFEMODE_MINIMAL;
+            }
+            else if (!strncmp(SafeBoot, "NETWORK", 7))
+            {
+                /* With Networking */
+                InitSafeBootMode = 1;
+                SafeBoot += 7;
+                MessageCode = BOOTING_IN_SAFEMODE_NETWORK;
+            }
+            else if (!strncmp(SafeBoot, "DSREPAIR", 8))
+            {
+                /* Domain Server Repair */
+                InitSafeBootMode = 3;
+                SafeBoot += 8;
+                MessageCode = BOOTING_IN_SAFEMODE_DSREPAIR;
+
+            }
+            else
+            {
+                /* Invalid */
+                InitSafeBootMode = 0;
+            }
+
+            /* Check if there's any settings left */
+            if (*SafeBoot)
+            {
+                /* Check if an alternate shell was requested */
+                if (!strncmp(SafeBoot, "(ALTERNATESHELL)", 16))
+                {
+                    /* Remember this for later */
+                    AlternateShell = TRUE;
+                }
+            }
+
+            /* Find the message to print out */
+            Status = RtlFindMessage(NtosEntry->DllBase,
+                                    11,
+                                    0,
+                                    MessageCode,
+                                    &MsgEntry);
+            if (NT_SUCCESS(Status))
+            {
+                /* Display it */
+                InbvDisplayString(MsgEntry->Text);
+            }
+        }
+    }
+
+    /* Make sure we have a command line */
+    if (CommandLine)
+    {
+        /* Check if bootlogging is enabled */
+        if (strstr(CommandLine, "BOOTLOG"))
+        {
+            /* Find the message to print out */
+            Status = RtlFindMessage(NtosEntry->DllBase,
+                                    11,
+                                    0,
+                                    BOOTLOG_ENABLED,
+                                    &MsgEntry);
+            if (NT_SUCCESS(Status))
+            {
+                /* Display it */
+                InbvDisplayString(MsgEntry->Text);
+            }
+
+            /* Setup boot logging */
+            //IopInitializeBootLogging(LoaderBlock, InitBuffer->BootlogHeader);
+        }
+    }
+
+    /* Setup the Executive in Phase 2 */
+    //ExInitSystemPhase2();
+
+    /* Update progress bar */
+    InbvUpdateProgressBar(25);
+
+#ifdef _WINKD_
+    /* No KD Time Slip is pending */
+    KdpTimeSlipPending = 0;
+#endif
+
+    /* Initialize in-place execution support */
+    XIPInit(LoaderBlock);
+
+    /* Set maximum update to 75% */
+    InbvSetProgressBarSubset(25, 75);
+
     /* Initialize the I/O Subsystem */
-    if (!IoInitSystem(KeLoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED);
+    if (!IoInitSystem(LoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED);
+
+    /* Set maximum update to 100% */
+    InbvSetProgressBarSubset(0, 100);
+
+    /* Are we in safe mode? */
+    if (InitSafeBootMode)
+    {
+        /* Open the safe boot key */
+        RtlInitUnicodeString(&KeyName,
+                             L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET"
+                             L"\\CONTROL\\SAFEBOOT");
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   NULL);
+        Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
+        if (NT_SUCCESS(Status))
+        {
+            /* First check if we have an alternate shell */
+            if (AlternateShell)
+            {
+                /* Make sure that the registry has one setup */
+                RtlInitUnicodeString(&KeyName, L"AlternateShell");
+                Status = NtQueryValueKey(KeyHandle,
+                                         &KeyName,
+                                         KeyValuePartialInformation,
+                                         &KeyPartialInfo,
+                                         sizeof(KeyPartialInfo),
+                                         &Length);
+                if (!NT_SUCCESS(Status)) AlternateShell = FALSE;
+            }
+
+            /* Create the option key */
+            RtlInitUnicodeString(&KeyName, L"Option");
+            InitializeObjectAttributes(&ObjectAttributes,
+                                       &KeyName,
+                                       OBJ_CASE_INSENSITIVE,
+                                       KeyHandle,
+                                       NULL);
+            Status = ZwCreateKey(&OptionHandle,
+                                 KEY_ALL_ACCESS,
+                                 &ObjectAttributes,
+                                 0,
+                                 NULL,
+                                 REG_OPTION_VOLATILE,
+                                 &Disposition);
+            NtClose(KeyHandle);
+
+            /* Check if the key create worked */
+            if (NT_SUCCESS(Status))
+            {
+                /* Write the safe boot type */
+                RtlInitUnicodeString(&KeyName, L"OptionValue");
+                NtSetValueKey(OptionHandle,
+                              &KeyName,
+                              0,
+                              REG_DWORD,
+                              &InitSafeBootMode,
+                              sizeof(InitSafeBootMode));
+
+                /* Check if we have to use an alternate shell */
+                if (AlternateShell)
+                {
+                    /* Remember this for later */
+                    Disposition = TRUE;
+                    RtlInitUnicodeString(&KeyName, L"UseAlternateShell");
+                    NtSetValueKey(OptionHandle,
+                                  &KeyName,
+                                  0,
+                                  REG_DWORD,
+                                  &Disposition,
+                                  sizeof(Disposition));
+                }
+
+                /* Close the options key handle */
+                NtClose(OptionHandle);
+            }
+        }
+    }
+
+    /* Are we in Win PE mode? */
+    if (InitIsWinPEMode)
+    {
+        /* Open the safe control key */
+        RtlInitUnicodeString(&KeyName,
+                             L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET"
+                             L"\\CONTROL");
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   NULL);
+        Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Bugcheck */
+            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0);
+        }
+
+        /* Create the MiniNT key */
+        RtlInitUnicodeString(&KeyName, L"MiniNT");
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   KeyHandle,
+                                   NULL);
+        Status = ZwCreateKey(&OptionHandle,
+                             KEY_ALL_ACCESS,
+                             &ObjectAttributes,
+                             0,
+                             NULL,
+                             REG_OPTION_VOLATILE,
+                             &Disposition);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Bugcheck */
+            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0);
+        }
+
+        /* Close the handles */
+        NtClose(KeyHandle);
+        NtClose(OptionHandle);
+    }
 
     /* Unmap Low memory, and initialize the MPW and Balancer Thread */
     MmInitSystem(2, LoaderBlock);
@@ -1234,7 +1836,8 @@
     InbvUpdateProgressBar(90);
 
     /* Launch initial process */
-    Status = ExpLoadInitialProcess(ProcessInfo);
+    ProcessInfo = &InitBuffer->ProcessInfo;
+    ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);
 
     /* Update progress bar */
     InbvUpdateProgressBar(100);
@@ -1246,9 +1849,12 @@
     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);
+
         /* Bugcheck the system if SMSS couldn't initialize */
         KeBugCheck(SESSION5_INITIALIZATION_FAILED);
     }
@@ -1257,13 +1863,25 @@
     ZwClose(ProcessInfo->ThreadHandle);
     ZwClose(ProcessInfo->ProcessHandle);
 
-    /* FIXME: We should free the initial process' memory!*/
+    /* Free the initial process environment */
+    Size = 0;
+    ZwFreeVirtualMemory(NtCurrentProcess(),
+                        (PVOID*)&Environment,
+                        &Size,
+                        MEM_RELEASE);
+
+    /* Free the initial process parameters */
+    Size = 0;
+    ZwFreeVirtualMemory(NtCurrentProcess(),
+                        (PVOID*)&ProcessParameters,
+                        &Size,
+                        MEM_RELEASE);
 
     /* Increase init phase */
-    ExpInitializationPhase += 1;
-
-    /* Free the process information */
-    ExFreePool(ProcessInfo);
+    ExpInitializationPhase++;
+
+    /* Free the boot buffer */
+    ExFreePool(InitBuffer);
 }
 
 VOID
@@ -1276,6 +1894,3 @@
     /* Jump into zero page thread */
     MmZeroPageThreadMain(NULL);
 }
-
-
-

Modified: trunk/reactos/ntoskrnl/include/internal/rtl.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/rtl.h?rev=26659&r1=26658&r2=26659&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/rtl.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/rtl.h Wed May  9 04:44:45 2007
@@ -10,6 +10,12 @@
     OUT RTL_ATOM *AtomList
 );
 
+VOID
+NTAPI
+RtlInitializeRangeListPackage(
+    VOID
+);
+
 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_NLS_H */
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/rtl/libsupp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/rtl/libsupp.c?rev=26659&r1=26658&r2=26659&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/rtl/libsupp.c (original)
+++ trunk/reactos/ntoskrnl/rtl/libsupp.c Wed May  9 04:44:45 2007
@@ -15,7 +15,29 @@
 
 extern ULONG NtGlobalFlag;
 
+typedef struct _RTL_RANGE_ENTRY
+{
+    LIST_ENTRY Entry;
+    RTL_RANGE Range;
+} RTL_RANGE_ENTRY, *PRTL_RANGE_ENTRY;
+
+PAGED_LOOKASIDE_LIST RtlpRangeListEntryLookasideList;
+
 /* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+RtlInitializeRangeListPackage(VOID)
+{
+    /* Setup the lookaside list for allocations (not used yet) */
+    ExInitializePagedLookasideList(&RtlpRangeListEntryLookasideList,
+                                   NULL,
+                                   NULL,
+                                   POOL_COLD_ALLOCATION,
+                                   sizeof(RTL_RANGE_ENTRY),
+                                   TAG('R', 'R', 'l', 'e'),
+                                   16);
+}
 
 BOOLEAN
 NTAPI




More information about the Ros-diffs mailing list