ReactOS 0.4.16-dev-753-g705a985
bootmgr.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for bootmgr.c:

Go to the source code of this file.

Classes

struct  _OS_LOADING_METHOD
 

Typedefs

typedef VOID(* EDIT_OS_ENTRY_PROC) (_Inout_ OperatingSystemItem *OperatingSystem)
 
typedef struct _OS_LOADING_METHOD OS_LOADING_METHOD
 
typedef struct _OS_LOADING_METHODPOS_LOADING_METHOD
 

Functions

 DBG_DEFAULT_CHANNEL (WARNING)
 
static VOID EditCustomBootReactOSSetup (_Inout_ OperatingSystemItem *OperatingSystem)
 
static VOID EditCustomBootNTOS (_Inout_ OperatingSystemItem *OperatingSystem)
 
static const OS_LOADING_METHODGetOSLoadingMethod (_In_ ULONG_PTR SectionId)
 
static PCHARBuildArgvForOsLoader (_In_ PCSTR LoadIdentifier, _In_ ULONG_PTR SectionId, _Out_ PULONG pArgc)
 This function converts the list of Key=Value options in the given operating system section into an ARC-compatible argument vector, providing in addition the extra mandatory Software Loading Environment Variables, following the ARC specification.
 
VOID LoadOperatingSystem (_In_ OperatingSystemItem *OperatingSystem)
 
BOOLEAN MainBootMenuKeyPressFilter (IN ULONG KeyPress, IN ULONG SelectedMenuItem, IN PVOID Context OPTIONAL)
 
VOID RunLoader (VOID)
 

Variables

static const OS_LOADING_METHOD OSLoadingMethods []
 

Typedef Documentation

◆ EDIT_OS_ENTRY_PROC

typedef VOID(* EDIT_OS_ENTRY_PROC) (_Inout_ OperatingSystemItem *OperatingSystem)

Definition at line 29 of file bootmgr.c.

◆ OS_LOADING_METHOD

◆ POS_LOADING_METHOD

Function Documentation

◆ BuildArgvForOsLoader()

static PCHAR * BuildArgvForOsLoader ( _In_ PCSTR  LoadIdentifier,
_In_ ULONG_PTR  SectionId,
_Out_ PULONG  pArgc 
)
static

This function converts the list of Key=Value options in the given operating system section into an ARC-compatible argument vector, providing in addition the extra mandatory Software Loading Environment Variables, following the ARC specification.

Definition at line 174 of file bootmgr.c.

