Reserve space for The Terminator
[reactos.git] / reactos / boot / freeldr / freeldr / inifile / inifile.c
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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21 #include "ini.h"
22 #include <ui.h>
23 #include <rtl.h>
24 #include <debug.h>
25 #include <mm.h>
26
27 BOOL IniOpenSection(PCHAR SectionName, ULONG* SectionId)
28 {
29 PINI_SECTION Section;
30
31 DbgPrint((DPRINT_INIFILE, "IniOpenSection() SectionName = %s\n", SectionName));
32
33 if (!IniFileSectionListHead)
34 return FALSE;
35
36 // Loop through each section and find the one they want
37 Section = (PINI_SECTION)RtlListGetHead((PLIST_ITEM)IniFileSectionListHead);
38 while (Section != NULL)
39 {
40 // Compare against the section name
41 if (stricmp(SectionName, Section->SectionName) == 0)
42 {
43 // We found it
44 *SectionId = (ULONG)Section;
45 DbgPrint((DPRINT_INIFILE, "IniOpenSection() Found it! SectionId = 0x%x\n", SectionId));
46 return TRUE;
47 }
48
49 // Get the next section in the list
50 Section = (PINI_SECTION)RtlListGetNext((PLIST_ITEM)Section);
51 }
52
53 DbgPrint((DPRINT_INIFILE, "IniOpenSection() Section not found.\n"));
54
55 return FALSE;
56 }
57
58 ULONG IniGetNumSectionItems(ULONG SectionId)
59 {
60 PINI_SECTION Section = (PINI_SECTION)SectionId;
61
62 DbgPrint((DPRINT_INIFILE, "IniGetNumSectionItems() SectionId = 0x%x\n", SectionId));
63 DbgPrint((DPRINT_INIFILE, "IniGetNumSectionItems() Item count = %d\n", Section->SectionItemCount));
64
65 return Section->SectionItemCount;
66 }
67
68 ULONG IniGetSectionSettingNameSize(ULONG SectionId, ULONG SettingIndex)
69 {
70 PINI_SECTION Section = (PINI_SECTION)SectionId;
71
72 // Return the size of the string plus 1 for the null-terminator
73 return (strlen(Section->SectionItemList[SettingIndex].ItemName) + 1);
74 }
75
76 ULONG IniGetSectionSettingValueSize(ULONG SectionId, ULONG SettingIndex)
77 {
78 PINI_SECTION Section = (PINI_SECTION)SectionId;
79
80 // Return the size of the string plus 1 for the null-terminator
81 return (strlen(Section->SectionItemList[SettingIndex].ItemValue) + 1);
82 }
83
84 BOOL IniReadSettingByNumber(ULONG SectionId, ULONG SettingNumber, PCHAR SettingName, ULONG NameSize, PCHAR SettingValue, ULONG ValueSize)
85 {
86 PINI_SECTION Section = (PINI_SECTION)SectionId;
87 PINI_SECTION_ITEM SectionItem;
88 #ifdef DEBUG
89 ULONG RealSettingNumber = SettingNumber;
90 #endif
91 DbgPrint((DPRINT_INIFILE, ".001 NameSize = %d ValueSize = %d\n", NameSize, ValueSize));
92
93 DbgPrint((DPRINT_INIFILE, "IniReadSettingByNumber() SectionId = 0x%x\n", SectionId));
94
95 // Loop through each section item and find the one they want
96 DbgPrint((DPRINT_INIFILE, ".01 NameSize = %d ValueSize = %d\n", NameSize, ValueSize));
97 SectionItem = (PINI_SECTION_ITEM)RtlListGetHead((PLIST_ITEM)Section->SectionItemList);
98 while (SectionItem != NULL)
99 {
100 DbgPrint((DPRINT_INIFILE, ".1 NameSize = %d ValueSize = %d\n", NameSize, ValueSize));
101 // Check to see if this is the setting they want
102 if (SettingNumber == 0)
103 {
104 DbgPrint((DPRINT_INIFILE, "IniReadSettingByNumber() Setting number %d found.\n", RealSettingNumber));
105 DbgPrint((DPRINT_INIFILE, "IniReadSettingByNumber() Setting name = %s\n", SectionItem->ItemName));
106 DbgPrint((DPRINT_INIFILE, "IniReadSettingByNumber() Setting value = %s\n", SectionItem->ItemValue));
107
108 DbgPrint((DPRINT_INIFILE, "1 NameSize = %d ValueSize = %d\n", NameSize, ValueSize));
109 RtlZeroMemory(SettingName, NameSize);
110 RtlZeroMemory(SettingValue, ValueSize);
111 DbgPrint((DPRINT_INIFILE, "2 NameSize = %d ValueSize = %d\n", NameSize, ValueSize));
112 strncpy(SettingName, SectionItem->ItemName, NameSize);
113 DbgPrint((DPRINT_INIFILE, "3 NameSize = %d ValueSize = %d\n", NameSize, ValueSize));
114 strncpy(SettingValue, SectionItem->ItemValue, ValueSize);
115 DbgPrint((DPRINT_INIFILE, "4 NameSize = %d ValueSize = %d\n", NameSize, ValueSize));
116 DbgDumpBuffer(DPRINT_INIFILE, SettingName, NameSize);
117 DbgDumpBuffer(DPRINT_INIFILE, SettingValue, ValueSize);
118
119 return TRUE;
120 }
121
122 // Nope, keep going
123 SettingNumber--;
124
125 // Get the next section item in the list
126 SectionItem = (PINI_SECTION_ITEM)RtlListGetNext((PLIST_ITEM)SectionItem);
127 }
128
129 DbgPrint((DPRINT_INIFILE, "IniReadSettingByNumber() Setting number %d not found.\n", RealSettingNumber));
130
131 return FALSE;
132 }
133
134 BOOL IniReadSettingByName(ULONG SectionId, PCHAR SettingName, PCHAR Buffer, ULONG BufferSize)
135 {
136 PINI_SECTION Section = (PINI_SECTION)SectionId;
137 PINI_SECTION_ITEM SectionItem;
138
139 DbgPrint((DPRINT_INIFILE, "IniReadSettingByName() SectionId = 0x%x\n", SectionId));
140
141 // Loop through each section item and find the one they want
142 SectionItem = (PINI_SECTION_ITEM)RtlListGetHead((PLIST_ITEM)Section->SectionItemList);
143 while (SectionItem != NULL)
144 {
145 // Check to see if this is the setting they want
146 if (stricmp(SettingName, SectionItem->ItemName) == 0)
147 {
148 DbgPrint((DPRINT_INIFILE, "IniReadSettingByName() Setting \'%s\' found.\n", SettingName));
149 DbgPrint((DPRINT_INIFILE, "IniReadSettingByName() Setting value = %s\n", SectionItem->ItemValue));
150
151 RtlZeroMemory(Buffer, BufferSize);
152 strncpy(Buffer, SectionItem->ItemValue, BufferSize);
153
154 return TRUE;
155 }
156
157 // Get the next section item in the list
158 SectionItem = (PINI_SECTION_ITEM)RtlListGetNext((PLIST_ITEM)SectionItem);
159 }
160
161 DbgPrint((DPRINT_INIFILE, "IniReadSettingByName() Setting \'%s\' not found.\n", SettingName));
162
163 return FALSE;
164 }
165
166 BOOL IniAddSection(PCHAR SectionName, ULONG* SectionId)
167 {
168 PINI_SECTION Section;
169
170 // Allocate a new section structure
171 Section = MmAllocateMemory(sizeof(INI_SECTION));
172 if (!Section)
173 {
174 return FALSE;
175 }
176
177 RtlZeroMemory(Section, sizeof(INI_SECTION));
178
179 // Allocate the section name buffer
180 Section->SectionName = MmAllocateMemory(strlen(SectionName));
181 if (!Section->SectionName)
182 {
183 MmFreeMemory(Section);
184 return FALSE;
185 }
186
187 // Get the section name
188 strcpy(Section->SectionName, SectionName);
189
190 // Add it to the section list head
191 IniFileSectionCount++;
192 if (IniFileSectionListHead == NULL)
193 {
194 IniFileSectionListHead = Section;
195 }
196 else
197 {
198 RtlListInsertTail((PLIST_ITEM)IniFileSectionListHead, (PLIST_ITEM)Section);
199 }
200
201 *SectionId = (ULONG)Section;
202
203 return TRUE;
204 }
205
206 BOOL IniAddSettingValueToSection(ULONG SectionId, PCHAR SettingName, PCHAR SettingValue)
207 {
208 PINI_SECTION Section = (PINI_SECTION)SectionId;
209 PINI_SECTION_ITEM SectionItem;
210
211 // Allocate a new item structure
212 SectionItem = MmAllocateMemory(sizeof(INI_SECTION_ITEM));
213 if (!SectionItem)
214 {
215 return FALSE;
216 }
217
218 RtlZeroMemory(SectionItem, sizeof(INI_SECTION_ITEM));
219
220 // Allocate the setting name buffer
221 SectionItem->ItemName = MmAllocateMemory(strlen(SettingName) + 1);
222 if (!SectionItem->ItemName)
223 {
224 MmFreeMemory(SectionItem);
225 return FALSE;
226 }
227
228 // Allocate the setting value buffer
229 SectionItem->ItemValue = MmAllocateMemory(strlen(SettingValue) + 1);
230 if (!SectionItem->ItemValue)
231 {
232 MmFreeMemory(SectionItem->ItemName);
233 MmFreeMemory(SectionItem);
234 return FALSE;
235 }
236
237 strcpy(SectionItem->ItemName, SettingName);
238 strcpy(SectionItem->ItemValue, SettingValue);
239
240 // Add it to the current section
241 Section->SectionItemCount++;
242 if (Section->SectionItemList == NULL)
243 {
244 Section->SectionItemList = SectionItem;
245 }
246 else
247 {
248 RtlListInsertTail((PLIST_ITEM)Section->SectionItemList, (PLIST_ITEM)SectionItem);
249 }
250
251 return TRUE;
252 }