3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 /* INCLUDES *******************************************************************/
25 DBG_DEFAULT_CHANNEL(INIFILE
);
27 /* GLOBALS ********************************************************************/
32 ARC_ENTRY_POINT OsLoader
;
33 } OSLoadingMethods
[] =
35 {"ReactOSSetup", LoadReactOSSetup
},
38 {"BootSector" , LoadAndBootBootSector
},
39 {"Drive" , LoadAndBootDrive
},
40 {"Partition" , LoadAndBootPartition
},
42 {"Linux" , LoadAndBootLinux
},
44 {"Windows" , LoadAndBootWindows
},
45 {"WindowsNT40" , LoadAndBootWindows
},
47 {"Windows2003" , LoadAndBootWindows
},
50 /* FUNCTIONS ******************************************************************/
54 IN PCSTR LoadIdentifier
,
55 IN ULONG_PTR SectionId
,
64 PCHAR SettingName
, SettingValue
;
67 * Convert the list of key=value options in the given operating system section
68 * into a ARC-compatible argument vector.
73 /* Validate the LoadIdentifier (to make tests simpler later) */
74 if (LoadIdentifier
&& !*LoadIdentifier
)
75 LoadIdentifier
= NULL
;
77 /* Count the number of operating systems in the section */
78 Count
= IniGetNumSectionItems(SectionId
);
80 /* The argument vector contains the program name, the LoadIdentifier (optional), and the items in the OS section */
85 /* Calculate the total size needed for the string buffer of the argument vector */
87 /* i == 0: Program name */
88 /* i == 1: LoadIdentifier */
91 Size
+= (strlen("LoadIdentifier=") + strlen(LoadIdentifier
) + 1) * sizeof(CHAR
);
93 for (i
= 0; i
< Count
; ++i
)
95 Size
+= IniGetSectionSettingNameSize(SectionId
, i
); // Counts also the NULL-terminator, that we transform into the '=' sign separator.
96 Size
+= IniGetSectionSettingValueSize(SectionId
, i
); // Counts also the NULL-terminator.
98 Size
+= sizeof(ANSI_NULL
); // Final NULL-terminator.
100 /* Allocate memory to hold the argument vector: pointers and string buffer */
101 Argv
= FrLdrHeapAlloc(Argc
* sizeof(PCHAR
) + Size
, TAG_STRING
);
105 /* Initialize the argument vector: loop through the section and copy the key=value options */
106 SettingName
= (PCHAR
)((ULONG_PTR
)Argv
+ (Argc
* sizeof(PCHAR
)));
108 /* i == 0: Program name */
110 /* i == 1: LoadIdentifier */
113 strcpy(SettingName
, "LoadIdentifier=");
114 strcat(SettingName
, LoadIdentifier
);
116 *Args
++ = SettingName
;
117 SettingName
+= (strlen(SettingName
) + 1);
119 for (i
= 0; i
< Count
; ++i
)
121 Size
= IniGetSectionSettingNameSize(SectionId
, i
);
122 SettingValue
= SettingName
+ Size
;
123 IniReadSettingByNumber(SectionId
, i
,
125 SettingValue
, IniGetSectionSettingValueSize(SectionId
, i
));
126 SettingName
[Size
- 1] = '=';
128 *Args
++ = SettingName
;
129 SettingName
+= (strlen(SettingName
) + 1);
133 /* Dump the argument vector for debugging */
134 for (i
= 0; i
< Argc
; ++i
)
136 TRACE("Argv[%lu]: '%s'\n", i
, Argv
[i
]);
144 VOID
LoadOperatingSystem(IN OperatingSystemItem
* OperatingSystem
)
147 PCSTR SectionName
= OperatingSystem
->SectionName
;
153 /* Try to open the operating system section in the .ini file */
154 if (!IniOpenSection(SectionName
, &SectionId
))
156 UiMessageBox("Section [%s] not found in freeldr.ini.", SectionName
);
160 /* Try to read the boot type */
161 *BootType
= ANSI_NULL
;
162 IniReadSettingByName(SectionId
, "BootType", BootType
, sizeof(BootType
));
164 /* We must have the "BootType" value (it has been possibly added by InitOperatingSystemList()) */
168 /* Install the drive mapper according to this section drive mappings */
169 DriveMapMapDrivesInSection(SectionName
);
172 /* Loop through the OS loading method table and find a suitable OS to boot */
173 for (i
= 0; i
< sizeof(OSLoadingMethods
) / sizeof(OSLoadingMethods
[0]); ++i
)
175 if (_stricmp(BootType
, OSLoadingMethods
[i
].BootType
) == 0)
177 Argv
= BuildArgvForOsLoader(OperatingSystem
->LoadIdentifier
, SectionId
, &Argc
);
180 OSLoadingMethods
[i
].OsLoader(Argc
, Argv
, NULL
);
181 FrLdrHeapFree(Argv
, TAG_STRING
);
188 LONG
GetTimeOut(VOID
)
190 CHAR TimeOutText
[20];
194 TimeOut
= CmdLineGetTimeOut();
198 if (!IniOpenSection("FreeLoader", &SectionId
))
201 if (IniReadSettingByName(SectionId
, "TimeOut", TimeOutText
, sizeof(TimeOutText
)))
202 TimeOut
= atoi(TimeOutText
);
209 BOOLEAN
MainBootMenuKeyPressFilter(ULONG KeyPress
)
211 if (KeyPress
== KEY_F8
)
217 /* We didn't handle the key */
225 ULONG OperatingSystemCount
;
226 OperatingSystemItem
* OperatingSystemList
;
227 PCSTR
* OperatingSystemDisplayNames
;
228 ULONG DefaultOperatingSystem
;
229 ULONG SelectedOperatingSystem
;
232 if (!MachInitializeBootDevices())
234 UiMessageBoxCritical("Error when detecting hardware.");
239 /* Load additional SCSI driver (if any) */
240 if (LoadBootDeviceDriver() != ESUCCESS
)
242 UiMessageBoxCritical("Unable to load additional boot device drivers.");
246 if (!IniFileInitialize())
248 UiMessageBoxCritical("Error initializing .ini file.");
252 /* Debugger main initialization */
255 if (!IniOpenSection("FreeLoader", &SectionId
))
257 UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini.");
261 TimeOut
= GetTimeOut();
263 /* UI main initialization */
264 if (!UiInitialize(TRUE
))
266 UiMessageBoxCritical("Unable to initialize UI.");
270 OperatingSystemList
= InitOperatingSystemList(&OperatingSystemCount
,
271 &DefaultOperatingSystem
);
272 if (!OperatingSystemList
)
274 UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot.");
277 if (OperatingSystemCount
== 0)
279 UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
283 /* Create list of display names */
284 OperatingSystemDisplayNames
= FrLdrTempAlloc(sizeof(PCSTR
) * OperatingSystemCount
, 'mNSO');
285 if (!OperatingSystemDisplayNames
)
288 for (i
= 0; i
< OperatingSystemCount
; i
++)
290 OperatingSystemDisplayNames
[i
] = OperatingSystemList
[i
].LoadIdentifier
;
293 /* Find all the message box settings and run them */
294 UiShowMessageBoxesInSection("FreeLoader");
298 /* Redraw the backdrop */
301 /* Show the operating system list menu */
302 if (!UiDisplayMenu("Please select the operating system to start:",
303 "For troubleshooting and advanced startup options for "
304 "ReactOS, press F8.",
306 OperatingSystemDisplayNames
,
307 OperatingSystemCount
,
308 DefaultOperatingSystem
,
310 &SelectedOperatingSystem
,
312 MainBootMenuKeyPressFilter
))
314 UiMessageBox("Press ENTER to reboot.");
320 /* Load the chosen operating system */
321 LoadOperatingSystem(&OperatingSystemList
[SelectedOperatingSystem
]);
325 UiUnInitialize("Rebooting...");