178{
179 SIZE_T Size;
180 ULONG Count;
181 ULONG i;
182 ULONG Argc;
183 PCHAR* Argv;
184 PCHAR* Args;
185 PCHAR SettingName, SettingValue;
186 PCCHAR BootPath = FrLdrGetBootPath();
187
188 *pArgc = 0;
189
190 ASSERT(SectionId != 0);
191
192 /* Normalize LoadIdentifier to make subsequent tests simpler */
193 if (LoadIdentifier && !*LoadIdentifier)
194 LoadIdentifier = NULL;
195
196 /* Count the number of operating systems in the section */
197 Count = IniGetNumSectionItems(SectionId);
198
199 /*
200 * The argument vector contains the program name, the SystemPartition,
201 * the LoadIdentifier (optional), and the items in the OS section.
202 * For POSIX compliance, a terminating NULL pointer (not counted in Argc)
203 * is appended, such that Argv[Argc] == NULL.
204 */
205 Argc = 2 + (LoadIdentifier ? 1 : 0) + Count;
206
207 /* Calculate the total size needed for the string buffer of the argument vector */
208 Size = 0;
209 /* i == 0: Program name */
210 // TODO: Provide one in the future...
211 /* i == 1: SystemPartition : from where FreeLdr has been started */
212 Size += (strlen("SystemPartition=") + strlen(BootPath) + 1) * sizeof(CHAR);
213 /* i == 2: LoadIdentifier : ASCII string that may be used
214 * to associate an identifier with a set of load parameters */
215 if (LoadIdentifier)
216 {
217 Size += (strlen("LoadIdentifier=") + strlen(LoadIdentifier) + 1) * sizeof(CHAR);
218 }
219 /* The section items */
220 for (i = 0; i < Count; ++i)
221 {
222 Size += IniGetSectionSettingNameSize(SectionId, i); // Counts also the NULL-terminator, that we transform into the '=' sign separator.
223 Size += IniGetSectionSettingValueSize(SectionId, i); // Counts also the NULL-terminator.
224 }
225 Size += sizeof(ANSI_NULL); // Final NULL-terminator.
226
227 /* Allocate memory to hold the argument vector: pointers and string buffer */
228 Argv = FrLdrHeapAlloc((Argc + 1) * sizeof(PCHAR) + Size, TAG_STRING);
229 if (!Argv)
230 return NULL;
231
232 /* Initialize the argument vector: loop through the section and copy the Key=Value options */
233 SettingName = (PCHAR)((ULONG_PTR)Argv + ((Argc + 1) * sizeof(PCHAR)));
234 Args = Argv;
235 /* i == 0: Program name */
236 *Args++ = NULL; // TODO: Provide one in the future...
237 /* i == 1: SystemPartition */
238 {
239 strcpy(SettingName, "SystemPartition=");
240 strcat(SettingName, BootPath);
241
242 *Args++ = SettingName;
243 SettingName += (strlen(SettingName) + 1);
244 }
245 /* i == 2: LoadIdentifier */
246 if (LoadIdentifier)
247 {
248 strcpy(SettingName, "LoadIdentifier=");
249 strcat(SettingName, LoadIdentifier);
250
251 *Args++ = SettingName;
252 SettingName += (strlen(SettingName) + 1);
253 }
254 /* The section items */
255 for (i = 0; i < Count; ++i)
256 {
257 Size = IniGetSectionSettingNameSize(SectionId, i);
258 SettingValue = SettingName + Size;
259 IniReadSettingByNumber(SectionId, i,
260 SettingName, Size,
261 SettingValue, IniGetSectionSettingValueSize(SectionId, i));
262 SettingName[Size - 1] = '=';
263
264 *Args++ = SettingName;
265 SettingName += (strlen(SettingName) + 1);
266 }
267 /* Terminating NULL pointer */
268 *Args = NULL;
269
270#if DBG
271 /* Dump the argument vector for debugging */
272 for (i = 0; i < Argc; ++i)
273 {
274 TRACE("Argv[%lu]: '%s'\n", i, Argv[i]);
275 }
276#endif
277
278 *pArgc = Argc;
279 return Argv;
280}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char ** Args
Definition: acdebug.h:353
PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: heap.c:533
#define NULL
Definition: types.h:112
PCCHAR FrLdrGetBootPath(VOID)
Definition: freeldr.c:196
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
ULONG IniGetSectionSettingValueSize(ULONG_PTR SectionId, ULONG SettingIndex)
Definition: inifile.c:108
ULONG IniGetNumSectionItems(ULONG_PTR SectionId)
Definition: inifile.c:60
ULONG IniGetSectionSettingNameSize(ULONG_PTR SectionId, ULONG SettingIndex)
Definition: inifile.c:95
BOOLEAN IniReadSettingByNumber(ULONG_PTR SectionId, ULONG SettingNumber, PCHAR SettingName, ULONG NameSize, PCHAR SettingValue, ULONG ValueSize)
Definition: inifile.c:121
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
int Count
Definition: noreturn.cpp:7
#define ANSI_NULL
#define TAG_STRING
Definition: oslist.h:22
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
#define TRACE(s)
Definition: solgame.cpp:4
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
char CHAR
Definition: xmlstorage.h:175

Referenced by LoadOperatingSystem().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( WARNING  )

◆ EditCustomBootNTOS()

static VOID EditCustomBootNTOS ( _Inout_ OperatingSystemItem OperatingSystem)
static

