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