ReactOS  0.4.15-dev-1377-ga59cecd
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 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";
40 const 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/NOGUIBOOT /DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";
41 const 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 
120 VOID
121 EditCustomBootDisk(
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 
215 VOID
216 EditCustomBootPartition(
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 
325 VOID
326 EditCustomBootSectorFile(
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 
458 VOID
459 EditCustomBootLinux(
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 
618 VOID
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
#define IN
Definition: typedefs.h:39
VOID OptionMenuCustomBoot(VOID)
#define TRUE
Definition: types.h:120
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:65
const CHAR ARCPathPrompt[]
Definition: custom.c:37
USHORT Minute
Definition: fw.h:15
#define FALSE
Definition: types.h:117
#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
const CHAR ReactOSSetupOptionsPrompt[]
Definition: custom.c:40
Definition: bl.h:892
unsigned char BOOLEAN
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:619
VOID OptionMenuReboot(VOID)
const CHAR CustomBootPrompt[]
Definition: custom.c:41
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
#define NULL
Definition: types.h:112
_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