OLD | NEW |
| (Empty) |
1 #include "PluginStdAfx.h" | |
2 | |
3 #include "PluginIniFileW.h" | |
4 #include "PluginChecksum.h" | |
5 | |
6 #if (defined PRODUCT_ADBLOCKPLUS) | |
7 #include "PluginClient.h" | |
8 #endif | |
9 | |
10 | |
11 CPluginIniFileW::CPluginIniFileW(const CString& filename, bool hasChecksum) : | |
12 m_isValidChecksum(false), m_isDirty(false), m_filename(filename), m_hasChecksu
m(hasChecksum), m_lastError(0) | |
13 { | |
14 m_checksum = std::auto_ptr<CPluginChecksum>(new CPluginChecksum()); | |
15 } | |
16 | |
17 void CPluginIniFileW::SetInitialChecksumString(const CString& str) | |
18 { | |
19 m_checksumInit = str; | |
20 } | |
21 | |
22 CString CPluginIniFileW::GetFilePath() const | |
23 { | |
24 return m_filename; | |
25 } | |
26 | |
27 | |
28 void CPluginIniFileW::Clear() | |
29 { | |
30 m_data.clear(); | |
31 m_sectionNames.clear(); | |
32 m_checksumInit.Empty(); | |
33 m_checksum->Clear(); | |
34 } | |
35 | |
36 bool CPluginIniFileW::Exists() | |
37 { | |
38 bool isExisting = false; | |
39 | |
40 HANDLE hFile = ::CreateFile(m_filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL); | |
41 if (hFile != INVALID_HANDLE_VALUE) | |
42 { | |
43 isExisting = true; | |
44 ::CloseHandle(hFile); | |
45 } | |
46 | |
47 return isExisting; | |
48 } | |
49 | |
50 bool CPluginIniFileW::ReadString(const CStringW& memFile) | |
51 { | |
52 bool isOk = true; | |
53 | |
54 DWORD checksumValue = 0; | |
55 | |
56 m_checksum->Clear(); | |
57 m_checksum->Add(m_checksumInit); | |
58 | |
59 CPluginIniFileW::TSectionData sectionData; | |
60 CStringW sectionName; | |
61 | |
62 bool bHasSection = false; | |
63 | |
64 // Parse file string | |
65 int pos = 0; | |
66 CStringW line = memFile.Tokenize(L"\r\n", pos); | |
67 | |
68 // Remove initial unicode-chars | |
69 if (line.GetAt(0) == 0xfeff) | |
70 { | |
71 line = line.Right(line.GetLength() - 1); | |
72 } | |
73 else | |
74 { | |
75 } | |
76 | |
77 while (pos >= 0) | |
78 { | |
79 line.Trim(); | |
80 | |
81 if (!line.IsEmpty()) | |
82 { | |
83 // Comment | |
84 if (line.GetAt(0) == L'#') | |
85 { | |
86 } | |
87 // Section start | |
88 else if (line.GetAt(0) == L'[' && line.GetAt(line.GetLength() - 1) == L']'
) | |
89 { | |
90 if (bHasSection) | |
91 { | |
92 m_data[sectionName] = sectionData; | |
93 sectionData.clear(); | |
94 } | |
95 | |
96 // Add section name to list | |
97 sectionName = line.Mid(1, line.GetLength() - 2); | |
98 | |
99 DEBUG_INI("Ini::Read section:" + sectionName) | |
100 | |
101 // Add to checksum | |
102 if (m_hasChecksum && sectionName != "Checksum") | |
103 { | |
104 m_checksum->Add(sectionName); | |
105 } | |
106 | |
107 m_sectionNames.insert(sectionName); | |
108 | |
109 bHasSection = true; | |
110 } | |
111 // Section data | |
112 else if (bHasSection) | |
113 { | |
114 int pos = 0; | |
115 if ((pos = line.Find(L'=')) > 0) | |
116 { | |
117 CStringW key = line.Left(pos).Trim(); | |
118 CStringW value = line.Right(line.GetLength() - pos - 1).Trim(); | |
119 | |
120 if (!key.IsEmpty()) | |
121 { | |
122 sectionData[key] = value; | |
123 } | |
124 | |
125 if (m_hasChecksum && sectionName != "Checksum") | |
126 { | |
127 m_checksum->Add(key); | |
128 m_checksum->Add(value); | |
129 } | |
130 } | |
131 else if (m_hasChecksum && sectionName == "Checksum") | |
132 { | |
133 checksumValue = (DWORD)_wtol(line); | |
134 } | |
135 } | |
136 else | |
137 { | |
138 DEBUG_INI("Ini::Read ignoring line::" + CString(line)) | |
139 } | |
140 } | |
141 | |
142 line = memFile.Tokenize(L"\r\n", pos); | |
143 } | |
144 | |
145 // Add final section | |
146 if (bHasSection) | |
147 { | |
148 m_data[sectionName] = sectionData; | |
149 } | |
150 | |
151 m_isValidChecksum = (checksumValue == m_checksum->Get()); | |
152 | |
153 return isOk; | |
154 } | |
155 | |
156 | |
157 bool CPluginIniFileW::Read() | |
158 { | |
159 bool isRead = true; | |
160 | |
161 m_lastError = 0; | |
162 | |
163 // Read file | |
164 HANDLE hFile = ::CreateFile(m_filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL); | |
165 if (hFile == INVALID_HANDLE_VALUE) | |
166 { | |
167 m_lastError = ::GetLastError(); | |
168 isRead = false; | |
169 } | |
170 else | |
171 { | |
172 DEBUG_INI("Ini::Reading file " + m_filename); | |
173 | |
174 // Read file | |
175 WCHAR buffer[1026]; | |
176 LPVOID pBuffer = buffer; | |
177 LPBYTE pByteBuffer = (LPBYTE)pBuffer; | |
178 DWORD dwBytesRead = 0; | |
179 CStringW fileContent; | |
180 BOOL bRead = TRUE; | |
181 while ((bRead = ::ReadFile(hFile, pBuffer, 1024, &dwBytesRead, NULL)) == TRU
E && dwBytesRead > 0) | |
182 { | |
183 pByteBuffer[dwBytesRead] = 0; | |
184 pByteBuffer[dwBytesRead+1] = 0; | |
185 | |
186 fileContent += buffer; | |
187 } | |
188 | |
189 // Read error | |
190 if (!bRead) | |
191 { | |
192 m_lastError = ::GetLastError(); | |
193 isRead = false; | |
194 } | |
195 | |
196 // Close file | |
197 ::CloseHandle(hFile); | |
198 | |
199 // Parse file | |
200 if (isRead) | |
201 { | |
202 isRead = ReadString(fileContent); | |
203 } | |
204 } | |
205 | |
206 return isRead; | |
207 } | |
208 | |
209 | |
210 bool CPluginIniFileW::Write() | |
211 { | |
212 bool isWritten = true; | |
213 | |
214 m_lastError = 0; | |
215 | |
216 DEBUG_INI("Ini::Write " + m_filename); | |
217 | |
218 // Save file | |
219 if (m_isDirty) | |
220 { | |
221 DEBUG_INI("Ini::Writing file " + m_filename); | |
222 | |
223 m_checksum->Clear(); | |
224 | |
225 // Create file | |
226 HANDLE hFile = ::CreateFile(m_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAY
S, FILE_ATTRIBUTE_NORMAL, NULL); | |
227 if (hFile == INVALID_HANDLE_VALUE) | |
228 { | |
229 m_lastError = ::GetLastError(); | |
230 isWritten = false; | |
231 } | |
232 else | |
233 { | |
234 CStringW line; | |
235 | |
236 // Write warning | |
237 if (m_hasChecksum) | |
238 { | |
239 line += "# Please do not edit this file!\r\n\r\n";; | |
240 } | |
241 | |
242 for (CPluginIniFileW::TData::iterator it = m_data.begin(); it != m_data.en
d(); ++it) | |
243 { | |
244 line += L"[" + it->first + L"]\r\n"; | |
245 | |
246 m_checksum->Add(it->first); | |
247 | |
248 for (CPluginIniFileW::TSectionData::iterator itValues = it->second.begin
(); itValues != it->second.end(); ++itValues) | |
249 { | |
250 line += itValues->first + L"=" + itValues->second + L"\r\n"; | |
251 | |
252 m_checksum->Add(itValues->first); | |
253 m_checksum->Add(itValues->second); | |
254 } | |
255 | |
256 line += L"\r\n"; | |
257 } | |
258 | |
259 // Add checksum | |
260 if (m_hasChecksum) | |
261 { | |
262 line += L"[Checksum]\r\n"; | |
263 | |
264 CStringW checksum; | |
265 checksum.Format(L"%lu\r\n", m_checksum->Get()); | |
266 | |
267 line += checksum; | |
268 } | |
269 | |
270 // Write file | |
271 DWORD dwBytesWritten = 0; | |
272 if (::WriteFile(hFile, line.GetBuffer(), line.GetLength()*2, &dwBytesWritt
en, NULL) && dwBytesWritten == line.GetLength()*2) | |
273 { | |
274 m_isDirty = false; | |
275 | |
276 Clear(); | |
277 } | |
278 else | |
279 { | |
280 m_lastError = ::GetLastError(); | |
281 isWritten = false; | |
282 } | |
283 | |
284 // Close file | |
285 ::CloseHandle(hFile); | |
286 } | |
287 } | |
288 | |
289 return isWritten; | |
290 } | |
291 | |
292 | |
293 // Used to retrieve a value give the section and key | |
294 CStringW CPluginIniFileW::GetValue(const CStringW& section, const CStringW& key)
const | |
295 { | |
296 CStringW value; | |
297 | |
298 TSectionData sectionData = GetSectionData(section); | |
299 | |
300 TSectionData::iterator it = sectionData.find(key); | |
301 if (it != sectionData.end()) | |
302 { | |
303 value = it->second; | |
304 } | |
305 | |
306 return value; | |
307 } | |
308 | |
309 | |
310 // Used to add or set a key value pair to a section | |
311 bool CPluginIniFileW::SetValue(const CStringW& section, const CStringW& key, con
st CStringW& value) | |
312 { | |
313 bool isSet = false; | |
314 | |
315 CPluginIniFileW::TData::iterator it = m_data.find(section); | |
316 if (it != m_data.end()) | |
317 { | |
318 CPluginIniFileW::TSectionData::iterator itValue = it->second.find(key); | |
319 if (itValue != it->second.end()) | |
320 { | |
321 if (itValue->second != value) | |
322 { | |
323 m_isDirty = true; | |
324 } | |
325 } | |
326 | |
327 it->second[key] = value; | |
328 isSet = true; | |
329 } | |
330 | |
331 return isSet; | |
332 } | |
333 | |
334 | |
335 // Used to add or set a key value pair to a section | |
336 bool CPluginIniFileW::SetValue(const CStringW& section, const CStringW& key, int
value) | |
337 { | |
338 CStringW valueStr; | |
339 valueStr.Format(L"%d", value); | |
340 | |
341 return SetValue(section, key, valueStr); | |
342 } | |
343 | |
344 | |
345 // Used to find out if a given section exists | |
346 bool CPluginIniFileW::HasSection(const CStringW& section) const | |
347 { | |
348 return m_sectionNames.find(section) != m_sectionNames.end(); | |
349 } | |
350 | |
351 | |
352 // Used to find out if a given key exists | |
353 bool CPluginIniFileW::HasKey(const CStringW& section, const CStringW& key) const | |
354 { | |
355 return !GetValue(section, key).IsEmpty(); | |
356 } | |
357 | |
358 | |
359 void CPluginIniFileW::UpdateSection(const CStringW& section, const CPluginIniFil
eW::TSectionData& data) | |
360 { | |
361 m_data[section] = data; | |
362 m_isDirty = true; | |
363 } | |
364 | |
365 | |
366 // Used to retrieve all of the section names in the ini file | |
367 const CPluginIniFileW::TSectionNames& CPluginIniFileW::GetSectionNames() const | |
368 { | |
369 return m_sectionNames; | |
370 } | |
371 | |
372 | |
373 // Used to retrieve all key/value pairs of a given section. | |
374 CPluginIniFileW::TSectionData CPluginIniFileW::GetSectionData(const CStringW& se
ction) const | |
375 { | |
376 CPluginIniFileW::TSectionData sectionData; | |
377 | |
378 CPluginIniFileW::TData::const_iterator it = m_data.find(section); | |
379 if (it != m_data.end()) | |
380 { | |
381 sectionData = it->second; | |
382 } | |
383 | |
384 return sectionData; | |
385 } | |
386 | |
387 bool CPluginIniFileW::IsValidChecksum() const | |
388 { | |
389 return m_isValidChecksum && m_hasChecksum || !m_hasChecksum; | |
390 } | |
391 | |
392 unsigned int CPluginIniFileW::GetLastError() const | |
393 { | |
394 return m_lastError; | |
395 } | |
OLD | NEW |