aboutsummaryrefslogtreecommitdiff
path: root/CPP/Windows/Registry.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CPP/Windows/Registry.cpp406
1 files changed, 406 insertions, 0 deletions
diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp
new file mode 100644
index 0000000..b20157d
--- /dev/null
+++ b/CPP/Windows/Registry.cpp
@@ -0,0 +1,406 @@
1// Windows/Registry.cpp
2
3#include "StdAfx.h"
4
5#include <wchar.h>
6// #include <stdio.h>
7
8#ifndef _UNICODE
9#include "../Common/StringConvert.h"
10#endif
11#include "Registry.h"
12
13#ifndef _UNICODE
14extern bool g_IsNT;
15#endif
16
17namespace NWindows {
18namespace NRegistry {
19
20#define MYASSERT(expr) // _ASSERTE(expr)
21#define MY_ASSUME(expr)
22
23/*
24static void Error()
25{
26 #ifdef _CONSOLE
27 printf("\nregistry error\n");
28 #else
29 MessageBoxW(0, L"registry error", L"", 0);
30 // exit(1);
31 #endif
32}
33
34#define MY_ASSUME(expr) { if (!(expr)) Error(); }
35*/
36
37LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
38 LPTSTR keyClass, DWORD options, REGSAM accessMask,
39 LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition) throw()
40{
41 MY_ASSUME(parentKey != NULL);
42 DWORD dispositionReal;
43 HKEY key = NULL;
44 LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,
45 options, accessMask, securityAttributes, &key, &dispositionReal);
46 if (disposition != NULL)
47 *disposition = dispositionReal;
48 if (res == ERROR_SUCCESS)
49 {
50 res = Close();
51 _object = key;
52 }
53 return res;
54}
55
56LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask) throw()
57{
58 MY_ASSUME(parentKey != NULL);
59 HKEY key = NULL;
60 LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);
61 if (res == ERROR_SUCCESS)
62 {
63 res = Close();
64 MYASSERT(res == ERROR_SUCCESS);
65 _object = key;
66 }
67 return res;
68}
69
70LONG CKey::Close() throw()
71{
72 LONG res = ERROR_SUCCESS;
73 if (_object != NULL)
74 {
75 res = RegCloseKey(_object);
76 _object = NULL;
77 }
78 return res;
79}
80
81// win95, win98: deletes sunkey and all its subkeys
82// winNT to be deleted must not have subkeys
83LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw()
84{
85 MY_ASSUME(_object != NULL);
86 return RegDeleteKey(_object, subKeyName);
87}
88
89LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw()
90{
91 CKey key;
92 LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
93 if (res != ERROR_SUCCESS)
94 return res;
95 FILETIME fileTime;
96 const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL
97 DWORD size = kBufSize;
98 TCHAR buffer[kBufSize];
99 while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
100 {
101 res = key.RecurseDeleteKey(buffer);
102 if (res != ERROR_SUCCESS)
103 return res;
104 size = kBufSize;
105 }
106 key.Close();
107 return DeleteSubKey(subKeyName);
108}
109
110
111/////////////////////////
112// Value Functions
113
114static inline UInt32 BoolToUINT32(bool value) { return (value ? 1: 0); }
115static inline bool UINT32ToBool(UInt32 value) { return (value != 0); }
116
117
118LONG CKey::DeleteValue(LPCTSTR name) throw()
119{
120 MY_ASSUME(_object != NULL);
121 return ::RegDeleteValue(_object, name);
122}
123
124#ifndef _UNICODE
125LONG CKey::DeleteValue(LPCWSTR name)
126{
127 MY_ASSUME(_object != NULL);
128 if (g_IsNT)
129 return ::RegDeleteValueW(_object, name);
130 return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name));
131}
132#endif
133
134LONG CKey::SetValue(LPCTSTR name, UInt32 value) throw()
135{
136 MY_ASSUME(_object != NULL);
137 return RegSetValueEx(_object, name, 0, REG_DWORD,
138 (const BYTE *)&value, sizeof(UInt32));
139}
140
141LONG CKey::SetValue(LPCTSTR name, bool value) throw()
142{
143 return SetValue(name, BoolToUINT32(value));
144}
145
146LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw()
147{
148 MYASSERT(value != NULL);
149 MY_ASSUME(_object != NULL);
150 return RegSetValueEx(_object, name, 0, REG_SZ,
151 (const BYTE *)value, ((DWORD)lstrlen(value) + 1) * sizeof(TCHAR));
152}
153
154/*
155LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
156{
157 MYASSERT(value != NULL);
158 MY_ASSUME(_object != NULL);
159 return RegSetValueEx(_object, name, NULL, REG_SZ,
160 (const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR));
161}
162*/
163
164#ifndef _UNICODE
165
166LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
167{
168 MYASSERT(value != NULL);
169 MY_ASSUME(_object != NULL);
170 if (g_IsNT)
171 return RegSetValueExW(_object, name, 0, REG_SZ,
172 (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t)));
173 return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name),
174 value == 0 ? 0 : (LPCSTR)GetSystemString(value));
175}
176
177#endif
178
179
180LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) throw()
181{
182 MYASSERT(value != NULL);
183 MY_ASSUME(_object != NULL);
184 return RegSetValueEx(_object, name, 0, REG_BINARY,
185 (const BYTE *)value, size);
186}
187
188LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
189{
190 MYASSERT(value != NULL);
191 CKey key;
192 LONG res = key.Create(parentKey, keyName);
193 if (res == ERROR_SUCCESS)
194 res = key.SetValue(valueName, value);
195 return res;
196}
197
198LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw()
199{
200 MYASSERT(value != NULL);
201 CKey key;
202 LONG res = key.Create(_object, keyName);
203 if (res == ERROR_SUCCESS)
204 res = key.SetValue(valueName, value);
205 return res;
206}
207
208LONG CKey::QueryValue(LPCTSTR name, UInt32 &value) throw()
209{
210 DWORD type = 0;
211 DWORD count = sizeof(DWORD);
212 LONG res = RegQueryValueEx(_object, name, NULL, &type,
213 (LPBYTE)&value, &count);
214 MYASSERT((res != ERROR_SUCCESS) || (type == REG_DWORD));
215 MYASSERT((res != ERROR_SUCCESS) || (count == sizeof(UInt32)));
216 return res;
217}
218
219LONG CKey::QueryValue(LPCTSTR name, bool &value) throw()
220{
221 UInt32 uintValue = BoolToUINT32(value);
222 LONG res = QueryValue(name, uintValue);
223 value = UINT32ToBool(uintValue);
224 return res;
225}
226
227LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value) throw()
228{
229 UInt32 newVal;
230 LONG res = QueryValue(name, newVal);
231 if (res == ERROR_SUCCESS)
232 value = newVal;
233 return res;
234}
235
236LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) throw()
237{
238 bool newVal = false;
239 LONG res = QueryValue(name, newVal);
240 if (res == ERROR_SUCCESS)
241 value = newVal;
242 return res;
243}
244
245LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count) throw()
246{
247 DWORD type = 0;
248 LONG res = RegQueryValueEx(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
249 MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
250 return res;
251}
252
253LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
254{
255 value.Empty();
256 DWORD type = 0;
257 UInt32 curSize = 0;
258 LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, (DWORD *)&curSize);
259 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
260 return res;
261 UInt32 curSize2 = curSize;
262 res = QueryValue(name, value.GetBuf(curSize), curSize2);
263 if (curSize > curSize2)
264 curSize = curSize2;
265 value.ReleaseBuf_CalcLen(curSize / sizeof(TCHAR));
266 return res;
267}
268
269
270#ifndef _UNICODE
271
272LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)
273{
274 DWORD type = 0;
275 LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
276 MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
277 return res;
278}
279
280LONG CKey::QueryValue(LPCWSTR name, UString &value)
281{
282 value.Empty();
283 DWORD type = 0;
284 UInt32 curSize = 0;
285
286 LONG res;
287
288 if (g_IsNT)
289 {
290 res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&curSize);
291 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
292 return res;
293 UInt32 curSize2 = curSize;
294 res = QueryValue(name, value.GetBuf(curSize), curSize2);
295 if (curSize > curSize2)
296 curSize = curSize2;
297 value.ReleaseBuf_CalcLen(curSize / sizeof(wchar_t));
298 }
299 else
300 {
301 AString vTemp;
302 res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);
303 value = GetUnicodeString(vTemp);
304 }
305
306 return res;
307}
308
309#endif
310
311
312LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count) throw()
313{
314 DWORD type = 0;
315 LONG res = RegQueryValueEx(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
316 MYASSERT((res != ERROR_SUCCESS) || (type == REG_BINARY));
317 return res;
318}
319
320
321LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
322{
323 DWORD type = 0;
324 dataSize = 0;
325 LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, (DWORD *)&dataSize);
326 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
327 return res;
328 value.Alloc(dataSize);
329 return QueryValue(name, (BYTE *)value, dataSize);
330}
331
332LONG CKey::EnumKeys(CSysStringVector &keyNames)
333{
334 keyNames.Clear();
335 CSysString keyName;
336 for (DWORD index = 0; ; index++)
337 {
338 const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL
339 FILETIME lastWriteTime;
340 UInt32 nameSize = kBufSize;
341 LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuf(kBufSize),
342 (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime);
343 keyName.ReleaseBuf_CalcLen(kBufSize);
344 if (result == ERROR_NO_MORE_ITEMS)
345 break;
346 if (result != ERROR_SUCCESS)
347 return result;
348 keyNames.Add(keyName);
349 }
350 return ERROR_SUCCESS;
351}
352
353LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
354{
355 size_t numChars = 0;
356
357 unsigned i;
358
359 for (i = 0; i < strings.Size(); i++)
360 numChars += strings[i].Len() + 1;
361
362 CObjArray<wchar_t> buffer(numChars);
363 size_t pos = 0;
364
365 for (i = 0; i < strings.Size(); i++)
366 {
367 const UString &s = strings[i];
368 size_t size = s.Len() + 1;
369 wmemcpy(buffer + pos, s, size);
370 pos += size;
371 }
372 return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t));
373}
374
375LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
376{
377 strings.Clear();
378 CByteBuffer buffer;
379 UInt32 dataSize = 0;
380 LONG res = QueryValue(valueName, buffer, dataSize);
381 if (res != ERROR_SUCCESS)
382 return res;
383 if (dataSize > buffer.Size())
384 return E_FAIL;
385 if (dataSize % sizeof(wchar_t) != 0)
386 return E_FAIL;
387
388 const wchar_t *data = (const wchar_t *)(const void *)(const Byte *)buffer;
389 size_t numChars = dataSize / sizeof(wchar_t);
390 size_t prev = 0;
391 UString s;
392
393 for (size_t i = 0; i < numChars; i++)
394 {
395 if (data[i] == 0)
396 {
397 s = data + prev;
398 strings.Add(s);
399 prev = i + 1;
400 }
401 }
402
403 return res;
404}
405
406}}