ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

init.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.