ReactOS 0.4.17-dev-37-g0bfb40d
advopts.c
Go to the documentation of this file.
1/*
2 * PROJECT: NT-compatible ReactOS/Windows OS Loader
3 * LICENSE: Dual-licensed:
4 * GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
5 * MIT (https://spdx.org/licenses/MIT)
6 * PURPOSE: Advanced Boot Options F8 menu.
7 * COPYRIGHT: Copyright 1998-2003 Brian Palmer <brianp@sginet.com>
8 * Copyright 2010 Cameron Gutman <cameron.gutman@reactos.org>
9 * Copyright 2012-2026 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
10 */
11
12/* INCLUDES *******************************************************************/
13
14#include <freeldr.h>
15#include "ntldropts.h"
16
17/* GLOBALS ********************************************************************/
18
19/* Named menu IDs */
20typedef enum _ADVOPTS_ACTION
21{
31#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override
32 ActionBootAcpiApic,
33 ActionBootAcpiSmp,
34#endif
35#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
36 ActionEditBootCmdLine,
37#endif
42
43typedef struct _ADVBOOT_OPTIONS
44{
48
49static ADVBOOT_OPTIONS AdvBootOptions[] = // OptionsMenuList
50{
51 {ActionSafeBoot, "Safe Mode"},
52 {ActionSafeBootNetwork, "Safe Mode with Networking"},
53 {ActionSafeBootAltShell, "Safe Mode with Command Prompt"},
54
56
57 {ActionBootLog, "Enable Boot Logging"},
58 {ActionVGAMode, "Enable VGA Mode"},
59 {ActionLKGConfig, "Last Known Good Configuration"},
60 {ActionSafeBootDSRepair, "Directory Services Restore Mode"}, // "(ReactOS domain controllers only)"
61 {ActionDebugMode, "Debugging Mode"},
62
63#if DBG && defined(_M_IX86)
64 /* For x86 *ONLY*, allow the user to override HAL/Kernel auto-detection.
65 * NOTE: This can always be done by manually editing the command-line if wanted. */
66 {ActionBootAcpiApic, NULL},
67 {ActionBootAcpiApic, "Boot with ACPI APIC"},
68 {ActionBootAcpiSmp, "Boot with ACPI Multiprocessor"},
69#endif
70
72
73#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
74 {ActionEditBootCmdLine, "Edit Boot Command Line (F10)"},
75#endif
76 {ActionStartNormally, "Start ReactOS normally"},
77 {ActionReboot, "Reboot"},
78 {ActionBackToPrevMenu, "Return to OS Choices menu"},
79};
80
81/* Advanced NT boot options */
83#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override
84UCHAR HALAutoDetectMode = BOOT_AUTODETECT;
85#endif
87
88/* FUNCTIONS ******************************************************************/
89
90static VOID
92 _Inout_z_bytecount_(BootOptsDescSize)
93 PSTR BootOptsDesc,
94 _In_ SIZE_T BootOptsDescSize)
95{
96 /* NOTE: Keep in sync with the 'enum SAFEBOOT_MODE'
97 * in winldr.h and the AdvBootOptions above. */
98 static const PCSTR* OptionNames[] =
99 {
100 /* NO_OPTION */ NULL,
101 /* SAFEBOOT */ &AdvBootOptions[0].Item,
102 /* SAFEBOOT_NETWORK */ &AdvBootOptions[1].Item,
103 /* SAFEBOOT_ALTSHELL */ &AdvBootOptions[2].Item,
104 /* SAFEBOOT_DSREPAIR */ &AdvBootOptions[7].Item,
105 /* LKG_CONFIG */ &AdvBootOptions[6].Item,
106 };
107
108 if (BootOptsDescSize < sizeof(CHAR))
109 return;
110
111 *BootOptsDesc = ANSI_NULL;
112
113#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override
114 if ((HALAutoDetectMode != BOOT_AUTODETECT) && (HALAutoDetectMode <= BOOT_ACPI_SMP))
115 {
116 static const PCSTR AutoDetectNames[] = {"", "ACPI APIC", "ACPI Multiprocessor"};
117 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AutoDetectNames[HALAutoDetectMode]);
118 }
119#endif
120
121 ASSERT(BootOptionChoice < RTL_NUMBER_OF(OptionNames));
122 if (BootOptionChoice != NO_OPTION) // && BootOptionChoice < RTL_NUMBER_OF(OptionNames)
123 {
124 if (*BootOptsDesc)
125 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", ");
126 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, *OptionNames[BootOptionChoice]);
127 }
128
130 {
131 /* Since these safe mode options come by default with boot logging,
132 * don't show "Boot Logging" when one of these is selected;
133 * instead just show the corresponding safe mode option name. */
134 if ( (BootOptionChoice != SAFEBOOT) &&
137 {
138 if (*BootOptsDesc)
139 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", ");
140 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AdvBootOptions[4].Item);
141 }
142 }
143
145 {
146 if (*BootOptsDesc)
147 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", ");
148 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AdvBootOptions[5].Item);
149 }
150
152 {
153 if (*BootOptsDesc)
154 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, ", ");
155 RtlStringCbCatA(BootOptsDesc, BootOptsDescSize, AdvBootOptions[8].Item);
156 }
157}
158
159VOID
161 _Inout_opt_ OperatingSystemItem* OperatingSystem)
162{
164 PCSTR OptionsMenuList[RTL_NUMBER_OF(AdvBootOptions)]; // FIXME!
165 ULONG i, MenuItemCount;
166 ULONG SelectedMenuItem = 0;
167
168 /* Build the menu, filtering out any item that may not be applicable,
169 * and set the "Start ReactOS normally" as default. */
170 for (i = 0, MenuItemCount = 0; i < RTL_NUMBER_OF(AdvBootOptions); ++i)
171 {
172 /* Hide the "Return to OS Choices" item if no OS entry is selected */
173 if ((AdvBootOptions[i].Id == ActionBackToPrevMenu) && !OperatingSystem)
174 continue;
175#if DBG && defined(_M_IX86)
176 /* Filter out ActionBootAcpiApic/ActionBootAcpiSmp
177 * if we aren't running on standard BIOS-based PC */
178 if (AdvBootOptions[i].Id == ActionBootAcpiApic ||
179 AdvBootOptions[i].Id == ActionBootAcpiSmp)
180 {
181#if defined(SARCH_XBOX) || defined(SARCH_PC98) || defined(UEFIBOOT)
182 continue;
183#endif
184 }
185#endif
186
187 /* Set the default option */
189 SelectedMenuItem = MenuItemCount;
190
191 MenuActionsMap[MenuItemCount] = AdvBootOptions[i].Id;
192 OptionsMenuList[MenuItemCount++] = AdvBootOptions[i].Item;
193 }
194
195doMenu:
196 /* Redraw the backdrop, but don't overwrite boot options */
198 if (OperatingSystem)
199 DisplayBootTimeOptions(OperatingSystem);
200
201 if (!UiDisplayMenu("Please select an option:",
202 NULL,
203 OptionsMenuList,
204 MenuItemCount,
205 SelectedMenuItem, -1,
206 &SelectedMenuItem,
207 TRUE,
208 NULL, NULL))
209 {
210 /* The user pressed ESC */
211 return;
212 }
213
214 switch (MenuActionsMap[SelectedMenuItem])
215 {
216 case ActionSafeBoot:
219 break;
223 break;
227 break;
228 case ActionBootLog:
230 break;
231 case ActionVGAMode:
233 break;
234 case ActionLKGConfig:
236 break;
239 break;
240 case ActionDebugMode:
242 break;
243#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override
244 case ActionBootAcpiApic:
245 HALAutoDetectMode = BOOT_ACPI_APIC;
246 break;
247 case ActionBootAcpiSmp:
248 HALAutoDetectMode = BOOT_ACPI_SMP;
249 break;
250#endif
251#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
252 case ActionEditBootCmdLine:
253 if (OperatingSystem)
254 EditOperatingSystemEntry(OperatingSystem);
255 goto doMenu;
256#endif
258 /* Reset all the parameters to their default values */
260#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override
261 HALAutoDetectMode = BOOT_AUTODETECT;
262#endif
263 BootFlags = 0;
264 break;
265 case ActionReboot:
267 return;
269 return; /* Just return to the caller */
271 }
272
273 /* Update the human-readable boot-option description string */
274 if (OperatingSystem)
275 {
276 GetBootOptionsDescription(OperatingSystem->AdvBootOptsDesc,
277 sizeof(OperatingSystem->AdvBootOptsDesc));
278 }
279}
280
281VOID
283 _Inout_z_bytecount_(BootOptionsSize)
284 PSTR BootOptions,
285 _In_ SIZE_T BootOptionsSize)
286{
287 /* NOTE: Keep in sync with the 'enum SAFEBOOT_MODE' in winldr.h */
288 static const PCSTR OptionsStr[] =
289 {
290 /* NO_OPTION */ NULL,
291 /* SAFEBOOT */ "SAFEBOOT:MINIMAL SOS NOGUIBOOT",
292 /* SAFEBOOT_NETWORK */ "SAFEBOOT:NETWORK SOS NOGUIBOOT",
293 /* SAFEBOOT_ALTSHELL */ "SAFEBOOT:MINIMAL(ALTERNATESHELL) SOS NOGUIBOOT",
294 /* SAFEBOOT_DSREPAIR */ "SAFEBOOT:DSREPAIR SOS",
295 /* LKG_CONFIG */ NULL,
296 };
297
298 PCSTR OptionsToAdd[2] = {NULL};
299 PCSTR OptionsToRemove[2] = {NULL};
300
301 if (BootOptionsSize < sizeof(CHAR))
302 return;
303
304#if DBG && defined(_M_IX86) // x86 *ONLY*: HAL/Kernel auto-detection override
305 if ((HALAutoDetectMode != BOOT_AUTODETECT) && (HALAutoDetectMode <= BOOT_ACPI_SMP))
306 {
307 static const PCSTR AutoDetectOptions[] =
308 {
309 /* BOOT_AUTODETECT */ NULL,
310 /* BOOT_ACPI_APIC */ "HAL=halaacpi.dll",
311 /* BOOT_ACPI_SMP */ "HAL=halmacpi.dll KERNEL=ntkrnlmp.exe",
312 };
313 PCSTR OptionsToRemove[] = {"/HAL=/KERNEL=", "/DETECTHAL", NULL};
314
315 OptionsToAdd[0] = AutoDetectOptions[HALAutoDetectMode];
316 NtLdrUpdateOptions(BootOptions, BootOptionsSize, FALSE,
317 OptionsToAdd, OptionsToRemove);
318 }
319#endif
320
321 switch (BootOptionChoice)
322 {
323 case SAFEBOOT:
324 case SAFEBOOT_NETWORK:
327 {
329
330 /* SAFEBOOT(:) options are self-excluding */
331 OptionsToAdd[0] = OptionsStr[BootOptionChoice];
332 OptionsToRemove[0] = "/SAFEBOOT/SAFEBOOT:";
333 NtLdrUpdateOptions(BootOptions, BootOptionsSize, TRUE,
334 OptionsToAdd, OptionsToRemove);
335 break;
336 }
337
338 case LKG_CONFIG:
339 DbgPrint("Last known good configuration is not yet supported!\n");
340 break;
341
342 default:
343 break;
344 }
345
347 NtLdrAddOptions(BootOptions, BootOptionsSize, TRUE, "BOOTLOG");
348
350 NtLdrAddOptions(BootOptions, BootOptionsSize, TRUE, "BASEVIDEO");
351
353 {
354 /* Remove NODEBUG if present, since we want to have debugging enabled */
355 OptionsToAdd[0] = "DEBUG";
356 OptionsToRemove[0] = "NODEBUG";
357 NtLdrUpdateOptions(BootOptions, BootOptionsSize, TRUE,
358 OptionsToAdd, OptionsToRemove);
359 }
360}
DWORD Id
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static ADVBOOT_OPTIONS AdvBootOptions[]
Definition: advopts.c:49
struct _ADVBOOT_OPTIONS ADVBOOT_OPTIONS
static VOID GetBootOptionsDescription(_Inout_z_bytecount_(BootOptsDescSize) PSTR BootOptsDesc, _In_ SIZE_T BootOptsDescSize)
Definition: advopts.c:91
_ADVOPTS_ACTION
Definition: advopts.c:21
@ ActionStartNormally
Definition: advopts.c:38
@ ActionBackToPrevMenu
Definition: advopts.c:40
@ ActionSafeBootDSRepair
Definition: advopts.c:26
@ ActionSafeBoot
Definition: advopts.c:23
@ ActionSafeBootAltShell
Definition: advopts.c:25
@ ActionSafeBootNetwork
Definition: advopts.c:24
@ ActionVGAMode
Definition: advopts.c:28
@ ActionDebugMode
Definition: advopts.c:30
@ ActionLKGConfig
Definition: advopts.c:29
@ ActionBootLog
Definition: advopts.c:27
@ ActionSeparator
Definition: advopts.c:22
@ ActionReboot
Definition: advopts.c:39
enum _ADVOPTS_ACTION ADVOPTS_ACTION
VOID AppendBootTimeOptions(_Inout_z_bytecount_(BootOptionsSize) PSTR BootOptions, _In_ SIZE_T BootOptionsSize)
Definition: advopts.c:282
VOID MenuNTOptions(_Inout_opt_ OperatingSystemItem *OperatingSystem)
Definition: advopts.c:160
enum SAFEBOOT_MODE BootOptionChoice
Definition: advopts.c:82
LOGICAL BootFlags
Definition: advopts.c:86
VOID OptionMenuReboot(VOID)
Definition: options.c:167
VOID DisplayBootTimeOptions(_In_ OperatingSystemItem *OperatingSystem)
Definition: options.c:154
VOID UiDrawBackdrop(ULONG DrawHeight)
Definition: ui.c:233
ULONG UiGetScreenHeight(VOID)
Definition: ui.c:655
BOOLEAN UiDisplayMenu(IN PCSTR MenuHeader, IN PCSTR MenuFooter OPTIONAL, 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
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define DbgPrint
Definition: hal.h:12
#define BOOT_DEBUGGING
Definition: winldr.h:69
#define BOOT_LOGGING
Definition: winldr.h:67
SAFEBOOT_MODE
Definition: winldr.h:48
@ SAFEBOOT
Definition: winldr.h:51
@ LKG_CONFIG
Definition: winldr.h:56
@ SAFEBOOT_DSREPAIR
Definition: winldr.h:54
@ SAFEBOOT_NETWORK
Definition: winldr.h:52
@ SAFEBOOT_ALTSHELL
Definition: winldr.h:53
@ NO_OPTION
Definition: winldr.h:49
#define BOOT_VGA_MODE
Definition: winldr.h:68
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_z_bytecount_(size)
Definition: ms_sal.h:948
#define _Inout_opt_
Definition: no_sal2.h:216
#define _In_
Definition: no_sal2.h:158
#define DEFAULT_UNREACHABLE
#define ANSI_NULL
VOID NtLdrUpdateOptions(_Inout_updates_z_(BufferSize) PSTR LoadOptions, _In_ ULONG BufferSize, _In_ BOOLEAN Append, _In_opt_ PCSTR OptionsToAdd[], _In_opt_ PCSTR OptionsToRemove[])
Updates the options in the buffer pointed by LoadOptions, of maximum size BufferSize,...
Definition: ntldropts.c:244
VOID NtLdrAddOptions(_Inout_updates_z_(BufferSize) PSTR Options, _In_ ULONG BufferSize, _In_ BOOLEAN Append, _In_opt_ PCSTR NewOptions)
Appends or prepends new options to the ones originally contained in the buffer pointed by Options,...
Definition: ntldropts.c:141
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625
char CHAR
Definition: pedump.c:57
char * PSTR
Definition: typedefs.h:51
unsigned char UCHAR
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
ULONG LOGICAL
Definition: umtypes.h:135
_In_ WDFCOLLECTION _In_ WDFOBJECT Item