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 NTSTATUS 95 NTAPI 96 INIT_FUNCTION 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 VOID 207 NTAPI 208 INIT_FUNCTION 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 VOID 383 NTAPI 384 INIT_FUNCTION 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 ULONG 600 NTAPI 601 INIT_FUNCTION 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 BOOLEAN 633 NTAPI 634 INIT_FUNCTION 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 BOOLEAN 656 NTAPI 657 INIT_FUNCTION 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 ExpInitUuids(); 715 716 /* Initialize keyed events */ 717 if (ExpInitializeKeyedEventImplementation() == FALSE) 718 { 719 DPRINT1("Executive: Keyed event initialization failed\n"); 720 return FALSE; 721 } 722 723 /* Initialize Win32K */ 724 if (ExpWin32kInit() == FALSE) 725 { 726 DPRINT1("Executive: Win32 initialization failed\n"); 727 return FALSE; 728 } 729 return TRUE; 730 } 731 732 BOOLEAN 733 NTAPI 734 INIT_FUNCTION 735 ExInitSystem(VOID) 736 { 737 /* Check the initialization phase */ 738 switch (ExpInitializationPhase) 739 { 740 case 0: 741 742 /* Do Phase 0 */ 743 return ExpInitSystemPhase0(); 744 745 case 1: 746 747 /* Do Phase 1 */ 748 return ExpInitSystemPhase1(); 749 750 default: 751 752 /* Don't know any other phase! Bugcheck! */ 753 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL); 754 return FALSE; 755 } 756 } 757 758 BOOLEAN 759 NTAPI 760 INIT_FUNCTION 761 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 762 { 763 PLOADER_PARAMETER_EXTENSION Extension; 764 765 /* Get the loader extension */ 766 Extension = LoaderBlock->Extension; 767 768 /* Validate the size (Windows 2003 loader doesn't provide more) */ 769 if (Extension->Size < LOADER_PARAMETER_EXTENSION_MIN_SIZE) return FALSE; 770 771 /* Don't validate upper versions */ 772 if (Extension->MajorVersion > VER_PRODUCTMAJORVERSION) return TRUE; 773 774 /* Fail if this is NT 4 */ 775 if (Extension->MajorVersion < VER_PRODUCTMAJORVERSION) return FALSE; 776 777 /* Fail if this is XP */ 778 if (Extension->MinorVersion < VER_PRODUCTMINORVERSION) return FALSE; 779 780 /* This is 2003 or newer, approve it */ 781 return TRUE; 782 } 783 784 VOID 785 NTAPI 786 INIT_FUNCTION 787 ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 788 { 789 ULONG i = 0; 790 PLIST_ENTRY NextEntry; 791 ULONG Count, Length; 792 PWCHAR Name; 793 PLDR_DATA_TABLE_ENTRY LdrEntry; 794 CHAR NameBuffer[256]; 795 STRING SymbolString; 796 NTSTATUS Status; 797 798 /* Loop the driver list */ 799 NextEntry = LoaderBlock->LoadOrderListHead.Flink; 800 while (NextEntry != &LoaderBlock->LoadOrderListHead) 801 { 802 /* Skip the first two images */ 803 if (i >= 2) 804 { 805 /* Get the entry */ 806 LdrEntry = CONTAINING_RECORD(NextEntry, 807 LDR_DATA_TABLE_ENTRY, 808 InLoadOrderLinks); 809 if (LdrEntry->FullDllName.Buffer[0] == L'\\') 810 { 811 /* We have a name, read its data */ 812 Name = LdrEntry->FullDllName.Buffer; 813 Length = LdrEntry->FullDllName.Length / sizeof(WCHAR); 814 815 /* Check if our buffer can hold it */ 816 if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL)) 817 { 818 /* It's too long */ 819 Status = STATUS_BUFFER_OVERFLOW; 820 } 821 else 822 { 823 /* Copy the name */ 824 Count = 0; 825 do 826 { 827 /* Copy the character */ 828 NameBuffer[Count++] = (CHAR)*Name++; 829 } while (Count < Length); 830 831 /* Null-terminate */ 832 NameBuffer[Count] = ANSI_NULL; 833 Status = STATUS_SUCCESS; 834 } 835 } 836 else 837 { 838 /* Safely print the string into our buffer */ 839 Status = RtlStringCbPrintfA(NameBuffer, 840 sizeof(NameBuffer), 841 "%S\\System32\\Drivers\\%wZ", 842 &SharedUserData->NtSystemRoot[2], 843 &LdrEntry->BaseDllName); 844 } 845 846 /* Check if the buffer was ok */ 847 if (NT_SUCCESS(Status)) 848 { 849 /* Initialize the STRING for the debugger */ 850 RtlInitString(&SymbolString, NameBuffer); 851 852 /* Load the symbols */ 853 DbgLoadImageSymbols(&SymbolString, 854 LdrEntry->DllBase, 855 (ULONG_PTR)PsGetCurrentProcessId()); 856 } 857 } 858 859 /* Go to the next entry */ 860 i++; 861 NextEntry = NextEntry->Flink; 862 } 863 } 864 865 VOID 866 NTAPI 867 INIT_FUNCTION 868 ExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, 869 IN ULONG_PTR PagesToDestroy, 870 IN TYPE_OF_MEMORY MemoryType) 871 { 872 PLIST_ENTRY ListEntry; 873 PMEMORY_ALLOCATION_DESCRIPTOR MemDescriptor; 874 875 DPRINT1("Burn RAM amount: %lu pages\n", PagesToDestroy); 876 877 /* Loop the memory descriptors, beginning at the end */ 878 for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Blink; 879 ListEntry != &LoaderBlock->MemoryDescriptorListHead; 880 ListEntry = ListEntry->Blink) 881 { 882 /* Get the memory descriptor structure */ 883 MemDescriptor = CONTAINING_RECORD(ListEntry, 884 MEMORY_ALLOCATION_DESCRIPTOR, 885 ListEntry); 886 887 /* Is memory free there or is it temporary? */ 888 if (MemDescriptor->MemoryType == LoaderFree || 889 MemDescriptor->MemoryType == LoaderFirmwareTemporary) 890 { 891 /* Check if the descriptor has more pages than we want */ 892 if (MemDescriptor->PageCount > PagesToDestroy) 893 { 894 /* Change block's page count, ntoskrnl doesn't care much */ 895 MemDescriptor->PageCount -= PagesToDestroy; 896 break; 897 } 898 else 899 { 900 /* Change block type */ 901 MemDescriptor->MemoryType = MemoryType; 902 PagesToDestroy -= MemDescriptor->PageCount; 903 904 /* Check if we are done */ 905 if (PagesToDestroy == 0) break; 906 } 907 } 908 } 909 } 910 911 VOID 912 NTAPI 913 INIT_FUNCTION 914 ExpInitializeExecutive(IN ULONG Cpu, 915 IN PLOADER_PARAMETER_BLOCK LoaderBlock) 916 { 917 PNLS_DATA_BLOCK NlsData; 918 CHAR Buffer[256]; 919 ANSI_STRING AnsiPath; 920 NTSTATUS Status; 921 PCHAR CommandLine, PerfMem; 922 ULONG PerfMemUsed; 923 PLDR_DATA_TABLE_ENTRY NtosEntry; 924 PMESSAGE_RESOURCE_ENTRY MsgEntry; 925 ANSI_STRING CSDString; 926 size_t Remaining = 0; 927 PCHAR RcEnd = NULL; 928 CHAR VersionBuffer[65]; 929 930 /* Validate Loader */ 931 if (!ExpIsLoaderValid(LoaderBlock)) 932 { 933 /* Invalid loader version */ 934 KeBugCheckEx(MISMATCHED_HAL, 935 3, 936 LoaderBlock->Extension->Size, 937 LoaderBlock->Extension->MajorVersion, 938 LoaderBlock->Extension->MinorVersion); 939 } 940 941 /* Initialize PRCB pool lookaside pointers */ 942 ExInitPoolLookasidePointers(); 943 944 /* Check if this is an application CPU */ 945 if (Cpu) 946 { 947 /* Then simply initialize it with HAL */ 948 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) 949 { 950 /* Initialization failed */ 951 KeBugCheck(HAL_INITIALIZATION_FAILED); 952 } 953 954 /* We're done */ 955 return; 956 } 957 958 /* Assume no text-mode or remote boot */ 959 ExpInTextModeSetup = FALSE; 960 IoRemoteBootClient = FALSE; 961 962 /* Check if we have a setup loader block */ 963 if (LoaderBlock->SetupLdrBlock) 964 { 965 /* Check if this is text-mode setup */ 966 if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_TEXT_MODE) ExpInTextModeSetup = TRUE; 967 968 /* Check if this is network boot */ 969 if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_REMOTE_BOOT) 970 { 971 /* Set variable */ 972 IoRemoteBootClient = TRUE; 973 974 /* Make sure we're actually booting off the network */ 975 ASSERT(!_memicmp(LoaderBlock->ArcBootDeviceName, "net(0)", 6)); 976 } 977 } 978 979 /* Set phase to 0 */ 980 ExpInitializationPhase = 0; 981 982 /* Get boot command line */ 983 CommandLine = LoaderBlock->LoadOptions; 984 if (CommandLine) 985 { 986 /* Upcase it for comparison and check if we're in performance mode */ 987 _strupr(CommandLine); 988 PerfMem = strstr(CommandLine, "PERFMEM"); 989 if (PerfMem) 990 { 991 /* Check if the user gave a number of bytes to use */ 992 PerfMem = strstr(PerfMem, "="); 993 if (PerfMem) 994 { 995 /* Read the number of pages we'll use */ 996 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); 997 if (PerfMem) 998 { 999 /* FIXME: TODO */ 1000 DPRINT1("BBT performance mode not yet supported." 1001 "/PERFMEM option ignored.\n"); 1002 } 1003 } 1004 } 1005 1006 /* Check if we're burning memory */ 1007 PerfMem = strstr(CommandLine, "BURNMEMORY"); 1008 if (PerfMem) 1009 { 1010 /* Check if the user gave a number of bytes to use */ 1011 PerfMem = strstr(PerfMem, "="); 1012 if (PerfMem) 1013 { 1014 /* Read the number of pages we'll use */ 1015 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); 1016 if (PerfMemUsed) ExBurnMemory(LoaderBlock, PerfMemUsed, LoaderBad); 1017 } 1018 } 1019 } 1020 1021 /* Setup NLS Base and offsets */ 1022 NlsData = LoaderBlock->NlsData; 1023 ExpNlsTableBase = NlsData->AnsiCodePageData; 1024 ExpAnsiCodePageDataOffset = 0; 1025 ExpOemCodePageDataOffset = (ULONG)((ULONG_PTR)NlsData->OemCodePageData - 1026 (ULONG_PTR)NlsData->AnsiCodePageData); 1027 ExpUnicodeCaseTableDataOffset = (ULONG)((ULONG_PTR)NlsData->UnicodeCodePageData - 1028 (ULONG_PTR)NlsData->AnsiCodePageData); 1029 1030 /* Initialize the NLS Tables */ 1031 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + 1032 ExpAnsiCodePageDataOffset), 1033 (PVOID)((ULONG_PTR)ExpNlsTableBase + 1034 ExpOemCodePageDataOffset), 1035 (PVOID)((ULONG_PTR)ExpNlsTableBase + 1036 ExpUnicodeCaseTableDataOffset), 1037 &ExpNlsTableInfo); 1038 RtlResetRtlTranslations(&ExpNlsTableInfo); 1039 1040 /* Now initialize the HAL */ 1041 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) 1042 { 1043 /* HAL failed to initialize, bugcheck */ 1044 KeBugCheck(HAL_INITIALIZATION_FAILED); 1045 } 1046 1047 /* Make sure interrupts are active now */ 1048 _enable(); 1049 1050 /* Clear the crypto exponent */ 1051 SharedUserData->CryptoExponent = 0; 1052 1053 /* Set global flags for the checked build */ 1054 #if DBG 1055 NtGlobalFlag |= FLG_ENABLE_CLOSE_EXCEPTIONS | 1056 FLG_ENABLE_KDEBUG_SYMBOL_LOAD; 1057 #endif 1058 1059 /* Setup NT System Root Path */ 1060 sprintf(Buffer, "C:%s", LoaderBlock->NtBootPathName); 1061 1062 /* Convert to ANSI_STRING and null-terminate it */ 1063 RtlInitString(&AnsiPath, Buffer); 1064 Buffer[--AnsiPath.Length] = ANSI_NULL; 1065 1066 /* Get the string from KUSER_SHARED_DATA's buffer */ 1067 RtlInitEmptyUnicodeString(&NtSystemRoot, 1068 SharedUserData->NtSystemRoot, 1069 sizeof(SharedUserData->NtSystemRoot)); 1070 1071 /* Now fill it in */ 1072 Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE); 1073 if (!NT_SUCCESS(Status)) KeBugCheck(SESSION3_INITIALIZATION_FAILED); 1074 1075 /* Setup bugcheck messages */ 1076 KiInitializeBugCheck(); 1077 1078 /* Setup initial system settings */ 1079 CmGetSystemControlValues(LoaderBlock->RegistryBase, CmControlVector); 1080 1081 /* Set the Service Pack Number and add it to the CSD Version number if needed */ 1082 CmNtSpBuildNumber = VER_PRODUCTBUILD_QFE; 1083 if (((CmNtCSDVersion & 0xFFFF0000) == 0) && (CmNtCSDReleaseType == 1)) 1084 { 1085 CmNtCSDVersion |= (VER_PRODUCTBUILD_QFE << 16); 1086 } 1087 1088 /* Add loaded CmNtGlobalFlag value */ 1089 NtGlobalFlag |= CmNtGlobalFlag; 1090 1091 /* Initialize the executive at phase 0 */ 1092 if (!ExInitSystem()) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 1093 1094 /* Initialize the memory manager at phase 0 */ 1095 if (!MmArmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 1096 1097 /* Load boot symbols */ 1098 ExpLoadBootSymbols(LoaderBlock); 1099 1100 /* Check if we should break after symbol load */ 1101 if (KdBreakAfterSymbolLoad) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); 1102 1103 /* Check if this loader is compatible with NT 5.2 */ 1104 if (LoaderBlock->Extension->Size >= sizeof(LOADER_PARAMETER_EXTENSION)) 1105 { 1106 /* Setup headless terminal settings */ 1107 HeadlessInit(LoaderBlock); 1108 } 1109 1110 /* Set system ranges */ 1111 #ifdef _M_AMD64 1112 SharedUserData->Reserved1 = MM_HIGHEST_USER_ADDRESS_WOW64; 1113 SharedUserData->Reserved3 = MM_SYSTEM_RANGE_START_WOW64; 1114 #else 1115 SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress; 1116 SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart; 1117 #endif 1118 1119 /* Make a copy of the NLS Tables */ 1120 ExpInitNls(LoaderBlock); 1121 1122 /* Get the kernel's load entry */ 1123 NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, 1124 LDR_DATA_TABLE_ENTRY, 1125 InLoadOrderLinks); 1126 1127 /* Check if this is a service pack */ 1128 if (CmNtCSDVersion & 0xFFFF) 1129 { 1130 /* Get the service pack string */ 1131 Status = RtlFindMessage(NtosEntry->DllBase, 1132 11, 1133 0, 1134 WINDOWS_NT_CSD_STRING, 1135 &MsgEntry); 1136 if (NT_SUCCESS(Status)) 1137 { 1138 /* Setup the string */ 1139 RtlInitAnsiString(&CSDString, (PCHAR)MsgEntry->Text); 1140 1141 /* Remove trailing newline */ 1142 while ((CSDString.Length > 0) && 1143 ((CSDString.Buffer[CSDString.Length - 1] == '\r') || 1144 (CSDString.Buffer[CSDString.Length - 1] == '\n'))) 1145 { 1146 /* Skip the trailing character */ 1147 CSDString.Length--; 1148 } 1149 1150 /* Fill the buffer with version information */ 1151 Status = RtlStringCbPrintfA(Buffer, 1152 sizeof(Buffer), 1153 "%Z %u%c", 1154 &CSDString, 1155 (CmNtCSDVersion & 0xFF00) >> 8, 1156 (CmNtCSDVersion & 0xFF) ? 1157 'A' + (CmNtCSDVersion & 0xFF) - 1 : 1158 ANSI_NULL); 1159 } 1160 else 1161 { 1162 /* Build default string */ 1163 Status = RtlStringCbPrintfA(Buffer, 1164 sizeof(Buffer), 1165 "CSD %04x", 1166 CmNtCSDVersion); 1167 } 1168 1169 /* Check for success */ 1170 if (!NT_SUCCESS(Status)) 1171 { 1172 /* Fail */ 1173 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1174 } 1175 } 1176 else 1177 { 1178 /* Then this is a beta */ 1179 Status = RtlStringCbCopyExA(Buffer, 1180 sizeof(Buffer), 1181 VER_PRODUCTBETA_STR, 1182 NULL, 1183 &Remaining, 1184 0); 1185 if (!NT_SUCCESS(Status)) 1186 { 1187 /* Fail */ 1188 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1189 } 1190 1191 /* Update length */ 1192 CmCSDVersionString.MaximumLength = sizeof(Buffer) - (USHORT)Remaining; 1193 } 1194 1195 /* Check if we have an RC number */ 1196 if ((CmNtCSDVersion & 0xFFFF0000) && (CmNtCSDReleaseType == 1)) 1197 { 1198 /* Check if we have no version data yet */ 1199 if (!(*Buffer)) 1200 { 1201 /* Set defaults */ 1202 Remaining = sizeof(Buffer); 1203 RcEnd = Buffer; 1204 } 1205 else 1206 { 1207 /* Add comma and space */ 1208 Status = RtlStringCbCatExA(Buffer, 1209 sizeof(Buffer), 1210 ", ", 1211 &RcEnd, 1212 &Remaining, 1213 0); 1214 if (!NT_SUCCESS(Status)) 1215 { 1216 /* Fail */ 1217 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1218 } 1219 } 1220 1221 /* Add the version format string */ 1222 Status = RtlStringCbPrintfA(RcEnd, 1223 Remaining, 1224 "v.%u", 1225 (CmNtCSDVersion & 0xFFFF0000) >> 16); 1226 if (!NT_SUCCESS(Status)) 1227 { 1228 /* Fail */ 1229 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1230 } 1231 } 1232 1233 /* Now setup the final string */ 1234 RtlInitAnsiString(&CSDString, Buffer); 1235 Status = RtlAnsiStringToUnicodeString(&CmCSDVersionString, 1236 &CSDString, 1237 TRUE); 1238 if (!NT_SUCCESS(Status)) 1239 { 1240 /* Fail */ 1241 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1242 } 1243 1244 /* Add our version */ 1245 Status = RtlStringCbPrintfA(VersionBuffer, 1246 sizeof(VersionBuffer), 1247 "%u.%u", 1248 VER_PRODUCTMAJORVERSION, 1249 VER_PRODUCTMINORVERSION); 1250 if (!NT_SUCCESS(Status)) 1251 { 1252 /* Fail */ 1253 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 1254 } 1255 1256 /* Build the final version string */ 1257 RtlCreateUnicodeStringFromAsciiz(&CmVersionString, VersionBuffer); 1258 1259 /* Check if the user wants a kernel stack trace database */ 1260 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) 1261 { 1262 /* FIXME: TODO */ 1263 DPRINT1("Kernel-mode stack trace support not yet present." 1264 "FLG_KERNEL_STACK_TRACE_DB flag ignored.\n"); 1265 } 1266 1267 /* Check if he wanted exception logging */ 1268 if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING) 1269 { 1270 /* FIXME: TODO */ 1271 DPRINT1("Kernel-mode exception logging support not yet present." 1272 "FLG_ENABLE_EXCEPTION_LOGGING flag ignored.\n"); 1273 } 1274 1275 /* Initialize the Handle Table */ 1276 ExpInitializeHandleTables(); 1277 1278 #if DBG 1279 /* On checked builds, allocate the system call count table */ 1280 KeServiceDescriptorTable[0].Count = 1281 ExAllocatePoolWithTag(NonPagedPool, 1282 KiServiceLimit * sizeof(ULONG), 1283 'llaC'); 1284 1285 /* Use it for the shadow table too */ 1286 KeServiceDescriptorTableShadow[0].Count = KeServiceDescriptorTable[0].Count; 1287 1288 /* Make sure allocation succeeded */ 1289 if (KeServiceDescriptorTable[0].Count) 1290 { 1291 /* Zero the call counts to 0 */ 1292 RtlZeroMemory(KeServiceDescriptorTable[0].Count, 1293 KiServiceLimit * sizeof(ULONG)); 1294 } 1295 #endif 1296 1297 /* Create the Basic Object Manager Types to allow new Object Types */ 1298 if (!ObInitSystem()) KeBugCheck(OBJECT_INITIALIZATION_FAILED); 1299 1300 /* Load basic Security for other Managers */ 1301 if (!SeInitSystem()) KeBugCheck(SECURITY_INITIALIZATION_FAILED); 1302 1303 /* Initialize the Process Manager */ 1304 if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS_INITIALIZATION_FAILED); 1305 1306 /* Initialize the PnP Manager */ 1307 if (!PpInitSystem()) KeBugCheck(PP0_INITIALIZATION_FAILED); 1308 1309 /* Initialize the User-Mode Debugging Subsystem */ 1310 DbgkInitialize(); 1311 1312 /* Calculate the tick count multiplier */ 1313 ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement); 1314 SharedUserData->TickCountMultiplier = ExpTickCountMultiplier; 1315 1316 /* Set the OS Version */ 1317 SharedUserData->NtMajorVersion = NtMajorVersion; 1318 SharedUserData->NtMinorVersion = NtMinorVersion; 1319 1320 /* Set the machine type */ 1321 SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_NATIVE; 1322 SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_NATIVE; 1323 } 1324 1325 VOID 1326 NTAPI 1327 MmFreeLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock); 1328 1329 VOID 1330 NTAPI 1331 INIT_FUNCTION 1332 Phase1InitializationDiscard(IN PVOID Context) 1333 { 1334 PLOADER_PARAMETER_BLOCK LoaderBlock = Context; 1335 NTSTATUS Status, MsgStatus; 1336 TIME_FIELDS TimeFields; 1337 LARGE_INTEGER SystemBootTime, UniversalBootTime, OldTime, Timeout; 1338 BOOLEAN SosEnabled, NoGuiBoot, ResetBias = FALSE, AlternateShell = FALSE; 1339 PLDR_DATA_TABLE_ENTRY NtosEntry; 1340 PMESSAGE_RESOURCE_ENTRY MsgEntry; 1341 PCHAR CommandLine, Y2KHackRequired, SafeBoot, Environment; 1342 PCHAR StringBuffer, EndBuffer, BeginBuffer, MpString = ""; 1343 PINIT_BUFFER InitBuffer; 1344 ANSI_STRING TempString; 1345 ULONG LastTzBias, Length, YearHack = 0, Disposition, MessageCode = 0; 1346 SIZE_T Size; 1347 size_t Remaining; 1348 PRTL_USER_PROCESS_INFORMATION ProcessInfo; 1349 KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo; 1350 UNICODE_STRING KeyName; 1351 OBJECT_ATTRIBUTES ObjectAttributes; 1352 HANDLE KeyHandle, OptionHandle; 1353 PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; 1354 1355 /* Allocate the initialization buffer */ 1356 InitBuffer = ExAllocatePoolWithTag(NonPagedPool, 1357 sizeof(INIT_BUFFER), 1358 TAG_INIT); 1359 if (!InitBuffer) 1360 { 1361 /* Bugcheck */ 1362 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 8, 0, 0); 1363 } 1364 1365 /* Set to phase 1 */ 1366 ExpInitializationPhase = 1; 1367 1368 /* Set us at maximum priority */ 1369 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); 1370 1371 /* Do Phase 1 HAL Initialization */ 1372 if (!HalInitSystem(1, LoaderBlock)) KeBugCheck(HAL1_INITIALIZATION_FAILED); 1373 1374 /* Get the command line and upcase it */ 1375 CommandLine = (LoaderBlock->LoadOptions ? _strupr(LoaderBlock->LoadOptions) : NULL); 1376 1377 /* Check if GUI Boot is enabled */ 1378 NoGuiBoot = (CommandLine && strstr(CommandLine, "NOGUIBOOT") != NULL); 1379 1380 /* Get the SOS setting */ 1381 SosEnabled = (CommandLine && strstr(CommandLine, "SOS") != NULL); 1382 1383 /* Setup the boot driver */ 1384 InbvEnableBootDriver(!NoGuiBoot); 1385 InbvDriverInitialize(LoaderBlock, IDB_MAX_RESOURCE); 1386 1387 /* Check if GUI boot is enabled */ 1388 if (!NoGuiBoot) 1389 { 1390 /* It is, display the boot logo and enable printing strings */ 1391 InbvEnableDisplayString(SosEnabled); 1392 DisplayBootBitmap(SosEnabled); 1393 } 1394 else 1395 { 1396 /* Release display ownership if not using GUI boot */ 1397 InbvNotifyDisplayOwnershipLost(NULL); 1398 1399 /* Don't allow boot-time strings */ 1400 InbvEnableDisplayString(FALSE); 1401 } 1402 1403 /* Check if this is LiveCD (WinPE) mode */ 1404 if (CommandLine && strstr(CommandLine, "MININT") != NULL) 1405 { 1406 /* Setup WinPE Settings */ 1407 InitIsWinPEMode = TRUE; 1408 InitWinPEModeType |= (strstr(CommandLine, "INRAM") != NULL) ? 0x80000000 : 0x00000001; 1409 } 1410 1411 /* Get the kernel's load entry */ 1412 NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, 1413 LDR_DATA_TABLE_ENTRY, 1414 InLoadOrderLinks); 1415 1416 /* Find the banner message */ 1417 MsgStatus = RtlFindMessage(NtosEntry->DllBase, 1418 11, 1419 0, 1420 WINDOWS_NT_BANNER, 1421 &MsgEntry); 1422 1423 /* Setup defaults and check if we have a version string */ 1424 StringBuffer = InitBuffer->VersionBuffer; 1425 BeginBuffer = StringBuffer; 1426 EndBuffer = StringBuffer; 1427 Remaining = sizeof(InitBuffer->VersionBuffer); 1428 if (CmCSDVersionString.Length) 1429 { 1430 /* Print the version string */ 1431 Status = RtlStringCbPrintfExA(StringBuffer, 1432 Remaining, 1433 &EndBuffer, 1434 &Remaining, 1435 0, 1436 ": %wZ", 1437 &CmCSDVersionString); 1438 if (!NT_SUCCESS(Status)) 1439 { 1440 /* Bugcheck */ 1441 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1442 } 1443 } 1444 else 1445 { 1446 /* No version */ 1447 *EndBuffer = ANSI_NULL; /* Null-terminate the string */ 1448 } 1449 1450 /* Skip over the null-terminator to start a new string */ 1451 ++EndBuffer; 1452 --Remaining; 1453 1454 /* Build the version number */ 1455 StringBuffer = InitBuffer->VersionNumber; 1456 Status = RtlStringCbPrintfA(StringBuffer, 1457 sizeof(InitBuffer->VersionNumber), 1458 "%u.%u", 1459 VER_PRODUCTMAJORVERSION, 1460 VER_PRODUCTMINORVERSION); 1461 if (!NT_SUCCESS(Status)) 1462 { 1463 /* Bugcheck */ 1464 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1465 } 1466 1467 /* Check if we had found a banner message */ 1468 if (NT_SUCCESS(MsgStatus)) 1469 { 1470 /* Create the banner message */ 1471 /* ReactOS specific: Report ReactOS version, NtBuildLab information and reported NT kernel version */ 1472 Status = RtlStringCbPrintfA(EndBuffer, 1473 Remaining, 1474 (PCHAR)MsgEntry->Text, 1475 KERNEL_VERSION_STR, 1476 NtBuildLab, 1477 StringBuffer, 1478 NtBuildNumber & 0xFFFF, 1479 BeginBuffer); 1480 if (!NT_SUCCESS(Status)) 1481 { 1482 /* Bugcheck */ 1483 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1484 } 1485 } 1486 else 1487 { 1488 /* Use hard-coded banner message */ 1489 Status = RtlStringCbCopyA(EndBuffer, Remaining, "REACTOS (R)\r\n"); 1490 if (!NT_SUCCESS(Status)) 1491 { 1492 /* Bugcheck */ 1493 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 1494 } 1495 } 1496 1497 /* Display the version string on-screen */ 1498 InbvDisplayString(EndBuffer); 1499 1500 /* Initialize Power Subsystem in Phase 0 */ 1501 if (!PoInitSystem(0)) KeBugCheck(INTERNAL_POWER_ERROR); 1502 1503 /* Check for Y2K hack */ 1504 Y2KHackRequired = CommandLine ? strstr(CommandLine, "YEAR") : NULL; 1505 if (Y2KHackRequired) Y2KHackRequired = strstr(Y2KHackRequired, "="); 1506 if (Y2KHackRequired) YearHack = atol(Y2KHackRequired + 1); 1507 1508 /* Query the clock */ 1509 if ((ExCmosClockIsSane) && (HalQueryRealTimeClock(&TimeFields))) 1510 { 1511 /* Check if we're using the Y2K hack */ 1512 if (Y2KHackRequired) TimeFields.Year = (CSHORT)YearHack; 1513 1514 /* Convert to time fields */ 1515 RtlTimeFieldsToTime(&TimeFields, &SystemBootTime); 1516 UniversalBootTime = SystemBootTime; 1517 1518 /* Check if real time is GMT */ 1519 if (!ExpRealTimeIsUniversal) 1520 { 1521 /* Check if we don't have a valid bias */ 1522 if (ExpLastTimeZoneBias == MAXULONG) 1523 { 1524 /* Reset */ 1525 ResetBias = TRUE; 1526 ExpLastTimeZoneBias = ExpAltTimeZoneBias; 1527 } 1528 1529 /* Calculate the bias in seconds */ 1530 ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60, 1531 10000000); 1532 1533 /* Set the boot time-zone bias */ 1534 SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart; 1535 SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart; 1536 SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart; 1537 1538 /* Convert the boot time to local time, and set it */ 1539 UniversalBootTime.QuadPart = SystemBootTime.QuadPart + 1540 ExpTimeZoneBias.QuadPart; 1541 } 1542 1543 /* Update the system time */ 1544 KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); 1545 1546 /* Do system callback */ 1547 PoNotifySystemTimeSet(); 1548 1549 /* Remember this as the boot time */ 1550 KeBootTime = UniversalBootTime; 1551 KeBootTimeBias = 0; 1552 } 1553 1554 /* Initialize all processors */ 1555 if (!HalAllProcessorsStarted()) KeBugCheck(HAL1_INITIALIZATION_FAILED); 1556 1557 #ifdef CONFIG_SMP 1558 /* HACK: We should use RtlFindMessage and not only fallback to this */ 1559 MpString = "MultiProcessor Kernel\r\n"; 1560 #endif 1561 1562 /* Setup the "MP" String */ 1563 RtlInitAnsiString(&TempString, MpString); 1564 1565 /* Make sure to remove the \r\n if we actually have a string */ 1566 while ((TempString.Length > 0) && 1567 ((TempString.Buffer[TempString.Length - 1] == '\r') || 1568 (TempString.Buffer[TempString.Length - 1] == '\n'))) 1569 { 1570 /* Skip the trailing character */ 1571 TempString.Length--; 1572 } 1573 1574 /* Get the information string from our resource file */ 1575 MsgStatus = RtlFindMessage(NtosEntry->DllBase, 1576 11, 1577 0, 1578 KeNumberProcessors > 1 ? 1579 WINDOWS_NT_INFO_STRING_PLURAL : 1580 WINDOWS_NT_INFO_STRING, 1581 &MsgEntry); 1582 1583 /* Get total RAM size */ 1584 Size = MmNumberOfPhysicalPages * PAGE_SIZE / 1024 / 1024; 1585 1586 /* Create the string */ 1587 StringBuffer = InitBuffer->VersionBuffer; 1588 Status = RtlStringCbPrintfA(StringBuffer, 1589 sizeof(InitBuffer->VersionBuffer), 1590 NT_SUCCESS(MsgStatus) ? 1591 (PCHAR)MsgEntry->Text : 1592 "%u System Processor [%u MB Memory] %Z\r\n", 1593 KeNumberProcessors, 1594 Size, 1595 &TempString); 1596 if (!NT_SUCCESS(Status)) 1597 { 1598 /* Bugcheck */ 1599 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 4, 0, 0); 1600 } 1601 1602 /* Display RAM and CPU count */ 1603 InbvDisplayString(StringBuffer); 1604 1605 /* Update the progress bar */ 1606 InbvUpdateProgressBar(5); 1607 1608 /* Call OB initialization again */ 1609 if (!ObInitSystem()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED); 1610 1611 /* Initialize Basic System Objects and Worker Threads */ 1612 if (!ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 1, 0); 1613 1614 /* Initialize the later stages of the kernel */ 1615 if (!KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 2, 0); 1616 1617 /* Call KD Providers at Phase 1 */ 1618 if (!KdInitSystem(ExpInitializationPhase, KeLoaderBlock)) 1619 { 1620 /* Failed, bugcheck */ 1621 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 3, 0); 1622 } 1623 1624 /* Initialize the SRM in Phase 1 */ 1625 if (!SeInitSystem()) KeBugCheck(SECURITY1_INITIALIZATION_FAILED); 1626 1627 /* Update the progress bar */ 1628 InbvUpdateProgressBar(10); 1629 1630 /* Create SystemRoot Link */ 1631 Status = ExpCreateSystemRootLink(LoaderBlock); 1632 if (!NT_SUCCESS(Status)) 1633 { 1634 /* Failed to create the system root link */ 1635 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0); 1636 } 1637 1638 /* Set up Region Maps, Sections and the Paging File */ 1639 if (!MmInitSystem(1, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED); 1640 1641 /* Create NLS section */ 1642 ExpInitNls(LoaderBlock); 1643 1644 /* Initialize Cache Views */ 1645 if (!CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED); 1646 1647 /* Initialize the Registry */ 1648 if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED); 1649 1650 /* Initialize Prefetcher */ 1651 CcPfInitializePrefetcher(); 1652 1653 /* Update progress bar */ 1654 InbvUpdateProgressBar(15); 1655 1656 /* Update timezone information */ 1657 LastTzBias = ExpLastTimeZoneBias; 1658 ExRefreshTimeZoneInformation(&SystemBootTime); 1659 1660 /* Check if we're resetting timezone data */ 1661 if (ResetBias) 1662 { 1663 /* Convert the local time to system time */ 1664 ExLocalTimeToSystemTime(&SystemBootTime, &UniversalBootTime); 1665 KeBootTime = UniversalBootTime; 1666 KeBootTimeBias = 0; 1667 1668 /* Set the new time */ 1669 KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); 1670 } 1671 else 1672 { 1673 /* Check if the timezone switched and update the time */ 1674 if (LastTzBias != ExpLastTimeZoneBias) ZwSetSystemTime(NULL, NULL); 1675 } 1676 1677 /* Initialize the File System Runtime Library */ 1678 if (!FsRtlInitSystem()) KeBugCheck(FILE_INITIALIZATION_FAILED); 1679 1680 /* Initialize range lists */ 1681 RtlInitializeRangeListPackage(); 1682 1683 /* Report all resources used by HAL */ 1684 HalReportResourceUsage(); 1685 1686 /* Call the debugger DLL */ 1687 KdDebuggerInitialize1(LoaderBlock); 1688 1689 /* Setup PnP Manager in phase 1 */ 1690 if (!PpInitSystem()) KeBugCheck(PP1_INITIALIZATION_FAILED); 1691 1692 /* Update progress bar */ 1693 InbvUpdateProgressBar(20); 1694 1695 /* Initialize LPC */ 1696 if (!LpcInitSystem()) KeBugCheck(LPC_INITIALIZATION_FAILED); 1697 1698 /* Make sure we have a command line */ 1699 if (CommandLine) 1700 { 1701 /* Check if this is a safe mode boot */ 1702 SafeBoot = strstr(CommandLine, "SAFEBOOT:"); 1703 if (SafeBoot) 1704 { 1705 /* Check what kind of boot this is */ 1706 SafeBoot += 9; 1707 if (!strncmp(SafeBoot, "MINIMAL", 7)) 1708 { 1709 /* Minimal mode */ 1710 InitSafeBootMode = 1; 1711 SafeBoot += 7; 1712 MessageCode = BOOTING_IN_SAFEMODE_MINIMAL; 1713 } 1714 else if (!strncmp(SafeBoot, "NETWORK", 7)) 1715 { 1716 /* With Networking */ 1717 InitSafeBootMode = 2; 1718 SafeBoot += 7; 1719 MessageCode = BOOTING_IN_SAFEMODE_NETWORK; 1720 } 1721 else if (!strncmp(SafeBoot, "DSREPAIR", 8)) 1722 { 1723 /* Domain Server Repair */ 1724 InitSafeBootMode = 3; 1725 SafeBoot += 8; 1726 MessageCode = BOOTING_IN_SAFEMODE_DSREPAIR; 1727 1728 } 1729 else 1730 { 1731 /* Invalid */ 1732 InitSafeBootMode = 0; 1733 } 1734 1735 /* Check if there's any settings left */ 1736 if (*SafeBoot) 1737 { 1738 /* Check if an alternate shell was requested */ 1739 if (!strncmp(SafeBoot, "(ALTERNATESHELL)", 16)) 1740 { 1741 /* Remember this for later */ 1742 AlternateShell = TRUE; 1743 } 1744 } 1745 1746 /* Find the message to print out */ 1747 Status = RtlFindMessage(NtosEntry->DllBase, 1748 11, 1749 0, 1750 MessageCode, 1751 &MsgEntry); 1752 if (NT_SUCCESS(Status)) 1753 { 1754 /* Display it */ 1755 InbvDisplayString((PCHAR)MsgEntry->Text); 1756 } 1757 } 1758 } 1759 1760 /* Make sure we have a command line */ 1761 if (CommandLine) 1762 { 1763 /* Check if bootlogging is enabled */ 1764 if (strstr(CommandLine, "BOOTLOG")) 1765 { 1766 /* Find the message to print out */ 1767 Status = RtlFindMessage(NtosEntry->DllBase, 1768 11, 1769 0, 1770 BOOTLOG_ENABLED, 1771 &MsgEntry); 1772 if (NT_SUCCESS(Status)) 1773 { 1774 /* Display it */ 1775 InbvDisplayString((PCHAR)MsgEntry->Text); 1776 } 1777 1778 /* Setup boot logging */ 1779 //IopInitializeBootLogging(LoaderBlock, InitBuffer->BootlogHeader); 1780 } 1781 } 1782 1783 /* Setup the Executive in Phase 2 */ 1784 //ExInitSystemPhase2(); 1785 1786 /* Update progress bar */ 1787 InbvUpdateProgressBar(25); 1788 1789 #ifdef _WINKD_ 1790 /* No KD Time Slip is pending */ 1791 KdpTimeSlipPending = 0; 1792 #endif 1793 1794 /* Initialize in-place execution support */ 1795 XIPInit(LoaderBlock); 1796 1797 /* Set maximum update to 75% */ 1798 InbvSetProgressBarSubset(25, 75); 1799 1800 /* Initialize the I/O Subsystem */ 1801 if (!IoInitSystem(LoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED); 1802 1803 /* Set maximum update to 100% */ 1804 InbvSetProgressBarSubset(0, 100); 1805 1806 /* Are we in safe mode? */ 1807 if (InitSafeBootMode) 1808 { 1809 /* Open the safe boot key */ 1810 RtlInitUnicodeString(&KeyName, 1811 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" 1812 L"\\CONTROL\\SAFEBOOT"); 1813 InitializeObjectAttributes(&ObjectAttributes, 1814 &KeyName, 1815 OBJ_CASE_INSENSITIVE, 1816 NULL, 1817 NULL); 1818 Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); 1819 if (NT_SUCCESS(Status)) 1820 { 1821 /* First check if we have an alternate shell */ 1822 if (AlternateShell) 1823 { 1824 /* Make sure that the registry has one setup */ 1825 RtlInitUnicodeString(&KeyName, L"AlternateShell"); 1826 Status = NtQueryValueKey(KeyHandle, 1827 &KeyName, 1828 KeyValuePartialInformation, 1829 &KeyPartialInfo, 1830 sizeof(KeyPartialInfo), 1831 &Length); 1832 if (!(NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)) 1833 { 1834 AlternateShell = FALSE; 1835 } 1836 } 1837 1838 /* Create the option key */ 1839 RtlInitUnicodeString(&KeyName, L"Option"); 1840 InitializeObjectAttributes(&ObjectAttributes, 1841 &KeyName, 1842 OBJ_CASE_INSENSITIVE, 1843 KeyHandle, 1844 NULL); 1845 Status = ZwCreateKey(&OptionHandle, 1846 KEY_ALL_ACCESS, 1847 &ObjectAttributes, 1848 0, 1849 NULL, 1850 REG_OPTION_VOLATILE, 1851 &Disposition); 1852 NtClose(KeyHandle); 1853 1854 /* Check if the key create worked */ 1855 if (NT_SUCCESS(Status)) 1856 { 1857 /* Write the safe boot type */ 1858 RtlInitUnicodeString(&KeyName, L"OptionValue"); 1859 NtSetValueKey(OptionHandle, 1860 &KeyName, 1861 0, 1862 REG_DWORD, 1863 &InitSafeBootMode, 1864 sizeof(InitSafeBootMode)); 1865 1866 /* Check if we have to use an alternate shell */ 1867 if (AlternateShell) 1868 { 1869 /* Remember this for later */ 1870 Disposition = TRUE; 1871 RtlInitUnicodeString(&KeyName, L"UseAlternateShell"); 1872 NtSetValueKey(OptionHandle, 1873 &KeyName, 1874 0, 1875 REG_DWORD, 1876 &Disposition, 1877 sizeof(Disposition)); 1878 } 1879 1880 /* Close the options key handle */ 1881 NtClose(OptionHandle); 1882 } 1883 } 1884 } 1885 1886 /* Are we in Win PE mode? */ 1887 if (InitIsWinPEMode) 1888 { 1889 /* Open the safe control key */ 1890 RtlInitUnicodeString(&KeyName, 1891 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" 1892 L"\\CONTROL"); 1893 InitializeObjectAttributes(&ObjectAttributes, 1894 &KeyName, 1895 OBJ_CASE_INSENSITIVE, 1896 NULL, 1897 NULL); 1898 Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); 1899 if (!NT_SUCCESS(Status)) 1900 { 1901 /* Bugcheck */ 1902 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); 1903 } 1904 1905 /* Create the MiniNT key */ 1906 RtlInitUnicodeString(&KeyName, L"MiniNT"); 1907 InitializeObjectAttributes(&ObjectAttributes, 1908 &KeyName, 1909 OBJ_CASE_INSENSITIVE, 1910 KeyHandle, 1911 NULL); 1912 Status = ZwCreateKey(&OptionHandle, 1913 KEY_ALL_ACCESS, 1914 &ObjectAttributes, 1915 0, 1916 NULL, 1917 REG_OPTION_VOLATILE, 1918 &Disposition); 1919 if (!NT_SUCCESS(Status)) 1920 { 1921 /* Bugcheck */ 1922 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); 1923 } 1924 1925 /* Close the handles */ 1926 NtClose(KeyHandle); 1927 NtClose(OptionHandle); 1928 } 1929 1930 /* FIXME: This doesn't do anything for now */ 1931 MmArmInitSystem(2, LoaderBlock); 1932 1933 /* Update progress bar */ 1934 InbvUpdateProgressBar(80); 1935 1936 /* Initialize VDM support */ 1937 #if defined(_M_IX86) 1938 KeI386VdmInitialize(); 1939 #endif 1940 1941 /* Initialize Power Subsystem in Phase 1*/ 1942 if (!PoInitSystem(1)) KeBugCheck(INTERNAL_POWER_ERROR); 1943 1944 /* Update progress bar */ 1945 InbvUpdateProgressBar(90); 1946 1947 /* Initialize the Process Manager at Phase 1 */ 1948 if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS1_INITIALIZATION_FAILED); 1949 1950 /* Make sure nobody touches the loader block again */ 1951 if (LoaderBlock == KeLoaderBlock) KeLoaderBlock = NULL; 1952 MmFreeLoaderBlock(LoaderBlock); 1953 LoaderBlock = Context = NULL; 1954 1955 /* Initialize the SRM in phase 1 */ 1956 if (!SeRmInitPhase1()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED); 1957 1958 /* Update progress bar */ 1959 InbvUpdateProgressBar(100); 1960 1961 /* Clear the screen */ 1962 if (InbvBootDriverInstalled) FinalizeBootLogo(); 1963 1964 /* Allow strings to be displayed */ 1965 InbvEnableDisplayString(TRUE); 1966 1967 /* Launch initial process */ 1968 DPRINT("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed); 1969 ProcessInfo = &InitBuffer->ProcessInfo; 1970 ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment); 1971 1972 /* Wait 5 seconds for initial process to initialize */ 1973 Timeout.QuadPart = Int32x32To64(5, -10000000); 1974 Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout); 1975 if (Status == STATUS_SUCCESS) 1976 { 1977 /* Failed, display error */ 1978 DPRINT1("INIT: Session Manager terminated.\n"); 1979 1980 /* Bugcheck the system if SMSS couldn't initialize */ 1981 KeBugCheck(SESSION5_INITIALIZATION_FAILED); 1982 } 1983 1984 /* Close process handles */ 1985 ZwClose(ProcessInfo->ThreadHandle); 1986 ZwClose(ProcessInfo->ProcessHandle); 1987 1988 /* Free the initial process environment */ 1989 Size = 0; 1990 ZwFreeVirtualMemory(NtCurrentProcess(), 1991 (PVOID*)&Environment, 1992 &Size, 1993 MEM_RELEASE); 1994 1995 /* Free the initial process parameters */ 1996 Size = 0; 1997 ZwFreeVirtualMemory(NtCurrentProcess(), 1998 (PVOID*)&ProcessParameters, 1999 &Size, 2000 MEM_RELEASE); 2001 2002 /* Increase init phase */ 2003 ExpInitializationPhase++; 2004 2005 /* Free the boot buffer */ 2006 ExFreePoolWithTag(InitBuffer, TAG_INIT); 2007 DPRINT("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed); 2008 } 2009 2010 VOID 2011 NTAPI 2012 Phase1Initialization(IN PVOID Context) 2013 { 2014 /* Do the .INIT part of Phase 1 which we can free later */ 2015 Phase1InitializationDiscard(Context); 2016 2017 /* Jump into zero page thread */ 2018 MmZeroPageThread(); 2019 } 2020