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
;
39 LPCSTR AnsiName
, OemName
, LangName
;
41 /* Get ANSI codepage file */
42 if (!InfFindFirstLine(InfHandle
, "NLS", "AnsiCodepage", &InfContext
))
44 ERR("Failed to find 'NLS/AnsiCodepage'\n");
47 if (!InfGetDataField(&InfContext
, 1, &AnsiName
))
49 ERR("Failed to get load options\n");
53 /* Get OEM codepage file */
54 if (!InfFindFirstLine(InfHandle
, "NLS", "OemCodepage", &InfContext
))
56 ERR("Failed to find 'NLS/AnsiCodepage'\n");
59 if (!InfGetDataField(&InfContext
, 1, &OemName
))
61 ERR("Failed to get load options\n");
65 if (!InfFindFirstLine(InfHandle
, "NLS", "UnicodeCasetable", &InfContext
))
67 ERR("Failed to find 'NLS/AnsiCodepage'\n");
70 if (!InfGetDataField(&InfContext
, 1, &LangName
))
72 ERR("Failed to get load options\n");
76 TRACE("NLS data '%s' '%s' '%s'\n", AnsiName
, OemName
, LangName
);
80 BOOLEAN Success
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
81 TRACE("NLS data loading %s\n", Success
? "successful" : "failed");
84 WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
87 /* TODO: Load OEM HAL font */
92 SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead
, HINF InfHandle
, LPCSTR SearchPath
)
94 INFCONTEXT InfContext
, dirContext
;
96 LPCSTR Media
, DriverName
, dirIndex
, ImagePath
;
97 WCHAR ServiceName
[256];
98 WCHAR ImagePathW
[256];
100 /* Open inf section */
101 if (!InfFindFirstLine(InfHandle
, "SourceDisksFiles", NULL
, &InfContext
))
104 /* Load all listed boot drivers */
107 if (InfGetDataField(&InfContext
, 7, &Media
) &&
108 InfGetDataField(&InfContext
, 0, &DriverName
) &&
109 InfGetDataField(&InfContext
, 13, &dirIndex
))
111 if ((strcmp(Media
, "x") == 0) &&
112 InfFindFirstLine(InfHandle
, "Directories", dirIndex
, &dirContext
) &&
113 InfGetDataField(&dirContext
, 1, &ImagePath
))
115 /* Convert name to widechar */
116 swprintf(ServiceName
, L
"%S", DriverName
);
118 /* Prepare image path */
119 swprintf(ImagePathW
, L
"%S", ImagePath
);
120 wcscat(ImagePathW
, L
"\\");
121 wcscat(ImagePathW
, ServiceName
);
123 /* Remove .sys extension */
124 ServiceName
[wcslen(ServiceName
) - 4] = 0;
126 /* Add it to the list */
127 Success
= WinLdrAddDriverToList(BootDriverListHead
,
128 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
133 ERR("Could not add boot driver '%s', '%s'\n", SearchPath
, DriverName
);
138 } while (InfFindNextLine(&InfContext
, &InfContext
));
142 /* SETUP STARTER **************************************************************/
154 CHAR BootOptions2
[256];
157 BOOLEAN BootFromFloppy
;
161 INFCONTEXT InfContext
;
162 PLOADER_PARAMETER_BLOCK LoaderBlock
;
163 PSETUP_LOADER_BLOCK SetupBlock
;
166 static LPCSTR SourcePaths
[] =
168 "", /* Only for floppy boot */
171 #elif defined(_M_MPPC)
173 #elif defined(_M_MRX000)
180 UiDrawStatusText("Setup is loading...");
183 UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup...");
185 /* Retrieve the system path */
186 *BootPath
= ANSI_NULL
;
187 ArgValue
= GetArgumentValue(Argc
, Argv
, "SystemPath");
190 RtlStringCbCopyA(BootPath
, sizeof(BootPath
), ArgValue
);
195 * IMPROVE: I don't want to call MachDiskGetBootPath here as a
196 * default choice because I can call it after (see few lines below).
197 * Instead I reset BootPath here so that we can build the full path
198 * using the general code from below.
200 // MachDiskGetBootPath(BootPath, sizeof(BootPath));
201 // RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
202 *BootPath
= ANSI_NULL
;
206 * Check whether BootPath is a full path
207 * and if not, create a full boot path.
209 * See FsOpenFile for the technique used.
211 if (strrchr(BootPath
, ')') == NULL
)
213 /* Temporarily save the boot path */
214 RtlStringCbCopyA(FileName
, sizeof(FileName
), BootPath
);
216 /* This is not a full path. Use the current (i.e. boot) device. */
217 MachDiskGetBootPath(BootPath
, sizeof(BootPath
));
219 /* Append a path separator if needed */
220 if (*FileName
!= '\\' && *FileName
!= '/')
221 RtlStringCbCatA(BootPath
, sizeof(BootPath
), "\\");
223 /* Append the remaining path */
224 RtlStringCbCatA(BootPath
, sizeof(BootPath
), FileName
);
227 /* Append a backslash if needed */
228 if (!*BootPath
|| BootPath
[strlen(BootPath
) - 1] != '\\')
229 RtlStringCbCatA(BootPath
, sizeof(BootPath
), "\\");
231 TRACE("BootPath: '%s'\n", BootPath
);
233 /* Retrieve the boot options */
234 *BootOptions2
= ANSI_NULL
;
235 ArgValue
= GetArgumentValue(Argc
, Argv
, "Options");
237 RtlStringCbCopyA(BootOptions2
, sizeof(BootOptions2
), ArgValue
);
239 TRACE("BootOptions: '%s'\n", BootOptions2
);
241 /* Check if a ramdisk file was given */
242 File
= strstr(BootOptions2
, "/RDPATH=");
245 /* Copy the file name and everything else after it */
246 RtlStringCbCopyA(FileName
, sizeof(FileName
), File
+ 8);
249 *strstr(FileName
, " ") = ANSI_NULL
;
251 /* Load the ramdisk */
252 if (!RamDiskLoadVirtualFile(FileName
))
254 UiMessageBox("Failed to load RAM disk file %s", FileName
);
259 /* Check if we booted from floppy */
260 BootFromFloppy
= strstr(BootPath
, "fdisk") != NULL
;
262 /* Open 'txtsetup.sif' from any of source paths */
263 File
= BootPath
+ strlen(BootPath
);
264 for (i
= BootFromFloppy
? 0 : 1; ; i
++)
266 SystemPath
= SourcePaths
[i
];
269 UiMessageBox("Failed to open txtsetup.sif");
272 RtlStringCbCopyA(File
, sizeof(BootPath
) - (File
- BootPath
)*sizeof(CHAR
), SystemPath
);
273 RtlStringCbCopyA(FileName
, sizeof(FileName
), BootPath
);
274 RtlStringCbCatA(FileName
, sizeof(FileName
), "txtsetup.sif");
275 if (InfOpenFile(&InfHandle
, FileName
, &ErrorLine
))
281 TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath
, SystemPath
);
283 /* Get Load options - debug and non-debug */
284 if (!InfFindFirstLine(InfHandle
, "SetupData", "OsLoadOptions", &InfContext
))
286 ERR("Failed to find 'SetupData/OsLoadOptions'\n");
290 if (!InfGetDataField(&InfContext
, 1, &LoadOptions
))
292 ERR("Failed to get load options\n");
297 /* Get debug load options and use them */
298 if (InfFindFirstLine(InfHandle
, "SetupData", "DbgOsLoadOptions", &InfContext
))
300 LPCSTR DbgLoadOptions
;
302 if (InfGetDataField(&InfContext
, 1, &DbgLoadOptions
))
303 LoadOptions
= DbgLoadOptions
;
307 /* Copy loadoptions (original string will be freed) */
308 BootOptions
= FrLdrTempAlloc(strlen(LoadOptions
) + 1, TAG_BOOT_OPTIONS
);
310 strcpy(BootOptions
, LoadOptions
);
312 TRACE("BootOptions: '%s'\n", BootOptions
);
314 /* Allocate and minimalist-initialize LPB */
315 AllocateAndInitLPB(&LoaderBlock
);
317 /* Allocate and initialize setup loader block */
318 SetupBlock
= &WinLdrSystemBlock
->SetupBlock
;
319 LoaderBlock
->SetupLdrBlock
= SetupBlock
;
321 /* Set textmode setup flag */
322 SetupBlock
->Flags
= SETUPLDR_TEXT_MODE
;
324 /* Load the system hive "setupreg.hiv" for setup */
326 UiDrawProgressBarCenter(15, 100, "Loading setup system hive...");
327 Success
= WinLdrInitSystemHive(LoaderBlock
, BootPath
, TRUE
);
328 TRACE("Setup SYSTEM hive %s\n", (Success
? "loaded" : "not loaded"));
329 /* Bail out if failure */
333 /* Load NLS data, they are in the System32 directory of the installation medium */
334 RtlStringCbCopyA(FileName
, sizeof(FileName
), BootPath
);
335 RtlStringCbCatA(FileName
, sizeof(FileName
), "system32\\");
336 SetupLdrLoadNlsData(LoaderBlock
, InfHandle
, FileName
);
338 // UiDrawStatusText("Press F6 if you need to install a 3rd-party SCSI or RAID driver...");
340 /* Get a list of boot drivers */
341 SetupLdrScanBootDrivers(&LoaderBlock
->BootDriverListHead
, InfHandle
, BootPath
);
343 /* Close the inf file */
344 InfCloseFile(InfHandle
);
346 UiDrawStatusText("The Setup program is starting...");
348 /* Load ReactOS Setup */
349 return LoadAndBootWindowsCommon(_WIN32_WINNT_WS03
,