从函数RunUSetup的循环处理里,可以看到第一个应处理,就是启动页面,也就是调用函数SetupStartPage,它的代码如下:
#001 /*
#002 * Start page
#003 * RETURNS
#004 * Number of the next page.
#005 */
#006 static PAGE_NUMBER
#007 SetupStartPage(PINPUT_RECORD Ir)
#008 {
#009 SYSTEM_DEVICE_INFORMATION Sdi;
#010 NTSTATUS Status;
#011 WCHAR FileNameBuffer[MAX_PATH];
#012 INFCONTEXT Context;
#013 PWCHAR Value;
#014 UINT ErrorLine;
#015 ULONG ReturnSize;
#016 PGENERIC_LIST_ENTRY ListEntry;
#017
在显示器上显示等待字符串。
#018 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT));
#019
#020
检查是否有一个硬盘可以使用。
#021 /* Check whether a harddisk is available */
#022 Status = NtQuerySystemInformation (SystemDeviceInformation,
#023 &Sdi,
#024 sizeof(SYSTEM_DEVICE_INFORMATION),
#025 &ReturnSize);
#026
如果没有硬盘可以使用,就返回出错。
#027 if (!NT_SUCCESS (Status))
#028 {
#029 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status);
#030 MUIDisplayError(ERROR_DRIVE_INFORMATION, Ir, POPUP_WAIT_ENTER);
#031 return QUIT_PAGE;
#032 }
#033
#034 if (Sdi.NumberOfDisks == 0)
#035 {
#036 MUIDisplayError(ERROR_NO_HDD, Ir, POPUP_WAIT_ENTER);
#037 return QUIT_PAGE;
#038 }
#039
获取源安装目录和根目录路径。
#040 /* Get the source path and source root path */
#041 Status = GetSourcePaths(&SourcePath,
#042 &SourceRootPath,
#043 &SourceRootDir);
#044
#045 if (!NT_SUCCESS(Status))
#046 {
#047 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status);
#048 MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER);
#049 return QUIT_PAGE;
#050 }
#051 #if 0
#052 else
#053 {
#054 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath);
#055 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
#056 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir);
#057 }
#058 #endif
#059
准备txtsetup.sif文件路径,以便加载它到内存。txtsetup.sif是一个安装信息文件(sif),主要用于 Reactos 的文本安装模式。
#060 /* Load txtsetup.sif from install media. */
#061 wcscpy(FileNameBuffer, SourcePath.Buffer);
#062 wcscat(FileNameBuffer, L"//txtsetup.sif");
#063
#064 SetupInf = SetupOpenInfFileW(FileNameBuffer,
#065 NULL,
#066 INF_STYLE_WIN4,
#067 &ErrorLine);
#068
#069 if (SetupInf == INVALID_HANDLE_VALUE)
#070 {
#071 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
#072 return QUIT_PAGE;
#073 }
#074
查找安装信息文件的版本信息。
#075 /* Open 'Version' section */
#076 if (!SetupFindFirstLineW (SetupInf, L"Version", L"Signature", &Context))
#077 {
#078 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
#079 return QUIT_PAGE;
#080 }
#081
#082 /* Get pointer 'Signature' key */
#083 if (!INF_GetData (&Context, NULL, &Value))
#084 {
#085 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
#086 return QUIT_PAGE;
#087 }
#088
检查版本标志是否为ReactOS。
#089 /* Check 'Signature' string */
#090 if (_wcsicmp(Value, L"$ReactOS$") != 0)
#091 {
#092 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER);
#093 return QUIT_PAGE;
#094 }
#095
启动即插即用事件处理线程。
#096 /* Start PnP thread */
#097 if (hPnpThread != INVALID_HANDLE_VALUE)
#098 {
#099 NtResumeThread(hPnpThread, NULL);
#100 hPnpThread = INVALID_HANDLE_VALUE;
#101 }
#102
检查是否需要自动安装,也就是不需要人为地关注的安装。
#103 CheckUnattendedSetup();
#104
如果自动安装启用,就进行系统默认的配置安装,否则就需要人工地选择后面的安装功能。
#105 if (IsUnattendedSetup)
#106 {
#107 //TODO
#108 //read options from inf
#109 ComputerList = CreateComputerTypeList(SetupInf);
#110 DisplayList = CreateDisplayDriverList(SetupInf);
#111 KeyboardList = CreateKeyboardDriverList(SetupInf);
#112 LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout);
#113 LanguageList = CreateLanguageList(SetupInf, DefaultLanguage);
#114
#115 /* new part */
#116
#117 wcscpy(SelectedLanguageId,LocaleID);
#118
#119
#120 /* first we hack LanguageList */
#121 ListEntry = GetFirstListEntry(LanguageList);
#122
#123 while (ListEntry != NULL)
#124 {
#125 if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry)))
#126 {
#127 DPRINT("found %S in LanguageList/n",GetListEntryUserData(ListEntry));
#128 SetCurrentListEntry(LanguageList, ListEntry);
#129 break;
#130 }
#131
#132 ListEntry = GetNextListEntry(ListEntry);
#133 }
#134 /* now LayoutList */
#135 ListEntry = GetFirstListEntry(LayoutList);
#136
#137 while (ListEntry != NULL)
#138 {
#139 if (!wcscmp(LocaleID, GetListEntryUserData(ListEntry)))
#140 {
#141 DPRINT("found %S in LayoutList/n",GetListEntryUserData(ListEntry));
#142 SetCurrentListEntry(LayoutList, ListEntry);
#143 break;
#144 }
#145
#146 ListEntry = GetNextListEntry(ListEntry);
#147 }
#148 SetConsoleCodePage();
#149
#150 return INSTALL_INTRO_PAGE;
#151 }
#152
在这里返回人工安装的下一个功能页面,就是语言选择。
#153 return LANGUAGE_PAGE;
#154 }
#155
通过上面这个函数,就可以打开安装信息文件,然后判断是否自动安装系统,如果是就进入自动安装过程。如果不是自动安装,就进入下一步的人工选项。