Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninit.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/ex/init.c 00005 * PURPOSE: Executive Initialization Code 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 * Eric Kohl 00008 */ 00009 00010 /* INCLUDES ******************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #include <reactos/buildno.h> 00014 #define NDEBUG 00015 #include <debug.h> 00016 00017 /* Temporary hack */ 00018 BOOLEAN 00019 NTAPI 00020 MmArmInitSystem( 00021 IN ULONG Phase, 00022 IN PLOADER_PARAMETER_BLOCK LoaderBlock 00023 ); 00024 00025 typedef struct _INIT_BUFFER 00026 { 00027 WCHAR DebugBuffer[256]; 00028 CHAR VersionBuffer[256]; 00029 CHAR BootlogHeader[256]; 00030 CHAR VersionNumber[24]; 00031 RTL_USER_PROCESS_INFORMATION ProcessInfo; 00032 WCHAR RegistryBuffer[256]; 00033 } INIT_BUFFER, *PINIT_BUFFER; 00034 00035 /* DATA **********************************************************************/ 00036 00037 /* NT Version Info */ 00038 ULONG NtMajorVersion = VER_PRODUCTMAJORVERSION; 00039 ULONG NtMinorVersion = VER_PRODUCTMINORVERSION; 00040 #if DBG 00041 ULONG NtBuildNumber = VER_PRODUCTBUILD | 0xC0000000; 00042 #else 00043 ULONG NtBuildNumber = VER_PRODUCTBUILD; 00044 #endif 00045 00046 /* NT System Info */ 00047 ULONG NtGlobalFlag = 0; 00048 ULONG ExSuiteMask; 00049 00050 /* Cm Version Info */ 00051 ULONG CmNtSpBuildNumber; 00052 ULONG CmNtCSDVersion; 00053 ULONG CmNtCSDReleaseType; 00054 UNICODE_STRING CmVersionString; 00055 UNICODE_STRING CmCSDVersionString; 00056 CHAR NtBuildLab[] = KERNEL_VERSION_BUILD_STR; 00057 00058 /* Init flags and settings */ 00059 ULONG ExpInitializationPhase; 00060 BOOLEAN ExpInTextModeSetup; 00061 BOOLEAN IoRemoteBootClient; 00062 ULONG InitSafeBootMode; 00063 BOOLEAN InitIsWinPEMode, InitWinPEModeType; 00064 00065 /* NT Boot Path */ 00066 UNICODE_STRING NtSystemRoot; 00067 00068 /* NT Initial User Application */ 00069 WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss.exe"; 00070 ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) - 00071 sizeof(WCHAR); 00072 ULONG NtInitialUserProcessBufferType = REG_SZ; 00073 00074 /* Boot NLS information */ 00075 PVOID ExpNlsTableBase; 00076 ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset; 00077 ULONG ExpUnicodeCaseTableDataOffset; 00078 NLSTABLEINFO ExpNlsTableInfo; 00079 SIZE_T ExpNlsTableSize; 00080 PVOID ExpNlsSectionPointer; 00081 00082 /* CMOS Timer Sanity */ 00083 BOOLEAN ExCmosClockIsSane = TRUE; 00084 BOOLEAN ExpRealTimeIsUniversal; 00085 00086 /* FUNCTIONS ****************************************************************/ 00087 00088 NTSTATUS 00089 NTAPI 00090 INIT_FUNCTION 00091 ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 00092 { 00093 UNICODE_STRING LinkName; 00094 OBJECT_ATTRIBUTES ObjectAttributes; 00095 HANDLE LinkHandle; 00096 NTSTATUS Status; 00097 ANSI_STRING AnsiName; 00098 CHAR Buffer[256]; 00099 ANSI_STRING TargetString; 00100 UNICODE_STRING TargetName; 00101 00102 /* Initialize the ArcName tree */ 00103 RtlInitUnicodeString(&LinkName, L"\\ArcName"); 00104 InitializeObjectAttributes(&ObjectAttributes, 00105 &LinkName, 00106 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 00107 NULL, 00108 SePublicDefaultUnrestrictedSd); 00109 00110 /* Create it */ 00111 Status = NtCreateDirectoryObject(&LinkHandle, 00112 DIRECTORY_ALL_ACCESS, 00113 &ObjectAttributes); 00114 if (!NT_SUCCESS(Status)) 00115 { 00116 /* Failed */ 00117 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 1, 0, 0); 00118 } 00119 00120 /* Close the LinkHandle */ 00121 NtClose(LinkHandle); 00122 00123 /* Initialize the Device tree */ 00124 RtlInitUnicodeString(&LinkName, L"\\Device"); 00125 InitializeObjectAttributes(&ObjectAttributes, 00126 &LinkName, 00127 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 00128 NULL, 00129 SePublicDefaultUnrestrictedSd); 00130 00131 /* Create it */ 00132 Status = NtCreateDirectoryObject(&LinkHandle, 00133 DIRECTORY_ALL_ACCESS, 00134 &ObjectAttributes); 00135 if (!NT_SUCCESS(Status)) 00136 { 00137 /* Failed */ 00138 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 2, 0, 0); 00139 } 00140 00141 /* Close the LinkHandle */ 00142 ObCloseHandle(LinkHandle, KernelMode); 00143 00144 /* Create the system root symlink name */ 00145 RtlInitAnsiString(&AnsiName, "\\SystemRoot"); 00146 Status = RtlAnsiStringToUnicodeString(&LinkName, &AnsiName, TRUE); 00147 if (!NT_SUCCESS(Status)) 00148 { 00149 /* Failed */ 00150 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 3, 0, 0); 00151 } 00152 00153 /* Initialize the attributes for the link */ 00154 InitializeObjectAttributes(&ObjectAttributes, 00155 &LinkName, 00156 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 00157 NULL, 00158 SePublicDefaultUnrestrictedSd); 00159 00160 /* Build the ARC name */ 00161 sprintf(Buffer, 00162 "\\ArcName\\%s%s", 00163 LoaderBlock->ArcBootDeviceName, 00164 LoaderBlock->NtBootPathName); 00165 Buffer[strlen(Buffer) - 1] = ANSI_NULL; 00166 00167 /* Convert it to Unicode */ 00168 RtlInitString(&TargetString, Buffer); 00169 Status = RtlAnsiStringToUnicodeString(&TargetName, 00170 &TargetString, 00171 TRUE); 00172 if (!NT_SUCCESS(Status)) 00173 { 00174 /* We failed, bugcheck */ 00175 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 4, 0, 0); 00176 } 00177 00178 /* Create it */ 00179 Status = NtCreateSymbolicLinkObject(&LinkHandle, 00180 SYMBOLIC_LINK_ALL_ACCESS, 00181 &ObjectAttributes, 00182 &TargetName); 00183 00184 /* Free the strings */ 00185 RtlFreeUnicodeString(&LinkName); 00186 RtlFreeUnicodeString(&TargetName); 00187 00188 /* Check if creating the link failed */ 00189 if (!NT_SUCCESS(Status)) 00190 { 00191 /* Failed */ 00192 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 5, 0, 0); 00193 } 00194 00195 /* Close the handle and return success */ 00196 ObCloseHandle(LinkHandle, KernelMode); 00197 return STATUS_SUCCESS; 00198 } 00199 00200 VOID 00201 NTAPI 00202 INIT_FUNCTION 00203 ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 00204 { 00205 LARGE_INTEGER SectionSize; 00206 NTSTATUS Status; 00207 HANDLE NlsSection; 00208 PVOID SectionBase = NULL; 00209 SIZE_T ViewSize = 0; 00210 LARGE_INTEGER SectionOffset = {{0, 0}}; 00211 PLIST_ENTRY ListHead, NextEntry; 00212 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; 00213 ULONG NlsTablesEncountered = 0; 00214 SIZE_T NlsTableSizes[3]; /* 3 NLS tables */ 00215 00216 /* Check if this is boot-time phase 0 initialization */ 00217 if (!ExpInitializationPhase) 00218 { 00219 /* Loop the memory descriptors */ 00220 ListHead = &LoaderBlock->MemoryDescriptorListHead; 00221 NextEntry = ListHead->Flink; 00222 while (NextEntry != ListHead) 00223 { 00224 /* Get the current block */ 00225 MdBlock = CONTAINING_RECORD(NextEntry, 00226 MEMORY_ALLOCATION_DESCRIPTOR, 00227 ListEntry); 00228 00229 /* Check if this is an NLS block */ 00230 if (MdBlock->MemoryType == LoaderNlsData) 00231 { 00232 /* Increase the table size */ 00233 ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE; 00234 00235 /* FreeLdr-specific */ 00236 NlsTableSizes[NlsTablesEncountered] = MdBlock->PageCount * PAGE_SIZE; 00237 NlsTablesEncountered++; 00238 ASSERT(NlsTablesEncountered < 4); 00239 } 00240 00241 /* Go to the next block */ 00242 NextEntry = MdBlock->ListEntry.Flink; 00243 } 00244 00245 /* Allocate the a new buffer since loader memory will be freed */ 00246 ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool, 00247 ExpNlsTableSize, 00248 TAG_RTLI); 00249 if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 00250 00251 /* Copy the codepage data in its new location. */ 00252 if (NlsTablesEncountered == 1) 00253 { 00254 /* Ntldr-way boot process */ 00255 RtlCopyMemory(ExpNlsTableBase, 00256 LoaderBlock->NlsData->AnsiCodePageData, 00257 ExpNlsTableSize); 00258 } 00259 else 00260 { 00261 /* 00262 * In NT, the memory blocks are contiguous, but in ReactOS they aren't, 00263 * so unless someone fixes FreeLdr, we'll have to use this icky hack. 00264 */ 00265 RtlCopyMemory(ExpNlsTableBase, 00266 LoaderBlock->NlsData->AnsiCodePageData, 00267 NlsTableSizes[0]); 00268 00269 RtlCopyMemory((PVOID)((ULONG_PTR)ExpNlsTableBase + NlsTableSizes[0]), 00270 LoaderBlock->NlsData->OemCodePageData, 00271 NlsTableSizes[1]); 00272 00273 RtlCopyMemory((PVOID)((ULONG_PTR)ExpNlsTableBase + NlsTableSizes[0] + 00274 NlsTableSizes[1]), 00275 LoaderBlock->NlsData->UnicodeCodePageData, 00276 NlsTableSizes[2]); 00277 /* End of Hack */ 00278 } 00279 00280 /* Initialize and reset the NLS TAbles */ 00281 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + 00282 ExpAnsiCodePageDataOffset), 00283 (PVOID)((ULONG_PTR)ExpNlsTableBase + 00284 ExpOemCodePageDataOffset), 00285 (PVOID)((ULONG_PTR)ExpNlsTableBase + 00286 ExpUnicodeCaseTableDataOffset), 00287 &ExpNlsTableInfo); 00288 RtlResetRtlTranslations(&ExpNlsTableInfo); 00289 return; 00290 } 00291 00292 /* Set the section size */ 00293 SectionSize.QuadPart = ExpNlsTableSize; 00294 00295 /* Create the NLS Section */ 00296 Status = ZwCreateSection(&NlsSection, 00297 SECTION_ALL_ACCESS, 00298 NULL, 00299 &SectionSize, 00300 PAGE_READWRITE, 00301 SEC_COMMIT | 0x1, 00302 NULL); 00303 if (!NT_SUCCESS(Status)) 00304 { 00305 /* Failed */ 00306 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 1, 0, 0); 00307 } 00308 00309 /* Get a pointer to the section */ 00310 Status = ObReferenceObjectByHandle(NlsSection, 00311 SECTION_ALL_ACCESS, 00312 MmSectionObjectType, 00313 KernelMode, 00314 &ExpNlsSectionPointer, 00315 NULL); 00316 ObCloseHandle(NlsSection, KernelMode); 00317 if (!NT_SUCCESS(Status)) 00318 { 00319 /* Failed */ 00320 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 2, 0, 0); 00321 } 00322 00323 /* Map the NLS Section in system space */ 00324 Status = MmMapViewInSystemSpace(ExpNlsSectionPointer, 00325 &SectionBase, 00326 &ExpNlsTableSize); 00327 if (!NT_SUCCESS(Status)) 00328 { 00329 /* Failed */ 00330 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 3, 0, 0); 00331 } 00332 00333 /* Copy the codepage data in its new location. */ 00334 ASSERT(SectionBase >= MmSystemRangeStart); 00335 RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); 00336 00337 /* Free the previously allocated buffer and set the new location */ 00338 ExFreePoolWithTag(ExpNlsTableBase, TAG_RTLI); 00339 ExpNlsTableBase = SectionBase; 00340 00341 /* Initialize the NLS Tables */ 00342 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + 00343 ExpAnsiCodePageDataOffset), 00344 (PVOID)((ULONG_PTR)ExpNlsTableBase + 00345 ExpOemCodePageDataOffset), 00346 (PVOID)((ULONG_PTR)ExpNlsTableBase + 00347 ExpUnicodeCaseTableDataOffset), 00348 &ExpNlsTableInfo); 00349 RtlResetRtlTranslations(&ExpNlsTableInfo); 00350 00351 /* Reset the base to 0 */ 00352 SectionBase = NULL; 00353 00354 /* Map the section in the system process */ 00355 Status = MmMapViewOfSection(ExpNlsSectionPointer, 00356 PsGetCurrentProcess(), 00357 &SectionBase, 00358 0L, 00359 0L, 00360 &SectionOffset, 00361 &ViewSize, 00362 ViewShare, 00363 0L, 00364 PAGE_READWRITE); 00365 if (!NT_SUCCESS(Status)) 00366 { 00367 /* Failed */ 00368 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 5, 0, 0); 00369 } 00370 00371 /* Copy the table into the system process and set this as the base */ 00372 RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); 00373 ExpNlsTableBase = SectionBase; 00374 } 00375 00376 VOID 00377 NTAPI 00378 INIT_FUNCTION 00379 ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer, 00380 OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, 00381 OUT PCHAR *ProcessEnvironment) 00382 { 00383 NTSTATUS Status; 00384 SIZE_T Size; 00385 PWSTR p; 00386 UNICODE_STRING NullString = RTL_CONSTANT_STRING(L""); 00387 UNICODE_STRING SmssName, Environment, SystemDriveString, DebugString; 00388 PVOID EnvironmentPtr = NULL; 00389 PRTL_USER_PROCESS_INFORMATION ProcessInformation; 00390 PRTL_USER_PROCESS_PARAMETERS ProcessParams = NULL; 00391 00392 NullString.Length = sizeof(WCHAR); 00393 00394 /* Use the initial buffer, after the strings */ 00395 ProcessInformation = &InitBuffer->ProcessInfo; 00396 00397 /* Allocate memory for the process parameters */ 00398 Size = sizeof(*ProcessParams) + ((MAX_PATH * 6) * sizeof(WCHAR)); 00399 Status = ZwAllocateVirtualMemory(NtCurrentProcess(), 00400 (PVOID*)&ProcessParams, 00401 0, 00402 &Size, 00403 MEM_RESERVE | MEM_COMMIT, 00404 PAGE_READWRITE); 00405 if (!NT_SUCCESS(Status)) 00406 { 00407 /* Failed, display error */ 00408 p = InitBuffer->DebugBuffer; 00409 _snwprintf(p, 00410 256 * sizeof(WCHAR), 00411 L"INIT: Unable to allocate Process Parameters. 0x%lx", 00412 Status); 00413 RtlInitUnicodeString(&DebugString, p); 00414 ZwDisplayString(&DebugString); 00415 00416 /* Bugcheck the system */ 00417 KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0); 00418 } 00419 00420 /* Setup the basic header, and give the process the low 1MB to itself */ 00421 ProcessParams->Length = (ULONG)Size; 00422 ProcessParams->MaximumLength = (ULONG)Size; 00423 ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED | 00424 RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB; 00425 00426 /* Allocate a page for the environment */ 00427 Size = PAGE_SIZE; 00428 Status = ZwAllocateVirtualMemory(NtCurrentProcess(), 00429 &EnvironmentPtr, 00430 0, 00431 &Size, 00432 MEM_RESERVE | MEM_COMMIT, 00433 PAGE_READWRITE); 00434 if (!NT_SUCCESS(Status)) 00435 { 00436 /* Failed, display error */ 00437 p = InitBuffer->DebugBuffer; 00438 _snwprintf(p, 00439 256 * sizeof(WCHAR), 00440 L"INIT: Unable to allocate Process Environment. 0x%lx", 00441 Status); 00442 RtlInitUnicodeString(&DebugString, p); 00443 ZwDisplayString(&DebugString); 00444 00445 /* Bugcheck the system */ 00446 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0); 00447 } 00448 00449 /* Write the pointer */ 00450 ProcessParams->Environment = EnvironmentPtr; 00451 00452 /* Make a buffer for the DOS path */ 00453 p = (PWSTR)(ProcessParams + 1); 00454 ProcessParams->CurrentDirectory.DosPath.Buffer = p; 00455 ProcessParams->CurrentDirectory.DosPath.MaximumLength = MAX_PATH * 00456 sizeof(WCHAR); 00457 00458 /* Copy the DOS path */ 00459 RtlCopyUnicodeString(&ProcessParams->CurrentDirectory.DosPath, 00460 &NtSystemRoot); 00461 00462 /* Make a buffer for the DLL Path */ 00463 p = (PWSTR)((PCHAR)ProcessParams->CurrentDirectory.DosPath.Buffer + 00464 ProcessParams->CurrentDirectory.DosPath.MaximumLength); 00465 ProcessParams->DllPath.Buffer = p; 00466 ProcessParams->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR); 00467 00468 /* Copy the DLL path and append the system32 directory */ 00469 RtlCopyUnicodeString(&ProcessParams->DllPath, 00470 &ProcessParams->CurrentDirectory.DosPath); 00471 RtlAppendUnicodeToString(&ProcessParams->DllPath, L"\\System32"); 00472 00473 /* Make a buffer for the image name */ 00474 p = (PWSTR)((PCHAR)ProcessParams->DllPath.Buffer + 00475 ProcessParams->DllPath.MaximumLength); 00476 ProcessParams->ImagePathName.Buffer = p; 00477 ProcessParams->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR); 00478 00479 /* Make sure the buffer is a valid string which within the given length */ 00480 if ((NtInitialUserProcessBufferType != REG_SZ) || 00481 ((NtInitialUserProcessBufferLength != MAXULONG) && 00482 ((NtInitialUserProcessBufferLength < sizeof(WCHAR)) || 00483 (NtInitialUserProcessBufferLength > 00484 sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR))))) 00485 { 00486 /* Invalid initial process string, bugcheck */ 00487 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, 00488 STATUS_INVALID_PARAMETER, 00489 NtInitialUserProcessBufferType, 00490 NtInitialUserProcessBufferLength, 00491 sizeof(NtInitialUserProcessBuffer)); 00492 } 00493 00494 /* Cut out anything after a space */ 00495 p = NtInitialUserProcessBuffer; 00496 while ((*p) && (*p != L' ')) p++; 00497 00498 /* Set the image path length */ 00499 ProcessParams->ImagePathName.Length = 00500 (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer); 00501 00502 /* Copy the actual buffer */ 00503 RtlCopyMemory(ProcessParams->ImagePathName.Buffer, 00504 NtInitialUserProcessBuffer, 00505 ProcessParams->ImagePathName.Length); 00506 00507 /* Null-terminate it */ 00508 ProcessParams->ImagePathName.Buffer[ProcessParams->ImagePathName.Length / 00509 sizeof(WCHAR)] = UNICODE_NULL; 00510 00511 /* Make a buffer for the command line */ 00512 p = (PWSTR)((PCHAR)ProcessParams->ImagePathName.Buffer + 00513 ProcessParams->ImagePathName.MaximumLength); 00514 ProcessParams->CommandLine.Buffer = p; 00515 ProcessParams->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR); 00516 00517 /* Add the image name to the command line */ 00518 RtlAppendUnicodeToString(&ProcessParams->CommandLine, 00519 NtInitialUserProcessBuffer); 00520 00521 /* Create the environment string */ 00522 RtlInitEmptyUnicodeString(&Environment, 00523 ProcessParams->Environment, 00524 (USHORT)Size); 00525 00526 /* Append the DLL path to it */ 00527 RtlAppendUnicodeToString(&Environment, L"Path=" ); 00528 RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath); 00529 RtlAppendUnicodeStringToString(&Environment, &NullString); 00530 00531 /* Create the system drive string */ 00532 SystemDriveString = NtSystemRoot; 00533 SystemDriveString.Length = 2 * sizeof(WCHAR); 00534 00535 /* Append it to the environment */ 00536 RtlAppendUnicodeToString(&Environment, L"SystemDrive="); 00537 RtlAppendUnicodeStringToString(&Environment, &SystemDriveString); 00538 RtlAppendUnicodeStringToString(&Environment, &NullString); 00539 00540 /* Append the system root to the environment */ 00541 RtlAppendUnicodeToString(&Environment, L"SystemRoot="); 00542 RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot); 00543 RtlAppendUnicodeStringToString(&Environment, &NullString); 00544 00545 /* Prepare the prefetcher */ 00546 //CcPfBeginBootPhase(150); 00547 00548 /* Create SMSS process */ 00549 SmssName = ProcessParams->ImagePathName; 00550 Status = RtlCreateUserProcess(&SmssName, 00551 OBJ_CASE_INSENSITIVE, 00552 RtlDeNormalizeProcessParams(ProcessParams), 00553 NULL, 00554 NULL, 00555 NULL, 00556 FALSE, 00557 NULL, 00558 NULL, 00559 ProcessInformation); 00560 if (!NT_SUCCESS(Status)) 00561 { 00562 /* Failed, display error */ 00563 p = InitBuffer->DebugBuffer; 00564 _snwprintf(p, 00565 256 * sizeof(WCHAR), 00566 L"INIT: Unable to create Session Manager. 0x%lx", 00567 Status); 00568 RtlInitUnicodeString(&DebugString, p); 00569 ZwDisplayString(&DebugString); 00570 00571 /* Bugcheck the system */ 00572 KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0); 00573 } 00574 00575 /* Resume the thread */ 00576 Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL); 00577 if (!NT_SUCCESS(Status)) 00578 { 00579 /* Failed, display error */ 00580 p = InitBuffer->DebugBuffer; 00581 _snwprintf(p, 00582 256 * sizeof(WCHAR), 00583 L"INIT: Unable to resume Session Manager. 0x%lx", 00584 Status); 00585 RtlInitUnicodeString(&DebugString, p); 00586 ZwDisplayString(&DebugString); 00587 00588 /* Bugcheck the system */ 00589 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); 00590 } 00591 00592 /* Return success */ 00593 *ProcessParameters = ProcessParams; 00594 *ProcessEnvironment = EnvironmentPtr; 00595 } 00596 00597 ULONG 00598 NTAPI 00599 INIT_FUNCTION 00600 ExComputeTickCountMultiplier(IN ULONG ClockIncrement) 00601 { 00602 ULONG MsRemainder = 0, MsIncrement; 00603 ULONG IncrementRemainder; 00604 ULONG i; 00605 00606 /* Count the number of milliseconds for each clock interrupt */ 00607 MsIncrement = ClockIncrement / (10 * 1000); 00608 00609 /* Count the remainder from the division above, with 24-bit precision */ 00610 IncrementRemainder = ClockIncrement - (MsIncrement * (10 * 1000)); 00611 for (i= 0; i < 24; i++) 00612 { 00613 /* Shift the remainders */ 00614 MsRemainder <<= 1; 00615 IncrementRemainder <<= 1; 00616 00617 /* Check if we've went past 1 ms */ 00618 if (IncrementRemainder >= (10 * 1000)) 00619 { 00620 /* Increase the remainder by one, and substract from increment */ 00621 IncrementRemainder -= (10 * 1000); 00622 MsRemainder |= 1; 00623 } 00624 } 00625 00626 /* Return the increment */ 00627 return (MsIncrement << 24) | MsRemainder; 00628 } 00629 00630 BOOLEAN 00631 NTAPI 00632 INIT_FUNCTION 00633 ExpInitSystemPhase0(VOID) 00634 { 00635 /* Initialize EXRESOURCE Support */ 00636 ExpResourceInitialization(); 00637 00638 /* Initialize the environment lock */ 00639 ExInitializeFastMutex(&ExpEnvironmentLock); 00640 00641 /* Initialize the lookaside lists and locks */ 00642 ExpInitLookasideLists(); 00643 00644 /* Initialize the Firmware Table resource and listhead */ 00645 InitializeListHead(&ExpFirmwareTableProviderListHead); 00646 ExInitializeResourceLite(&ExpFirmwareTableResource); 00647 00648 /* Set the suite mask to maximum and return */ 00649 ExSuiteMask = 0xFFFFFFFF; 00650 return TRUE; 00651 } 00652 00653 BOOLEAN 00654 NTAPI 00655 INIT_FUNCTION 00656 ExpInitSystemPhase1(VOID) 00657 { 00658 /* Initialize worker threads */ 00659 ExpInitializeWorkerThreads(); 00660 00661 /* Initialize pushlocks */ 00662 ExpInitializePushLocks(); 00663 00664 /* Initialize events and event pairs */ 00665 ExpInitializeEventImplementation(); 00666 ExpInitializeEventPairImplementation(); 00667 ExpInitializeKeyedEventImplementation(); 00668 00669 /* Initialize callbacks */ 00670 ExpInitializeCallbacks(); 00671 00672 /* Initialize mutants */ 00673 ExpInitializeMutantImplementation(); 00674 00675 /* Initialize semaphores */ 00676 ExpInitializeSemaphoreImplementation(); 00677 00678 /* Initialize timers */ 00679 ExpInitializeTimerImplementation(); 00680 00681 /* Initialize profiling */ 00682 ExpInitializeProfileImplementation(); 00683 00684 /* Initialize UUIDs */ 00685 ExpInitUuids(); 00686 00687 /* Initialize Win32K */ 00688 ExpWin32kInit(); 00689 return TRUE; 00690 } 00691 00692 BOOLEAN 00693 NTAPI 00694 INIT_FUNCTION 00695 ExInitSystem(VOID) 00696 { 00697 /* Check the initialization phase */ 00698 switch (ExpInitializationPhase) 00699 { 00700 case 0: 00701 00702 /* Do Phase 0 */ 00703 return ExpInitSystemPhase0(); 00704 00705 case 1: 00706 00707 /* Do Phase 1 */ 00708 return ExpInitSystemPhase1(); 00709 00710 default: 00711 00712 /* Don't know any other phase! Bugcheck! */ 00713 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL); 00714 return FALSE; 00715 } 00716 } 00717 00718 BOOLEAN 00719 NTAPI 00720 INIT_FUNCTION 00721 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 00722 { 00723 PLOADER_PARAMETER_EXTENSION Extension; 00724 00725 /* Get the loader extension */ 00726 Extension = LoaderBlock->Extension; 00727 00728 /* Validate the size (larger structures are OK, we'll just ignore them) */ 00729 if (Extension->Size < sizeof(LOADER_PARAMETER_EXTENSION)) return FALSE; 00730 00731 /* Don't validate upper versions */ 00732 if (Extension->MajorVersion > VER_PRODUCTMAJORVERSION) return TRUE; 00733 00734 /* Fail if this is NT 4 */ 00735 if (Extension->MajorVersion < VER_PRODUCTMAJORVERSION) return FALSE; 00736 00737 /* Fail if this is XP */ 00738 if (Extension->MinorVersion < VER_PRODUCTMINORVERSION) return FALSE; 00739 00740 /* This is 2003 or newer, approve it */ 00741 return TRUE; 00742 } 00743 00744 VOID 00745 NTAPI 00746 INIT_FUNCTION 00747 ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 00748 { 00749 ULONG i = 0; 00750 PLIST_ENTRY NextEntry; 00751 ULONG Count, Length; 00752 PWCHAR Name; 00753 PLDR_DATA_TABLE_ENTRY LdrEntry; 00754 CHAR NameBuffer[256]; 00755 STRING SymbolString; 00756 NTSTATUS Status; 00757 00758 /* Loop the driver list */ 00759 NextEntry = LoaderBlock->LoadOrderListHead.Flink; 00760 while (NextEntry != &LoaderBlock->LoadOrderListHead) 00761 { 00762 /* Skip the first two images */ 00763 if (i >= 2) 00764 { 00765 /* Get the entry */ 00766 LdrEntry = CONTAINING_RECORD(NextEntry, 00767 LDR_DATA_TABLE_ENTRY, 00768 InLoadOrderLinks); 00769 if (LdrEntry->FullDllName.Buffer[0] == L'\\') 00770 { 00771 /* We have a name, read its data */ 00772 Name = LdrEntry->FullDllName.Buffer; 00773 Length = LdrEntry->FullDllName.Length / sizeof(WCHAR); 00774 00775 /* Check if our buffer can hold it */ 00776 if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL)) 00777 { 00778 /* It's too long */ 00779 Status = STATUS_BUFFER_OVERFLOW; 00780 } 00781 else 00782 { 00783 /* Copy the name */ 00784 Count = 0; 00785 do 00786 { 00787 /* Copy the character */ 00788 NameBuffer[Count++] = (CHAR)*Name++; 00789 } while (Count < Length); 00790 00791 /* Null-terminate */ 00792 NameBuffer[Count] = ANSI_NULL; 00793 Status = STATUS_SUCCESS; 00794 } 00795 } 00796 else 00797 { 00798 /* Safely print the string into our buffer */ 00799 Status = RtlStringCbPrintfA(NameBuffer, 00800 sizeof(NameBuffer), 00801 "%S\\System32\\Drivers\\%wZ", 00802 &SharedUserData->NtSystemRoot[2], 00803 &LdrEntry->BaseDllName); 00804 } 00805 00806 /* Check if the buffer was ok */ 00807 if (NT_SUCCESS(Status)) 00808 { 00809 /* Initialize the STRING for the debugger */ 00810 RtlInitString(&SymbolString, NameBuffer); 00811 00812 /* Load the symbols */ 00813 DbgLoadImageSymbols(&SymbolString, 00814 LdrEntry->DllBase, 00815 (ULONG_PTR)ZwCurrentProcess()); 00816 } 00817 } 00818 00819 /* Go to the next entry */ 00820 i++; 00821 NextEntry = NextEntry->Flink; 00822 } 00823 } 00824 00825 VOID 00826 NTAPI 00827 INIT_FUNCTION 00828 ExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, 00829 IN ULONG_PTR PagesToDestroy, 00830 IN TYPE_OF_MEMORY MemoryType) 00831 { 00832 PLIST_ENTRY ListEntry; 00833 PMEMORY_ALLOCATION_DESCRIPTOR MemDescriptor; 00834 00835 DPRINT1("Burn RAM amount: %d pages\n", PagesToDestroy); 00836 00837 /* Loop the memory descriptors, beginning at the end */ 00838 for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Blink; 00839 ListEntry != &LoaderBlock->MemoryDescriptorListHead; 00840 ListEntry = ListEntry->Blink) 00841 { 00842 /* Get the memory descriptor structure */ 00843 MemDescriptor = CONTAINING_RECORD(ListEntry, 00844 MEMORY_ALLOCATION_DESCRIPTOR, 00845 ListEntry); 00846 00847 /* Is memory free there or is it temporary? */ 00848 if (MemDescriptor->MemoryType == LoaderFree || 00849 MemDescriptor->MemoryType == LoaderFirmwareTemporary) 00850 { 00851 /* Check if the descriptor has more pages than we want */ 00852 if (MemDescriptor->PageCount > PagesToDestroy) 00853 { 00854 /* Change block's page count, ntoskrnl doesn't care much */ 00855 MemDescriptor->PageCount -= PagesToDestroy; 00856 break; 00857 } 00858 else 00859 { 00860 /* Change block type */ 00861 MemDescriptor->MemoryType = MemoryType; 00862 PagesToDestroy -= MemDescriptor->PageCount; 00863 00864 /* Check if we are done */ 00865 if (PagesToDestroy == 0) break; 00866 } 00867 } 00868 } 00869 } 00870 00871 VOID 00872 NTAPI 00873 INIT_FUNCTION 00874 ExpInitializeExecutive(IN ULONG Cpu, 00875 IN PLOADER_PARAMETER_BLOCK LoaderBlock) 00876 { 00877 PNLS_DATA_BLOCK NlsData; 00878 CHAR Buffer[256]; 00879 ANSI_STRING AnsiPath; 00880 NTSTATUS Status; 00881 PCHAR CommandLine, PerfMem; 00882 ULONG PerfMemUsed; 00883 PLDR_DATA_TABLE_ENTRY NtosEntry; 00884 PMESSAGE_RESOURCE_ENTRY MsgEntry; 00885 ANSI_STRING CsdString; 00886 size_t Remaining = 0; 00887 PCHAR RcEnd = NULL; 00888 CHAR VersionBuffer [65]; 00889 00890 /* Validate Loader */ 00891 if (!ExpIsLoaderValid(LoaderBlock)) 00892 { 00893 /* Invalid loader version */ 00894 KeBugCheckEx(MISMATCHED_HAL, 00895 3, 00896 LoaderBlock->Extension->Size, 00897 LoaderBlock->Extension->MajorVersion, 00898 LoaderBlock->Extension->MinorVersion); 00899 } 00900 00901 /* Initialize PRCB pool lookaside pointers */ 00902 ExInitPoolLookasidePointers(); 00903 00904 /* Check if this is an application CPU */ 00905 if (Cpu) 00906 { 00907 /* Then simply initialize it with HAL */ 00908 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) 00909 { 00910 /* Initialization failed */ 00911 KeBugCheck(HAL_INITIALIZATION_FAILED); 00912 } 00913 00914 /* We're done */ 00915 return; 00916 } 00917 00918 /* Assume no text-mode or remote boot */ 00919 ExpInTextModeSetup = FALSE; 00920 IoRemoteBootClient = FALSE; 00921 00922 /* Check if we have a setup loader block */ 00923 if (LoaderBlock->SetupLdrBlock) 00924 { 00925 /* Check if this is text-mode setup */ 00926 if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_TEXT_MODE) ExpInTextModeSetup = TRUE; 00927 00928 /* Check if this is network boot */ 00929 if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_REMOTE_BOOT) 00930 { 00931 /* Set variable */ 00932 IoRemoteBootClient = TRUE; 00933 00934 /* Make sure we're actually booting off the network */ 00935 ASSERT(!_memicmp(LoaderBlock->ArcBootDeviceName, "net(0)", 6)); 00936 } 00937 } 00938 00939 /* Set phase to 0 */ 00940 ExpInitializationPhase = 0; 00941 00942 /* Get boot command line */ 00943 CommandLine = LoaderBlock->LoadOptions; 00944 if (CommandLine) 00945 { 00946 /* Upcase it for comparison and check if we're in performance mode */ 00947 _strupr(CommandLine); 00948 PerfMem = strstr(CommandLine, "PERFMEM"); 00949 if (PerfMem) 00950 { 00951 /* Check if the user gave a number of bytes to use */ 00952 PerfMem = strstr(PerfMem, "="); 00953 if (PerfMem) 00954 { 00955 /* Read the number of pages we'll use */ 00956 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); 00957 if (PerfMem) 00958 { 00959 /* FIXME: TODO */ 00960 DPRINT1("BBT performance mode not yet supported." 00961 "/PERFMEM option ignored.\n"); 00962 } 00963 } 00964 } 00965 00966 /* Check if we're burning memory */ 00967 PerfMem = strstr(CommandLine, "BURNMEMORY"); 00968 if (PerfMem) 00969 { 00970 /* Check if the user gave a number of bytes to use */ 00971 PerfMem = strstr(PerfMem, "="); 00972 if (PerfMem) 00973 { 00974 /* Read the number of pages we'll use */ 00975 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); 00976 if (PerfMemUsed) ExBurnMemory(LoaderBlock, PerfMemUsed, LoaderBad); 00977 } 00978 } 00979 } 00980 00981 /* Setup NLS Base and offsets */ 00982 NlsData = LoaderBlock->NlsData; 00983 ExpNlsTableBase = NlsData->AnsiCodePageData; 00984 ExpAnsiCodePageDataOffset = 0; 00985 ExpOemCodePageDataOffset = (ULONG)((ULONG_PTR)NlsData->OemCodePageData - 00986 (ULONG_PTR)NlsData->AnsiCodePageData); 00987 ExpUnicodeCaseTableDataOffset = (ULONG)((ULONG_PTR)NlsData->UnicodeCodePageData - 00988 (ULONG_PTR)NlsData->AnsiCodePageData); 00989 00990 /* Initialize the NLS Tables */ 00991 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + 00992 ExpAnsiCodePageDataOffset), 00993 (PVOID)((ULONG_PTR)ExpNlsTableBase + 00994 ExpOemCodePageDataOffset), 00995 (PVOID)((ULONG_PTR)ExpNlsTableBase + 00996 ExpUnicodeCaseTableDataOffset), 00997 &ExpNlsTableInfo); 00998 RtlResetRtlTranslations(&ExpNlsTableInfo); 00999 01000 /* Now initialize the HAL */ 01001 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) 01002 { 01003 /* HAL failed to initialize, bugcheck */ 01004 KeBugCheck(HAL_INITIALIZATION_FAILED); 01005 } 01006 01007 /* Make sure interrupts are active now */ 01008 _enable(); 01009 01010 /* Clear the crypto exponent */ 01011 SharedUserData->CryptoExponent = 0; 01012 01013 /* Set global flags for the checked build */ 01014 #if DBG 01015 NtGlobalFlag |= FLG_ENABLE_CLOSE_EXCEPTIONS | 01016 FLG_ENABLE_KDEBUG_SYMBOL_LOAD; 01017 #endif 01018 01019 /* Setup NT System Root Path */ 01020 sprintf(Buffer, "C:%s", LoaderBlock->NtBootPathName); 01021 01022 /* Convert to ANSI_STRING and null-terminate it */ 01023 RtlInitString(&AnsiPath, Buffer); 01024 Buffer[--AnsiPath.Length] = ANSI_NULL; 01025 01026 /* Get the string from KUSER_SHARED_DATA's buffer */ 01027 RtlInitEmptyUnicodeString(&NtSystemRoot, 01028 SharedUserData->NtSystemRoot, 01029 sizeof(SharedUserData->NtSystemRoot)); 01030 01031 /* Now fill it in */ 01032 Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE); 01033 if (!NT_SUCCESS(Status)) KeBugCheck(SESSION3_INITIALIZATION_FAILED); 01034 01035 /* Setup bugcheck messages */ 01036 KiInitializeBugCheck(); 01037 01038 /* Setup initial system settings */ 01039 CmGetSystemControlValues(LoaderBlock->RegistryBase, CmControlVector); 01040 01041 /* Load static defaults for Service Pack 1 and add our SVN revision */ 01042 CmNtCSDVersion = 0x100 | (KERNEL_VERSION_BUILD_HEX << 16); 01043 CmNtCSDReleaseType = 0; 01044 01045 /* Set Service Pack data for Service Pack 1 */ 01046 CmNtSpBuildNumber = 1830; 01047 if (!(CmNtCSDVersion & 0xFFFF0000)) 01048 { 01049 /* Check the release type */ 01050 if (CmNtCSDReleaseType == 1) CmNtSpBuildNumber |= 1830 << 16; 01051 } 01052 01053 /* Add loaded CmNtGlobalFlag value */ 01054 NtGlobalFlag |= CmNtGlobalFlag; 01055 01056 /* Initialize the executive at phase 0 */ 01057 if (!ExInitSystem()) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 01058 01059 /* Initialize the memory manager at phase 0 */ 01060 if (!MmArmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED); 01061 01062 /* Load boot symbols */ 01063 ExpLoadBootSymbols(LoaderBlock); 01064 01065 /* Check if we should break after symbol load */ 01066 if (KdBreakAfterSymbolLoad) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); 01067 01068 /* Check if this loader is compatible with NT 5.2 */ 01069 if (LoaderBlock->Extension->Size >= sizeof(LOADER_PARAMETER_EXTENSION)) 01070 { 01071 /* Setup headless terminal settings */ 01072 HeadlessInit(LoaderBlock); 01073 } 01074 01075 /* Set system ranges */ 01076 #ifdef _M_AMD64 01077 SharedUserData->Reserved1 = MM_HIGHEST_USER_ADDRESS_WOW64; 01078 SharedUserData->Reserved3 = MM_SYSTEM_RANGE_START_WOW64; 01079 #else 01080 SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress; 01081 SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart; 01082 #endif 01083 01084 /* Make a copy of the NLS Tables */ 01085 ExpInitNls(LoaderBlock); 01086 01087 /* Get the kernel's load entry */ 01088 NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, 01089 LDR_DATA_TABLE_ENTRY, 01090 InLoadOrderLinks); 01091 01092 /* Check if this is a service pack */ 01093 if (CmNtCSDVersion & 0xFFFF) 01094 { 01095 /* Get the service pack string */ 01096 Status = RtlFindMessage(NtosEntry->DllBase, 01097 11, 01098 0, 01099 WINDOWS_NT_CSD_STRING, 01100 &MsgEntry); 01101 if (NT_SUCCESS(Status)) 01102 { 01103 /* Setup the string */ 01104 RtlInitAnsiString(&CsdString, (PCHAR)MsgEntry->Text); 01105 01106 /* Remove trailing newline */ 01107 while ((CsdString.Length > 0) && 01108 ((CsdString.Buffer[CsdString.Length - 1] == '\r') || 01109 (CsdString.Buffer[CsdString.Length - 1] == '\n'))) 01110 { 01111 /* Skip the trailing character */ 01112 CsdString.Length--; 01113 } 01114 01115 /* Fill the buffer with version information */ 01116 Status = RtlStringCbPrintfA(Buffer, 01117 sizeof(Buffer), 01118 "%Z %u%c", 01119 &CsdString, 01120 (CmNtCSDVersion & 0xFF00) >> 8, 01121 (CmNtCSDVersion & 0xFF) ? 01122 'A' + (CmNtCSDVersion & 0xFF) - 1 : 01123 ANSI_NULL); 01124 } 01125 else 01126 { 01127 /* Build default string */ 01128 Status = RtlStringCbPrintfA(Buffer, 01129 sizeof(Buffer), 01130 "CSD %04x", 01131 CmNtCSDVersion); 01132 } 01133 01134 /* Check for success */ 01135 if (!NT_SUCCESS(Status)) 01136 { 01137 /* Fail */ 01138 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 01139 } 01140 } 01141 else 01142 { 01143 /* Then this is a beta */ 01144 Status = RtlStringCbCopyExA(Buffer, 01145 sizeof(Buffer), 01146 VER_PRODUCTBETA_STR, 01147 NULL, 01148 &Remaining, 01149 0); 01150 if (!NT_SUCCESS(Status)) 01151 { 01152 /* Fail */ 01153 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 01154 } 01155 01156 /* Update length */ 01157 CmCSDVersionString.MaximumLength = sizeof(Buffer) - (USHORT)Remaining; 01158 } 01159 01160 /* Check if we have an RC number */ 01161 if (CmNtCSDVersion & 0xFFFF0000) 01162 { 01163 /* Check if we have no version data yet */ 01164 if (!(*Buffer)) 01165 { 01166 /* Set defaults */ 01167 Remaining = sizeof(Buffer); 01168 RcEnd = Buffer; 01169 } 01170 else 01171 { 01172 /* Add comma and space */ 01173 Status = RtlStringCbCatExA(Buffer, 01174 sizeof(Buffer), 01175 ", ", 01176 &RcEnd, 01177 &Remaining, 01178 0); 01179 if (!NT_SUCCESS(Status)) 01180 { 01181 /* Fail */ 01182 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 01183 } 01184 } 01185 01186 /* Add the version format string */ 01187 Status = RtlStringCbPrintfA(RcEnd, 01188 Remaining, 01189 "v. %u", 01190 (CmNtCSDVersion & 0xFFFF0000) >> 16); 01191 if (!NT_SUCCESS(Status)) 01192 { 01193 /* Fail */ 01194 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 01195 } 01196 } 01197 01198 /* Now setup the final string */ 01199 RtlInitAnsiString(&CsdString, Buffer); 01200 Status = RtlAnsiStringToUnicodeString(&CmCSDVersionString, 01201 &CsdString, 01202 TRUE); 01203 if (!NT_SUCCESS(Status)) 01204 { 01205 /* Fail */ 01206 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 01207 } 01208 01209 /* Add our version */ 01210 Status = RtlStringCbPrintfA(VersionBuffer, 01211 sizeof(VersionBuffer), 01212 "%u.%u", 01213 VER_PRODUCTMAJORVERSION, 01214 VER_PRODUCTMINORVERSION); 01215 if (!NT_SUCCESS(Status)) 01216 { 01217 /* Fail */ 01218 KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); 01219 } 01220 01221 /* Build the final version string */ 01222 RtlCreateUnicodeStringFromAsciiz(&CmVersionString, VersionBuffer); 01223 01224 /* Check if the user wants a kernel stack trace database */ 01225 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) 01226 { 01227 /* FIXME: TODO */ 01228 DPRINT1("Kernel-mode stack trace support not yet present." 01229 "FLG_KERNEL_STACK_TRACE_DB flag ignored.\n"); 01230 } 01231 01232 /* Check if he wanted exception logging */ 01233 if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING) 01234 { 01235 /* FIXME: TODO */ 01236 DPRINT1("Kernel-mode exception logging support not yet present." 01237 "FLG_ENABLE_EXCEPTION_LOGGING flag ignored.\n"); 01238 } 01239 01240 /* Initialize the Handle Table */ 01241 ExpInitializeHandleTables(); 01242 01243 #if DBG 01244 /* On checked builds, allocate the system call count table */ 01245 KeServiceDescriptorTable[0].Count = 01246 ExAllocatePoolWithTag(NonPagedPool, 01247 KiServiceLimit * sizeof(ULONG), 01248 'llaC'); 01249 01250 /* Use it for the shadow table too */ 01251 KeServiceDescriptorTableShadow[0].Count = KeServiceDescriptorTable[0].Count; 01252 01253 /* Make sure allocation succeeded */ 01254 if (KeServiceDescriptorTable[0].Count) 01255 { 01256 /* Zero the call counts to 0 */ 01257 RtlZeroMemory(KeServiceDescriptorTable[0].Count, 01258 KiServiceLimit * sizeof(ULONG)); 01259 } 01260 #endif 01261 01262 /* Create the Basic Object Manager Types to allow new Object Types */ 01263 if (!ObInitSystem()) KeBugCheck(OBJECT_INITIALIZATION_FAILED); 01264 01265 /* Load basic Security for other Managers */ 01266 if (!SeInitSystem()) KeBugCheck(SECURITY_INITIALIZATION_FAILED); 01267 01268 /* Initialize the Process Manager */ 01269 if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS_INITIALIZATION_FAILED); 01270 01271 /* Initialize the PnP Manager */ 01272 if (!PpInitSystem()) KeBugCheck(PP0_INITIALIZATION_FAILED); 01273 01274 /* Initialize the User-Mode Debugging Subsystem */ 01275 DbgkInitialize(); 01276 01277 /* Calculate the tick count multiplier */ 01278 ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement); 01279 SharedUserData->TickCountMultiplier = ExpTickCountMultiplier; 01280 01281 /* Set the OS Version */ 01282 SharedUserData->NtMajorVersion = NtMajorVersion; 01283 SharedUserData->NtMinorVersion = NtMinorVersion; 01284 01285 /* Set the machine type */ 01286 SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_NATIVE; 01287 SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_NATIVE; 01288 } 01289 01290 VOID 01291 NTAPI 01292 MmFreeLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock); 01293 01294 VOID 01295 NTAPI 01296 INIT_FUNCTION 01297 Phase1InitializationDiscard(IN PVOID Context) 01298 { 01299 PLOADER_PARAMETER_BLOCK LoaderBlock = Context; 01300 NTSTATUS Status, MsgStatus; 01301 TIME_FIELDS TimeFields; 01302 LARGE_INTEGER SystemBootTime, UniversalBootTime, OldTime, Timeout; 01303 BOOLEAN SosEnabled, NoGuiBoot, ResetBias = FALSE, AlternateShell = FALSE; 01304 PLDR_DATA_TABLE_ENTRY NtosEntry; 01305 PMESSAGE_RESOURCE_ENTRY MsgEntry; 01306 PCHAR CommandLine, Y2KHackRequired, SafeBoot, Environment; 01307 PCHAR StringBuffer, EndBuffer, BeginBuffer, MpString = ""; 01308 PINIT_BUFFER InitBuffer; 01309 ANSI_STRING TempString; 01310 ULONG LastTzBias, Length, YearHack = 0, Disposition, MessageCode = 0; 01311 SIZE_T Size; 01312 size_t Remaining; 01313 PRTL_USER_PROCESS_INFORMATION ProcessInfo; 01314 KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo; 01315 UNICODE_STRING KeyName; 01316 OBJECT_ATTRIBUTES ObjectAttributes; 01317 HANDLE KeyHandle, OptionHandle; 01318 PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL; 01319 01320 /* Allocate the initialization buffer */ 01321 InitBuffer = ExAllocatePoolWithTag(NonPagedPool, 01322 sizeof(INIT_BUFFER), 01323 TAG_INIT); 01324 if (!InitBuffer) 01325 { 01326 /* Bugcheck */ 01327 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 8, 0, 0); 01328 } 01329 01330 /* Set to phase 1 */ 01331 ExpInitializationPhase = 1; 01332 01333 /* Set us at maximum priority */ 01334 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY); 01335 01336 /* Do Phase 1 HAL Initialization */ 01337 if (!HalInitSystem(1, LoaderBlock)) KeBugCheck(HAL1_INITIALIZATION_FAILED); 01338 01339 /* Get the command line and upcase it */ 01340 CommandLine = _strupr(LoaderBlock->LoadOptions); 01341 01342 /* Check if GUI Boot is enabled */ 01343 NoGuiBoot = (strstr(CommandLine, "NOGUIBOOT")) ? TRUE: FALSE; 01344 01345 /* Get the SOS setting */ 01346 SosEnabled = strstr(CommandLine, "SOS") ? TRUE: FALSE; 01347 01348 /* Setup the boot driver */ 01349 InbvEnableBootDriver(!NoGuiBoot); 01350 InbvDriverInitialize(LoaderBlock, 18); 01351 01352 /* Check if GUI boot is enabled */ 01353 if (!NoGuiBoot) 01354 { 01355 /* It is, display the boot logo and enable printing strings */ 01356 InbvEnableDisplayString(SosEnabled); 01357 DisplayBootBitmap(SosEnabled); 01358 } 01359 else 01360 { 01361 /* Release display ownership if not using GUI boot */ 01362 InbvNotifyDisplayOwnershipLost(NULL); 01363 01364 /* Don't allow boot-time strings */ 01365 InbvEnableDisplayString(FALSE); 01366 } 01367 01368 /* Check if this is LiveCD (WinPE) mode */ 01369 if (strstr(CommandLine, "MININT")) 01370 { 01371 /* Setup WinPE Settings */ 01372 InitIsWinPEMode = TRUE; 01373 InitWinPEModeType |= (strstr(CommandLine, "INRAM")) ? 0x80000000 : 1; 01374 } 01375 01376 /* Get the kernel's load entry */ 01377 NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, 01378 LDR_DATA_TABLE_ENTRY, 01379 InLoadOrderLinks); 01380 01381 /* Find the banner message */ 01382 MsgStatus = RtlFindMessage(NtosEntry->DllBase, 01383 11, 01384 0, 01385 WINDOWS_NT_BANNER, 01386 &MsgEntry); 01387 01388 /* Setup defaults and check if we have a version string */ 01389 StringBuffer = InitBuffer->VersionBuffer; 01390 BeginBuffer = StringBuffer; 01391 EndBuffer = StringBuffer; 01392 Remaining = sizeof(InitBuffer->VersionBuffer); 01393 if (CmCSDVersionString.Length) 01394 { 01395 /* Print the version string */ 01396 Status = RtlStringCbPrintfExA(StringBuffer, 01397 Remaining, 01398 &EndBuffer, 01399 &Remaining, 01400 0, 01401 ": %wZ", 01402 &CmCSDVersionString); 01403 if (!NT_SUCCESS(Status)) 01404 { 01405 /* Bugcheck */ 01406 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 01407 } 01408 } 01409 else 01410 { 01411 /* No version */ 01412 *EndBuffer = ANSI_NULL; /* Null-terminate the string */ 01413 } 01414 01415 /* Skip over the null-terminator to start a new string */ 01416 ++EndBuffer; 01417 --Remaining; 01418 01419 /* Build the version number */ 01420 StringBuffer = InitBuffer->VersionNumber; 01421 Status = RtlStringCbPrintfA(StringBuffer, 01422 sizeof(InitBuffer->VersionNumber), 01423 "%u.%u", 01424 VER_PRODUCTMAJORVERSION, 01425 VER_PRODUCTMINORVERSION); 01426 if (!NT_SUCCESS(Status)) 01427 { 01428 /* Bugcheck */ 01429 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 01430 } 01431 01432 /* Check if we had found a banner message */ 01433 if (NT_SUCCESS(MsgStatus)) 01434 { 01435 /* Create the banner message */ 01436 Status = RtlStringCbPrintfA(EndBuffer, 01437 Remaining, 01438 (PCHAR)MsgEntry->Text, 01439 StringBuffer, 01440 NtBuildNumber & 0xFFFF, 01441 BeginBuffer); 01442 if (!NT_SUCCESS(Status)) 01443 { 01444 /* Bugcheck */ 01445 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 01446 } 01447 } 01448 else 01449 { 01450 /* Use hard-coded banner message */ 01451 Status = RtlStringCbCopyA(EndBuffer, Remaining, "REACTOS (R)\n"); 01452 if (!NT_SUCCESS(Status)) 01453 { 01454 /* Bugcheck */ 01455 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); 01456 } 01457 } 01458 01459 /* Display the version string on-screen */ 01460 InbvDisplayString(EndBuffer); 01461 01462 /* Initialize Power Subsystem in Phase 0 */ 01463 if (!PoInitSystem(0)) KeBugCheck(INTERNAL_POWER_ERROR); 01464 01465 /* Check for Y2K hack */ 01466 Y2KHackRequired = strstr(CommandLine, "YEAR"); 01467 if (Y2KHackRequired) Y2KHackRequired = strstr(Y2KHackRequired, "="); 01468 if (Y2KHackRequired) YearHack = atol(Y2KHackRequired + 1); 01469 01470 /* Query the clock */ 01471 if ((ExCmosClockIsSane) && (HalQueryRealTimeClock(&TimeFields))) 01472 { 01473 /* Check if we're using the Y2K hack */ 01474 if (Y2KHackRequired) TimeFields.Year = (CSHORT)YearHack; 01475 01476 /* Convert to time fields */ 01477 RtlTimeFieldsToTime(&TimeFields, &SystemBootTime); 01478 UniversalBootTime = SystemBootTime; 01479 01480 /* Check if real time is GMT */ 01481 if (!ExpRealTimeIsUniversal) 01482 { 01483 /* Check if we don't have a valid bias */ 01484 if (ExpLastTimeZoneBias == MAXULONG) 01485 { 01486 /* Reset */ 01487 ResetBias = TRUE; 01488 ExpLastTimeZoneBias = ExpAltTimeZoneBias; 01489 } 01490 01491 /* Calculate the bias in seconds */ 01492 ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60, 01493 10000000); 01494 01495 /* Set the boot time-zone bias */ 01496 SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart; 01497 SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart; 01498 SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart; 01499 01500 /* Convert the boot time to local time, and set it */ 01501 UniversalBootTime.QuadPart = SystemBootTime.QuadPart + 01502 ExpTimeZoneBias.QuadPart; 01503 } 01504 01505 /* Update the system time */ 01506 KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); 01507 01508 /* Do system callback */ 01509 PoNotifySystemTimeSet(); 01510 01511 /* Remember this as the boot time */ 01512 KeBootTime = UniversalBootTime; 01513 KeBootTimeBias = 0; 01514 } 01515 01516 /* Initialize all processors */ 01517 if (!HalAllProcessorsStarted()) KeBugCheck(HAL1_INITIALIZATION_FAILED); 01518 01519 #ifdef CONFIG_SMP 01520 /* HACK: We should use RtlFindMessage and not only fallback to this */ 01521 MpString = "MultiProcessor Kernel\r\n"; 01522 #endif 01523 01524 /* Setup the "MP" String */ 01525 RtlInitAnsiString(&TempString, MpString); 01526 01527 /* Make sure to remove the \r\n if we actually have a string */ 01528 while ((TempString.Length > 0) && 01529 ((TempString.Buffer[TempString.Length - 1] == '\r') || 01530 (TempString.Buffer[TempString.Length - 1] == '\n'))) 01531 { 01532 /* Skip the trailing character */ 01533 TempString.Length--; 01534 } 01535 01536 /* Get the information string from our resource file */ 01537 MsgStatus = RtlFindMessage(NtosEntry->DllBase, 01538 11, 01539 0, 01540 KeNumberProcessors > 1 ? 01541 WINDOWS_NT_INFO_STRING_PLURAL : 01542 WINDOWS_NT_INFO_STRING, 01543 &MsgEntry); 01544 01545 /* Get total RAM size */ 01546 Size = MmNumberOfPhysicalPages * PAGE_SIZE / 1024 / 1024; 01547 01548 /* Create the string */ 01549 StringBuffer = InitBuffer->VersionBuffer; 01550 Status = RtlStringCbPrintfA(StringBuffer, 01551 sizeof(InitBuffer->VersionBuffer), 01552 NT_SUCCESS(MsgStatus) ? 01553 (PCHAR)MsgEntry->Text : 01554 "%u System Processor [%u MB Memory] %Z\n", 01555 KeNumberProcessors, 01556 Size, 01557 &TempString); 01558 if (!NT_SUCCESS(Status)) 01559 { 01560 /* Bugcheck */ 01561 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 4, 0, 0); 01562 } 01563 01564 /* Display RAM and CPU count */ 01565 InbvDisplayString(StringBuffer); 01566 01567 /* Update the progress bar */ 01568 InbvUpdateProgressBar(5); 01569 01570 /* Call OB initialization again */ 01571 if (!ObInitSystem()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED); 01572 01573 /* Initialize Basic System Objects and Worker Threads */ 01574 if (!ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 1, 0); 01575 01576 /* Initialize the later stages of the kernel */ 01577 if (!KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 2, 0); 01578 01579 /* Call KD Providers at Phase 1 */ 01580 if (!KdInitSystem(ExpInitializationPhase, KeLoaderBlock)) 01581 { 01582 /* Failed, bugcheck */ 01583 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 3, 0); 01584 } 01585 01586 /* Initialize the SRM in Phase 1 */ 01587 if (!SeInitSystem()) KeBugCheck(SECURITY1_INITIALIZATION_FAILED); 01588 01589 /* Update the progress bar */ 01590 InbvUpdateProgressBar(10); 01591 01592 /* Create SystemRoot Link */ 01593 Status = ExpCreateSystemRootLink(LoaderBlock); 01594 if (!NT_SUCCESS(Status)) 01595 { 01596 /* Failed to create the system root link */ 01597 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0); 01598 } 01599 01600 /* Set up Region Maps, Sections and the Paging File */ 01601 if (!MmInitSystem(1, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED); 01602 01603 /* Create NLS section */ 01604 ExpInitNls(LoaderBlock); 01605 01606 /* Initialize Cache Views */ 01607 if (!CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED); 01608 01609 /* Initialize the Registry */ 01610 if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED); 01611 01612 /* Initialize Prefetcher */ 01613 CcPfInitializePrefetcher(); 01614 01615 /* Update progress bar */ 01616 InbvUpdateProgressBar(15); 01617 01618 /* Update timezone information */ 01619 LastTzBias = ExpLastTimeZoneBias; 01620 ExRefreshTimeZoneInformation(&SystemBootTime); 01621 01622 /* Check if we're resetting timezone data */ 01623 if (ResetBias) 01624 { 01625 /* Convert the local time to system time */ 01626 ExLocalTimeToSystemTime(&SystemBootTime, &UniversalBootTime); 01627 KeBootTime = UniversalBootTime; 01628 KeBootTimeBias = 0; 01629 01630 /* Set the new time */ 01631 KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); 01632 } 01633 else 01634 { 01635 /* Check if the timezone switched and update the time */ 01636 if (LastTzBias != ExpLastTimeZoneBias) ZwSetSystemTime(NULL, NULL); 01637 } 01638 01639 /* Initialize the File System Runtime Library */ 01640 if (!FsRtlInitSystem()) KeBugCheck(FILE_INITIALIZATION_FAILED); 01641 01642 /* Initialize range lists */ 01643 RtlInitializeRangeListPackage(); 01644 01645 /* Report all resources used by HAL */ 01646 HalReportResourceUsage(); 01647 01648 /* Call the debugger DLL */ 01649 KdDebuggerInitialize1(LoaderBlock); 01650 01651 /* Setup PnP Manager in phase 1 */ 01652 if (!PpInitSystem()) KeBugCheck(PP1_INITIALIZATION_FAILED); 01653 01654 /* Update progress bar */ 01655 InbvUpdateProgressBar(20); 01656 01657 /* Initialize LPC */ 01658 if (!LpcInitSystem()) KeBugCheck(LPC_INITIALIZATION_FAILED); 01659 01660 /* Make sure we have a command line */ 01661 if (CommandLine) 01662 { 01663 /* Check if this is a safe mode boot */ 01664 SafeBoot = strstr(CommandLine, "SAFEBOOT:"); 01665 if (SafeBoot) 01666 { 01667 /* Check what kind of boot this is */ 01668 SafeBoot += 9; 01669 if (!strncmp(SafeBoot, "MINIMAL", 7)) 01670 { 01671 /* Minimal mode */ 01672 InitSafeBootMode = 1; 01673 SafeBoot += 7; 01674 MessageCode = BOOTING_IN_SAFEMODE_MINIMAL; 01675 } 01676 else if (!strncmp(SafeBoot, "NETWORK", 7)) 01677 { 01678 /* With Networking */ 01679 InitSafeBootMode = 2; 01680 SafeBoot += 7; 01681 MessageCode = BOOTING_IN_SAFEMODE_NETWORK; 01682 } 01683 else if (!strncmp(SafeBoot, "DSREPAIR", 8)) 01684 { 01685 /* Domain Server Repair */ 01686 InitSafeBootMode = 3; 01687 SafeBoot += 8; 01688 MessageCode = BOOTING_IN_SAFEMODE_DSREPAIR; 01689 01690 } 01691 else 01692 { 01693 /* Invalid */ 01694 InitSafeBootMode = 0; 01695 } 01696 01697 /* Check if there's any settings left */ 01698 if (*SafeBoot) 01699 { 01700 /* Check if an alternate shell was requested */ 01701 if (!strncmp(SafeBoot, "(ALTERNATESHELL)", 16)) 01702 { 01703 /* Remember this for later */ 01704 AlternateShell = TRUE; 01705 } 01706 } 01707 01708 /* Find the message to print out */ 01709 Status = RtlFindMessage(NtosEntry->DllBase, 01710 11, 01711 0, 01712 MessageCode, 01713 &MsgEntry); 01714 if (NT_SUCCESS(Status)) 01715 { 01716 /* Display it */ 01717 InbvDisplayString((PCHAR)MsgEntry->Text); 01718 } 01719 } 01720 } 01721 01722 /* Make sure we have a command line */ 01723 if (CommandLine) 01724 { 01725 /* Check if bootlogging is enabled */ 01726 if (strstr(CommandLine, "BOOTLOG")) 01727 { 01728 /* Find the message to print out */ 01729 Status = RtlFindMessage(NtosEntry->DllBase, 01730 11, 01731 0, 01732 BOOTLOG_ENABLED, 01733 &MsgEntry); 01734 if (NT_SUCCESS(Status)) 01735 { 01736 /* Display it */ 01737 InbvDisplayString((PCHAR)MsgEntry->Text); 01738 } 01739 01740 /* Setup boot logging */ 01741 //IopInitializeBootLogging(LoaderBlock, InitBuffer->BootlogHeader); 01742 } 01743 } 01744 01745 /* Setup the Executive in Phase 2 */ 01746 //ExInitSystemPhase2(); 01747 01748 /* Update progress bar */ 01749 InbvUpdateProgressBar(25); 01750 01751 #ifdef _WINKD_ 01752 /* No KD Time Slip is pending */ 01753 KdpTimeSlipPending = 0; 01754 #endif 01755 01756 /* Initialize in-place execution support */ 01757 XIPInit(LoaderBlock); 01758 01759 /* Set maximum update to 75% */ 01760 InbvSetProgressBarSubset(25, 75); 01761 01762 /* Initialize the I/O Subsystem */ 01763 if (!IoInitSystem(LoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED); 01764 01765 /* Set maximum update to 100% */ 01766 InbvSetProgressBarSubset(0, 100); 01767 01768 /* Are we in safe mode? */ 01769 if (InitSafeBootMode) 01770 { 01771 /* Open the safe boot key */ 01772 RtlInitUnicodeString(&KeyName, 01773 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" 01774 L"\\CONTROL\\SAFEBOOT"); 01775 InitializeObjectAttributes(&ObjectAttributes, 01776 &KeyName, 01777 OBJ_CASE_INSENSITIVE, 01778 NULL, 01779 NULL); 01780 Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); 01781 if (NT_SUCCESS(Status)) 01782 { 01783 /* First check if we have an alternate shell */ 01784 if (AlternateShell) 01785 { 01786 /* Make sure that the registry has one setup */ 01787 RtlInitUnicodeString(&KeyName, L"AlternateShell"); 01788 Status = NtQueryValueKey(KeyHandle, 01789 &KeyName, 01790 KeyValuePartialInformation, 01791 &KeyPartialInfo, 01792 sizeof(KeyPartialInfo), 01793 &Length); 01794 if (!(NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)) 01795 { 01796 AlternateShell = FALSE; 01797 } 01798 } 01799 01800 /* Create the option key */ 01801 RtlInitUnicodeString(&KeyName, L"Option"); 01802 InitializeObjectAttributes(&ObjectAttributes, 01803 &KeyName, 01804 OBJ_CASE_INSENSITIVE, 01805 KeyHandle, 01806 NULL); 01807 Status = ZwCreateKey(&OptionHandle, 01808 KEY_ALL_ACCESS, 01809 &ObjectAttributes, 01810 0, 01811 NULL, 01812 REG_OPTION_VOLATILE, 01813 &Disposition); 01814 NtClose(KeyHandle); 01815 01816 /* Check if the key create worked */ 01817 if (NT_SUCCESS(Status)) 01818 { 01819 /* Write the safe boot type */ 01820 RtlInitUnicodeString(&KeyName, L"OptionValue"); 01821 NtSetValueKey(OptionHandle, 01822 &KeyName, 01823 0, 01824 REG_DWORD, 01825 &InitSafeBootMode, 01826 sizeof(InitSafeBootMode)); 01827 01828 /* Check if we have to use an alternate shell */ 01829 if (AlternateShell) 01830 { 01831 /* Remember this for later */ 01832 Disposition = TRUE; 01833 RtlInitUnicodeString(&KeyName, L"UseAlternateShell"); 01834 NtSetValueKey(OptionHandle, 01835 &KeyName, 01836 0, 01837 REG_DWORD, 01838 &Disposition, 01839 sizeof(Disposition)); 01840 } 01841 01842 /* Close the options key handle */ 01843 NtClose(OptionHandle); 01844 } 01845 } 01846 } 01847 01848 /* Are we in Win PE mode? */ 01849 if (InitIsWinPEMode) 01850 { 01851 /* Open the safe control key */ 01852 RtlInitUnicodeString(&KeyName, 01853 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" 01854 L"\\CONTROL"); 01855 InitializeObjectAttributes(&ObjectAttributes, 01856 &KeyName, 01857 OBJ_CASE_INSENSITIVE, 01858 NULL, 01859 NULL); 01860 Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); 01861 if (!NT_SUCCESS(Status)) 01862 { 01863 /* Bugcheck */ 01864 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); 01865 } 01866 01867 /* Create the MiniNT key */ 01868 RtlInitUnicodeString(&KeyName, L"MiniNT"); 01869 InitializeObjectAttributes(&ObjectAttributes, 01870 &KeyName, 01871 OBJ_CASE_INSENSITIVE, 01872 KeyHandle, 01873 NULL); 01874 Status = ZwCreateKey(&OptionHandle, 01875 KEY_ALL_ACCESS, 01876 &ObjectAttributes, 01877 0, 01878 NULL, 01879 REG_OPTION_VOLATILE, 01880 &Disposition); 01881 if (!NT_SUCCESS(Status)) 01882 { 01883 /* Bugcheck */ 01884 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); 01885 } 01886 01887 /* Close the handles */ 01888 NtClose(KeyHandle); 01889 NtClose(OptionHandle); 01890 } 01891 01892 /* FIXME: This doesn't do anything for now */ 01893 MmArmInitSystem(2, LoaderBlock); 01894 01895 /* Update progress bar */ 01896 InbvUpdateProgressBar(80); 01897 01898 /* Initialize VDM support */ 01899 #if defined(_M_IX86) 01900 KeI386VdmInitialize(); 01901 #endif 01902 01903 /* Initialize Power Subsystem in Phase 1*/ 01904 if (!PoInitSystem(1)) KeBugCheck(INTERNAL_POWER_ERROR); 01905 01906 /* Update progress bar */ 01907 InbvUpdateProgressBar(90); 01908 01909 /* Initialize the Process Manager at Phase 1 */ 01910 if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS1_INITIALIZATION_FAILED); 01911 01912 /* Make sure nobody touches the loader block again */ 01913 if (LoaderBlock == KeLoaderBlock) KeLoaderBlock = NULL; 01914 MmFreeLoaderBlock(LoaderBlock); 01915 LoaderBlock = Context = NULL; 01916 01917 /* Update progress bar */ 01918 InbvUpdateProgressBar(100); 01919 01920 /* Allow strings to be displayed */ 01921 InbvEnableDisplayString(TRUE); 01922 01923 /* Launch initial process */ 01924 DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed); 01925 ProcessInfo = &InitBuffer->ProcessInfo; 01926 ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment); 01927 01928 /* Wait 5 seconds for initial process to initialize */ 01929 Timeout.QuadPart = Int32x32To64(5, -10000000); 01930 Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout); 01931 if (Status == STATUS_SUCCESS) 01932 { 01933 /* Failed, display error */ 01934 DPRINT1("INIT: Session Manager terminated.\n"); 01935 01936 /* Bugcheck the system if SMSS couldn't initialize */ 01937 KeBugCheck(SESSION5_INITIALIZATION_FAILED); 01938 } 01939 01940 /* Close process handles */ 01941 ZwClose(ProcessInfo->ThreadHandle); 01942 ZwClose(ProcessInfo->ProcessHandle); 01943 01944 /* Free the initial process environment */ 01945 Size = 0; 01946 ZwFreeVirtualMemory(NtCurrentProcess(), 01947 (PVOID*)&Environment, 01948 &Size, 01949 MEM_RELEASE); 01950 01951 /* Free the initial process parameters */ 01952 Size = 0; 01953 ZwFreeVirtualMemory(NtCurrentProcess(), 01954 (PVOID*)&ProcessParameters, 01955 &Size, 01956 MEM_RELEASE); 01957 01958 /* Clean the screen */ 01959 if (InbvBootDriverInstalled) FinalizeBootLogo(); 01960 01961 /* Increase init phase */ 01962 ExpInitializationPhase++; 01963 01964 /* Free the boot buffer */ 01965 ExFreePoolWithTag(InitBuffer, TAG_INIT); 01966 DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed); 01967 } 01968 01969 VOID 01970 NTAPI 01971 Phase1Initialization(IN PVOID Context) 01972 { 01973 /* Do the .INIT part of Phase 1 which we can free later */ 01974 Phase1InitializationDiscard(Context); 01975 01976 /* Jump into zero page thread */ 01977 MmZeroPageThread(); 01978 } Generated on Sat May 26 2012 04:22:07 for ReactOS by
1.7.6.1
|