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 #include <freeldr.h>
21
22 #include <debug.h>
23 DBG_DEFAULT_CHANNEL(INIFILE);
24
IniOpenSection(PCSTR SectionName,ULONG_PTR * SectionId)25 BOOLEAN IniOpenSection(PCSTR SectionName, ULONG_PTR* SectionId)
26 {
27 PLIST_ENTRY Entry;
28 PINI_SECTION Section;
29
30 TRACE("IniOpenSection() SectionName = %s\n", SectionName);
31
32 // Loop through each section and find the one we want
33 for (Entry = IniFileSectionListHead.Flink;
34 Entry != &IniFileSectionListHead;
35 Entry = Entry->Flink)
36 {
37 Section = CONTAINING_RECORD(Entry, INI_SECTION, ListEntry);
38
39 // Compare against the section name
40 if (_stricmp(SectionName, Section->SectionName) == 0)
41 {
42 // We found it
43 if (SectionId)
44 *SectionId = (ULONG_PTR)Section;
45 TRACE("IniOpenSection() Found it! SectionId = 0x%x\n", SectionId);
46 return TRUE;
47 }
48 }
49
50 TRACE("IniOpenSection() Section not found.\n");
51
52 return FALSE;
53 }
54
IniGetNumSectionItems(ULONG_PTR SectionId)55 ULONG IniGetNumSectionItems(ULONG_PTR SectionId)
56 {
57 PINI_SECTION Section = (PINI_SECTION)SectionId;
58
59 TRACE("IniGetNumSectionItems() SectionId = 0x%x\n", SectionId);
60 TRACE("IniGetNumSectionItems() Item count = %d\n", Section->SectionItemCount);
61
62 return Section->SectionItemCount;
63 }
64
IniGetSettingByNumber(ULONG_PTR SectionId,ULONG SettingNumber)65 PINI_SECTION_ITEM IniGetSettingByNumber(ULONG_PTR SectionId, ULONG SettingNumber)
66 {
67 PINI_SECTION Section = (PINI_SECTION)SectionId;
68 PLIST_ENTRY Entry;
69 PINI_SECTION_ITEM SectionItem;
70
71 // Loop through each section item and find the one we want
72 for (Entry = Section->SectionItemList.Flink;
73 Entry != &Section->SectionItemList;
74 Entry = Entry->Flink)
75 {
76 SectionItem = CONTAINING_RECORD(Entry, INI_SECTION_ITEM, ListEntry);
77
78 // Check to see if this is the setting we want
79 if (SettingNumber == 0)
80 {
81 return SectionItem;
82 }
83
84 // Nope, keep going
85 SettingNumber--;
86 }
87 return NULL;
88 }
89
IniGetSectionSettingNameSize(ULONG_PTR SectionId,ULONG SettingIndex)90 ULONG IniGetSectionSettingNameSize(ULONG_PTR SectionId, ULONG SettingIndex)
91 {
92 PINI_SECTION_ITEM SectionItem;
93
94 // Retrieve requested setting
95 SectionItem = IniGetSettingByNumber(SectionId, SettingIndex);
96 if (!SectionItem)
97 return 0;
98
99 // Return the size of the string plus 1 for the null-terminator
100 return (ULONG)(strlen(SectionItem->ItemName) + 1);
101 }
102
IniGetSectionSettingValueSize(ULONG_PTR SectionId,ULONG SettingIndex)103 ULONG IniGetSectionSettingValueSize(ULONG_PTR SectionId, ULONG SettingIndex)
104 {
105 PINI_SECTION_ITEM SectionItem;
106
107 // Retrieve requested setting
108 SectionItem = IniGetSettingByNumber(SectionId, SettingIndex);
109 if (!SectionItem)
110 return 0;
111
112 // Return the size of the string plus 1 for the null-terminator
113 return (ULONG)(strlen(SectionItem->ItemValue) + 1);
114 }
115
IniReadSettingByNumber(ULONG_PTR SectionId,ULONG SettingNumber,PCHAR SettingName,ULONG NameSize,PCHAR SettingValue,ULONG ValueSize)116 BOOLEAN IniReadSettingByNumber(ULONG_PTR SectionId, ULONG SettingNumber, PCHAR SettingName, ULONG NameSize, PCHAR SettingValue, ULONG ValueSize)
117 {
118 PINI_SECTION_ITEM SectionItem;
119 TRACE(".001 NameSize = %d ValueSize = %d\n", NameSize, ValueSize);
120
121 TRACE("IniReadSettingByNumber() SectionId = 0x%x\n", SectionId);
122
123 // Retrieve requested setting
124 SectionItem = IniGetSettingByNumber(SectionId, SettingNumber);
125 if (!SectionItem)
126 {
127 TRACE("IniReadSettingByNumber() Setting number %d not found.\n", SettingNumber);
128 return FALSE;
129 }
130
131 TRACE("IniReadSettingByNumber() Setting number %d found.\n", SettingNumber);
132 TRACE("IniReadSettingByNumber() Setting name = %s\n", SectionItem->ItemName);
133 TRACE("IniReadSettingByNumber() Setting value = %s\n", SectionItem->ItemValue);
134
135 TRACE("1 NameSize = %d ValueSize = %d\n", NameSize, ValueSize);
136 TRACE("2 NameSize = %d ValueSize = %d\n", NameSize, ValueSize);
137 strncpy(SettingName, SectionItem->ItemName, NameSize - 1);
138 SettingName[NameSize - 1] = '\0';
139 TRACE("3 NameSize = %d ValueSize = %d\n", NameSize, ValueSize);
140 strncpy(SettingValue, SectionItem->ItemValue, ValueSize - 1);
141 SettingValue[ValueSize - 1] = '\0';
142 TRACE("4 NameSize = %d ValueSize = %d\n", NameSize, ValueSize);
143 DbgDumpBuffer(DPRINT_INIFILE, SettingName, NameSize);
144 DbgDumpBuffer(DPRINT_INIFILE, SettingValue, ValueSize);
145
146 return TRUE;
147 }
148
IniReadSettingByName(ULONG_PTR SectionId,PCSTR SettingName,PCHAR Buffer,ULONG BufferSize)149 BOOLEAN IniReadSettingByName(ULONG_PTR SectionId, PCSTR SettingName, PCHAR Buffer, ULONG BufferSize)
150 {
151 PINI_SECTION Section = (PINI_SECTION)SectionId;
152 PLIST_ENTRY Entry;
153 PINI_SECTION_ITEM SectionItem;
154
155 TRACE("IniReadSettingByName() SectionId = 0x%x\n", SectionId);
156
157 // Loop through each section item and find the one we want
158 for (Entry = Section->SectionItemList.Flink;
159 Entry != &Section->SectionItemList;
160 Entry = Entry->Flink)
161 {
162 SectionItem = CONTAINING_RECORD(Entry, INI_SECTION_ITEM, ListEntry);
163
164 // Check to see if this is the setting we want
165 if (_stricmp(SettingName, SectionItem->ItemName) == 0)
166 {
167 TRACE("IniReadSettingByName() Setting \'%s\' found.\n", SettingName);
168 TRACE("IniReadSettingByName() Setting value = %s\n", SectionItem->ItemValue);
169
170 strncpy(Buffer, SectionItem->ItemValue, BufferSize - 1);
171 Buffer[BufferSize - 1] = '\0';
172
173 return TRUE;
174 }
175 }
176
177 WARN("IniReadSettingByName() Setting \'%s\' not found.\n", SettingName);
178
179 return FALSE;
180 }
181
IniAddSection(PCSTR SectionName,ULONG_PTR * SectionId)182 BOOLEAN IniAddSection(PCSTR SectionName, ULONG_PTR* SectionId)
183 {
184 PINI_SECTION Section;
185
186 // Allocate a new section structure
187 Section = FrLdrTempAlloc(sizeof(INI_SECTION), TAG_INI_SECTION);
188 if (!Section)
189 {
190 return FALSE;
191 }
192
193 RtlZeroMemory(Section, sizeof(INI_SECTION));
194
195 // Allocate the section name buffer
196 Section->SectionName = FrLdrTempAlloc(strlen(SectionName) + sizeof(CHAR), TAG_INI_NAME);
197 if (!Section->SectionName)
198 {
199 FrLdrTempFree(Section, TAG_INI_SECTION);
200 return FALSE;
201 }
202
203 // Get the section name
204 strcpy(Section->SectionName, SectionName);
205 InitializeListHead(&Section->SectionItemList);
206
207 // Add it to the section list head
208 IniFileSectionCount++;
209 InsertHeadList(&IniFileSectionListHead, &Section->ListEntry);
210
211 *SectionId = (ULONG_PTR)Section;
212
213 return TRUE;
214 }
215
IniFreeSection(PINI_SECTION Section)216 VOID IniFreeSection(PINI_SECTION Section)
217 {
218 PLIST_ENTRY ListEntry;
219 PINI_SECTION_ITEM SectionItem;
220
221 // Loop while there are section items
222 while (!IsListEmpty(&Section->SectionItemList))
223 {
224 // Remove the section item
225 ListEntry = RemoveHeadList(&Section->SectionItemList);
226 SectionItem = CONTAINING_RECORD(ListEntry, INI_SECTION_ITEM, ListEntry);
227
228 // Free it
229 FrLdrTempFree(SectionItem->ItemName, TAG_INI_NAME);
230 FrLdrTempFree(SectionItem->ItemValue, TAG_INI_VALUE);
231 FrLdrTempFree(SectionItem, TAG_INI_SECTION_ITEM);
232 }
233
234 FrLdrTempFree(Section->SectionName, TAG_INI_NAME);
235 FrLdrTempFree(Section, TAG_INI_SECTION);
236 }
237
IniCleanup(VOID)238 VOID IniCleanup(VOID)
239 {
240 PLIST_ENTRY ListEntry;
241 PINI_SECTION Section;
242
243 // Loop while there are sections
244 while (!IsListEmpty(&IniFileSectionListHead))
245 {
246 // Remove the section
247 ListEntry = RemoveHeadList(&IniFileSectionListHead);
248 Section = CONTAINING_RECORD(ListEntry, INI_SECTION, ListEntry);
249
250 // Free it
251 IniFreeSection(Section);
252 }
253 }
254
IniAddSettingValueToSection(ULONG_PTR SectionId,PCSTR SettingName,PCSTR SettingValue)255 BOOLEAN IniAddSettingValueToSection(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue)
256 {
257 PINI_SECTION Section = (PINI_SECTION)SectionId;
258 PINI_SECTION_ITEM SectionItem;
259
260 // Allocate a new item structure
261 SectionItem = FrLdrTempAlloc(sizeof(INI_SECTION_ITEM), TAG_INI_SECTION_ITEM);
262 if (!SectionItem)
263 {
264 return FALSE;
265 }
266
267 RtlZeroMemory(SectionItem, sizeof(INI_SECTION_ITEM));
268
269 // Allocate the setting name buffer
270 SectionItem->ItemName = FrLdrTempAlloc(strlen(SettingName) + 1, TAG_INI_NAME);
271 if (!SectionItem->ItemName)
272 {
273 FrLdrTempFree(SectionItem, TAG_INI_SECTION_ITEM);
274 return FALSE;
275 }
276
277 // Allocate the setting value buffer
278 SectionItem->ItemValue = FrLdrTempAlloc(strlen(SettingValue) + 1, TAG_INI_VALUE);
279 if (!SectionItem->ItemValue)
280 {
281 FrLdrTempFree(SectionItem->ItemName, TAG_INI_NAME);
282 FrLdrTempFree(SectionItem, TAG_INI_SECTION_ITEM);
283 return FALSE;
284 }
285
286 strcpy(SectionItem->ItemName, SettingName);
287 strcpy(SectionItem->ItemValue, SettingValue);
288
289 // Add it to the current section
290 Section->SectionItemCount++;
291 InsertTailList(&Section->SectionItemList, &SectionItem->ListEntry);
292
293 return TRUE;
294 }
295
IniModifySettingValue(ULONG_PTR SectionId,PCSTR SettingName,PCSTR SettingValue)296 BOOLEAN IniModifySettingValue(ULONG_PTR SectionId, PCSTR SettingName, PCSTR SettingValue)
297 {
298 PINI_SECTION Section = (PINI_SECTION)SectionId;
299 PLIST_ENTRY Entry;
300 PINI_SECTION_ITEM SectionItem;
301 PCHAR NewItemValue;
302
303 // Loop through each section item and find the one we want
304 for (Entry = Section->SectionItemList.Flink;
305 Entry != &Section->SectionItemList;
306 Entry = Entry->Flink)
307 {
308 SectionItem = CONTAINING_RECORD(Entry, INI_SECTION_ITEM, ListEntry);
309
310 // Check to see if this is the setting we want
311 if (_stricmp(SectionItem->ItemName, SettingName) == 0)
312 {
313 break;
314 }
315 // Nope, keep going
316 }
317 // If the section item does not exist, create it
318 if (Entry == &Section->SectionItemList)
319 {
320 return IniAddSettingValueToSection(SectionId, SettingName, SettingValue);
321 }
322
323 // Reallocate the new setting value buffer
324 NewItemValue = FrLdrTempAlloc(strlen(SettingValue) + 1, TAG_INI_VALUE);
325 if (!NewItemValue)
326 {
327 // We failed, bail out
328 return FALSE;
329 }
330 FrLdrTempFree(SectionItem->ItemValue, TAG_INI_VALUE);
331 SectionItem->ItemValue = NewItemValue;
332
333 strcpy(SectionItem->ItemValue, SettingValue);
334
335 return TRUE;
336 }
337