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