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