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