ReactOS 0.4.15-dev-7842-g558ab78
custom.c
Go to the documentation of this file.
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#if defined(_M_IX86) || defined(_M_AMD64)
27
28const CHAR BootSectorFilePrompt[] = "Enter the boot sector file path.\n\nExamples:\n\\BOOTSECT.DOS\n/boot/bootsect.dos";
29const CHAR LinuxKernelPrompt[] = "Enter the Linux kernel image path.\n\nExamples:\n/vmlinuz\n/boot/vmlinuz-2.4.18";
30const 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.";
31const 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 || _M_AMD64 */
34
35const 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";
36const CHAR BootPartitionPrompt[] = "Enter the boot partition.\n\nEnter 0 for the active (bootable) partition.";
37const CHAR ARCPathPrompt[] = "Enter the boot ARC path.\n\nExamples:\nmulti(0)disk(0)rdisk(0)partition(1)\nmulti(0)disk(0)fdisk(0)";
38const CHAR ReactOSSystemPathPrompt[] = "Enter the path to your ReactOS system directory.\n\nExamples:\n\\REACTOS\n\\ROS";
39const CHAR ReactOSOptionsPrompt[] = "Enter the load 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";
40const CHAR ReactOSSetupOptionsPrompt[] = "Enter additional load options you want passed to the ReactOS Setup.\nThese options will supplement those obtained from the TXTSETUP.SIF\nfile, unless you also specify the /SIFOPTIONSOVERRIDE option switch.\n\nExample:\n/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /NOGUIBOOT";
41const CHAR CustomBootPrompt[] = "Press ENTER to boot your custom boot setup.";
42
43/* FUNCTIONS ******************************************************************/
44
45#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
46
48{
49 PCSTR CustomBootMenuList[] = {
50#if defined(_M_IX86) || defined(_M_AMD64)
51 "Disk",
52 "Partition",
53 "Boot Sector File",
54 "Linux",
55#endif
56 "ReactOS",
57 "ReactOS Setup"
58 };
59 ULONG SelectedMenuItem;
60 OperatingSystemItem OperatingSystem;
61
62 if (!UiDisplayMenu("Please choose a boot method:", NULL,
63 FALSE,
64 CustomBootMenuList,
65 RTL_NUMBER_OF(CustomBootMenuList),
66 0, -1,
67 &SelectedMenuItem,
68 TRUE,
69 NULL, NULL))
70 {
71 /* The user pressed ESC */
72 return;
73 }
74
75 /* Initialize a new custom OS entry */
76 OperatingSystem.SectionId = 0;
77 switch (SelectedMenuItem)
78 {
79#if defined(_M_IX86) || defined(_M_AMD64)
80 case 0: // Disk
81 EditCustomBootDisk(&OperatingSystem);
82 break;
83 case 1: // Partition
84 EditCustomBootPartition(&OperatingSystem);
85 break;
86 case 2: // Boot Sector File
87 EditCustomBootSectorFile(&OperatingSystem);
88 break;
89 case 3: // Linux
90 EditCustomBootLinux(&OperatingSystem);
91 break;
92 case 4: // ReactOS
93 EditCustomBootReactOS(&OperatingSystem, FALSE);
94 break;
95 case 5: // ReactOS Setup
96 EditCustomBootReactOS(&OperatingSystem, TRUE);
97 break;
98#else
99 case 0: // ReactOS
100 EditCustomBootReactOS(&OperatingSystem, FALSE);
101 break;
102 case 1: // ReactOS Setup
103 EditCustomBootReactOS(&OperatingSystem, TRUE);
104 break;
105#endif /* _M_IX86 || _M_AMD64 */
106 }
107
108 /* And boot it */
109 if (OperatingSystem.SectionId != 0)
110 {
112 LoadOperatingSystem(&OperatingSystem);
113 }
114}
115
116#endif // HAS_OPTION_MENU_CUSTOM_BOOT
117
118#if defined(_M_IX86) || defined(_M_AMD64)
119
120VOID
121EditCustomBootDisk(
122 IN OUT OperatingSystemItem* OperatingSystem)
123{
124 TIMEINFO* TimeInfo;
125 ULONG_PTR SectionId = OperatingSystem->SectionId;
126 CHAR SectionName[100];
127 /* This construct is a trick for saving some stack space */
128 union
129 {
130 struct
131 {
132 CHAR Guard1;
133 CHAR Drive[20];
134 CHAR Guard2;
135 };
136 CHAR ArcPath[200];
137 } BootStrings;
138
139 RtlZeroMemory(SectionName, sizeof(SectionName));
140 RtlZeroMemory(&BootStrings, sizeof(BootStrings));
141
142 if (SectionId != 0)
143 {
144 /* Load the settings */
145
146 /* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */
147 *BootStrings.ArcPath = ANSI_NULL;
148 IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
149 if (!*BootStrings.ArcPath)
150 {
151 /* We don't, retrieve the boot drive value instead */
152 IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
153 }
154 }
155
156 if (!*BootStrings.ArcPath)
157 {
158 if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
159 return;
160 }
161 if (!*BootStrings.Drive)
162 {
163 if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
164 return;
165 }
166
167 /* Modify the settings values and return if we were in edit mode */
168 if (SectionId != 0)
169 {
170 /* Modify the BootPath if we have one */
171 if (*BootStrings.ArcPath)
172 {
173 IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
174 }
175 else if (*BootStrings.Drive)
176 {
177 /* Otherwise, modify the BootDrive */
178 IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
179 }
180 return;
181 }
182
183 /* Generate a unique section name */
184 TimeInfo = ArcGetTime();
185 RtlStringCbPrintfA(SectionName, sizeof(SectionName),
186 "CustomBootDisk%u%u%u%u%u%u",
187 TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
188 TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
189
190 /* Add the section */
191 if (!IniAddSection(SectionName, &SectionId))
192 return;
193
194 /* Add the BootType */
195 if (!IniAddSettingValueToSection(SectionId, "BootType", "Drive"))
196 return;
197
198 /* Add the BootPath if we have one */
199 if (*BootStrings.ArcPath)
200 {
201 if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
202 return;
203 }
204 else if (*BootStrings.Drive)
205 {
206 /* Otherwise, add the BootDrive */
207 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
208 return;
209 }
210
211 OperatingSystem->SectionId = SectionId;
212 OperatingSystem->LoadIdentifier = NULL;
213}
214
215VOID
216EditCustomBootPartition(
217 IN OUT OperatingSystemItem* OperatingSystem)
218{
219 TIMEINFO* TimeInfo;
220 ULONG_PTR SectionId = OperatingSystem->SectionId;
221 CHAR SectionName[100];
222 /* This construct is a trick for saving some stack space */
223 union
224 {
225 struct
226 {
227 CHAR Guard1;
228 CHAR Drive[20];
229 CHAR Partition[20];
230 CHAR Guard2;
231 };
232 CHAR ArcPath[200];
233 } BootStrings;
234
235 RtlZeroMemory(SectionName, sizeof(SectionName));
236 RtlZeroMemory(&BootStrings, sizeof(BootStrings));
237
238 if (SectionId != 0)
239 {
240 /* Load the settings */
241
242 /*
243 * Check whether we have a "BootPath" value (takes precedence
244 * over both "BootDrive" and "BootPartition").
245 */
246 *BootStrings.ArcPath = ANSI_NULL;
247 IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
248 if (!*BootStrings.ArcPath)
249 {
250 /* We don't, retrieve the boot drive and partition values instead */
251 IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
252 IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
253 }
254 }
255
256 if (!*BootStrings.ArcPath)
257 {
258 if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
259 return;
260
261 if (*BootStrings.Drive)
262 {
263 if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition, sizeof(BootStrings.Partition)))
264 return;
265 }
266 }
267 if (!*BootStrings.Drive)
268 {
269 if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
270 return;
271 }
272
273 /* Modify the settings values and return if we were in edit mode */
274 if (SectionId != 0)
275 {
276 /* Modify the BootPath if we have one */
277 if (*BootStrings.ArcPath)
278 {
279 IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
280 }
281 else if (*BootStrings.Drive)
282 {
283 /* Otherwise, modify the BootDrive and BootPartition */
284 IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
285 IniModifySettingValue(SectionId, "BootPartition", BootStrings.Partition);
286 }
287 return;
288 }
289
290 /* Generate a unique section name */
291 TimeInfo = ArcGetTime();
292 RtlStringCbPrintfA(SectionName, sizeof(SectionName),
293 "CustomBootPartition%u%u%u%u%u%u",
294 TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
295 TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
296
297 /* Add the section */
298 if (!IniAddSection(SectionName, &SectionId))
299 return;
300
301 /* Add the BootType */
302 if (!IniAddSettingValueToSection(SectionId, "BootType", "Partition"))
303 return;
304
305 /* Add the BootPath if we have one */
306 if (*BootStrings.ArcPath)
307 {
308 if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
309 return;
310 }
311 else if (*BootStrings.Drive)
312 {
313 /* Otherwise, add the BootDrive and BootPartition */
314 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
315 return;
316
317 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
318 return;
319 }
320
321 OperatingSystem->SectionId = SectionId;
322 OperatingSystem->LoadIdentifier = NULL;
323}
324
325VOID
326EditCustomBootSectorFile(
327 IN OUT OperatingSystemItem* OperatingSystem)
328{
329 TIMEINFO* TimeInfo;
330 ULONG_PTR SectionId = OperatingSystem->SectionId;
331 CHAR SectionName[100];
332 /* This construct is a trick for saving some stack space */
333 union
334 {
335 struct
336 {
337 CHAR Guard1;
338 CHAR Drive[20];
339 CHAR Partition[20];
340 CHAR Guard2;
341 };
342 CHAR ArcPath[200];
343 } BootStrings;
344 CHAR BootSectorFileString[200];
345
346 RtlZeroMemory(SectionName, sizeof(SectionName));
347 RtlZeroMemory(&BootStrings, sizeof(BootStrings));
348 RtlZeroMemory(BootSectorFileString, sizeof(BootSectorFileString));
349
350 if (SectionId != 0)
351 {
352 /* Load the settings */
353
354 /*
355 * Check whether we have a "BootPath" value (takes precedence
356 * over both "BootDrive" and "BootPartition").
357 */
358 *BootStrings.ArcPath = ANSI_NULL;
359 IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
360 if (!*BootStrings.ArcPath)
361 {
362 /* We don't, retrieve the boot drive and partition values instead */
363 IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
364 IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
365 }
366
367 IniReadSettingByName(SectionId, "BootSectorFile", BootSectorFileString, sizeof(BootSectorFileString));
368 }
369
370 if (!*BootStrings.ArcPath)
371 {
372 if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
373 return;
374
375 if (*BootStrings.Drive)
376 {
377 if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition, sizeof(BootStrings.Partition)))
378 return;
379 }
380 }
381 if (!*BootStrings.Drive)
382 {
383 if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
384 return;
385 }
386
387 if (!UiEditBox(BootSectorFilePrompt, BootSectorFileString, sizeof(BootSectorFileString)))
388 return;
389
390 /* Modify the settings values and return if we were in edit mode */
391 if (SectionId != 0)
392 {
393 /* Modify the BootPath if we have one */
394 if (*BootStrings.ArcPath)
395 {
396 IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
397 }
398 else if (*BootStrings.Drive)
399 {
400 /* Otherwise, modify the BootDrive and BootPartition */
401 IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
402 IniModifySettingValue(SectionId, "BootPartition", BootStrings.Partition);
403 }
404 else
405 {
406 /*
407 * Otherwise, zero out all values: BootSectorFile will be
408 * relative to the default system partition.
409 */
410 IniModifySettingValue(SectionId, "BootPath", "");
411 IniModifySettingValue(SectionId, "BootDrive", "");
412 IniModifySettingValue(SectionId, "BootPartition", "");
413 }
414
415 IniModifySettingValue(SectionId, "BootSectorFile", BootSectorFileString);
416 return;
417 }
418
419 /* Generate a unique section name */
420 TimeInfo = ArcGetTime();
421 RtlStringCbPrintfA(SectionName, sizeof(SectionName),
422 "CustomBootSectorFile%u%u%u%u%u%u",
423 TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
424 TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
425
426 /* Add the section */
427 if (!IniAddSection(SectionName, &SectionId))
428 return;
429
430 /* Add the BootType */
431 if (!IniAddSettingValueToSection(SectionId, "BootType", "BootSector"))
432 return;
433
434 /* Add the BootPath if we have one */
435 if (*BootStrings.ArcPath)
436 {
437 if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
438 return;
439 }
440 else if (*BootStrings.Drive)
441 {
442 /* Otherwise, add the BootDrive and BootPartition */
443 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
444 return;
445
446 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
447 return;
448 }
449
450 /* Add the BootSectorFile */
451 if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", BootSectorFileString))
452 return;
453
454 OperatingSystem->SectionId = SectionId;
455 OperatingSystem->LoadIdentifier = NULL;
456}
457
458VOID
459EditCustomBootLinux(
460 IN OUT OperatingSystemItem* OperatingSystem)
461{
462 TIMEINFO* TimeInfo;
463 ULONG_PTR SectionId = OperatingSystem->SectionId;
464 CHAR SectionName[100];
465 /* This construct is a trick for saving some stack space */
466 union
467 {
468 struct
469 {
470 CHAR Guard1;
471 CHAR Drive[20];
472 CHAR Partition[20];
473 CHAR Guard2;
474 };
475 CHAR ArcPath[200];
476 } BootStrings;
477 CHAR LinuxKernelString[200];
478 CHAR LinuxInitrdString[200];
479 CHAR LinuxCommandLineString[200];
480
481 RtlZeroMemory(SectionName, sizeof(SectionName));
482 RtlZeroMemory(&BootStrings, sizeof(BootStrings));
483 RtlZeroMemory(LinuxKernelString, sizeof(LinuxKernelString));
484 RtlZeroMemory(LinuxInitrdString, sizeof(LinuxInitrdString));
485 RtlZeroMemory(LinuxCommandLineString, sizeof(LinuxCommandLineString));
486
487 if (SectionId != 0)
488 {
489 /* Load the settings */
490
491 /*
492 * Check whether we have a "BootPath" value (takes precedence
493 * over both "BootDrive" and "BootPartition").
494 */
495 *BootStrings.ArcPath = ANSI_NULL;
496 IniReadSettingByName(SectionId, "BootPath", BootStrings.ArcPath, sizeof(BootStrings.ArcPath));
497 if (!*BootStrings.ArcPath)
498 {
499 /* We don't, retrieve the boot drive and partition values instead */
500 IniReadSettingByName(SectionId, "BootDrive", BootStrings.Drive, sizeof(BootStrings.Drive));
501 IniReadSettingByName(SectionId, "BootPartition", BootStrings.Partition, sizeof(BootStrings.Partition));
502 }
503
504 IniReadSettingByName(SectionId, "Kernel", LinuxKernelString, sizeof(LinuxKernelString));
505 IniReadSettingByName(SectionId, "Initrd", LinuxInitrdString, sizeof(LinuxInitrdString));
506 IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLineString, sizeof(LinuxCommandLineString));
507 }
508
509 if (!*BootStrings.ArcPath)
510 {
511 if (!UiEditBox(BootDrivePrompt, BootStrings.Drive, sizeof(BootStrings.Drive)))
512 return;
513
514 if (*BootStrings.Drive)
515 {
516 if (!UiEditBox(BootPartitionPrompt, BootStrings.Partition, sizeof(BootStrings.Partition)))
517 return;
518 }
519 }
520 if (!*BootStrings.Drive)
521 {
522 if (!UiEditBox(ARCPathPrompt, BootStrings.ArcPath, sizeof(BootStrings.ArcPath)))
523 return;
524 }
525
526 if (!UiEditBox(LinuxKernelPrompt, LinuxKernelString, sizeof(LinuxKernelString)))
527 return;
528
529 if (!UiEditBox(LinuxInitrdPrompt, LinuxInitrdString, sizeof(LinuxInitrdString)))
530 return;
531
532 if (!UiEditBox(LinuxCommandLinePrompt, LinuxCommandLineString, sizeof(LinuxCommandLineString)))
533 return;
534
535 /* Modify the settings values and return if we were in edit mode */
536 if (SectionId != 0)
537 {
538 /* Modify the BootPath if we have one */
539 if (*BootStrings.ArcPath)
540 {
541 IniModifySettingValue(SectionId, "BootPath", BootStrings.ArcPath);
542 }
543 else if (*BootStrings.Drive)
544 {
545 /* Otherwise, modify the BootDrive and BootPartition */
546 IniModifySettingValue(SectionId, "BootDrive", BootStrings.Drive);
547 IniModifySettingValue(SectionId, "BootPartition", BootStrings.Partition);
548 }
549 else
550 {
551 /*
552 * Otherwise, zero out all values: BootSectorFile will be
553 * relative to the default system partition.
554 */
555 IniModifySettingValue(SectionId, "BootPath", "");
556 IniModifySettingValue(SectionId, "BootDrive", "");
557 IniModifySettingValue(SectionId, "BootPartition", "");
558 }
559
560 IniModifySettingValue(SectionId, "Kernel", LinuxKernelString);
561 IniModifySettingValue(SectionId, "Initrd", LinuxInitrdString);
562 IniModifySettingValue(SectionId, "CommandLine", LinuxCommandLineString);
563 return;
564 }
565
566 /* Generate a unique section name */
567 TimeInfo = ArcGetTime();
568 RtlStringCbPrintfA(SectionName, sizeof(SectionName),
569 "CustomLinux%u%u%u%u%u%u",
570 TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
571 TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
572
573 /* Add the section */
574 if (!IniAddSection(SectionName, &SectionId))
575 return;
576
577 /* Add the BootType */
578 if (!IniAddSettingValueToSection(SectionId, "BootType", "Linux"))
579 return;
580
581 /* Add the BootPath if we have one */
582 if (*BootStrings.ArcPath)
583 {
584 if (!IniAddSettingValueToSection(SectionId, "BootPath", BootStrings.ArcPath))
585 return;
586 }
587 else if (*BootStrings.Drive)
588 {
589 /* Otherwise, add the BootDrive and BootPartition */
590 if (!IniAddSettingValueToSection(SectionId, "BootDrive", BootStrings.Drive))
591 return;
592
593 if (!IniAddSettingValueToSection(SectionId, "BootPartition", BootStrings.Partition))
594 return;
595 }
596
597 /* Add the Kernel */
598 if (!IniAddSettingValueToSection(SectionId, "Kernel", LinuxKernelString))
599 return;
600
601 /* Add the Initrd */
602 if (*LinuxInitrdString)
603 {
604 if (!IniAddSettingValueToSection(SectionId, "Initrd", LinuxInitrdString))
605 return;
606 }
607
608 /* Add the CommandLine */
609 if (!IniAddSettingValueToSection(SectionId, "CommandLine", LinuxCommandLineString))
610 return;
611
612 OperatingSystem->SectionId = SectionId;
613 OperatingSystem->LoadIdentifier = "Custom Linux Setup";
614}
615
616#endif /* _M_IX86 || _M_AMD64 */
617
618VOID
620 IN OUT OperatingSystemItem* OperatingSystem,
621 IN BOOLEAN IsSetup)
622{
623 TIMEINFO* TimeInfo;
624 ULONG_PTR SectionId = OperatingSystem->SectionId;
625 CHAR SectionName[100];
626 CHAR BootDriveString[20];
627 CHAR BootPartitionString[20];
628 CHAR ReactOSSystemPath[200];
629 CHAR ReactOSARCPath[200];
630 CHAR ReactOSOptions[200];
631
632 RtlZeroMemory(SectionName, sizeof(SectionName));
633 RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
634 RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
635 RtlZeroMemory(ReactOSSystemPath, sizeof(ReactOSSystemPath));
636 RtlZeroMemory(ReactOSARCPath, sizeof(ReactOSARCPath));
637 RtlZeroMemory(ReactOSOptions, sizeof(ReactOSOptions));
638
639 if (SectionId != 0)
640 {
641 /* Load the settings */
642 IniReadSettingByName(SectionId, "SystemPath", ReactOSARCPath, sizeof(ReactOSARCPath));
643 IniReadSettingByName(SectionId, "Options", ReactOSOptions, sizeof(ReactOSOptions));
644 }
645
646 if (SectionId == 0)
647 {
648 if (!UiEditBox(BootDrivePrompt, BootDriveString, sizeof(BootDriveString)))
649 return;
650
651 if (!UiEditBox(BootPartitionPrompt, BootPartitionString, sizeof(BootPartitionString)))
652 return;
653
654 if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath, sizeof(ReactOSSystemPath)))
655 return;
656 }
657 else
658 {
659 if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSARCPath, sizeof(ReactOSARCPath)))
660 return;
661 }
662
663 if (!UiEditBox(IsSetup ? ReactOSSetupOptionsPrompt : ReactOSOptionsPrompt, ReactOSOptions, sizeof(ReactOSOptions)))
664 return;
665
666 /* Modify the settings values and return if we were in edit mode */
667 if (SectionId != 0)
668 {
669 IniModifySettingValue(SectionId, "SystemPath", ReactOSARCPath);
670 IniModifySettingValue(SectionId, "Options", ReactOSOptions);
671 return;
672 }
673
674 /* Generate a unique section name */
675 TimeInfo = ArcGetTime();
676 RtlStringCbPrintfA(SectionName, sizeof(SectionName),
677 "CustomReactOS%u%u%u%u%u%u",
678 TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
679 TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
680
681 /* Add the section */
682 if (!IniAddSection(SectionName, &SectionId))
683 return;
684
685 /* Add the BootType */
686 if (!IniAddSettingValueToSection(SectionId, "BootType", IsSetup ? "ReactOSSetup" : "Windows2003"))
687 return;
688
689 /* Construct the ReactOS ARC system path */
690 ConstructArcPath(ReactOSARCPath, ReactOSSystemPath,
691 DriveMapGetBiosDriveNumber(BootDriveString),
692 atoi(BootPartitionString));
693
694 /* Add the system path */
695 if (!IniAddSettingValueToSection(SectionId, "SystemPath", ReactOSARCPath))
696 return;
697
698 /* Add the CommandLine */
699 if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
700 return;
701
702 OperatingSystem->SectionId = SectionId;
703 OperatingSystem->LoadIdentifier = NULL;
704}
705
706#ifdef HAS_OPTION_MENU_REBOOT
707
709{
710 UiMessageBox("The system will now reboot.");
711 Reboot();
712}
713
714#endif // HAS_OPTION_MENU_REBOOT
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
TIMEINFO * ArcGetTime(VOID)
Definition: arcemul.c:27
PWCHAR Drive
Definition: chkdsk.c:73
@ Reboot
Definition: bl.h:891
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, UCHAR Disk, ULONG Partition)
Definition: arcname.c:175
const CHAR ReactOSSystemPathPrompt[]
Definition: custom.c:38
const CHAR CustomBootPrompt[]
Definition: custom.c:41
const CHAR BootDrivePrompt[]
Definition: custom.c:35
VOID EditCustomBootReactOS(IN OUT OperatingSystemItem *OperatingSystem, IN BOOLEAN IsSetup)
Definition: custom.c:619
const CHAR ReactOSOptionsPrompt[]
Definition: custom.c:39
const CHAR ReactOSSetupOptionsPrompt[]
Definition: custom.c:40
const CHAR BootPartitionPrompt[]
Definition: custom.c:36
const CHAR ARCPathPrompt[]
Definition: custom.c:37
#define DriveMapGetBiosDriveNumber(DeviceName)
Definition: hardware.h:35
BOOLEAN UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
Definition: ui.c:634
BOOLEAN UiDisplayMenu(IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, IN BOOLEAN ShowBootOptions, IN PCSTR MenuItemList[], IN ULONG MenuItemCount, IN ULONG DefaultMenuItem, IN LONG MenuTimeOut, OUT PULONG SelectedMenuItem, IN BOOLEAN CanEscape, IN UiMenuKeyPressFilterCallback KeyPressFilter OPTIONAL, IN PVOID Context OPTIONAL)
Definition: ui.c:605
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
VOID OptionMenuCustomBoot(VOID)
VOID OptionMenuReboot(VOID)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID LoadOperatingSystem(_In_ OperatingSystemItem *OperatingSystem)
Definition: bootmgr.c:210
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
BOOLEAN IniAddSection(PCSTR SectionName, ULONG_PTR *SectionId)
Definition: inifile.c:182
BOOLEAN IniAddSettingValueToSection(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue)
Definition: inifile.c:255
BOOLEAN IniModifySettingValue(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue)
Definition: inifile.c:296
BOOLEAN IniReadSettingByName(ULONG_PTR SectionId, PCSTR SettingName, PCHAR Buffer, ULONG BufferSize)
Definition: inifile.c:149
#define ANSI_NULL
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
Definition: fw.h:10
USHORT Month
Definition: fw.h:12
USHORT Day
Definition: fw.h:13
USHORT Minute
Definition: fw.h:15
USHORT Hour
Definition: fw.h:14
USHORT Second
Definition: fw.h:16
USHORT Year
Definition: fw.h:11
ULONG_PTR SectionId
Definition: oslist.h:26
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char CHAR
Definition: xmlstorage.h:175