4 * Copyright (C) 2009 Aleksey Bragin <aleksey@reactos.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <ndk/ldrtypes.h>
25 #include <arc/setupblk.h>
29 DBG_DEFAULT_CHANNEL(WINDOWS
);
30 #define TAG_BOOT_OPTIONS 'pOtB'
33 VOID
AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK
*OutLoaderBlock
);
36 SetupLdrLoadNlsData(PLOADER_PARAMETER_BLOCK LoaderBlock
, HINF InfHandle
, LPCSTR SearchPath
)
38 INFCONTEXT InfContext
;
40 LPCSTR AnsiName
, OemName
, LangName
;
42 /* Get ANSI codepage file */
43 if (!InfFindFirstLine(InfHandle
, "NLS", "AnsiCodepage", &InfContext
))
45 ERR("Failed to find 'NLS/AnsiCodepage'\n");
48 if (!InfGetDataField(&InfContext
, 1, &AnsiName
))
50 ERR("Failed to get load options\n");
54 /* Get OEM codepage file */
55 if (!InfFindFirstLine(InfHandle
, "NLS", "OemCodepage", &InfContext
))
57 ERR("Failed to find 'NLS/AnsiCodepage'\n");
60 if (!InfGetDataField(&InfContext
, 1, &OemName
))
62 ERR("Failed to get load options\n");
66 if (!InfFindFirstLine(InfHandle
, "NLS", "UnicodeCasetable", &InfContext
))
68 ERR("Failed to find 'NLS/AnsiCodepage'\n");
71 if (!InfGetDataField(&InfContext
, 1, &LangName
))
73 ERR("Failed to get load options\n");
77 TRACE("NLS data %s %s %s\n", AnsiName
, OemName
, LangName
);
79 Success
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
80 TRACE("NLS data loading %s\n", Success
? "successful" : "failed");
82 /* TODO: Load OEM HAL font */
87 SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead
, HINF InfHandle
, LPCSTR SearchPath
)
89 INFCONTEXT InfContext
, dirContext
;
91 LPCSTR Media
, DriverName
, dirIndex
, ImagePath
;
92 WCHAR ServiceName
[256];
93 WCHAR ImagePathW
[256];
95 /* Open inf section */
96 if (!InfFindFirstLine(InfHandle
, "SourceDisksFiles", NULL
, &InfContext
))
99 /* Load all listed boot drivers */
102 if (InfGetDataField(&InfContext
, 7, &Media
) &&
103 InfGetDataField(&InfContext
, 0, &DriverName
) &&
104 InfGetDataField(&InfContext
, 13, &dirIndex
))
106 if ((strcmp(Media
, "x") == 0) &&
107 InfFindFirstLine(InfHandle
, "Directories", dirIndex
, &dirContext
) &&
108 InfGetDataField(&dirContext
, 1, &ImagePath
))
110 /* Convert name to widechar */
111 swprintf(ServiceName
, L
"%S", DriverName
);
113 /* Prepare image path */
114 swprintf(ImagePathW
, L
"%S", ImagePath
);
115 wcscat(ImagePathW
, L
"\\");
116 wcscat(ImagePathW
, ServiceName
);
118 /* Remove .sys extension */
119 ServiceName
[wcslen(ServiceName
) - 4] = 0;
121 /* Add it to the list */
122 Success
= WinLdrAddDriverToList(BootDriverListHead
,
123 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
128 ERR("could not add boot driver %s, %s\n", SearchPath
, DriverName
);
133 } while (InfFindNextLine(&InfContext
, &InfContext
));
137 /* SETUP STARTER **************************************************************/
140 LoadReactOSSetup(IN OperatingSystemItem
* OperatingSystem
,
141 IN USHORT OperatingSystemVersion
)
144 PCSTR SectionName
= OperatingSystem
->SystemPartition
;
145 CHAR SettingsValue
[80];
147 CHAR BootOptions2
[256];
153 BOOLEAN BootFromFloppy
;
157 INFCONTEXT InfContext
;
158 PLOADER_PARAMETER_BLOCK LoaderBlock
;
159 PSETUP_LOADER_BLOCK SetupBlock
;
161 LPCSTR SourcePaths
[] =
163 "", /* Only for floppy boot */
166 #elif defined(_M_MPPC)
168 #elif defined(_M_MRX000)
175 UiDrawStatusText("Setup is loading...");
177 /* Get OS setting value */
178 SettingsValue
[0] = ANSI_NULL
;
179 IniOpenSection("Operating Systems", &SectionId
);
180 IniReadSettingByName(SectionId
, SectionName
, SettingsValue
, sizeof(SettingsValue
));
182 /* Open the operating system section specified in the .ini file */
183 HasSection
= IniOpenSection(SectionName
, &SectionId
);
186 UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup...");
188 /* Read the system path is set in the .ini file */
190 !IniReadSettingByName(SectionId
, "SystemPath", BootPath
, sizeof(BootPath
)))
193 * IMPROVE: I don't want to call MachDiskGetBootPath here as a
194 * default choice because I can call it after (see few lines below).
195 * Also doing the strcpy call as it is done in winldr.c is not
196 * really what we want. Instead I reset BootPath here so that
197 * we can build the full path using the general code from below.
199 // MachDiskGetBootPath(BootPath, sizeof(BootPath));
200 // strcpy(BootPath, SectionName);
205 * Check whether BootPath is a full path
206 * and if not, create a full boot path.
208 * See FsOpenFile for the technique used.
210 if (strrchr(BootPath
, ')') == NULL
)
212 /* Temporarily save the boot path */
213 strcpy(FileName
, BootPath
);
215 /* This is not a full path. Use the current (i.e. boot) device. */
216 MachDiskGetBootPath(BootPath
, sizeof(BootPath
));
218 /* Append a path separator if needed */
219 if (FileName
[0] != '\\' && FileName
[0] != '/')
220 strcat(BootPath
, "\\");
222 /* Append the remaining path */
223 strcat(BootPath
, FileName
);
226 /* Append a backslash if needed */
227 if ((strlen(BootPath
) == 0) || BootPath
[strlen(BootPath
) - 1] != '\\')
228 strcat(BootPath
, "\\");
230 /* Read booting options */
231 if (!HasSection
|| !IniReadSettingByName(SectionId
, "Options", BootOptions2
, sizeof(BootOptions2
)))
233 /* Get options after the title */
234 PCSTR p
= SettingsValue
;
235 while (*p
== ' ' || *p
== '"')
237 while (*p
!= '\0' && *p
!= '"')
239 strcpy(BootOptions2
, p
);
240 TRACE("BootOptions: '%s'\n", BootOptions2
);
243 /* Check if a ramdisk file was given */
244 File
= strstr(BootOptions2
, "/RDPATH=");
247 /* Copy the file name and everything else after it */
248 strcpy(FileName
, File
+ 8);
251 *strstr(FileName
, " ") = ANSI_NULL
;
253 /* Load the ramdisk */
254 if (!RamDiskLoadVirtualFile(FileName
))
256 UiMessageBox("Failed to load RAM disk file %s", FileName
);
261 TRACE("BootPath: '%s'\n", BootPath
);
263 /* And check if we booted from floppy */
264 BootFromFloppy
= strstr(BootPath
, "fdisk") != NULL
;
266 /* Open 'txtsetup.sif' from any of source paths */
267 File
= BootPath
+ strlen(BootPath
);
268 for (i
= BootFromFloppy
? 0 : 1; ; i
++)
270 SystemPath
= SourcePaths
[i
];
273 UiMessageBox("Failed to open txtsetup.sif");
276 strcpy(File
, SystemPath
);
277 strcpy(FileName
, BootPath
);
278 strcat(FileName
, "txtsetup.sif");
279 if (InfOpenFile(&InfHandle
, FileName
, &ErrorLine
))
285 TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath
, SystemPath
);
287 /* Get Load options - debug and non-debug */
288 if (!InfFindFirstLine(InfHandle
, "SetupData", "OsLoadOptions", &InfContext
))
290 ERR("Failed to find 'SetupData/OsLoadOptions'\n");
294 if (!InfGetDataField(&InfContext
, 1, &LoadOptions
))
296 ERR("Failed to get load options\n");
301 /* Get debug load options and use them */
302 if (InfFindFirstLine(InfHandle
, "SetupData", "DbgOsLoadOptions", &InfContext
))
304 LPCSTR DbgLoadOptions
;
306 if (InfGetDataField(&InfContext
, 1, &DbgLoadOptions
))
307 LoadOptions
= DbgLoadOptions
;
311 /* Copy loadoptions (original string will be freed) */
312 BootOptions
= FrLdrTempAlloc(strlen(LoadOptions
) + 1, TAG_BOOT_OPTIONS
);
313 strcpy(BootOptions
, LoadOptions
);
315 TRACE("BootOptions: '%s'\n", BootOptions
);
317 /* Allocate and minimalist-initialize LPB */
318 AllocateAndInitLPB(&LoaderBlock
);
320 /* Allocate and initialize setup loader block */
321 SetupBlock
= &WinLdrSystemBlock
->SetupBlock
;
322 LoaderBlock
->SetupLdrBlock
= SetupBlock
;
324 /* Set textmode setup flag */
325 SetupBlock
->Flags
= SETUPLDR_TEXT_MODE
;
327 /* Load the system hive "setupreg.hiv" for setup */
329 UiDrawProgressBarCenter(15, 100, "Loading setup system hive...");
330 Success
= WinLdrInitSystemHive(LoaderBlock
, BootPath
, TRUE
);
331 TRACE("Setup SYSTEM hive %s\n", (Success
? "loaded" : "not loaded"));
332 /* Bail out if failure */
336 /* Load NLS data, they are in the System32 directory of the installation medium */
337 strcpy(FileName
, BootPath
);
338 strcat(FileName
, "system32\\");
339 SetupLdrLoadNlsData(LoaderBlock
, InfHandle
, FileName
);
341 // UiDrawStatusText("Press F6 if you need to install a 3rd-party SCSI or RAID driver...");
343 /* Get a list of boot drivers */
344 SetupLdrScanBootDrivers(&LoaderBlock
->BootDriverListHead
, InfHandle
, BootPath
);
346 /* Close the inf file */
347 InfCloseFile(InfHandle
);
349 UiDrawStatusText("The Setup program is starting...");
351 /* Load ReactOS Setup */
352 LoadAndBootWindowsCommon(_WIN32_WINNT_WS03
,