Reactos
at master 2067 lines 70 kB view raw
1/* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: ntoskrnl/ex/init.c 5 * PURPOSE: Executive Initialization Code 6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 7 * Eric Kohl 8 */ 9 10/* INCLUDES ******************************************************************/ 11 12#include <ntoskrnl.h> 13#include <reactos/buildno.h> 14#include "inbv/logo.h" 15 16#define NDEBUG 17#include <debug.h> 18 19/* This is the size that we can expect from the win 2003 loader */ 20#define LOADER_PARAMETER_EXTENSION_MIN_SIZE \ 21 RTL_SIZEOF_THROUGH_FIELD(LOADER_PARAMETER_EXTENSION, AcpiTableSize) 22 23/* Temporary hack */ 24CODE_SEG("INIT") 25BOOLEAN 26NTAPI 27MmArmInitSystem( 28 IN ULONG Phase, 29 IN PLOADER_PARAMETER_BLOCK LoaderBlock 30); 31 32typedef struct _INIT_BUFFER 33{ 34 WCHAR DebugBuffer[256]; 35 CHAR VersionBuffer[256]; 36 CHAR BootlogHeader[256]; 37 CHAR VersionNumber[24]; 38 RTL_USER_PROCESS_INFORMATION ProcessInfo; 39 WCHAR RegistryBuffer[256]; 40} INIT_BUFFER, *PINIT_BUFFER; 41 42/* DATA **********************************************************************/ 43 44/* NT Version Info */ 45ULONG NtMajorVersion = VER_PRODUCTMAJORVERSION; 46ULONG NtMinorVersion = VER_PRODUCTMINORVERSION; 47#if DBG /* Checked Build */ 48ULONG NtBuildNumber = VER_PRODUCTBUILD | 0xC0000000; 49#else /* Free Build */ 50ULONG NtBuildNumber = VER_PRODUCTBUILD; 51#endif 52 53/* NT System Info */ 54ULONG NtGlobalFlag = 0; 55ULONG ExSuiteMask; 56 57/* Cm Version Info */ 58ULONG CmNtSpBuildNumber; 59ULONG CmNtCSDVersion; 60ULONG CmNtCSDReleaseType; 61UNICODE_STRING CmVersionString; 62UNICODE_STRING CmCSDVersionString; 63 64CHAR NtBuildLab[] = KERNEL_VERSION_BUILD_STR "." 65 REACTOS_COMPILER_NAME "_" REACTOS_COMPILER_VERSION; 66 67/* Init flags and settings */ 68ULONG ExpInitializationPhase; 69BOOLEAN ExpInTextModeSetup; 70BOOLEAN IoRemoteBootClient; 71ULONG InitSafeBootMode; 72BOOLEAN InitIsWinPEMode, InitWinPEModeType; 73BOOLEAN SosEnabled; // Used by driver.c!IopDisplayLoadingMessage() 74 75/* NT Boot Path */ 76UNICODE_STRING NtSystemRoot; 77 78/* NT Initial User Application */ 79WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss.exe"; 80ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) - 81 sizeof(WCHAR); 82ULONG NtInitialUserProcessBufferType = REG_SZ; 83 84/* Boot NLS information */ 85PVOID ExpNlsTableBase; 86ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; 87ULONG ExpUnicodeCaseTableDataOffset; 88NLSTABLEINFO ExpNlsTableInfo; 89SIZE_T ExpNlsTableSize; 90PVOID ExpNlsSectionPointer; 91 92/* CMOS Timer Sanity */ 93BOOLEAN ExCmosClockIsSane = TRUE; 94BOOLEAN ExpRealTimeIsUniversal; 95 96/* FUNCTIONS ****************************************************************/ 97 98CODE_SEG("INIT") 99NTSTATUS 100NTAPI 101ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 102{ 103 UNICODE_STRING LinkName; 104 OBJECT_ATTRIBUTES ObjectAttributes; 105 HANDLE LinkHandle; 106 NTSTATUS Status; 107 ANSI_STRING AnsiName; 108 CHAR Buffer[256]; 109 ANSI_STRING TargetString; 110 UNICODE_STRING TargetName; 111 112 /* Initialize the ArcName tree */ 113 RtlInitUnicodeString(&LinkName, L"\\ArcName"); 114 InitializeObjectAttributes(&ObjectAttributes, 115 &LinkName, 116 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 117 NULL, 118 SePublicDefaultUnrestrictedSd); 119 120 /* Create it */ 121 Status = NtCreateDirectoryObject(&LinkHandle, 122 DIRECTORY_ALL_ACCESS, 123 &ObjectAttributes); 124 if (!NT_SUCCESS(Status)) 125 { 126 /* Failed */ 127 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 1, 0, 0); 128 } 129 130 /* Close the LinkHandle */ 131 NtClose(LinkHandle); 132 133 /* Initialize the Device tree */ 134 RtlInitUnicodeString(&LinkName, L"\\Device"); 135 InitializeObjectAttributes(&ObjectAttributes, 136 &LinkName, 137 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 138 NULL, 139 SePublicDefaultUnrestrictedSd); 140 141 /* Create it */ 142 Status = NtCreateDirectoryObject(&LinkHandle, 143 DIRECTORY_ALL_ACCESS, 144 &ObjectAttributes); 145 if (!NT_SUCCESS(Status)) 146 { 147 /* Failed */ 148 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 2, 0, 0); 149 } 150 151 /* Close the LinkHandle */ 152 ObCloseHandle(LinkHandle, KernelMode); 153 154 /* Create the system root symlink name */ 155 RtlInitAnsiString(&AnsiName, "\\SystemRoot"); 156 Status = RtlAnsiStringToUnicodeString(&LinkName, &AnsiName, TRUE); 157 if (!NT_SUCCESS(Status)) 158 { 159 /* Failed */ 160 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 3, 0, 0); 161 } 162 163 /* Initialize the attributes for the link */ 164 InitializeObjectAttributes(&ObjectAttributes, 165 &LinkName, 166 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 167 NULL, 168 SePublicDefaultUnrestrictedSd); 169 170 /* Build the ARC name */ 171 sprintf(Buffer, 172 "\\ArcName\\%s%s", 173 LoaderBlock->ArcBootDeviceName, 174 LoaderBlock->NtBootPathName); 175 Buffer[strlen(Buffer) - 1] = ANSI_NULL; 176 177 /* Convert it to Unicode */ 178 RtlInitString(&TargetString, Buffer); 179 Status = RtlAnsiStringToUnicodeString(&TargetName, 180 &TargetString, 181 TRUE); 182 if (!NT_SUCCESS(Status)) 183 { 184 /* We failed, bugcheck */ 185 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 4, 0, 0); 186 } 187 188 /* Create it */ 189 Status = NtCreateSymbolicLinkObject(&LinkHandle, 190 SYMBOLIC_LINK_ALL_ACCESS, 191 &ObjectAttributes, 192 &TargetName); 193 194 /* Free the strings */ 195 RtlFreeUnicodeString(&LinkName); 196 RtlFreeUnicodeString(&TargetName); 197 198 /* Check if creating the link failed */ 199 if (!NT_SUCCESS(Status)) 200 { 201 /* Failed */ 202 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 5, 0, 0); 203 } 204 205 /* Close the handle and return success */ 206 ObCloseHandle(LinkHandle, KernelMode); 207 return STATUS_SUCCESS; 208} 209 210CODE_SEG("INIT") 211VOID 212NTAPI 213ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 214{ 215 LARGE_INTEGER SectionSize; 216 NTSTATUS Status; 217 HANDLE NlsSection; 218 PVOID SectionBase = NULL; 219 SIZE_T ViewSize = 0; 220 LARGE_INTEGER SectionOffset = {{0, 0}}; 221 PLIST_ENTRY ListHead, NextEntry; 222 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; 223 ULONG NlsTablesEncountered = 0; 224 SIZE_T NlsTableSizes[3] = {0, 0, 0}; /* 3 NLS tables */ 225 226 /* Check if this is boot-time phase 0 initialization */ 227 if (!ExpInitializationPhase) 228 { 229 /* Loop the memory descriptors */ 230 ListHead = &LoaderBlock->MemoryDescriptorListHead; 231 NextEntry = ListHead->Flink; 232 while (NextEntry != ListHead) 233 { 234 /* Get the current block */ 235 MdBlock = CONTAINING_RECORD(NextEntry, 236 MEMORY_ALLOCATION_DESCRIPTOR, 237 ListEntry); 238 239 /* Check if this is an NLS block */ 240 if (MdBlock->MemoryType == LoaderNlsData) 241 { 242 /* Increase the table size */ 243 ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE; 244 245 /* FreeLdr-specific */ 246 NlsTableSizes[NlsTablesEncountered] = MdBlock->PageCount * PAGE_SIZE; 247 NlsTablesEncountered++; 248 ASSERT(NlsTablesEncountered < 4); 249 } 250 251 /* Go to the next block */ 252 NextEntry = MdBlock->ListEntry.Flink; 253 } 254 255 /* Allocate the a new buffer since loader memory will be freed */ 256 ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool, 257 ExpNlsTableSize, 258 TAG_RTLI); 259 if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 260 261 /* Copy the codepage data in its new location. */ 262 if (NlsTablesEncountered == 1) 263 { 264 /* Ntldr-way boot process */ 265 RtlCopyMemory(ExpNlsTableBase, 266 LoaderBlock->NlsData->AnsiCodePageData, 267 ExpNlsTableSize); 268 } 269 else 270 { 271 /* 272 * In NT, the memory blocks are contiguous, but in ReactOS they aren't, 273 * so unless someone fixes FreeLdr, we'll have to use this icky hack. 274 */ 275 RtlCopyMemory(ExpNlsTableBase, 276 LoaderBlock->NlsData->AnsiCodePageData, 277 NlsTableSizes[0]); 278 279 RtlCopyMemory((PVOID)((ULONG_PTR)ExpNlsTableBase + NlsTableSizes[0]), 280 LoaderBlock->NlsData->OemCodePageData, 281 NlsTableSizes[1]); 282 283 RtlCopyMemory((PVOID)((ULONG_PTR)ExpNlsTableBase + NlsTableSizes[0] + 284 NlsTableSizes[1]), 285 LoaderBlock->NlsData->UnicodeCodePageData, 286 NlsTableSizes[2]); 287 /* End of Hack */ 288 } 289 290 /* Initialize and reset the NLS TAbles */ 291 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + 292 ExpAnsiCodePageDataOffset), 293 (PVOID)((ULONG_PTR)ExpNlsTableBase + 294 ExpOemCodePageDataOffset), 295 (PVOID)((ULONG_PTR)ExpNlsTableBase + 296 ExpUnicodeCaseTableDataOffset), 297 &ExpNlsTableInfo); 298 RtlResetRtlTranslations(&ExpNlsTableInfo); 299 return; 300 } 301 302 /* Set the section size */ 303 SectionSize.QuadPart = ExpNlsTableSize; 304 305 /* Create the NLS Section */ 306 Status = ZwCreateSection(&NlsSection, 307 SECTION_ALL_ACCESS, 308 NULL, 309 &SectionSize, 310 PAGE_READWRITE, 311 SEC_COMMIT | 0x1, 312 NULL); 313 if (!NT_SUCCESS(Status)) 314 { 315 /* Failed */ 316 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 1, 0, 0); 317 } 318 319 /* Get a pointer to the section */ 320 Status = ObReferenceObjectByHandle(NlsSection, 321 SECTION_ALL_ACCESS, 322 MmSectionObjectType, 323 KernelMode, 324 &ExpNlsSectionPointer, 325 NULL); 326 ObCloseHandle(NlsSection, KernelMode); 327 if (!NT_SUCCESS(Status)) 328 { 329 /* Failed */ 330 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 2, 0, 0); 331 } 332 333 /* Map the NLS Section in system space */ 334 Status = MmMapViewInSystemSpace(ExpNlsSectionPointer, 335 &SectionBase, 336 &ExpNlsTableSize); 337 if (!NT_SUCCESS(Status)) 338 { 339 /* Failed */ 340 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 3, 0, 0); 341 } 342 343 /* Copy the codepage data in its new location. */ 344 ASSERT(SectionBase >= MmSystemRangeStart); 345 RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); 346 347 /* Free the previously allocated buffer and set the new location */ 348 ExFreePoolWithTag(ExpNlsTableBase, TAG_RTLI); 349 ExpNlsTableBase = SectionBase; 350 351 /* Initialize the NLS Tables */ 352 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + 353 ExpAnsiCodePageDataOffset), 354 (PVOID)((ULONG_PTR)ExpNlsTableBase + 355 ExpOemCodePageDataOffset), 356 (PVOID)((ULONG_PTR)ExpNlsTableBase + 357 ExpUnicodeCaseTableDataOffset), 358 &ExpNlsTableInfo); 359 RtlResetRtlTranslations(&ExpNlsTableInfo); 360 361 /* Reset the base to 0 */ 362 SectionBase = NULL; 363 364 /* Map the section in the system process */ 365 Status = MmMapViewOfSection(ExpNlsSectionPointer, 366 PsGetCurrentProcess(), 367 &SectionBase, 368 0L, 369 0L, 370 &SectionOffset, 371 &ViewSize, 372 ViewShare, 373 0L, 374 PAGE_READWRITE); 375 if (!NT_SUCCESS(Status)) 376 { 377 /* Failed */ 378 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 5, 0, 0); 379 } 380 381 /* Copy the table into the system process and set this as the base */ 382 RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); 383 ExpNlsTableBase = SectionBase; 384} 385 386CODE_SEG("INIT") 387VOID 388NTAPI 389ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer, 390 OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, 391 OUT PCHAR *ProcessEnvironment) 392{ 393 NTSTATUS Status; 394 SIZE_T Size; 395 PWSTR p; 396 UNICODE_STRING NullString = RTL_CONSTANT_STRING(L""); 397 UNICODE_STRING SmssName, Environment, SystemDriveString, DebugString; 398 PVOID EnvironmentPtr = NULL; 399 PRTL_USER_PROCESS_INFORMATION ProcessInformation; 400 PRTL_USER_PROCESS_PARAMETERS ProcessParams = NULL; 401 402 NullString.Length = sizeof(WCHAR); 403 404 /* Use the initial buffer, after the strings */ 405 ProcessInformation = &InitBuffer->ProcessInfo; 406 407 /* Allocate memory for the process parameters */ 408 Size = sizeof(*ProcessParams) + ((MAX_WIN32_PATH * 6) * sizeof(WCHAR)); 409 Status = ZwAllocateVirtualMemory(NtCurrentProcess(), 410 (PVOID*)&ProcessParams, 411 0, 412 &Size, 413 MEM_RESERVE | MEM_COMMIT, 414 PAGE_READWRITE); 415 if (!NT_SUCCESS(Status)) 416 { 417 /* Failed, display error */ 418 _snwprintf(InitBuffer->DebugBuffer, 419 sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), 420 L"INIT: Unable to allocate Process Parameters. 0x%lx", 421 Status); 422 RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); 423 ZwDisplayString(&DebugString); 424 425 /* Bugcheck the system */ 426 KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0); 427 } 428 429 /* Setup the basic header, and give the process the low 1MB to itself */ 430 ProcessParams->Length = (ULONG)Size; 431 ProcessParams->MaximumLength = (ULONG)Size; 432 ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED | 433 RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; 434 435 /* Allocate a page for the environment */ 436 Size = PAGE_SIZE; 437 Status = ZwAllocateVirtualMemory(NtCurrentProcess(), 438 &EnvironmentPtr, 439 0, 440 &Size, 441 MEM_RESERVE | MEM_COMMIT, 442 PAGE_READWRITE); 443 if (!NT_SUCCESS(Status)) 444 { 445 /* Failed, display error */ 446 _snwprintf(InitBuffer->DebugBuffer, 447 sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), 448 L"INIT: Unable to allocate Process Environment. 0x%lx", 449 Status); 450 RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); 451 ZwDisplayString(&DebugString); 452 453 /* Bugcheck the system */ 454 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0); 455 } 456 457 /* Write the pointer */ 458 ProcessParams->Environment = EnvironmentPtr; 459 460 /* Make a buffer for the DOS path */ 461 p = (PWSTR)(ProcessParams + 1); 462 ProcessParams->CurrentDirectory.DosPath.Buffer = p; 463 ProcessParams->CurrentDirectory.DosPath.MaximumLength = MAX_WIN32_PATH * 464 sizeof(WCHAR); 465 466 /* Copy the DOS path */ 467 RtlCopyUnicodeString(&ProcessParams->CurrentDirectory.DosPath, 468 &NtSystemRoot); 469 470 /* Make a buffer for the DLL Path */ 471 p = (PWSTR)((PCHAR)ProcessParams->CurrentDirectory.DosPath.Buffer + 472 ProcessParams->CurrentDirectory.DosPath.MaximumLength); 473 ProcessParams->DllPath.Buffer = p; 474 ProcessParams->DllPath.MaximumLength = MAX_WIN32_PATH * sizeof(WCHAR); 475 476 /* Copy the DLL path and append the system32 directory */ 477 RtlCopyUnicodeString(&ProcessParams->DllPath, 478 &ProcessParams->CurrentDirectory.DosPath); 479 RtlAppendUnicodeToString(&ProcessParams->DllPath, L"\\System32"); 480 481 /* Make a buffer for the image name */ 482 p = (PWSTR)((PCHAR)ProcessParams->DllPath.Buffer + 483 ProcessParams->DllPath.MaximumLength); 484 ProcessParams->ImagePathName.Buffer = p; 485 ProcessParams->ImagePathName.MaximumLength = MAX_WIN32_PATH * sizeof(WCHAR); 486 487 /* Make sure the buffer is a valid string which within the given length */ 488 if ((NtInitialUserProcessBufferType != REG_SZ) || 489 ((NtInitialUserProcessBufferLength != MAXULONG) && 490 ((NtInitialUserProcessBufferLength < sizeof(WCHAR)) || 491 (NtInitialUserProcessBufferLength > 492 sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR))))) 493 { 494 /* Invalid initial process string, bugcheck */ 495 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, 496 STATUS_INVALID_PARAMETER, 497 NtInitialUserProcessBufferType, 498 NtInitialUserProcessBufferLength, 499 sizeof(NtInitialUserProcessBuffer)); 500 } 501 502 /* Cut out anything after a space */ 503 p = NtInitialUserProcessBuffer; 504 while ((*p) && (*p != L' ')) p++; 505 506 /* Set the image path length */ 507 ProcessParams->ImagePathName.Length = 508 (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer); 509 510 /* Copy the actual buffer */ 511 RtlCopyMemory(ProcessParams->ImagePathName.Buffer, 512 NtInitialUserProcessBuffer, 513 ProcessParams->ImagePathName.Length); 514 515 /* Null-terminate it */ 516 ProcessParams->ImagePathName.Buffer[ProcessParams->ImagePathName.Length / 517 sizeof(WCHAR)] = UNICODE_NULL; 518 519 /* Make a buffer for the command line */ 520 p = (PWSTR)((PCHAR)ProcessParams->ImagePathName.Buffer + 521 ProcessParams->ImagePathName.MaximumLength); 522 ProcessParams->CommandLine.Buffer = p; 523 ProcessParams->CommandLine.MaximumLength = MAX_WIN32_PATH * sizeof(WCHAR); 524 525 /* Add the image name to the command line */ 526 RtlAppendUnicodeToString(&ProcessParams->CommandLine, 527 NtInitialUserProcessBuffer); 528 529 /* Create the environment string */ 530 RtlInitEmptyUnicodeString(&Environment, 531 ProcessParams->Environment, 532 (USHORT)Size); 533 534 /* Append the DLL path to it */ 535 RtlAppendUnicodeToString(&Environment, L"Path="); 536 RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath); 537 RtlAppendUnicodeStringToString(&Environment, &NullString); 538 539 /* Create the system drive string */ 540 SystemDriveString = NtSystemRoot; 541 SystemDriveString.Length = 2 * sizeof(WCHAR); 542 543 /* Append it to the environment */ 544 RtlAppendUnicodeToString(&Environment, L"SystemDrive="); 545 RtlAppendUnicodeStringToString(&Environment, &SystemDriveString); 546 RtlAppendUnicodeStringToString(&Environment, &NullString); 547 548 /* Append the system root to the environment */ 549 RtlAppendUnicodeToString(&Environment, L"SystemRoot="); 550 RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot); 551 RtlAppendUnicodeStringToString(&Environment, &NullString); 552 553 /* Prepare the prefetcher */ 554 //CcPfBeginBootPhase(150); 555 556 /* Create SMSS process */ 557 SmssName = ProcessParams->ImagePathName; 558 Status = RtlCreateUserProcess(&SmssName, 559 OBJ_CASE_INSENSITIVE, 560 RtlDeNormalizeProcessParams(ProcessParams), 561 NULL, 562 NULL, 563 NULL, 564 FALSE, 565 NULL, 566 NULL, 567 ProcessInformation); 568 if (!NT_SUCCESS(Status)) 569 { 570 /* Failed, display error */ 571 _snwprintf(InitBuffer->DebugBuffer, 572 sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), 573 L"INIT: Unable to create Session Manager. 0x%lx", 574 Status); 575 RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); 576 ZwDisplayString(&DebugString); 577 578 /* Bugcheck the system */ 579 KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0); 580 } 581 582 /* Resume the thread */ 583 Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL); 584 if (!NT_SUCCESS(Status)) 585 { 586 /* Failed, display error */ 587 _snwprintf(InitBuffer->DebugBuffer, 588 sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), 589 L"INIT: Unable to resume Session Manager. 0x%lx", 590 Status); 591 RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); 592 ZwDisplayString(&DebugString); 593 594 /* Bugcheck the system */ 595 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); 596 } 597 598 /* Return success */ 599 *ProcessParameters = ProcessParams; 600 *ProcessEnvironment = EnvironmentPtr; 601} 602 603CODE_SEG("INIT") 604ULONG 605NTAPI 606ExComputeTickCountMultiplier(IN ULONG ClockIncrement) 607{ 608 ULONG MsRemainder = 0, MsIncrement; 609 ULONG IncrementRemainder; 610 ULONG i; 611 612 /* Count the number of milliseconds for each clock interrupt */ 613 MsIncrement = ClockIncrement / (10 * 1000); 614 615 /* Count the remainder from the division above, with 24-bit precision */ 616 IncrementRemainder = ClockIncrement - (MsIncrement * (10 * 1000)); 617 for (i= 0; i < 24; i++) 618 { 619 /* Shift the remainders */ 620 MsRemainder <<= 1; 621 IncrementRemainder <<= 1; 622 623 /* Check if we've went past 1 ms */ 624 if (IncrementRemainder >= (10 * 1000)) 625 { 626 /* Increase the remainder by one, and substract from increment */ 627 IncrementRemainder -= (10 * 1000); 628 MsRemainder |= 1; 629 } 630 } 631 632 /* Return the increment */ 633 return (MsIncrement << 24) | MsRemainder; 634} 635 636CODE_SEG("INIT") 637BOOLEAN 638NTAPI 639ExpInitSystemPhase0(VOID) 640{ 641 /* Initialize EXRESOURCE Support */ 642 ExpResourceInitialization(); 643 644 /* Initialize the environment lock */ 645 ExInitializeFastMutex(&ExpEnvironmentLock); 646 647 /* Initialize the lookaside lists and locks */ 648 ExpInitLookasideLists(); 649 650 /* Initialize the Firmware Table resource and listhead */ 651 InitializeListHead(&ExpFirmwareTableProviderListHead); 652 ExInitializeResourceLite(&ExpFirmwareTableResource); 653 ExInitializeResourceLite(&ExpTimeRefreshLock); 654 655 /* Set the suite mask to maximum and return */ 656 ExSuiteMask = 0xFFFFFFFF; 657 return TRUE; 658} 659 660CODE_SEG("INIT") 661BOOLEAN 662NTAPI 663ExpInitSystemPhase1(VOID) 664{ 665 /* Initialize worker threads */ 666 ExpInitializeWorkerThreads(); 667 668 /* Initialize pushlocks */ 669 ExpInitializePushLocks(); 670 671 /* Initialize events and event pairs */ 672 if (ExpInitializeEventImplementation() == FALSE) 673 { 674 DPRINT1("Executive: Event initialization failed\n"); 675 return FALSE; 676 } 677 if (ExpInitializeEventPairImplementation() == FALSE) 678 { 679 DPRINT1("Executive: Event Pair initialization failed\n"); 680 return FALSE; 681 } 682 683 /* Initialize mutants */ 684 if (ExpInitializeMutantImplementation() == FALSE) 685 { 686 DPRINT1("Executive: Mutant initialization failed\n"); 687 return FALSE; 688 } 689 690 /* Initialize callbacks */ 691 if (ExpInitializeCallbacks() == FALSE) 692 { 693 DPRINT1("Executive: Callback initialization failed\n"); 694 return FALSE; 695 } 696 697 /* Initialize semaphores */ 698 if (ExpInitializeSemaphoreImplementation() == FALSE) 699 { 700 DPRINT1("Executive: Semaphore initialization failed\n"); 701 return FALSE; 702 } 703 704 /* Initialize timers */ 705 if (ExpInitializeTimerImplementation() == FALSE) 706 { 707 DPRINT1("Executive: Timer initialization failed\n"); 708 return FALSE; 709 } 710 711 /* Initialize profiling */ 712 if (ExpInitializeProfileImplementation() == FALSE) 713 { 714 DPRINT1("Executive: Profile initialization failed\n"); 715 return FALSE; 716 } 717 718 /* Initialize UUIDs */ 719 if (ExpUuidInitialization() == FALSE) 720 { 721 DPRINT1("Executive: Uuid initialization failed\n"); 722 return FALSE; 723 } 724 725 /* Initialize keyed events */ 726 if (ExpInitializeKeyedEventImplementation() == FALSE) 727 { 728 DPRINT1("Executive: Keyed event initialization failed\n"); 729 return FALSE; 730 } 731 732 /* Initialize Win32K */ 733 if (ExpWin32kInit() == FALSE) 734 { 735 DPRINT1("Executive: Win32 initialization failed\n"); 736 return FALSE; 737 } 738 return TRUE; 739} 740 741CODE_SEG("INIT") 742BOOLEAN 743NTAPI 744ExInitSystem(VOID) 745{ 746 /* Check the initialization phase */ 747 switch (ExpInitializationPhase) 748 { 749 case 0: 750 751 /* Do Phase 0 */ 752 return ExpInitSystemPhase0(); 753 754 case 1: 755 756 /* Do Phase 1 */ 757 return ExpInitSystemPhase1(); 758 759 default: 760 761 /* Don't know any other phase! Bugcheck! */ 762 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL); 763 return FALSE; 764 } 765} 766 767CODE_SEG("INIT") 768BOOLEAN 769NTAPI 770ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 771{ 772 PLOADER_PARAMETER_EXTENSION Extension; 773 774 /* Get the loader extension */ 775 Extension = LoaderBlock->Extension; 776 777 /* Validate the size (Windows 2003 loader doesn't provide more) */ 778 if (Extension->Size < LOADER_PARAMETER_EXTENSION_MIN_SIZE) return FALSE; 779 780 /* Don't validate upper versions */ 781 if (Extension->MajorVersion > VER_PRODUCTMAJORVERSION) return TRUE; 782 783 /* Fail if this is NT 4 */ 784 if (Extension->MajorVersion < VER_PRODUCTMAJORVERSION) return FALSE; 785 786 /* Fail if this is XP */ 787 if (Extension->MinorVersion < VER_PRODUCTMINORVERSION) return FALSE; 788 789 /* This is 2003 or newer, approve it */ 790 return TRUE; 791} 792 793static CODE_SEG("INIT") 794VOID 795ExpLoadBootSymbols( 796 _In_ PLOADER_PARAMETER_BLOCK LoaderBlock) 797{ 798 PLIST_ENTRY NextEntry; 799 PLDR_DATA_TABLE_ENTRY LdrEntry; 800 NTSTATUS Status; 801 ULONG i; 802 ULONG Count, Length; 803 PWCHAR Name; 804 STRING ImageName; 805 CHAR NameBuffer[256]; 806 807 /* Loop over the boot modules list */ 808 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink, i = 0; 809 NextEntry != &LoaderBlock->LoadOrderListHead; 810 NextEntry = NextEntry->Flink, ++i) 811 { 812 /* Skip the first two images: HAL and kernel */ 813 if (i < 2) 814 continue; 815 816 /* Get the entry */ 817 LdrEntry = CONTAINING_RECORD(NextEntry, 818 LDR_DATA_TABLE_ENTRY, 819 InLoadOrderLinks); 820 if (LdrEntry->FullDllName.Buffer[0] == L'\\') 821 { 822 /* We have a name, read its data */ 823 Name = LdrEntry->FullDllName.Buffer; 824 Length = LdrEntry->FullDllName.Length / sizeof(WCHAR); 825 826 /* Check if our buffer can hold it */ 827 if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL)) 828 { 829 /* It's too long */ 830 Status = STATUS_BUFFER_OVERFLOW; 831 } 832 else 833 { 834 /* Copy the name */ 835 Count = 0; 836 do 837 { 838 /* Do cheap Unicode to ANSI conversion */ 839 NameBuffer[Count++] = (CHAR)*Name++; 840 } while (Count < Length); 841 842 /* Null-terminate */ 843 NameBuffer[Count] = ANSI_NULL; 844 Status = STATUS_SUCCESS; 845 } 846 } 847 else 848 { 849 /* Safely print the string into our buffer */ 850 Status = RtlStringCbPrintfA(NameBuffer, 851 sizeof(NameBuffer), 852 "%S\\System32\\Drivers\\%wZ", 853 &SharedUserData->NtSystemRoot[2], 854 &LdrEntry->BaseDllName); 855 } 856 857 /* Check if the buffer is OK */ 858 if (NT_SUCCESS(Status)) 859 { 860 /* Load the symbols */ 861 RtlInitString(&ImageName, NameBuffer); 862 DbgLoadImageSymbols(&ImageName, 863 LdrEntry->DllBase, 864 (ULONG_PTR)PsGetCurrentProcessId()); 865 } 866 867#ifdef CONFIG_SMP 868 /* Check that the image is safe to use if we have more than one CPU */ 869 if (!MmVerifyImageIsOkForMpUse(LdrEntry->DllBase)) 870 { 871 KeBugCheckEx(UP_DRIVER_ON_MP_SYSTEM, 872 (ULONG_PTR)LdrEntry->DllBase, 873 0, 0, 0); 874 } 875#endif // CONFIG_SMP 876 } 877} 878 879CODE_SEG("INIT") 880VOID 881NTAPI 882ExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, 883 IN ULONG_PTR PagesToDestroy, 884 IN TYPE_OF_MEMORY MemoryType) 885{ 886 PLIST_ENTRY ListEntry; 887 PMEMORY_ALLOCATION_DESCRIPTOR MemDescriptor; 888 889 DPRINT1("Burn RAM amount: %lu pages\n", PagesToDestroy); 890 891 /* Loop the memory descriptors, beginning at the end */ 892 for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Blink; 893 ListEntry != &LoaderBlock->MemoryDescriptorListHead; 894 ListEntry = ListEntry->Blink) 895 { 896 /* Get the memory descriptor structure */ 897 MemDescriptor = CONTAINING_RECORD(ListEntry, 898 MEMORY_ALLOCATION_DESCRIPTOR, 899 ListEntry); 900 901 /* Is memory free there or is it temporary? */ 902 if (MemDescriptor->MemoryType == LoaderFree || 903 MemDescriptor->MemoryType == LoaderFirmwareTemporary) 904 { 905 /* Check if the descriptor has more pages than we want */ 906 if (MemDescriptor->PageCount > PagesToDestroy) 907 { 908 /* Change block's page count, ntoskrnl doesn't care much */ 909 MemDescriptor->PageCount -= PagesToDestroy; 910 break; 911 } 912 else 913 { 914 /* Change block type */ 915 MemDescriptor->MemoryType = MemoryType; 916 PagesToDestroy -= MemDescriptor->PageCount; 917 918 /* Check if we are done */ 919 if (PagesToDestroy == 0) break; 920 } 921 } 922 } 923} 924 925CODE_SEG("INIT") 926VOID 927NTAPI 928ExpInitializeExecutive(IN ULONG Cpu, 929 IN PLOADER_PARAMETER_BLOCK LoaderBlock) 930{ 931 PNLS_DATA_BLOCK NlsData; 932 CHAR Buffer[256]; 933 ANSI_STRING AnsiPath; 934 NTSTATUS Status; 935 PCHAR CommandLine, PerfMem; 936 ULONG PerfMemUsed; 937 PLDR_DATA_TABLE_ENTRY NtosEntry; 938 PMESSAGE_RESOURCE_ENTRY MsgEntry; 939 ANSI_STRING CSDString; 940 size_t Remaining = 0; 941 PCHAR RcEnd = NULL; 942 CHAR VersionBuffer[65]; 943 944 /* Validate Loader */ 945 if (!ExpIsLoaderValid(LoaderBlock)) 946 { 947 /* Invalid loader version */ 948 KeBugCheckEx(MISMATCHED_HAL, 949 3, 950 LoaderBlock->Extension->Size, 951 LoaderBlock->Extension->MajorVersion, 952 LoaderBlock->Extension->MinorVersion); 953 } 954 955 /* Initialize PRCB pool lookaside pointers */ 956 ExInitPoolLookasidePointers(); 957 958 /* Check if this is an application CPU */ 959 if (Cpu) 960 { 961 /* Then simply initialize it with HAL */ 962 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) 963 { 964 /* Initialization failed */ 965 KeBugCheck(HAL_INITIALIZATION_FAILED); 966 } 967 968 /* We're done */ 969 return; 970 } 971 972 /* Assume no text-mode or remote boot */ 973 ExpInTextModeSetup = FALSE; 974 IoRemoteBootClient = FALSE; 975 976 /* Check if we have a setup loader block */ 977 if (LoaderBlock->SetupLdrBlock) 978 { 979 /* Check if this is text-mode setup */ 980 if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_TEXT_MODE) 981 ExpInTextModeSetup = TRUE; 982 983 /* Check if this is network boot */ 984 if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_REMOTE_BOOT) 985 { 986 /* Set variable */ 987 IoRemoteBootClient = TRUE; 988 989 /* Make sure we're actually booting off the network */ 990 ASSERT(!_memicmp(LoaderBlock->ArcBootDeviceName, "net(0)", 6)); 991 } 992 } 993 994 /* Set phase to 0 */ 995 ExpInitializationPhase = 0; 996 997 /* Get boot command line */ 998 CommandLine = LoaderBlock->LoadOptions; 999 if (CommandLine) 1000 { 1001 /* Upcase it for comparison and check if we're in performance mode */ 1002 _strupr(CommandLine); 1003 PerfMem = strstr(CommandLine, "PERFMEM"); 1004 if (PerfMem) 1005 { 1006 /* Check if the user gave a number of bytes to use */ 1007 PerfMem = strstr(PerfMem, "="); 1008 if (PerfMem) 1009 { 1010 /* Read the number of pages we'll use */ 1011 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); 1012 if (PerfMemUsed) 1013 { 1014 /* FIXME: TODO */ 1015 DPRINT1("BBT performance mode not yet supported." 1016 "/PERFMEM option ignored.\n"); 1017 } 1018 } 1019 } 1020 1021 /* Check if we're burning memory */ 1022 PerfMem = strstr(CommandLine, "BURNMEMORY"); 1023 if (PerfMem) 1024 { 1025 /* Check if the user gave a number of bytes to use */ 1026 PerfMem = strstr(PerfMem, "="); 1027 if (PerfMem) 1028 { 1029 /* Read the number of pages we'll use */ 1030 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); 1031 if (PerfMemUsed) ExBurnMemory(LoaderBlock, PerfMemUsed, LoaderBad); 1032 } 1033 } 1034 } 1035 1036 /* Setup NLS Base and offsets */ 1037 NlsData = LoaderBlock->NlsData; 1038 ExpNlsTableBase = NlsData->AnsiCodePageData; 1039 ExpAnsiCodePageDataOffset = 0; 1040 ExpOemCodePageDataOffset = (ULONG)((ULONG_PTR)NlsData->OemCodePageData - 1041 (ULONG_PTR)NlsData->AnsiCodePageData); 1042 ExpUnicodeCaseTableDataOffset = (ULONG)((ULONG_PTR)NlsData->UnicodeCodePageData - 1043 (ULONG_PTR)NlsData->AnsiCodePageData); 1044 1045 /* Initialize the NLS Tables */ 1046 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + 1047 ExpAnsiCodePageDataOffset), 1048 (PVOID)((ULONG_PTR)ExpNlsTableBase + 1049 ExpOemCodePageDataOffset), 1050 (PVOID)((ULONG_PTR)ExpNlsTableBase + 1051 ExpUnicodeCaseTableDataOffset), 1052 &ExpNlsTableInfo); 1053 RtlResetRtlTranslations(&ExpNlsTableInfo); 1054 1055 /* Now initialize the HAL */ 1056 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) 1057 { 1058 /* HAL failed to initialize, bugcheck */ 1059 KeBugCheck(HAL_INITIALIZATION_FAILED); 1060 } 1061 1062 /* Make sure interrupts are active now */ 1063 _enable(); 1064 1065 /* Clear the crypto exponent */ 1066 SharedUserData->CryptoExponent = 0; 1067 1068 /* Set global flags for the checked build */ 1069#if DBG 1070 NtGlobalFlag |= FLG_ENABLE_CLOSE_EXCEPTIONS | 1071 FLG_ENABLE_KDEBUG_SYMBOL_LOAD; 1072#endif 1073 1074 /* Setup NT System Root Path */ 1075 sprintf(Buffer, "C:%s", LoaderBlock->NtBootPathName); 1076 1077 /* Convert to ANSI_STRING and null-terminate it */ 1078 RtlInitString(&AnsiPath, Buffer); 1079 Buffer[--AnsiPath.Length] = ANSI_NULL; 1080 1081 /* Get the string from KUSER_SHARED_DATA's buffer */ 1082 RtlInitEmptyUnicodeString(&NtSystemRoot, 1083 SharedUserData->NtSystemRoot, 1084 sizeof(SharedUserData->NtSystemRoot)); 1085 1086 /* Now fill it in */ 1087 Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE); 1088 if (!NT_SUCCESS(Status)) KeBugCheck(SESSION3_INITIALIZATION_FAILED); 1089 1090 /* Setup bugcheck messages */ 1091 KiInitializeBugCheck(); 1092 1093 /* Setup initial system settings */ 1094 CmGetSystemControlValues(LoaderBlock->RegistryBase, CmControlVector); 1095 1096 /* Set the Service Pack Number and add it to the CSD Version number if needed */ 1097 CmNtSpBuildNumber = VER_PRODUCTBUILD_QFE; 1098 if (((CmNtCSDVersion & 0xFFFF0000) == 0) && (CmNtCSDReleaseType == 1)) 1099 { 1100 CmNtCSDVersion |= (VER_PRODUCTBUILD_QFE << 16); 1101 } 1102 1103 /* Add loaded CmNtGlobalFlag value */ 1104 NtGlobalFlag |= CmNtGlobalFlag; 1105 1106 /* Initialize the executive at phase 0 */ 1107 if (!ExInitSystem()) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 1108 1109 /* Initialize the memory manager at phase 0 */ 1110 if (!MmArmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 1111 1112 /* Load boot symbols */ 1113 ExpLoadBootSymbols(LoaderBlock); 1114 1115 /* Check if we should break after symbol load */ 1116 if (KdBreakAfterSymbolLoad) 1117 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); 1118 1119 /* Check if this loader is compatible with NT 5.2 */ 1120 if (LoaderBlock->Extension->Size >= sizeof(LOADER_PARAMETER_EXTENSION)) 1121 { 1122 /* Setup headless terminal settings */ 1123 HeadlessInit(LoaderBlock); 1124 } 1125 1126 /* Set system ranges */ 1127#ifdef _M_AMD64 1128 SharedUserData->Reserved1 = MM_HIGHEST_USER_ADDRESS_WOW64; 1129 SharedUserData->Reserved3 = MM_SYSTEM_RANGE_START_WOW64; 1130#else 1131 SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress; 1132 SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart; 1133#endif 1134 1135 /* Make a copy of the NLS Tables */ 1136 ExpInitNls(LoaderBlock); 1137 1138 /* Get the kernel's load entry */ 1139 NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, 1140 LDR_DATA_TABLE_ENTRY, 1141 InLoadOrderLinks); 1142 1143 /* Check if this is a service pack */ 1144 if (CmNtCSDVersion & 0xFFFF) 1145 { 1146 /* Get the service pack string */ 1147 Status = RtlFindMessage(NtosEntry->DllBase, 1148 RT_MESSAGETABLE, 1149 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), 1150 WINDOWS_NT_CSD_STRING, 1151 &MsgEntry); 1152 if (NT_SUCCESS(Status)) 1153 { 1154 /* Setup the string */ 1155 RtlInitAnsiString(&CSDString, (PCHAR)MsgEntry->Text); 1156 1157 /* Remove trailing newline */ 1158 while ((CSDString.Length > 0) && 1159 ((CSDString.Buffer[CSDString.Length - 1] == '\r') || 1160 (CSDString.Buffer[CSDString.Length - 1] == '\n'))) 1161 { 1162 /* Skip the trailing character */ 1163 CSDString.Length--; 1164 } 1165 1166 /* Fill the buffer with version information */ 1167 Status = RtlStringCbPrintfA(Buffer, 1168 sizeof(Buffer), 1169 "%Z %u%c", 1170 &CSDString, 1171 (CmNtCSDVersion & 0xFF00) >> 8, 1172 (CmNtCSDVersion & 0xFF) ? 1173 'A' + (CmNtCSDVersion & 0xFF) - 1 : 1174 ANSI_NULL); 1175 } 1176 else 1177 { 1178 /* Build default string */ 1179 Status = RtlStringCbPrintfA(Buffer, 1180 sizeof(Buffer), 1181 "CSD %04x", 1182 CmNtCSDVersion); 1183 } 1184 1185 /* Check for success */ 1186 if (!NT_SUCCESS(Status)) 1187 { 1188 /* Fail */ 1189 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1190 } 1191 } 1192 else 1193 { 1194 /* Then this is a beta */ 1195 Status = RtlStringCbCopyExA(Buffer, 1196 sizeof(Buffer), 1197 VER_PRODUCTBETA_STR, 1198 NULL, 1199 &Remaining, 1200 0); 1201 if (!NT_SUCCESS(Status)) 1202 { 1203 /* Fail */ 1204 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1205 } 1206 1207 /* Update length */ 1208 CmCSDVersionString.MaximumLength = sizeof(Buffer) - (USHORT)Remaining; 1209 } 1210 1211 /* Check if we have an RC number */ 1212 if ((CmNtCSDVersion & 0xFFFF0000) && (CmNtCSDReleaseType == 1)) 1213 { 1214 /* Check if we have no version data yet */ 1215 if (!(*Buffer)) 1216 { 1217 /* Set defaults */ 1218 Remaining = sizeof(Buffer); 1219 RcEnd = Buffer; 1220 } 1221 else 1222 { 1223 /* Add comma and space */ 1224 Status = RtlStringCbCatExA(Buffer, 1225 sizeof(Buffer), 1226 ", ", 1227 &RcEnd, 1228 &Remaining, 1229 0); 1230 if (!NT_SUCCESS(Status)) 1231 { 1232 /* Fail */ 1233 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1234 } 1235 } 1236 1237 /* Add the version format string */ 1238 Status = RtlStringCbPrintfA(RcEnd, 1239 Remaining, 1240 "v.%u", 1241 (CmNtCSDVersion & 0xFFFF0000) >> 16); 1242 if (!NT_SUCCESS(Status)) 1243 { 1244 /* Fail */ 1245 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1246 } 1247 } 1248 1249 /* Now setup the final string */ 1250 RtlInitAnsiString(&CSDString, Buffer); 1251 Status = RtlAnsiStringToUnicodeString(&CmCSDVersionString, 1252 &CSDString, 1253 TRUE); 1254 if (!NT_SUCCESS(Status)) 1255 { 1256 /* Fail */ 1257 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1258 } 1259 1260 /* Add our version */ 1261 Status = RtlStringCbPrintfA(VersionBuffer, 1262 sizeof(VersionBuffer), 1263 "%u.%u", 1264 VER_PRODUCTMAJORVERSION, 1265 VER_PRODUCTMINORVERSION); 1266 if (!NT_SUCCESS(Status)) 1267 { 1268 /* Fail */ 1269 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1270 } 1271 1272 /* Build the final version string */ 1273 RtlCreateUnicodeStringFromAsciiz(&CmVersionString, VersionBuffer); 1274 1275 /* Check if the user wants a kernel stack trace database */ 1276 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) 1277 { 1278 /* FIXME: TODO */ 1279 DPRINT1("Kernel-mode stack trace support not yet present." 1280 "FLG_KERNEL_STACK_TRACE_DB flag ignored.\n"); 1281 } 1282 1283 /* Check if he wanted exception logging */ 1284 if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING) 1285 { 1286 /* FIXME: TODO */ 1287 DPRINT1("Kernel-mode exception logging support not yet present." 1288 "FLG_ENABLE_EXCEPTION_LOGGING flag ignored.\n"); 1289 } 1290 1291 /* Initialize the Handle Table */ 1292 ExpInitializeHandleTables(); 1293 1294#if DBG 1295 /* On checked builds, allocate the system call count table */ 1296 KeServiceDescriptorTable[0].Count = 1297 ExAllocatePoolWithTag(NonPagedPool, 1298 KiServiceLimit * sizeof(ULONG), 1299 'llaC'); 1300 1301 /* Use it for the shadow table too */ 1302 KeServiceDescriptorTableShadow[0].Count = KeServiceDescriptorTable[0].Count; 1303 1304 /* Make sure allocation succeeded */ 1305 if (KeServiceDescriptorTable[0].Count) 1306 { 1307 /* Zero the call counts to 0 */ 1308 RtlZeroMemory(KeServiceDescriptorTable[0].Count, 1309 KiServiceLimit * sizeof(ULONG)); 1310 } 1311#endif 1312 1313 /* Create the Basic Object Manager Types to allow new Object Types */ 1314 if (!ObInitSystem()) KeBugCheck(OBJECT_INITIALIZATION_FAILED); 1315 1316 /* Load basic Security for other Managers */ 1317 if (!SeInitSystem()) KeBugCheck(SECURITY_INITIALIZATION_FAILED); 1318 1319 /* Initialize the Process Manager */ 1320 if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS_INITIALIZATION_FAILED); 1321 1322 /* Initialize the PnP Manager */ 1323 if (!PpInitSystem()) KeBugCheck(PP0_INITIALIZATION_FAILED); 1324 1325 /* Initialize the User-Mode Debugging Subsystem */ 1326 DbgkInitialize(); 1327 1328 /* Calculate the tick count multiplier */ 1329 ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement); 1330 SharedUserData->TickCountMultiplier = ExpTickCountMultiplier; 1331 1332 /* Set the OS Version */ 1333 SharedUserData->NtMajorVersion = NtMajorVersion; 1334 SharedUserData->NtMinorVersion = NtMinorVersion; 1335 1336 /* Set the machine type */ 1337 SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_NATIVE; 1338 SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_NATIVE; 1339 1340 /* ReactOS magic */ 1341 *(PULONG)(KI_USER_SHARED_DATA + PAGE_SIZE - sizeof(ULONG)) = 0x8eac705; 1342} 1343 1344VOID 1345NTAPI 1346MmFreeLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock); 1347 1348CODE_SEG("INIT") 1349VOID 1350NTAPI 1351Phase1InitializationDiscard(IN PVOID Context) 1352{ 1353 PLOADER_PARAMETER_BLOCK LoaderBlock = Context; 1354 NTSTATUS Status, MsgStatus; 1355 TIME_FIELDS TimeFields; 1356 LARGE_INTEGER SystemBootTime, UniversalBootTime, OldTime, Timeout; 1357 BOOLEAN NoGuiBoot, ResetBias = FALSE, AlternateShell = FALSE; 1358 PLDR_DATA_TABLE_ENTRY NtosEntry; 1359 PMESSAGE_RESOURCE_ENTRY MsgEntry; 1360 PCHAR CommandLine, Y2KHackRequired, SafeBoot, Environment; 1361 PCHAR StringBuffer, EndBuffer, BeginBuffer, MpString = ""; 1362 PINIT_BUFFER InitBuffer; 1363 ANSI_STRING TempString; 1364 ULONG LastTzBias, Length, YearHack = 0, Disposition, MessageCode = 0; 1365 SIZE_T Size; 1366 size_t Remaining; 1367 PRTL_USER_PROCESS_INFORMATION ProcessInfo; 1368 KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo; 1369 UNICODE_STRING KeyName; 1370 OBJECT_ATTRIBUTES ObjectAttributes; 1371 HANDLE KeyHandle, OptionHandle; 1372 PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; 1373 1374 /* Allocate the initialization buffer */ 1375 InitBuffer = ExAllocatePoolWithTag(NonPagedPool, 1376 sizeof(INIT_BUFFER), 1377 TAG_INIT); 1378 if (!InitBuffer) 1379 { 1380 /* Bugcheck */ 1381 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 8, 0, 0); 1382 } 1383 1384 /* Set to phase 1 */ 1385 ExpInitializationPhase = 1; 1386 1387 /* Set us at maximum priority */ 1388 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); 1389 1390 /* Do Phase 1 HAL Initialization */ 1391 if (!HalInitSystem(1, LoaderBlock)) KeBugCheck(HAL1_INITIALIZATION_FAILED); 1392 1393 /* Get the command line and upcase it */ 1394 CommandLine = (LoaderBlock->LoadOptions ? _strupr(LoaderBlock->LoadOptions) : NULL); 1395 1396 /* Check if GUI Boot is enabled */ 1397 NoGuiBoot = (CommandLine && strstr(CommandLine, "NOGUIBOOT") != NULL); 1398 1399 /* Get the SOS setting */ 1400 SosEnabled = (CommandLine && strstr(CommandLine, "SOS") != NULL); 1401 1402 /* Setup the boot video driver */ 1403 InbvEnableBootDriver(!NoGuiBoot); 1404 InbvDriverInitialize(LoaderBlock, IDB_MAX_RESOURCES); 1405 1406 /* Check if GUI boot is enabled */ 1407 if (!NoGuiBoot) 1408 { 1409 /* It is, display the boot logo and enable printing strings */ 1410 InbvEnableDisplayString(SosEnabled); 1411 DisplayBootBitmap(SosEnabled); 1412 } 1413 else 1414 { 1415 /* Release display ownership if not using GUI boot */ 1416 InbvNotifyDisplayOwnershipLost(NULL); 1417 1418 /* Don't allow boot-time strings */ 1419 InbvEnableDisplayString(FALSE); 1420 } 1421 1422 /* Check if this is LiveCD (WinPE) mode */ 1423 if (CommandLine && strstr(CommandLine, "MININT") != NULL) 1424 { 1425 /* Setup WinPE Settings */ 1426 InitIsWinPEMode = TRUE; 1427 InitWinPEModeType |= (strstr(CommandLine, "INRAM") != NULL) ? 0x80000000 : 0x00000001; 1428 } 1429 1430 /* Get the kernel's load entry */ 1431 NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, 1432 LDR_DATA_TABLE_ENTRY, 1433 InLoadOrderLinks); 1434 1435 /* Find the banner message */ 1436 MsgStatus = RtlFindMessage(NtosEntry->DllBase, 1437 RT_MESSAGETABLE, 1438 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), 1439 WINDOWS_NT_BANNER, 1440 &MsgEntry); 1441 1442 /* Setup defaults and check if we have a version string */ 1443 StringBuffer = InitBuffer->VersionBuffer; 1444 BeginBuffer = StringBuffer; 1445 EndBuffer = StringBuffer; 1446 Remaining = sizeof(InitBuffer->VersionBuffer); 1447 if (CmCSDVersionString.Length) 1448 { 1449 /* Print the version string */ 1450 Status = RtlStringCbPrintfExA(StringBuffer, 1451 Remaining, 1452 &EndBuffer, 1453 &Remaining, 1454 0, 1455 ": %wZ", 1456 &CmCSDVersionString); 1457 if (!NT_SUCCESS(Status)) 1458 { 1459 /* Bugcheck */ 1460 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1461 } 1462 } 1463 else 1464 { 1465 /* No version */ 1466 *EndBuffer = ANSI_NULL; /* Null-terminate the string */ 1467 } 1468 1469 /* Skip over the null-terminator to start a new string */ 1470 ++EndBuffer; 1471 --Remaining; 1472 1473 /* Build the version number */ 1474 StringBuffer = InitBuffer->VersionNumber; 1475 Status = RtlStringCbPrintfA(StringBuffer, 1476 sizeof(InitBuffer->VersionNumber), 1477 "%u.%u", 1478 VER_PRODUCTMAJORVERSION, 1479 VER_PRODUCTMINORVERSION); 1480 if (!NT_SUCCESS(Status)) 1481 { 1482 /* Bugcheck */ 1483 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1484 } 1485 1486 /* Check if we had found a banner message */ 1487 if (NT_SUCCESS(MsgStatus)) 1488 { 1489 /* Create the banner message */ 1490 /* ReactOS specific: Report ReactOS version, NtBuildLab information and reported NT kernel version */ 1491 Status = RtlStringCbPrintfA(EndBuffer, 1492 Remaining, 1493 (PCHAR)MsgEntry->Text, 1494 KERNEL_VERSION_STR, 1495 NtBuildLab, 1496 StringBuffer, 1497 NtBuildNumber & 0xFFFF, 1498 BeginBuffer); 1499 if (!NT_SUCCESS(Status)) 1500 { 1501 /* Bugcheck */ 1502 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1503 } 1504 } 1505 else 1506 { 1507 /* Use hard-coded banner message */ 1508 Status = RtlStringCbCopyA(EndBuffer, Remaining, "REACTOS (R)\r\n"); 1509 if (!NT_SUCCESS(Status)) 1510 { 1511 /* Bugcheck */ 1512 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1513 } 1514 } 1515 1516 /* Display the version string on-screen */ 1517 InbvDisplayString(EndBuffer); 1518 1519 /* Initialize Power Subsystem in Phase 0 */ 1520 if (!PoInitSystem(0)) KeBugCheck(INTERNAL_POWER_ERROR); 1521 1522 /* Check for Y2K hack */ 1523 Y2KHackRequired = CommandLine ? strstr(CommandLine, "YEAR") : NULL; 1524 if (Y2KHackRequired) Y2KHackRequired = strstr(Y2KHackRequired, "="); 1525 if (Y2KHackRequired) YearHack = atol(Y2KHackRequired + 1); 1526 1527 /* Query the clock */ 1528 if ((ExCmosClockIsSane) && (HalQueryRealTimeClock(&TimeFields))) 1529 { 1530 /* Check if we're using the Y2K hack */ 1531 if (Y2KHackRequired) TimeFields.Year = (CSHORT)YearHack; 1532 1533 /* Convert to time fields */ 1534 RtlTimeFieldsToTime(&TimeFields, &SystemBootTime); 1535 UniversalBootTime = SystemBootTime; 1536 1537 /* Check if real time is GMT */ 1538 if (!ExpRealTimeIsUniversal) 1539 { 1540 /* Check if we don't have a valid bias */ 1541 if (ExpLastTimeZoneBias == MAXULONG) 1542 { 1543 /* Reset */ 1544 ResetBias = TRUE; 1545 ExpLastTimeZoneBias = ExpAltTimeZoneBias; 1546 } 1547 1548 /* Calculate the bias in seconds */ 1549 ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60, 1550 10000000); 1551 1552 /* Set the boot time-zone bias */ 1553 SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart; 1554 SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart; 1555 SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart; 1556 1557 /* Convert the boot time to local time, and set it */ 1558 UniversalBootTime.QuadPart = SystemBootTime.QuadPart + 1559 ExpTimeZoneBias.QuadPart; 1560 } 1561 1562 /* Update the system time and notify the system */ 1563 KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); 1564 PoNotifySystemTimeSet(); 1565 1566 /* Remember this as the boot time */ 1567 KeBootTime = UniversalBootTime; 1568 KeBootTimeBias = 0; 1569 } 1570 1571#ifdef CONFIG_SMP 1572 /* 1573 * IMPORTANT NOTE: 1574 * Because ReactOS is a "nice" OS, we do not care _at all_ 1575 * about any number of registered/licensed processors: 1576 * no usage of KeRegisteredProcessors nor KeLicensedProcessors. 1577 */ 1578 if (CommandLine) 1579 { 1580 PSTR Option; 1581 1582 /* Check for NUMPROC: maximum number of logical processors 1583 * that can be started (including dynamically) at run-time */ 1584 Option = strstr(CommandLine, "NUMPROC"); 1585 if (Option) Option = strstr(Option, "="); 1586 if (Option) KeNumprocSpecified = atol(Option + 1); 1587 1588 /* Check for BOOTPROC (NT6+ and ReactOS): maximum number 1589 * of logical processors that can be started at boot-time */ 1590 Option = strstr(CommandLine, "BOOTPROC"); 1591 if (Option) Option = strstr(Option, "="); 1592 if (Option) KeBootprocSpecified = atol(Option + 1); 1593 1594 /* Check for MAXPROC (NT6+ and ReactOS): forces the kernel to report 1595 * as existing the maximum number of processors that can be handled */ 1596 if (strstr(CommandLine, "MAXPROC")) 1597 KeMaximumProcessors = MAXIMUM_PROCESSORS; 1598 } 1599 1600 /* Start Application Processors */ 1601 KeStartAllProcessors(); 1602#endif 1603 1604 /* Initialize all processors */ 1605 if (!HalAllProcessorsStarted()) KeBugCheck(HAL1_INITIALIZATION_FAILED); 1606 1607#ifdef CONFIG_SMP 1608 /* HACK: We should use RtlFindMessage and not only fallback to this */ 1609 MpString = "MultiProcessor Kernel\r\n"; 1610#endif 1611 1612 /* Setup the "MP" String */ 1613 RtlInitAnsiString(&TempString, MpString); 1614 1615 /* Make sure to remove the \r\n if we actually have a string */ 1616 while ((TempString.Length > 0) && 1617 ((TempString.Buffer[TempString.Length - 1] == '\r') || 1618 (TempString.Buffer[TempString.Length - 1] == '\n'))) 1619 { 1620 /* Skip the trailing character */ 1621 TempString.Length--; 1622 } 1623 1624 /* Get the information string from our resource file */ 1625 MsgStatus = RtlFindMessage(NtosEntry->DllBase, 1626 RT_MESSAGETABLE, 1627 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), 1628 KeNumberProcessors > 1 ? 1629 WINDOWS_NT_INFO_STRING_PLURAL : 1630 WINDOWS_NT_INFO_STRING, 1631 &MsgEntry); 1632 1633 /* Get total RAM size, in MiB */ 1634 /* Round size up. Assumed to better match actual physical RAM size */ 1635 Size = ALIGN_UP_BY(MmNumberOfPhysicalPages * PAGE_SIZE, 1024 * 1024) / (1024 * 1024); 1636 1637 /* Create the string */ 1638 StringBuffer = InitBuffer->VersionBuffer; 1639 Status = RtlStringCbPrintfA(StringBuffer, 1640 sizeof(InitBuffer->VersionBuffer), 1641 NT_SUCCESS(MsgStatus) ? 1642 (PCHAR)MsgEntry->Text : 1643 "%u System Processor [%Iu MB Memory] %Z\r\n", 1644 KeNumberProcessors, 1645 Size, 1646 &TempString); 1647 if (!NT_SUCCESS(Status)) 1648 { 1649 /* Bugcheck */ 1650 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 4, 0, 0); 1651 } 1652 1653 /* Display RAM and CPU count */ 1654 InbvDisplayString(StringBuffer); 1655 1656 /* Update the progress bar */ 1657 InbvUpdateProgressBar(5); 1658 1659 /* Call OB initialization again */ 1660 if (!ObInitSystem()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED); 1661 1662 /* Initialize Basic System Objects and Worker Threads */ 1663 if (!ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 1, 0); 1664 1665 /* Initialize the later stages of the kernel */ 1666 if (!KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 2, 0); 1667 1668 /* Call KD Providers at Phase 1 */ 1669 if (!KdInitSystem(ExpInitializationPhase, KeLoaderBlock)) 1670 { 1671 /* Failed, bugcheck */ 1672 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 3, 0); 1673 } 1674 1675 /* Initialize the SRM in Phase 1 */ 1676 if (!SeInitSystem()) KeBugCheck(SECURITY1_INITIALIZATION_FAILED); 1677 1678 /* Update the progress bar */ 1679 InbvUpdateProgressBar(10); 1680 1681 /* Create SystemRoot Link */ 1682 Status = ExpCreateSystemRootLink(LoaderBlock); 1683 if (!NT_SUCCESS(Status)) 1684 { 1685 /* Failed to create the system root link */ 1686 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0); 1687 } 1688 1689 /* Set up Region Maps, Sections and the Paging File */ 1690 if (!MmInitSystem(1, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED); 1691 1692 /* Create NLS section */ 1693 ExpInitNls(LoaderBlock); 1694 1695 /* Initialize Cache Views */ 1696 if (!CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED); 1697 1698 /* Initialize the Registry */ 1699 if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED); 1700 1701 /* Initialize Prefetcher */ 1702 CcPfInitializePrefetcher(); 1703 1704 /* Update progress bar */ 1705 InbvUpdateProgressBar(15); 1706 1707 /* Update timezone information */ 1708 LastTzBias = ExpLastTimeZoneBias; 1709 ExRefreshTimeZoneInformation(&SystemBootTime); 1710 1711 /* Check if we're resetting timezone data */ 1712 if (ResetBias) 1713 { 1714 /* Convert the local time to system time */ 1715 ExLocalTimeToSystemTime(&SystemBootTime, &UniversalBootTime); 1716 KeBootTime = UniversalBootTime; 1717 KeBootTimeBias = 0; 1718 1719 /* Set the new time */ 1720 KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); 1721 } 1722 else 1723 { 1724 /* Check if the timezone switched and update the time */ 1725 if (LastTzBias != ExpLastTimeZoneBias) 1726 ZwSetSystemTime(NULL, NULL); 1727 } 1728 1729 /* Initialize the File System Runtime Library */ 1730 if (!FsRtlInitSystem()) KeBugCheck(FILE_INITIALIZATION_FAILED); 1731 1732 /* Initialize range lists */ 1733 RtlInitializeRangeListPackage(); 1734 1735 /* Report all resources used by HAL */ 1736 HalReportResourceUsage(); 1737 1738 /* Call the debugger DLL */ 1739 KdDebuggerInitialize1(LoaderBlock); 1740 1741 /* Setup PnP Manager in phase 1 */ 1742 if (!PpInitSystem()) KeBugCheck(PP1_INITIALIZATION_FAILED); 1743 1744 /* Update progress bar */ 1745 InbvUpdateProgressBar(20); 1746 1747 /* Initialize LPC */ 1748 if (!LpcInitSystem()) KeBugCheck(LPC_INITIALIZATION_FAILED); 1749 1750 /* Make sure we have a command line */ 1751 if (CommandLine) 1752 { 1753 /* Check if this is a safe mode boot */ 1754 SafeBoot = strstr(CommandLine, "SAFEBOOT:"); 1755 if (SafeBoot) 1756 { 1757 /* Check what kind of boot this is */ 1758 SafeBoot += 9; 1759 if (!strncmp(SafeBoot, "MINIMAL", 7)) 1760 { 1761 /* Minimal mode */ 1762 InitSafeBootMode = 1; 1763 SafeBoot += 7; 1764 MessageCode = BOOTING_IN_SAFEMODE_MINIMAL; 1765 } 1766 else if (!strncmp(SafeBoot, "NETWORK", 7)) 1767 { 1768 /* With Networking */ 1769 InitSafeBootMode = 2; 1770 SafeBoot += 7; 1771 MessageCode = BOOTING_IN_SAFEMODE_NETWORK; 1772 } 1773 else if (!strncmp(SafeBoot, "DSREPAIR", 8)) 1774 { 1775 /* Domain Server Repair */ 1776 InitSafeBootMode = 3; 1777 SafeBoot += 8; 1778 MessageCode = BOOTING_IN_SAFEMODE_DSREPAIR; 1779 1780 } 1781 else 1782 { 1783 /* Invalid */ 1784 InitSafeBootMode = 0; 1785 } 1786 1787 /* Check if there's any settings left */ 1788 if (*SafeBoot) 1789 { 1790 /* Check if an alternate shell was requested */ 1791 if (!strncmp(SafeBoot, "(ALTERNATESHELL)", 16)) 1792 { 1793 /* Remember this for later */ 1794 AlternateShell = TRUE; 1795 } 1796 } 1797 1798 /* Find the message to print out */ 1799 Status = RtlFindMessage(NtosEntry->DllBase, 1800 RT_MESSAGETABLE, 1801 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), 1802 MessageCode, 1803 &MsgEntry); 1804 if (NT_SUCCESS(Status)) 1805 { 1806 /* Display it */ 1807 InbvDisplayString((PCSTR)MsgEntry->Text); 1808 } 1809 } 1810 } 1811 1812 /* Make sure we have a command line */ 1813 if (CommandLine) 1814 { 1815 /* Check if bootlogging is enabled */ 1816 if (strstr(CommandLine, "BOOTLOG")) 1817 { 1818 /* Find the message to print out */ 1819 Status = RtlFindMessage(NtosEntry->DllBase, 1820 RT_MESSAGETABLE, 1821 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), 1822 BOOTLOG_ENABLED, 1823 &MsgEntry); 1824 if (NT_SUCCESS(Status)) 1825 { 1826 /* Display it */ 1827 InbvDisplayString((PCSTR)MsgEntry->Text); 1828 } 1829 1830 /* Setup boot logging */ 1831 //IopInitializeBootLogging(LoaderBlock, InitBuffer->BootlogHeader); 1832 } 1833 } 1834 1835 /* Setup the Executive in Phase 2 */ 1836 //ExInitSystemPhase2(); 1837 1838 /* Update progress bar */ 1839 InbvUpdateProgressBar(25); 1840 1841 /* No KD Time Slip is pending */ 1842 KdpTimeSlipPending = 0; 1843 1844 /* Initialize in-place execution support */ 1845 XIPInit(LoaderBlock); 1846 1847 /* Set maximum update to 75% */ 1848 InbvSetProgressBarSubset(25, 75); 1849 1850 /* Initialize the I/O Subsystem */ 1851 if (!IoInitSystem(LoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED); 1852 1853 /* Set maximum update to 100% */ 1854 InbvSetProgressBarSubset(0, 100); 1855 1856 /* Are we in safe mode? */ 1857 if (InitSafeBootMode) 1858 { 1859 /* Open the safe boot key */ 1860 RtlInitUnicodeString(&KeyName, 1861 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" 1862 L"\\CONTROL\\SAFEBOOT"); 1863 InitializeObjectAttributes(&ObjectAttributes, 1864 &KeyName, 1865 OBJ_CASE_INSENSITIVE, 1866 NULL, 1867 NULL); 1868 Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); 1869 if (NT_SUCCESS(Status)) 1870 { 1871 /* First check if we have an alternate shell */ 1872 if (AlternateShell) 1873 { 1874 /* Make sure that the registry has one setup */ 1875 RtlInitUnicodeString(&KeyName, L"AlternateShell"); 1876 Status = NtQueryValueKey(KeyHandle, 1877 &KeyName, 1878 KeyValuePartialInformation, 1879 &KeyPartialInfo, 1880 sizeof(KeyPartialInfo), 1881 &Length); 1882 if (!(NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)) 1883 { 1884 AlternateShell = FALSE; 1885 } 1886 } 1887 1888 /* Create the option key */ 1889 RtlInitUnicodeString(&KeyName, L"Option"); 1890 InitializeObjectAttributes(&ObjectAttributes, 1891 &KeyName, 1892 OBJ_CASE_INSENSITIVE, 1893 KeyHandle, 1894 NULL); 1895 Status = ZwCreateKey(&OptionHandle, 1896 KEY_ALL_ACCESS, 1897 &ObjectAttributes, 1898 0, 1899 NULL, 1900 REG_OPTION_VOLATILE, 1901 &Disposition); 1902 NtClose(KeyHandle); 1903 1904 /* Check if the key create worked */ 1905 if (NT_SUCCESS(Status)) 1906 { 1907 /* Write the safe boot type */ 1908 RtlInitUnicodeString(&KeyName, L"OptionValue"); 1909 NtSetValueKey(OptionHandle, 1910 &KeyName, 1911 0, 1912 REG_DWORD, 1913 &InitSafeBootMode, 1914 sizeof(InitSafeBootMode)); 1915 1916 /* Check if we have to use an alternate shell */ 1917 if (AlternateShell) 1918 { 1919 /* Remember this for later */ 1920 Disposition = TRUE; 1921 RtlInitUnicodeString(&KeyName, L"UseAlternateShell"); 1922 NtSetValueKey(OptionHandle, 1923 &KeyName, 1924 0, 1925 REG_DWORD, 1926 &Disposition, 1927 sizeof(Disposition)); 1928 } 1929 1930 /* Close the options key handle */ 1931 NtClose(OptionHandle); 1932 } 1933 } 1934 } 1935 1936 /* Are we in Win PE mode? */ 1937 if (InitIsWinPEMode) 1938 { 1939 /* Open the safe control key */ 1940 RtlInitUnicodeString(&KeyName, 1941 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" 1942 L"\\CONTROL"); 1943 InitializeObjectAttributes(&ObjectAttributes, 1944 &KeyName, 1945 OBJ_CASE_INSENSITIVE, 1946 NULL, 1947 NULL); 1948 Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); 1949 if (!NT_SUCCESS(Status)) 1950 { 1951 /* Bugcheck */ 1952 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); 1953 } 1954 1955 /* Create the MiniNT key */ 1956 RtlInitUnicodeString(&KeyName, L"MiniNT"); 1957 InitializeObjectAttributes(&ObjectAttributes, 1958 &KeyName, 1959 OBJ_CASE_INSENSITIVE, 1960 KeyHandle, 1961 NULL); 1962 Status = ZwCreateKey(&OptionHandle, 1963 KEY_ALL_ACCESS, 1964 &ObjectAttributes, 1965 0, 1966 NULL, 1967 REG_OPTION_VOLATILE, 1968 &Disposition); 1969 if (!NT_SUCCESS(Status)) 1970 { 1971 /* Bugcheck */ 1972 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); 1973 } 1974 1975 /* Close the handles */ 1976 NtClose(KeyHandle); 1977 NtClose(OptionHandle); 1978 } 1979 1980 /* FIXME: This doesn't do anything for now */ 1981 MmArmInitSystem(2, LoaderBlock); 1982 1983 /* Update progress bar */ 1984 InbvUpdateProgressBar(80); 1985 1986 /* Initialize VDM support */ 1987#if defined(_M_IX86) 1988 KeI386VdmInitialize(); 1989#endif 1990 1991 /* Initialize Power Subsystem in Phase 1*/ 1992 if (!PoInitSystem(1)) KeBugCheck(INTERNAL_POWER_ERROR); 1993 1994 /* Update progress bar */ 1995 InbvUpdateProgressBar(90); 1996 1997 /* Initialize the Process Manager at Phase 1 */ 1998 if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS1_INITIALIZATION_FAILED); 1999 2000 /* Make sure nobody touches the loader block again */ 2001 if (LoaderBlock == KeLoaderBlock) KeLoaderBlock = NULL; 2002 MmFreeLoaderBlock(LoaderBlock); 2003 LoaderBlock = Context = NULL; 2004 2005 /* Initialize the SRM in phase 1 */ 2006 if (!SeRmInitPhase1()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED); 2007 2008 /* Update progress bar */ 2009 InbvUpdateProgressBar(100); 2010 2011 /* Clear the screen */ 2012 if (InbvBootDriverInstalled) FinalizeBootLogo(); 2013 2014 /* Allow strings to be displayed */ 2015 InbvEnableDisplayString(TRUE); 2016 2017 /* Launch initial process */ 2018 ProcessInfo = &InitBuffer->ProcessInfo; 2019 ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment); 2020 2021 /* Wait 5 seconds for initial process to initialize */ 2022 Timeout.QuadPart = Int32x32To64(5, -10000000); 2023 Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout); 2024 if (Status == STATUS_SUCCESS) 2025 { 2026 /* Failed, display error */ 2027 DPRINT1("INIT: Session Manager terminated.\n"); 2028 2029 /* Bugcheck the system if SMSS couldn't initialize */ 2030 KeBugCheck(SESSION5_INITIALIZATION_FAILED); 2031 } 2032 2033 /* Close process handles */ 2034 ZwClose(ProcessInfo->ThreadHandle); 2035 ZwClose(ProcessInfo->ProcessHandle); 2036 2037 /* Free the initial process environment */ 2038 Size = 0; 2039 ZwFreeVirtualMemory(NtCurrentProcess(), 2040 (PVOID*)&Environment, 2041 &Size, 2042 MEM_RELEASE); 2043 2044 /* Free the initial process parameters */ 2045 Size = 0; 2046 ZwFreeVirtualMemory(NtCurrentProcess(), 2047 (PVOID*)&ProcessParameters, 2048 &Size, 2049 MEM_RELEASE); 2050 2051 /* Increase init phase */ 2052 ExpInitializationPhase++; 2053 2054 /* Free the boot buffer */ 2055 ExFreePoolWithTag(InitBuffer, TAG_INIT); 2056} 2057 2058VOID 2059NTAPI 2060Phase1Initialization(IN PVOID Context) 2061{ 2062 /* Do the .INIT part of Phase 1 which we can free later */ 2063 Phase1InitializationDiscard(Context); 2064 2065 /* Jump into zero page thread */ 2066 MmZeroPageThread(); 2067}