Reintegrate header-work branch. Important changes include continued work on headers...
[reactos.git] / reactos / boot / freeldr / freeldr / arch / i386 / 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 #include <freeldr.h>
21
22
23 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";
24 const CHAR BootPartitionPrompt[] = "Enter the boot partition.\n\nEnter 0 for the active (bootable) partition.";
25 const CHAR BootSectorFilePrompt[] = "Enter the boot sector file path.\n\nExamples:\n\\BOOTSECT.DOS\n/boot/bootsect.dos";
26 const CHAR LinuxKernelPrompt[] = "Enter the Linux kernel image path.\n\nExamples:\n/vmlinuz\n/boot/vmlinuz-2.4.18";
27 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.";
28 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";
29 const CHAR ReactOSSystemPathPrompt[] = "Enter the path to your ReactOS system directory.\n\nExamples:\n\\REACTOS\n\\ROS";
30 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";
31
32 const CHAR CustomBootPrompt[] = "Press ENTER to boot your custom boot setup.";
33
34 VOID OptionMenuCustomBoot(VOID)
35 {
36 PCSTR CustomBootMenuList[] = {
37 "Disk",
38 "Partition",
39 "Boot Sector File",
40 "ReactOS",
41 "Linux"
42 };
43 ULONG CustomBootMenuCount = sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]);
44 ULONG SelectedMenuItem;
45
46 if (!UiDisplayMenu(CustomBootMenuList, CustomBootMenuCount, 0, -1, &SelectedMenuItem, TRUE, NULL))
47 {
48 // The user pressed ESC
49 return;
50 }
51
52 switch (SelectedMenuItem)
53 {
54 case 0: // Disk
55 OptionMenuCustomBootDisk();
56 break;
57 case 1: // Partition
58 OptionMenuCustomBootPartition();
59 break;
60 case 2: // Boot Sector File
61 OptionMenuCustomBootBootSectorFile();
62 break;
63 case 3: // ReactOS
64 OptionMenuCustomBootReactOS();
65 break;
66 case 4: // Linux
67 OptionMenuCustomBootLinux();
68 break;
69 }
70 }
71
72 VOID OptionMenuCustomBootDisk(VOID)
73 {
74 CHAR SectionName[100];
75 CHAR BootDriveString[20];
76 ULONG SectionId;
77 TIMEINFO* TimeInfo;
78
79 RtlZeroMemory(SectionName, sizeof(SectionName));
80 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
81
82 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
83 {
84 return;
85 }
86
87 // Generate a unique section name
88 TimeInfo = ArcGetTime();
89 sprintf(SectionName, "CustomBootDisk%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
90
91 // Add the section
92 if (!IniAddSection(SectionName, &SectionId))
93 {
94 return;
95 }
96
97 // Add the BootType
98 if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
99 {
100 return;
101 }
102
103 // Add the BootDrive
104 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
105 {
106 return;
107 }
108
109 UiMessageBox(CustomBootPrompt);
110
111 LoadAndBootDrive(SectionName);
112 }
113
114 VOID OptionMenuCustomBootPartition(VOID)
115 {
116 CHAR SectionName[100];
117 CHAR BootDriveString[20];
118 CHAR BootPartitionString[20];
119 ULONG SectionId;
120 TIMEINFO* TimeInfo;
121
122 RtlZeroMemory(SectionName, sizeof(SectionName));
123 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
124 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
125
126 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
127 {
128 return;
129 }
130
131 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
132 {
133 return;
134 }
135
136 // Generate a unique section name
137 TimeInfo = ArcGetTime();
138 sprintf(SectionName, "CustomBootPartition%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
139
140 // Add the section
141 if (!IniAddSection(SectionName, &SectionId))
142 {
143 return;
144 }
145
146 // Add the BootType
147 if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
148 {
149 return;
150 }
151
152 // Add the BootDrive
153 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
154 {
155 return;
156 }
157
158 // Add the BootPartition
159 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
160 {
161 return;
162 }
163
164 UiMessageBox(CustomBootPrompt);
165
166 LoadAndBootPartition(SectionName);
167 }
168
169 VOID OptionMenuCustomBootBootSectorFile(VOID)
170 {
171 CHAR SectionName[100];
172 CHAR BootDriveString[20];
173 CHAR BootPartitionString[20];
174 CHAR BootSectorFileString[200];
175 ULONG SectionId;
176 TIMEINFO* TimeInfo;
177
178 RtlZeroMemory(SectionName, sizeof(SectionName));
179 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
180 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
181 RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
182
183 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
184 {
185 return;
186 }
187
188 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
189 {
190 return;
191 }
192
193 if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, 200))
194 {
195 return;
196 }
197
198 // Generate a unique section name
199 TimeInfo = ArcGetTime();
200 sprintf(SectionName, "CustomBootSectorFile%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
201
202 // Add the section
203 if (!IniAddSection(SectionName, &SectionId))
204 {
205 return;
206 }
207
208 // Add the BootType
209 if (!IniAddSettingValueToSection(SectionId, "BootType", "BootSector"))
210 {
211 return;
212 }
213
214 // Add the BootDrive
215 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
216 {
217 return;
218 }
219
220 // Add the BootPartition
221 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
222 {
223 return;
224 }
225
226 // Add the BootSectorFile
227 if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString))
228 {
229 return;
230 }
231
232 UiMessageBox(CustomBootPrompt);
233
234 LoadAndBootBootSector(SectionName);
235 }
236
237 VOID OptionMenuCustomBootReactOS(VOID)
238 {
239 CHAR SectionName[100];
240 CHAR BootDriveString[20];
241 CHAR BootPartitionString[20];
242 CHAR ReactOSSystemPath[200];
243 CHAR ReactOSARCPath[200];
244 CHAR ReactOSOptions[200];
245 ULONG SectionId;
246 TIMEINFO* TimeInfo;
247
248 RtlZeroMemory(SectionName, sizeof(SectionName));
249 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
250 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
251 RtlZeroMemory(ReactOSSystemPath, sizeof(ReactOSSystemPath));
252 RtlZeroMemory(ReactOSOptions, sizeof(ReactOSOptions));
253
254 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
255 {
256 return;
257 }
258
259 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
260 {
261 return;
262 }
263
264 if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath, 200))
265 {
266 return;
267 }
268
269 if (!UiEditBox(ReactOSOptionsPrompt, ReactOSOptions, 200))
270 {
271 return;
272 }
273
274 // Generate a unique section name
275 TimeInfo = ArcGetTime();
276 sprintf(SectionName, "CustomReactOS%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
277
278 // Add the section
279 if (!IniAddSection(SectionName, &SectionId))
280 {
281 return;
282 }
283
284 // Add the BootType
285 if (!IniAddSettingValueToSection(SectionId, "BootType", "ReactOS"))
286 {
287 return;
288 }
289
290 // Construct the ReactOS ARC system path
291 ConstructArcPath(ReactOSARCPath, ReactOSSystemPath, DriveMapGetBiosDriveNumber(BootDriveString), atoi(BootPartitionString));
292
293 // Add the system path
294 if (!IniAddSettingValueToSection(SectionId, "SystemPath", ReactOSARCPath))
295 {
296 return;
297 }
298
299 // Add the CommandLine
300 if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
301 {
302 return;
303 }
304
305 UiMessageBox(CustomBootPrompt);
306
307 LoadAndBootReactOS(SectionName);
308 }
309
310 VOID OptionMenuCustomBootLinux(VOID)
311 {
312 CHAR SectionName[100];
313 CHAR BootDriveString[20];
314 CHAR BootPartitionString[20];
315 CHAR LinuxKernelString[200];
316 CHAR LinuxInitrdString[200];
317 CHAR LinuxCommandLineString[200];
318 ULONG SectionId;
319 TIMEINFO* TimeInfo;
320
321 RtlZeroMemory(SectionName, sizeof(SectionName));
322 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
323 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
324 RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString));
325 RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
326 RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
327
328 if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
329 {
330 return;
331 }
332
333 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
334 {
335 return;
336 }
337
338 if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, 200))
339 {
340 return;
341 }
342
343 if (!UiEditBox(LinuxInitrdPrompt, LinuxInitrdString, 200))
344 {
345 return;
346 }
347
348 if (!UiEditBox(LinuxCommandLinePrompt, LinuxCommandLineString, 200))
349 {
350 return;
351 }
352
353 // Generate a unique section name
354 TimeInfo = ArcGetTime();
355 sprintf(SectionName, "CustomLinux%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 {
360 return;
361 }
362
363 // Add the BootType
364 if (!IniAddSettingValueToSection(SectionId, "BootType", "Linux"))
365 {
366 return;
367 }
368
369 // Add the BootDrive
370 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootDriveString))
371 {
372 return;
373 }
374
375 // Add the BootPartition
376 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootPartitionString))
377 {
378 return;
379 }
380
381 // Add the Kernel
382 if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString))
383 {
384 return;
385 }
386
387 // Add the Initrd
388 if (strlen(LinuxInitrdString) > 0)
389 {
390 if (!IniAddSettingValueToSection(SectionId, "Initrd", LinuxInitrdString))
391 {
392 return;
393 }
394 }
395
396 // Add the CommandLine
397 if (!IniAddSettingValueToSection(SectionId, "CommandLine", LinuxCommandLineString))
398 {
399 return;
400 }
401
402 UiMessageBox(CustomBootPrompt);
403
404 LoadAndBootLinux(SectionName, "Custom Linux Setup");
405 }
406
407 VOID OptionMenuReboot(VOID)
408 {
409 UiMessageBox("The system will now reboot.");
410
411 DiskStopFloppyMotor();
412 SoftReboot();
413 }