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