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