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=266…
==============================================================================
--- 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/…
==============================================================================
--- 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…
==============================================================================
--- 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