Definition at line 41 of file bootmgr.c.

43{
44 EditCustomBootReactOS(OperatingSystem, FALSE);
45}
VOID EditCustomBootReactOS(IN OUT OperatingSystemItem *OperatingSystem, IN BOOLEAN IsSetup)
Definition: custom.c:485
#define FALSE
Definition: types.h:117

◆ EditCustomBootReactOSSetup()

static VOID EditCustomBootReactOSSetup ( _Inout_ OperatingSystemItem OperatingSystem)
static

Definition at line 34 of file bootmgr.c.

36{
37 EditCustomBootReactOS(OperatingSystem, TRUE);
38}
#define TRUE
Definition: types.h:120

◆ GetOSLoadingMethod()

static const OS_LOADING_METHOD * GetOSLoadingMethod ( _In_ ULONG_PTR  SectionId)
static

Definition at line 108 of file bootmgr.c.

110{
111 ULONG i;
112 CHAR BootType[80];
113
114 /* The operating system section has been opened by InitOperatingSystemList() */
115 ASSERT(SectionId != 0);
116
117 /* Try to read the boot type. We must have the value (it
118 * has been possibly added by InitOperatingSystemList()) */
119 *BootType = ANSI_NULL;
120 IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
121 ASSERT(*BootType);
122
124#ifdef HAS_DEPRECATED_OPTIONS
125 if ((_stricmp(BootType, "Drive") == 0) ||
126 (_stricmp(BootType, "Partition") == 0))
127 {
128 /* Display the deprecation warning message */
130 "The '%s' configuration you are booting into is no longer\n"
131 "supported and will be removed in future FreeLoader versions.\n"
132 "\n"
133 "Please edit FREELDR.INI to replace all occurrences of\n"
134 "\n"
135 " %*s to:\n"
136 " BootType=%s ------> BootType=BootSector",
137 BootType,
138 strlen(BootType), "", // Indentation
139 BootType);
140
141 /* Type fixup */
142 strcpy(BootType, "BootSector");
143 if (!IniModifySettingValue(SectionId, "BootType", BootType))
144 {
145 ERR("Could not fixup the BootType entry for OS '%s', ignoring.\n",
146 ((PINI_SECTION)SectionId)->SectionName);
147 }
148 }
149#endif // HAS_DEPRECATED_OPTIONS
151
152 /* Find the suitable OS loading method */
153 for (i = 0; ; ++i)
154 {
156 {
157 UiMessageBox("Unknown boot entry type '%s'", BootType);
158 return NULL;
159 }
160 if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
161 return &OSLoadingMethods[i];
162 }
164}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define ERR(fmt,...)
Definition: precomp.h:57
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
#define _stricmp
Definition: cat.c:22
static const OS_LOADING_METHOD OSLoadingMethods[]
Definition: bootmgr.c:55
VOID WarnDeprecated(_In_ PCSTR MsgFmt,...)
BOOLEAN IniModifySettingValue(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue)
Definition: inifile.c:301
BOOLEAN IniReadSettingByName(ULONG_PTR SectionId, PCSTR SettingName, PCHAR Buffer, ULONG BufferSize)
Definition: inifile.c:154
#define UNREACHABLE

Referenced by LoadOperatingSystem().

◆ LoadOperatingSystem()

VOID LoadOperatingSystem ( _In_ OperatingSystemItem OperatingSystem)

Definition at line 283 of file bootmgr.c.

