[freeldr] Move custom.c, drivemap.c/h, miscboot.c/h to i386 directories
[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 #include <freeldr.h>
21
22 VOID RunLoader(VOID)
23 {
24 CHAR SettingValue[80];
25 ULONG_PTR SectionId;
26 ULONG OperatingSystemCount;
27 PCSTR *OperatingSystemSectionNames;
28 PCSTR *OperatingSystemDisplayNames;
29 PCSTR SectionName;
30 ULONG DefaultOperatingSystem;
31 LONG TimeOut;
32 ULONG SelectedOperatingSystem;
33
34 // FIXME: if possible, only detect and register ARC devices...
35 if (!MachHwDetect())
36 {
37 UiMessageBoxCritical("Error when detecting hardware");
38 return;
39 }
40
41 if (!IniFileInitialize())
42 {
43 UiMessageBoxCritical("Error initializing .ini file");
44 return;
45 }
46
47 if (!IniOpenSection("FreeLoader", &SectionId))
48 {
49 UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini.");
50 return;
51 }
52 TimeOut = GetTimeOut();
53
54 if (!UiInitialize(TimeOut))
55 {
56 UiMessageBoxCritical("Unable to initialize UI.");
57 return;
58 }
59
60
61 if (!InitOperatingSystemList(&OperatingSystemSectionNames, &OperatingSystemDisplayNames, &OperatingSystemCount))
62 {
63 UiMessageBox("Press ENTER to reboot.");
64 goto reboot;
65 }
66
67 if (OperatingSystemCount == 0)
68 {
69 UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
70 goto reboot;
71 }
72
73 DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemSectionNames, OperatingSystemCount);
74
75 //
76 // Find all the message box settings and run them
77 //
78 UiShowMessageBoxesInSection("FreeLoader");
79
80 for (;;)
81 {
82
83 // Redraw the backdrop
84 UiDrawBackdrop();
85
86 // Show the operating system list menu
87 if (!UiDisplayMenu(OperatingSystemDisplayNames, OperatingSystemCount, DefaultOperatingSystem, TimeOut, &SelectedOperatingSystem, FALSE, MainBootMenuKeyPressFilter))
88 {
89 UiMessageBox("Press ENTER to reboot.");
90 goto reboot;
91 }
92
93 TimeOut = -1;
94
95 // Try to open the operating system section in the .ini file
96 SettingValue[0] = ANSI_NULL;
97 SectionName = OperatingSystemSectionNames[SelectedOperatingSystem];
98 if (IniOpenSection(SectionName, &SectionId))
99 {
100 // Try to read the boot type
101 IniReadSettingByName(SectionId, "BootType", SettingValue, sizeof(SettingValue));
102 }
103
104 if (SettingValue[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
105 {
106 // Try to infere boot type value
107 #ifdef __i386__
108 CHAR LastChar;
109 LastChar = SectionName[strlen(SectionName) - 1];
110 if (LastChar == '\\' ||
111 (strstr(SectionName, ")partition(") != NULL &&
112 strstr(SectionName, ")partition(0)") == NULL))
113 {
114 strcpy(SettingValue, "Partition");
115 }
116 else if (LastChar == ')' || LastChar == ':')
117 {
118 strcpy(SettingValue, "Drive");
119 }
120 else if (TRUE)
121 {
122 strcpy(SettingValue, "BootSector");
123 }
124 else
125 #endif
126 {
127 strcpy(SettingValue, "Windows2003");
128 }
129 }
130
131 // Install the drive mapper according to this sections drive mappings
132 #ifdef __i386__
133 DriveMapMapDrivesInSection(SectionName);
134 #endif
135 if (_stricmp(SettingValue, "ReactOS") == 0)
136 {
137 LoadAndBootReactOS(SectionName);
138 }
139 #ifdef FREELDR_REACTOS_SETUP
140 else if (_stricmp(SettingValue, "ReactOSSetup") == 0)
141 {
142 // In future we could pass the selected OS details through this
143 // to have different install methods, etc.
144 LoadReactOSSetup();
145 }
146 #ifdef __i386__
147 else if (_stricmp(SettingValue, "ReactOSSetup2") == 0)
148 {
149 // WinLdr-style boot
150 LoadReactOSSetup2();
151 }
152 #endif
153 #endif
154 #ifdef __i386__
155 else if (_stricmp(SettingValue, "WindowsNT40") == 0)
156 {
157 LoadAndBootWindows(SectionName, _WIN32_WINNT_NT4);
158 }
159 else if (_stricmp(SettingValue, "Windows2003") == 0)
160 {
161 LoadAndBootWindows(SectionName, _WIN32_WINNT_WS03);
162 }
163 else if (_stricmp(SettingValue, "Linux") == 0)
164 {
165 LoadAndBootLinux(SectionName, OperatingSystemDisplayNames[SelectedOperatingSystem]);
166 }
167 else if (_stricmp(SettingValue, "BootSector") == 0)
168 {
169 LoadAndBootBootSector(SectionName);
170 }
171 else if (_stricmp(SettingValue, "Partition") == 0)
172 {
173 LoadAndBootPartition(SectionName);
174 }
175 else if (_stricmp(SettingValue, "Drive") == 0)
176 {
177 LoadAndBootDrive(SectionName);
178 }
179 #endif
180 }
181
182
183 reboot:
184 UiUnInitialize("Rebooting...");
185 return;
186 }
187
188 ULONG GetDefaultOperatingSystem(PCSTR OperatingSystemList[], ULONG OperatingSystemCount)
189 {
190 CHAR DefaultOSText[80];
191 PCSTR DefaultOSName;
192 ULONG_PTR SectionId;
193 ULONG DefaultOS = 0;
194 ULONG Idx;
195
196 if (!IniOpenSection("FreeLoader", &SectionId))
197 {
198 return 0;
199 }
200
201 DefaultOSName = CmdLineGetDefaultOS();
202 if (NULL == DefaultOSName)
203 {
204 if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
205 {
206 DefaultOSName = DefaultOSText;
207 }
208 }
209
210 if (NULL != DefaultOSName)
211 {
212 for (Idx=0; Idx<OperatingSystemCount; Idx++)
213 {
214 if (_stricmp(DefaultOSName, OperatingSystemList[Idx]) == 0)
215 {
216 DefaultOS = Idx;
217 break;
218 }
219 }
220 }
221
222 return DefaultOS;
223 }
224
225 LONG GetTimeOut(VOID)
226 {
227 CHAR TimeOutText[20];
228 LONG TimeOut;
229 ULONG_PTR SectionId;
230
231 TimeOut = CmdLineGetTimeOut();
232 if (0 <= TimeOut)
233 {
234 return TimeOut;
235 }
236
237 if (!IniOpenSection("FreeLoader", &SectionId))
238 {
239 return -1;
240 }
241
242 if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
243 {
244 TimeOut = atoi(TimeOutText);
245 }
246 else
247 {
248 TimeOut = -1;
249 }
250
251 return TimeOut;
252 }
253
254 BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
255 {
256 if (KeyPress == KEY_F8)
257 {
258 DoOptionsMenu();
259
260 return TRUE;
261 }
262
263 // We didn't handle the key
264 return FALSE;
265 }