ReactOS 0.4.15-dev-7931-gfd331f1
oslist.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#include <debug.h>
26
27#define TAG_OS_ITEM 'tISO'
28
29/* FUNCTIONS ******************************************************************/
30
32{
33 PSTR Dest;
34
35 if (!Source)
36 return NULL;
37
39 if (Dest)
40 strcpy(Dest, Source);
41
42 return Dest;
43}
44
47 IN ULONG_PTR FrLdrSectionId,
48 OUT PULONG OperatingSystemCount,
49 OUT PULONG DefaultOperatingSystem)
50{
51 ULONG DefaultOS = 0;
52 PCSTR DefaultOSName = NULL;
53 CHAR DefaultOSText[80];
54
57 ULONG i;
58 ULONG_PTR OsSectionId, SectionId;
59 PCHAR TitleStart, TitleEnd;
60 PCSTR OsLoadOptions;
61 BOOLEAN HadSection;
62 BOOLEAN HadNoBootType;
63 CHAR SettingName[260];
64 CHAR SettingValue[260];
65 CHAR BootType[80];
66 CHAR TempBuffer[sizeof(SettingValue)/sizeof(CHAR)];
67
68 /* Open the [Operating Systems] section */
69 if (!IniOpenSection("Operating Systems", &OsSectionId))
70 return NULL;
71
72 /* Count the number of operating systems in the section */
73 Count = IniGetNumSectionItems(OsSectionId);
74
75 /* Allocate memory to hold operating system lists */
77 if (!Items)
78 return NULL;
79
80 /* Retrieve which OS is the default one */
81 DefaultOSName = CmdLineGetDefaultOS();
82 if (!DefaultOSName || !*DefaultOSName)
83 {
84 if ((FrLdrSectionId != 0) &&
85 IniReadSettingByName(FrLdrSectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
86 {
87 DefaultOSName = DefaultOSText;
88 }
89 }
90
91 /* Now loop through the operating system section and load each item */
92 for (i = 0; i < Count; ++i)
93 {
94 IniReadSettingByNumber(OsSectionId, i,
95 SettingName, sizeof(SettingName),
96 SettingValue, sizeof(SettingValue));
97 if (!*SettingName)
98 {
99 ERR("Invalid OS entry %lu, skipping.\n", i);
100 continue;
101 }
102
103 /* Retrieve the start and end of the title */
104 TitleStart = SettingValue;
105 /* Trim any leading whitespace and quotes */
106 while (*TitleStart == ' ' || *TitleStart == '\t' || *TitleStart == '"')
107 ++TitleStart;
108 TitleEnd = TitleStart;
109 /* Go up to the first last quote */
110 while (*TitleEnd != ANSI_NULL && *TitleEnd != '"')
111 ++TitleEnd;
112
113 /* NULL-terminate the title */
114 if (*TitleEnd)
115 *TitleEnd++ = ANSI_NULL; // Skip the quote too.
116
117 /* Retrieve the options after the quoted title */
118 if (*TitleEnd)
119 {
120 /* Trim any trailing whitespace and quotes */
121 while (*TitleEnd == ' ' || *TitleEnd == '\t' || *TitleEnd == '"')
122 ++TitleEnd;
123 }
124 OsLoadOptions = (*TitleEnd ? TitleEnd : NULL);
125
126 // TRACE("\n"
127 // "SettingName = '%s'\n"
128 // "TitleStart = '%s'\n"
129 // "OsLoadOptions = '%s'\n",
130 // SettingName, TitleStart, OsLoadOptions);
131
132 /* Find the default OS item while we haven't got one */
133 if (DefaultOSName && _stricmp(DefaultOSName, SettingName) == 0)
134 {
135 DefaultOS = i;
136 DefaultOSName = NULL; // We have found the first one, don't search for others.
137 }
138
139 /*
140 * Determine whether this is a legacy operating system entry of the form:
141 *
142 * [Operating Systems]
143 * ArcOsLoadPartition="LoadIdentifier" /List /of /Options
144 *
145 * and if so, convert it into a new operating system INI entry:
146 *
147 * [Operating Systems]
148 * SectionIdentifier="LoadIdentifier"
149 *
150 * [SectionIdentifier]
151 * BootType=...
152 * SystemPath=ArcOsLoadPartition
153 * Options=/List /of /Options
154 *
155 * The "BootType" value is heuristically determined from the form of
156 * the ArcOsLoadPartition: if this is an ARC path, the "BootType" value
157 * is "Windows", otherwise if this is a DOS path the "BootType" value
158 * is "BootSector". This ensures backwards-compatibility with NTLDR.
159 */
160
161 /* Try to open the operating system section in the .ini file */
162 SectionId = 0;
163 HadSection = IniOpenSection(SettingName, &SectionId);
164 if (HadSection)
165 {
166 /* This is a new OS entry: try to read the boot type */
167 IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
168 }
169 else
170 {
171 /* This is a legacy OS entry: no explicit BootType specified, we will infer one */
172 *BootType = ANSI_NULL;
173 }
174
175 /* Check whether we have got a BootType value; if not, try to infer one */
176 HadNoBootType = (*BootType == ANSI_NULL);
177 if (HadNoBootType)
178 {
179#ifdef _M_IX86
180 ULONG FileId;
181 if (ArcOpen(SettingName, OpenReadOnly, &FileId) == ESUCCESS)
182 {
183 ArcClose(FileId);
184 strcpy(BootType, "BootSector");
185 }
186 else
187#endif
188 {
189 strcpy(BootType, "Windows");
190 }
191 }
192
193 /* This is a legacy OS entry: convert it into a new OS entry */
194 if (!HadSection)
195 {
196 TIMEINFO* TimeInfo;
197
198 /* Save the system path from the original SettingName (overwritten below) */
199 RtlStringCbCopyA(TempBuffer, sizeof(TempBuffer), SettingName);
200
201 /* Generate a unique section name */
202 TimeInfo = ArcGetTime();
203 if (_stricmp(BootType, "BootSector") == 0)
204 {
205 RtlStringCbPrintfA(SettingName, sizeof(SettingName),
206 "BootSectorFile%u%u%u%u%u%u",
207 TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
208 TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
209 }
210 else if (_stricmp(BootType, "Windows") == 0)
211 {
212 RtlStringCbPrintfA(SettingName, sizeof(SettingName),
213 "Windows%u%u%u%u%u%u",
214 TimeInfo->Year, TimeInfo->Day, TimeInfo->Month,
215 TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
216 }
217 else
218 {
219 ASSERT(FALSE);
220 }
221
222 /* Add the section */
223 if (!IniAddSection(SettingName, &SectionId))
224 {
225 ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
226 continue;
227 }
228
229 /* Add the system path */
230 if (_stricmp(BootType, "BootSector") == 0)
231 {
232 if (!IniAddSettingValueToSection(SectionId, "BootSectorFile", TempBuffer))
233 {
234 ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
235 continue;
236 }
237 }
238 else if (_stricmp(BootType, "Windows") == 0)
239 {
240 if (!IniAddSettingValueToSection(SectionId, "SystemPath", TempBuffer))
241 {
242 ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
243 continue;
244 }
245 }
246 else
247 {
248 ASSERT(FALSE);
249 }
250
251 /* Add the OS options */
252 if (OsLoadOptions && !IniAddSettingValueToSection(SectionId, "Options", OsLoadOptions))
253 {
254 ERR("Could not convert legacy OS entry %lu, skipping.\n", i);
255 continue;
256 }
257 }
258
259 /* Add or modify the BootType if needed */
260 if (HadNoBootType && !IniModifySettingValue(SectionId, "BootType", BootType))
261 {
262 ERR("Could not fixup the BootType entry for OS '%s', ignoring.\n", SettingName);
263 }
264
265 /*
266 * If this is a new OS entry, but some options were given appended to
267 * the OS entry item, append them instead to the "Options=" value.
268 */
269 if (HadSection && OsLoadOptions && *OsLoadOptions)
270 {
271 /* Read the original "Options=" value */
272 *TempBuffer = ANSI_NULL;
273 if (!IniReadSettingByName(SectionId, "Options", TempBuffer, sizeof(TempBuffer)))
274 TRACE("No 'Options' value found for OS '%s', ignoring.\n", SettingName);
275
276 /* Concatenate the options together */
277 RtlStringCbCatA(TempBuffer, sizeof(TempBuffer), " ");
278 RtlStringCbCatA(TempBuffer, sizeof(TempBuffer), OsLoadOptions);
279
280 /* Save them */
281 if (!IniModifySettingValue(SectionId, "Options", TempBuffer))
282 ERR("Could not modify the options for OS '%s', ignoring.\n", SettingName);
283 }
284
285 /* Copy the OS section ID and its identifier */
286 Items[i].SectionId = SectionId;
287 Items[i].LoadIdentifier = CopyString(TitleStart);
288 // TRACE("We did Items[%lu]: SectionName = '%s' (SectionId = 0x%p), LoadIdentifier = '%s'\n",
289 // i, SettingName, Items[i].SectionId, Items[i].LoadIdentifier);
290 }
291
292 /* Return success */
293 *OperatingSystemCount = Count;
294 *DefaultOperatingSystem = DefaultOS;
295 return Items;
296}
unsigned char BOOLEAN
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
TIMEINFO * ArcGetTime(VOID)
Definition: arcemul.c:27
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:220
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:174
#define _stricmp
Definition: cat.c:22
PCSTR CmdLineGetDefaultOS(VOID)
Definition: cmdline.c:129
#define NULL
Definition: types.h:112
#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
BOOLEAN IniAddSection(PCSTR SectionName, ULONG_PTR *SectionId)
Definition: inifile.c:182
ULONG IniGetNumSectionItems(ULONG_PTR SectionId)
Definition: inifile.c:55
BOOLEAN IniAddSettingValueToSection(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue)
Definition: inifile.c:255
BOOLEAN IniModifySettingValue(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue)
Definition: inifile.c:296
BOOLEAN IniReadSettingByNumber(ULONG_PTR SectionId, ULONG SettingNumber, PCHAR SettingName, ULONG NameSize, PCHAR SettingValue, ULONG ValueSize)
Definition: inifile.c:116
BOOLEAN IniReadSettingByName(ULONG_PTR SectionId, PCSTR SettingName, PCHAR Buffer, ULONG BufferSize)
Definition: inifile.c:149
BOOLEAN IniOpenSection(PCSTR SectionName, ULONG_PTR *SectionId)
Definition: inifile.c:25
#define ASSERT(a)
Definition: mode.c:44
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
int Count
Definition: noreturn.cpp:7
#define ANSI_NULL
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625
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
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
#define TAG_OS_ITEM
Definition: oslist.c:27
static PCSTR CopyString(PCSTR Source)
Definition: oslist.c:31
OperatingSystemItem * InitOperatingSystemList(IN ULONG_PTR FrLdrSectionId, OUT PULONG OperatingSystemCount, OUT PULONG DefaultOperatingSystem)
Definition: oslist.c:46
#define TAG_STRING
Definition: oslist.h:22
@ ESUCCESS
Definition: arc.h:32
@ OpenReadOnly
Definition: arc.h:65
#define TRACE(s)
Definition: solgame.cpp:4
Definition: fw.h:10
USHORT Month
Definition: fw.h:12
USHORT Day
Definition: fw.h:13
USHORT Minute
Definition: fw.h:15
USHORT Hour
Definition: fw.h:14
USHORT Second
Definition: fw.h:16
USHORT Year
Definition: fw.h:11
ULONG_PTR SectionId
Definition: oslist.h:26
@ INIFILE
Definition: tnconfig.cpp:129
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
char CHAR
Definition: xmlstorage.h:175