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