285{
286 ULONG_PTR SectionId = OperatingSystem->SectionId;
287 const OS_LOADING_METHOD* OSLoadingMethod;
288 ULONG Argc;
289 PCHAR* Argv;
290
291 /* Find the suitable OS loader to start */
292 OSLoadingMethod = GetOSLoadingMethod(SectionId);
293 if (!OSLoadingMethod)
294 return;
295 ASSERT(OSLoadingMethod->OsLoader);
296
297 /* Build the ARC-compatible argument vector */
298 Argv = BuildArgvForOsLoader(OperatingSystem->LoadIdentifier, SectionId, &Argc);
299 if (!Argv)
300 return; // Unexpected failure.
301
302#ifdef _M_IX86
303#ifndef UEFIBOOT
304 /* Install the drive mapper according to this section drive mappings */
305 DriveMapMapDrivesInSection(SectionId);
306#endif
307#endif
308
309 /* Start the OS loader */
310 OSLoadingMethod->OsLoader(Argc, Argv, NULL);
312}
VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: heap.c:539
static PCHAR * BuildArgvForOsLoader(_In_ PCSTR LoadIdentifier, _In_ ULONG_PTR SectionId, _Out_ PULONG pArgc)
This function converts the list of Key=Value options in the given operating system section into an AR...
Definition: bootmgr.c:174
static const OS_LOADING_METHOD * GetOSLoadingMethod(_In_ ULONG_PTR SectionId)
Definition: bootmgr.c:108
ARC_ENTRY_POINT OsLoader
Definition: bootmgr.c:51

Referenced by RunLoader().

◆ MainBootMenuKeyPressFilter()

BOOLEAN MainBootMenuKeyPressFilter ( IN ULONG  KeyPress,
IN ULONG  SelectedMenuItem,
IN PVOID Context  OPTIONAL 
)

Definition at line 331 of file bootmgr.c.

335{
336 /* Any key-press cancels the global timeout */
337 GetBootMgrInfo()->TimeOut = -1;
338
339 switch (KeyPress)
340 {
341 case KEY_F8:
342 DoOptionsMenu(&((OperatingSystemItem*)Context)[SelectedMenuItem]);
344 return TRUE;
345
346#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
347 case KEY_F10:
348 EditOperatingSystemEntry(&((OperatingSystemItem*)Context)[SelectedMenuItem]);
349 return TRUE;
350#endif
351
352 default:
353 /* We didn't handle the key */
354 return FALSE;
355 }
356}
VOID DoOptionsMenu(IN OperatingSystemItem *OperatingSystem)
Definition: options.c:92
VOID DisplayBootTimeOptions(VOID)
Definition: options.c:180
PBOOTMGRINFO GetBootMgrInfo(VOID)
Definition: settings.c:191
#define KEY_F8
Definition: keycodes.h:58
#define KEY_F10
Definition: keycodes.h:60
LONG TimeOut
Definition: settings.h:14

Referenced by RunLoader().

◆ RunLoader()

VOID RunLoader ( VOID  )

Definition at line 358 of file bootmgr.c.

