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