[FREELDR] Always change video mode back to text-mode before starting up ReactOS.
[reactos.git] / boot / freeldr / freeldr / custom.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 #ifdef _M_IX86
27
28 const CHAR BootSectorFilePrompt[] = "Enter the boot sector file path.\n\nExamples:\n\\BOOTSECT.DOS\n/boot/bootsect.dos";
29 const CHAR LinuxKernelPrompt[] = "Enter the Linux kernel image path.\n\nExamples:\n/vmlinuz\n/boot/vmlinuz-2.4.18";
30 const CHAR LinuxInitrdPrompt[] = "Enter the initrd image path.\n\nExamples:\n/initrd.gz\n/boot/root.img.gz\n\nLeave blank for no initial ram disk.";
31 const CHAR LinuxCommandLinePrompt[] = "Enter the Linux kernel command line.\n\nExamples:\nroot=/dev/hda1\nroot=/dev/fd0 read-only\nroot=/dev/sdb1 init=/sbin/init";
32
33 #endif // _M_IX86
34
35 const CHAR BootDrivePrompt[] = "Enter the boot drive.\n\nExamples:\nfd0 - first floppy drive\nhd0 - first hard drive\nhd1 - second hard drive\ncd0 - first CD-ROM drive.\n\nBIOS drive numbers may also be used:\n0 - first floppy drive\n0x80 - first hard drive\n0x81 - second hard drive";
36 const CHAR BootPartitionPrompt[] = "Enter the boot partition.\n\nEnter 0 for the active (bootable) partition.";
37 const CHAR ReactOSSystemPathPrompt[] = "Enter the path to your ReactOS system directory.\n\nExamples:\n\\REACTOS\n\\ROS";
38 const CHAR ReactOSOptionsPrompt[] = "Enter the options you want passed to the kernel.\n\nExamples:\n/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200\n/FASTDETECT /SOS /NOGUIBOOT\n/BASEVIDEO /MAXMEM=64\n/KERNEL=NTKRNLMP.EXE /HAL=HALMPS.DLL";
39 const CHAR CustomBootPrompt[] = "Press ENTER to boot your custom boot setup.";
40
41 /* FUNCTIONS ******************************************************************/
42
43 VOID OptionMenuCustomBoot(VOID)
44 {
45 PCSTR CustomBootMenuList[] = {
46 #ifdef _M_IX86
47 "Disk",
48 "Partition",
49 "Boot Sector File",
50 "Linux",
51 #endif
52 "ReactOS"
53 };
54 ULONG SelectedMenuItem;
55
56 if (!UiDisplayMenu("Please choose a boot method:", "",
57 FALSE,
58 CustomBootMenuList,
59 sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]),
60 0, -1,
61 &SelectedMenuItem,
62 TRUE,
63 NULL))
64 {
65 /* The user pressed ESC */
66 return;
67 }
68
69 switch (SelectedMenuItem)
70 {
71 #ifdef _M_IX86
72 case 0: // Disk
73 OptionMenuCustomBootDisk();
74 break;
75 case 1: // Partition
76 OptionMenuCustomBootPartition();
77 break;
78 case 2: // Boot Sector File
79 OptionMenuCustomBootBootSectorFile();
80 break;
81 case 3: // Linux
82 OptionMenuCustomBootLinux();
83 break;
84 case 4: // ReactOS
85 #else
86 case 0:
87 #endif
88 OptionMenuCustomBootReactOS();
89 break;
90 }
91 }
92
93 #ifdef _M_IX86
94
95 VOID OptionMenuCustomBootDisk(VOID)
96 {
97 ULONG_PTR SectionId;
98 CHAR SectionName[100];
99 CHAR BootDriveString[20];
100 TIMEINFO* TimeInfo;
101 OperatingSystemItem OperatingSystem;
102
103 RtlZeroMemory(SectionName, sizeof(SectionName));
104 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
105
106 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
107 return;
108
109 /* Generate a unique section name */
110 TimeInfo = ArcGetTime();
111 sprintf(SectionName, "CustomBootDisk%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
112
113 /* Add the section */
114 if (!IniAddSection(SectionName, &SectionId))
115 return;
116
117 /* Add the BootType */
118 if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
119 return;
120
121 /* Add the BootDrive */
122 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
123 return;
124
125 UiMessageBox(CustomBootPrompt);
126
127 OperatingSystem.SystemPartition = SectionName;
128 OperatingSystem.LoadIdentifier = NULL;
129 OperatingSystem.OsLoadOptions = NULL;
130
131 // LoadAndBootDrive(&OperatingSystem, 0);
132 LoadOperatingSystem(&OperatingSystem);
133 }
134
135 VOID OptionMenuCustomBootPartition(VOID)
136 {
137 ULONG_PTR SectionId;
138 CHAR SectionName[100];
139 CHAR BootDriveString[20];
140 CHAR BootPartitionString[20];
141 TIMEINFO* TimeInfo;
142 OperatingSystemItem OperatingSystem;
143
144 RtlZeroMemory(SectionName, sizeof(SectionName));
145 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
146 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
147
148 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
149 return;
150
151 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
152 return;
153
154 /* Generate a unique section name */
155 TimeInfo = ArcGetTime();
156 sprintf(SectionName, "CustomBootPartition%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
157
158 /* Add the section */
159 if (!IniAddSection(SectionName, &SectionId))
160 return;
161
162 /* Add the BootType */
163 if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
164 return;
165
166 /* Add the BootDrive */
167 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
168 return;
169
170 /* Add the BootPartition */
171 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
172 return;
173
174 UiMessageBox(CustomBootPrompt);
175
176 OperatingSystem.SystemPartition = SectionName;
177 OperatingSystem.LoadIdentifier = NULL;
178 OperatingSystem.OsLoadOptions = NULL;
179
180 // LoadAndBootPartition(&OperatingSystem, 0);
181 LoadOperatingSystem(&OperatingSystem);
182 }
183
184 VOID OptionMenuCustomBootBootSectorFile(VOID)
185 {
186 ULONG_PTR SectionId;
187 CHAR SectionName[100];
188 CHAR BootDriveString[20];
189 CHAR BootPartitionString[20];
190 CHAR BootSectorFileString[200];
191 TIMEINFO* TimeInfo;
192 OperatingSystemItem OperatingSystem;
193
194 RtlZeroMemory(SectionName, sizeof(SectionName));
195 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
196 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
197 RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
198
199 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
200 return;
201
202 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
203 return;
204
205 if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, 200))
206 return;
207
208 /* Generate a unique section name */
209 TimeInfo = ArcGetTime();
210 sprintf(SectionName, "CustomBootSectorFile%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
211
212 /* Add the section */
213 if (!IniAddSection(SectionName, &SectionId))
214 return;
215
216 /* Add the BootType */
217 if (!IniAddSettingValueToSection(SectionId, "BootType", "BootSector"))
218 return;
219
220 /* Add the BootDrive */
221 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
222 return;
223
224 /* Add the BootPartition */
225 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
226 return;
227
228 /* Add the BootSectorFile */
229 if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString))
230 return;
231
232 UiMessageBox(CustomBootPrompt);
233
234 OperatingSystem.SystemPartition = SectionName;
235 OperatingSystem.LoadIdentifier = NULL;
236 OperatingSystem.OsLoadOptions = NULL;
237
238 // LoadAndBootBootSector(&OperatingSystem, 0);
239 LoadOperatingSystem(&OperatingSystem);
240 }
241
242 VOID OptionMenuCustomBootLinux(VOID)
243 {
244 ULONG_PTR SectionId;
245 CHAR SectionName[100];
246 CHAR BootDriveString[20];
247 CHAR BootPartitionString[20];
248 CHAR LinuxKernelString[200];
249 CHAR LinuxInitrdString[200];
250 CHAR LinuxCommandLineString[200];
251 TIMEINFO* TimeInfo;
252 OperatingSystemItem OperatingSystem;
253
254 RtlZeroMemory(SectionName, sizeof(SectionName));
255 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
256 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
257 RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString));
258 RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
259 RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
260
261 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
262 return;
263
264 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
265 return;
266
267 if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, 200))
268 return;
269
270 if (!UiEditBox(LinuxInitrdPrompt, LinuxInitrdString, 200))
271 return;
272
273 if (!UiEditBox(LinuxCommandLinePrompt, LinuxCommandLineString, 200))
274 return;
275
276 /* Generate a unique section name */
277 TimeInfo = ArcGetTime();
278 sprintf(SectionName, "CustomLinux%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
279
280 /* Add the section */
281 if (!IniAddSection(SectionName, &SectionId))
282 return;
283
284 /* Add the BootType */
285 if (!IniAddSettingValueToSection(SectionId, "BootType", "Linux"))
286 return;
287
288 /* Add the BootDrive */
289 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
290 return;
291
292 /* Add the BootPartition */
293 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
294 return;
295
296 /* Add the Kernel */
297 if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString))
298 return;
299
300 /* Add the Initrd */
301 if (strlen(LinuxInitrdString) > 0)
302 {
303 if (!IniAddSettingValueToSection(SectionId, "Initrd", LinuxInitrdString))
304 return;
305 }
306
307 /* Add the CommandLine */
308 if (!IniAddSettingValueToSection(SectionId, "CommandLine", LinuxCommandLineString))
309 return;
310
311 UiMessageBox(CustomBootPrompt);
312
313 OperatingSystem.SystemPartition = SectionName;
314 OperatingSystem.LoadIdentifier = "Custom Linux Setup";
315 OperatingSystem.OsLoadOptions = NULL;
316
317 // LoadAndBootLinux(&OperatingSystem, 0);
318 LoadOperatingSystem(&OperatingSystem);
319 }
320
321 #endif // _M_IX86
322
323 VOID OptionMenuCustomBootReactOS(VOID)
324 {
325 ULONG_PTR SectionId;
326 CHAR SectionName[100];
327 CHAR BootDriveString[20];
328 CHAR BootPartitionString[20];
329 CHAR ReactOSSystemPath[200];
330 CHAR ReactOSARCPath[200];
331 CHAR ReactOSOptions[200];
332 TIMEINFO* TimeInfo;
333 OperatingSystemItem OperatingSystem;
334
335 RtlZeroMemory(SectionName, sizeof(SectionName));
336 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
337 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
338 RtlZeroMemory(ReactOSSystemPath, sizeof(ReactOSSystemPath));
339 RtlZeroMemory(ReactOSOptions, sizeof(ReactOSOptions));
340
341 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
342 return;
343
344 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
345 return;
346
347 if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath, 200))
348 return;
349
350 if (!UiEditBox(ReactOSOptionsPrompt, ReactOSOptions, 200))
351 return;
352
353 /* Generate a unique section name */
354 TimeInfo = ArcGetTime();
355 sprintf(SectionName, "CustomReactOS%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
356
357 /* Add the section */
358 if (!IniAddSection(SectionName, &SectionId))
359 return;
360
361 /* Add the BootType */
362 if (!IniAddSettingValueToSection(SectionId, "BootType", "Windows2003"))
363 return;
364
365 /* Construct the ReactOS ARC system path */
366 ConstructArcPath(ReactOSARCPath, ReactOSSystemPath, DriveMapGetBiosDriveNumber(BootDriveString), atoi(BootPartitionString));
367
368 /* Add the system path */
369 if (!IniAddSettingValueToSection(SectionId, "SystemPath", ReactOSARCPath))
370 return;
371
372 /* Add the CommandLine */
373 if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
374 return;
375
376 UiMessageBox(CustomBootPrompt);
377
378 OperatingSystem.SystemPartition = SectionName;
379 OperatingSystem.LoadIdentifier = NULL;
380 OperatingSystem.OsLoadOptions = NULL; // ReactOSOptions
381
382 // LoadAndBootWindows(&OperatingSystem, _WIN32_WINNT_WS03);
383 LoadOperatingSystem(&OperatingSystem);
384 }
385
386 VOID OptionMenuReboot(VOID)
387 {
388 UiMessageBox("The system will now reboot.");
389
390 #if defined(__i386__) || defined(_M_AMD64)
391 DiskStopFloppyMotor();
392 #endif
393 Reboot();
394 }