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