359{
360 OperatingSystemItem* OperatingSystemList;
361 PCSTR* OperatingSystemDisplayNames;
362 ULONG OperatingSystemCount;
363 ULONG DefaultOperatingSystem;
364 ULONG SelectedOperatingSystem;
365 ULONG i;
366
367#ifdef _M_IX86
368#ifndef UEFIBOOT
369 /* Load additional SCSI driver (if any) */
371 {
372 UiMessageBoxCritical("Unable to load additional boot device drivers.");
373 }
374#endif
375#endif
376
377 /* Open FREELDR.INI and load the global FreeLoader settings */
378 if (!IniFileInitialize())
379 {
380 UiMessageBoxCritical("Error initializing .ini file.");
381 return;
382 }
384#if 0
385 if (FALSE)
386 {
387 UiMessageBoxCritical("Could not load global FreeLoader settings.");
388 return;
389 }
390#endif
391
392 /* Debugger main initialization */
394
395 /* UI main initialization */
396 if (!UiInitialize(TRUE))
397 {
398 UiMessageBoxCritical("Unable to initialize UI.");
399 return;
400 }
401
402 OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount,
403 &DefaultOperatingSystem);
404 if (!OperatingSystemList)
405 {
406 UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot.");
407 goto Reboot;
408 }
409 if (OperatingSystemCount == 0)
410 {
411 UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
412 goto Reboot;
413 }
414
415 /* Create list of display names */
416 OperatingSystemDisplayNames = FrLdrTempAlloc(sizeof(PCSTR) * OperatingSystemCount, 'mNSO');
417 if (!OperatingSystemDisplayNames)
418 goto Reboot;
419
420 for (i = 0; i < OperatingSystemCount; i++)
421 {
422 OperatingSystemDisplayNames[i] = OperatingSystemList[i].LoadIdentifier;
423 }
424
425 /* Find all the message box settings and run them */
427
428 for (;;)
429 {
430 /* Redraw the backdrop */
432
433 /* Show the operating system list menu */
434 if (!UiDisplayMenu("Please select the operating system to start:",
435 "For troubleshooting and advanced startup options for "
436 "ReactOS, press F8.",
437 OperatingSystemDisplayNames,
438 OperatingSystemCount,
439 DefaultOperatingSystem,
440 GetBootMgrInfo()->TimeOut,
441 &SelectedOperatingSystem,
442 FALSE,
444 OperatingSystemList))
445 {
446 UiMessageBox("Press ENTER to reboot.");
447 goto Reboot;
448 }
449
450 /* Load the chosen operating system */
451 LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]);
452
453 GetBootMgrInfo()->TimeOut = -1;
454
455 /* If we get there, the OS loader failed. As it may have
456 * messed up the display, re-initialize the UI. */
457#ifndef _M_ARM
458 UiUnInitialize("");
459#endif
461 }
462
463Reboot:
464 UiUnInitialize("Rebooting...");
465 IniCleanup();
466 return;
467}
void LoadSettings(void)
Definition: settings.c:53
@ Reboot
Definition: bl.h:891
ULONG LoadBootDeviceDriver(VOID)
Definition: scsiport.c:1635
#define DebugInit(DebugString)
Definition: debug.h:120
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
VOID UiShowMessageBoxesInSection(IN ULONG_PTR SectionId)
Definition: ui.c:524
VOID UiMessageBoxCritical(_In_ PCSTR MessageText)
Definition: ui.c:372
VOID UiUnInitialize(PCSTR BootText)
Definition: ui.c:224
VOID UiDrawBackdrop(VOID)
Definition: ui.c:233
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
BOOLEAN UiInitialize(BOOLEAN ShowUi)
Definition: ui.c:92
static CCHAR DebugString[256]
Definition: settings.c:16
VOID LoadOperatingSystem(_In_ OperatingSystemItem *OperatingSystem)
Definition: bootmgr.c:283
BOOLEAN MainBootMenuKeyPressFilter(IN ULONG KeyPress, IN ULONG SelectedMenuItem, IN PVOID Context OPTIONAL)
Definition: bootmgr.c:331
BOOLEAN IniFileInitialize(VOID)
Definition: ini_init.c:25
VOID IniCleanup(VOID)
Definition: inifile.c:243
OperatingSystemItem * InitOperatingSystemList(_Out_ PULONG OperatingSystemCount, _Out_ PULONG DefaultOperatingSystem)
Definition: oslist.c:46
@ ESUCCESS
Definition: arc.h:32
const char * PCSTR
Definition: typedefs.h:52

Referenced by ExecuteLoaderCleanly().

Variable Documentation

◆ OSLoadingMethods

const OS_LOADING_METHOD OSLoadingMethods[]
static
Initial value:
=
{
}
static VOID EditCustomBootNTOS(_Inout_ OperatingSystemItem *OperatingSystem)
Definition: bootmgr.c:41
static VOID EditCustomBootReactOSSetup(_Inout_ OperatingSystemItem *OperatingSystem)
Definition: bootmgr.c:34
ARC_STATUS LoadReactOSSetup(IN ULONG Argc, IN PCHAR Argv[], IN PCHAR Envp[])
Definition: setupldr.c:475
ARC_STATUS LoadAndBootWindows(IN ULONG Argc, IN PCHAR Argv[], IN PCHAR Envp[])
Definition: winldr.c:979

Definition at line 55 of file bootmgr.c.

Referenced by GetOSLoadingMethod().