[FREELDR] FrLdrBugCheckWithMessage() is varags, it doesn't make sense to mark it...
[reactos.git] / reactos / boot / freeldr / freeldr / bootmgr.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
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.
9 *
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.
14 *
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.
18 */
19
20 /* INCLUDES *******************************************************************/
21
22 #include <freeldr.h>
23
24 /* GLOBALS ********************************************************************/
25
26 // ARC Disk Information
27 ARC_DISK_SIGNATURE reactos_arc_disk_info[32];
28 ULONG reactos_disk_count = 0;
29 CHAR reactos_arc_strings[32][256];
30
31 typedef
32 VOID
33 (*OS_LOADING_METHOD)(IN OperatingSystemItem* OperatingSystem,
34 IN USHORT OperatingSystemVersion);
35
36 struct
37 {
38 CHAR BootType[80];
39 USHORT OperatingSystemVersion;
40 OS_LOADING_METHOD Load;
41 } OSLoadingMethods[] =
42 {
43 {"ReactOSSetup", 0 , LoadReactOSSetup },
44
45 #ifdef _M_IX86
46 {"BootSector" , 0 , LoadAndBootBootSector},
47 {"Drive" , 0 , LoadAndBootDrive },
48 {"Partition" , 0 , LoadAndBootPartition },
49
50 {"Linux" , 0 , LoadAndBootLinux },
51
52 {"Windows" , 0 , LoadAndBootWindows },
53 {"WindowsNT40" , _WIN32_WINNT_NT4 , LoadAndBootWindows },
54 #endif
55 {"Windows2003" , _WIN32_WINNT_WS03, LoadAndBootWindows },
56 };
57
58 /* FUNCTIONS ******************************************************************/
59
60 VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
61 {
62 ULONG_PTR SectionId;
63 PCSTR SectionName = OperatingSystem->SystemPartition;
64 CHAR BootType[80];
65 ULONG i;
66
67 /* Try to open the operating system section in the .ini file */
68 if (IniOpenSection(SectionName, &SectionId))
69 {
70 /* Try to read the boot type */
71 IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
72 }
73 else
74 {
75 BootType[0] = ANSI_NULL;
76 }
77
78 if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
79 {
80 /* Try to infere the boot type value */
81 #ifdef _M_IX86
82 ULONG FileId;
83 if (ArcOpen((PSTR)SectionName, OpenReadOnly, &FileId) == ESUCCESS)
84 {
85 ArcClose(FileId);
86 strcpy(BootType, "BootSector");
87 }
88 else
89 #endif
90 {
91 strcpy(BootType, "Windows");
92 }
93 }
94
95 /* Install the drive mapper according to this section drive mappings */
96 #if defined(_M_IX86) && !defined(_MSC_VER)
97 DriveMapMapDrivesInSection(SectionName);
98 #endif
99
100 /* Loop through the OS loading method table and find a suitable OS to boot */
101 for (i = 0; i < sizeof(OSLoadingMethods) / sizeof(OSLoadingMethods[0]); ++i)
102 {
103 if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
104 {
105 OSLoadingMethods[i].Load(OperatingSystem,
106 OSLoadingMethods[i].OperatingSystemVersion);
107 return;
108 }
109 }
110 }
111
112 ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount)
113 {
114 CHAR DefaultOSText[80];
115 PCSTR DefaultOSName;
116 ULONG_PTR SectionId;
117 ULONG DefaultOS = 0;
118 ULONG Idx;
119
120 if (!IniOpenSection("FreeLoader", &SectionId))
121 return 0;
122
123 DefaultOSName = CmdLineGetDefaultOS();
124 if (DefaultOSName == NULL)
125 {
126 if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
127 {
128 DefaultOSName = DefaultOSText;
129 }
130 }
131
132 if (DefaultOSName != NULL)
133 {
134 for (Idx = 0; Idx<OperatingSystemCount; Idx++)
135 {
136 if (_stricmp(DefaultOSName, OperatingSystemList[Idx].SystemPartition) == 0)
137 {
138 DefaultOS = Idx;
139 break;
140 }
141 }
142 }
143
144 return DefaultOS;
145 }
146
147 LONG GetTimeOut(VOID)
148 {
149 CHAR TimeOutText[20];
150 LONG TimeOut;
151 ULONG_PTR SectionId;
152
153 TimeOut = CmdLineGetTimeOut();
154 if (TimeOut >= 0)
155 return TimeOut;
156
157 if (!IniOpenSection("FreeLoader", &SectionId))
158 return -1;
159
160 if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
161 TimeOut = atoi(TimeOutText);
162 else
163 TimeOut = -1;
164
165 return TimeOut;
166 }
167
168 BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
169 {
170 if (KeyPress == KEY_F8)
171 {
172 DoOptionsMenu();
173 return TRUE;
174 }
175
176 /* We didn't handle the key */
177 return FALSE;
178 }
179
180 VOID RunLoader(VOID)
181 {
182 ULONG_PTR SectionId;
183 ULONG OperatingSystemCount;
184 OperatingSystemItem* OperatingSystemList;
185 PCSTR* OperatingSystemDisplayNames;
186 ULONG DefaultOperatingSystem;
187 LONG TimeOut;
188 ULONG SelectedOperatingSystem;
189 ULONG i;
190
191 if (!MachInitializeBootDevices())
192 {
193 UiMessageBoxCritical("Error when detecting hardware.");
194 return;
195 }
196
197 #ifdef _M_IX86
198 /* Load additional SCSI driver (if any) */
199 if (LoadBootDeviceDriver() != ESUCCESS)
200 {
201 UiMessageBoxCritical("Unable to load additional boot device drivers.");
202 }
203 #endif
204
205 if (!IniFileInitialize())
206 {
207 UiMessageBoxCritical("Error initializing .ini file.");
208 return;
209 }
210
211 if (!IniOpenSection("FreeLoader", &SectionId))
212 {
213 UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini.");
214 return;
215 }
216
217 TimeOut = GetTimeOut();
218
219 if (!UiInitialize(TRUE))
220 {
221 UiMessageBoxCritical("Unable to initialize UI.");
222 return;
223 }
224
225 OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount);
226 if (!OperatingSystemList)
227 {
228 UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot.");
229 goto Reboot;
230 }
231
232 if (OperatingSystemCount == 0)
233 {
234 UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
235 goto Reboot;
236 }
237
238 DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemList, OperatingSystemCount);
239
240 /* Create list of display names */
241 OperatingSystemDisplayNames = FrLdrTempAlloc(sizeof(PCSTR) * OperatingSystemCount, 'mNSO');
242 if (!OperatingSystemDisplayNames)
243 goto Reboot;
244
245 for (i = 0; i < OperatingSystemCount; i++)
246 {
247 OperatingSystemDisplayNames[i] = OperatingSystemList[i].LoadIdentifier;
248 }
249
250 /* Find all the message box settings and run them */
251 UiShowMessageBoxesInSection("FreeLoader");
252
253 for (;;)
254 {
255 /* Redraw the backdrop */
256 UiDrawBackdrop();
257
258 /* Show the operating system list menu */
259 if (!UiDisplayMenu("Please select the operating system to start:",
260 "For troubleshooting and advanced startup options for "
261 "ReactOS, press F8.",
262 TRUE,
263 OperatingSystemDisplayNames,
264 OperatingSystemCount,
265 DefaultOperatingSystem,
266 TimeOut,
267 &SelectedOperatingSystem,
268 FALSE,
269 MainBootMenuKeyPressFilter))
270 {
271 UiMessageBox("Press ENTER to reboot.");
272 goto Reboot;
273 }
274
275 TimeOut = -1;
276
277 /* Load the chosen operating system */
278 LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]);
279 }
280
281 Reboot:
282 UiUnInitialize("Rebooting...");
283 return;
284 }