xref: /reactos/boot/freeldr/freeldr/settings.c (revision 34e76ade)
1 /*
2  * PROJECT:     FreeLoader
3  * LICENSE:     BSD - See COPYING.ARM in the top level directory
4  *              or MIT (https://spdx.org/licenses/MIT)
5  * PURPOSE:     Command-line parsing and global settings management
6  * COPYRIGHT:   Copyright 2008-2010 ReactOS Portable Systems Group <ros.arm@reactos.org>
7  *              Copyright 2015-2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <freeldr.h>
13 
14 /* GLOBALS ********************************************************************/
15 
16 static CCHAR DebugString[256];
17 static CCHAR DefaultOs[256];
18 BOOTMGRINFO BootMgrInfo = {NULL, NULL, -1, 0};
19 
20 /* FUNCTIONS ******************************************************************/
21 
22 static VOID
CmdLineParse(_In_ PCSTR CmdLine)23 CmdLineParse(
24     _In_ PCSTR CmdLine)
25 {
26     PCHAR End, Setting;
27     ULONG_PTR Length, Offset = 0;
28 
29     /*
30      * Get the debug string, in the following format:
31      * "debug=option1=XXX;option2=YYY;..."
32      * and translate it into the format:
33      * "OPTION1=XXX OPTION2=YYY ..."
34      */
35     Setting = strstr(CmdLine, "debug=");
36     if (Setting)
37     {
38         /* Check if there are more command-line parameters following */
39         Setting += sizeof("debug=") - sizeof(ANSI_NULL);
40         End = strstr(Setting, " ");
41         Length = (End ? (End - Setting) : strlen(Setting));
42 
43         /* Copy the debug string and upcase it */
44         RtlStringCbCopyNA(DebugString, sizeof(DebugString), Setting, Length);
45         _strupr(DebugString);
46 
47         /* Replace all separators ';' by spaces */
48         Setting = DebugString;
49         while (*Setting)
50         {
51             if (*Setting == ';') *Setting = ' ';
52             Setting++;
53         }
54 
55         BootMgrInfo.DebugString = DebugString;
56     }
57 
58     /* Get the timeout */
59     Setting = strstr(CmdLine, "timeout=");
60     if (Setting)
61     {
62         BootMgrInfo.TimeOut = atoi(Setting +
63                                    sizeof("timeout=") - sizeof(ANSI_NULL));
64     }
65 
66     /* Get the default OS */
67     Setting = strstr(CmdLine, "defaultos=");
68     if (Setting)
69     {
70         /* Check if there are more command-line parameters following */
71         Setting += sizeof("defaultos=") - sizeof(ANSI_NULL);
72         End = strstr(Setting, " ");
73         Length = (End ? (End - Setting) : strlen(Setting));
74 
75         /* Copy the default OS */
76         RtlStringCbCopyNA(DefaultOs, sizeof(DefaultOs), Setting, Length);
77         BootMgrInfo.DefaultOs = DefaultOs;
78     }
79 
80     /* Get the ramdisk base address */
81     Setting = strstr(CmdLine, "rdbase=");
82     if (Setting)
83     {
84         gInitRamDiskBase =
85             (PVOID)(ULONG_PTR)strtoull(Setting +
86                                        sizeof("rdbase=") - sizeof(ANSI_NULL),
87                                        NULL, 0);
88     }
89 
90     /* Get the ramdisk size */
91     Setting = strstr(CmdLine, "rdsize=");
92     if (Setting)
93     {
94         gInitRamDiskSize = strtoul(Setting +
95                                    sizeof("rdsize=") - sizeof(ANSI_NULL),
96                                    NULL, 0);
97     }
98 
99     /* Get the ramdisk offset */
100     Setting = strstr(CmdLine, "rdoffset=");
101     if (Setting)
102     {
103         Offset = strtoul(Setting +
104                          sizeof("rdoffset=") - sizeof(ANSI_NULL),
105                          NULL, 0);
106     }
107 
108     /* Fix it up */
109     gInitRamDiskBase = (PVOID)((ULONG_PTR)gInitRamDiskBase + Offset);
110 }
111 
112 VOID
LoadSettings(_In_opt_ PCSTR CmdLine)113 LoadSettings(
114     _In_opt_ PCSTR CmdLine)
115 {
116     /* Pre-initialization: The settings originate from the command-line.
117      * Main initialization: Overwrite them if needed with those from freeldr.ini */
118     if (CmdLine)
119     {
120         CmdLineParse(CmdLine);
121         return;
122     }
123     else if (IsListEmpty(&IniFileSectionListHead))
124     {
125         // ERR("LoadSettings() called but no freeldr.ini\n");
126         return;
127     }
128 
129     BOOLEAN FoundLoaderSection = FALSE;
130     PCSTR LoaderSections[] = {
131         "FreeLoader",
132         "Boot Loader",
133         "FlexBoot",
134         "MultiBoot",
135     };
136 
137     /* Search for the first section in LoaderSections and load the settings,
138      * prioritizing the order in the file.
139      * If a section is already loaded, skip further checks. */
140     if (!BootMgrInfo.FrLdrSection)
141     {
142         for (ULONG i = 0; i < sizeof(LoaderSections) / sizeof(LoaderSections[0]); i++)
143         {
144             PCSTR Section = LoaderSections[i];
145 
146             if (IniOpenSection(Section, &BootMgrInfo.FrLdrSection))
147             {
148                 FoundLoaderSection = TRUE;
149                 break;
150             }
151         }
152 
153         if (!FoundLoaderSection)
154         {
155             UiMessageBoxCritical("Bootloader Section not found in freeldr.ini");
156             return;
157         }
158     }
159 
160     /* Get the debug string. Always override it with the one from freeldr.ini */
161     if (IniReadSettingByName(BootMgrInfo.FrLdrSection, "Debug",
162                              DebugString, sizeof(DebugString)))
163     {
164         BootMgrInfo.DebugString = DebugString;
165     }
166 
167     /* Get the timeout. Keep the existing one if it is valid,
168      * otherwise retrieve it from freeldr.ini */
169     if (BootMgrInfo.TimeOut < 0)
170     {
171         CHAR TimeOutText[20];
172         BootMgrInfo.TimeOut = -1;
173         if (IniReadSettingByName(BootMgrInfo.FrLdrSection, "TimeOut",
174                                  TimeOutText, sizeof(TimeOutText)))
175         {
176             BootMgrInfo.TimeOut = atoi(TimeOutText);
177         }
178     }
179 
180     /* Get the default OS */
181     if (!BootMgrInfo.DefaultOs || !*BootMgrInfo.DefaultOs)
182     {
183         if (IniReadSettingByName(BootMgrInfo.FrLdrSection, "DefaultOS",
184                                  DefaultOs, sizeof(DefaultOs)))
185         {
186             BootMgrInfo.DefaultOs = DefaultOs;
187         }
188     }
189 }
190 
191 /* EOF */
192