1 #include "precomp.h"
2 #include "utils.h"
3 #include "regutils.h"
4
5 LRESULT
RegQueryRegistryKeys(IN HKEY hRootKey,IN LPCWSTR KeyName,IN PQUERY_REGISTRY_KEYS_TABLE QueryTable,IN PVOID Context)6 RegQueryRegistryKeys(IN HKEY hRootKey,
7 IN LPCWSTR KeyName,
8 IN PQUERY_REGISTRY_KEYS_TABLE QueryTable,
9 IN PVOID Context)
10 {
11 HKEY hSubKey = NULL;
12
13 if (RegOpenKeyExW(hRootKey, KeyName, 0, KEY_ENUMERATE_SUB_KEYS, &hSubKey) == ERROR_SUCCESS)
14 {
15 HKEY hEntryKey = NULL;
16
17 LRESULT lError = ERROR_SUCCESS;
18 DWORD dwIndex = 0;
19 WCHAR szValueName[MAX_VALUE_NAME] = L"";
20 DWORD dwValueLength = ARRAYSIZE(szValueName);
21
22 while ( (lError = RegEnumKeyExW(hSubKey, dwIndex, szValueName, &dwValueLength, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS )
23 {
24 if ( (lError == ERROR_SUCCESS) && (RegOpenKeyExW(hSubKey, szValueName, 0, KEY_QUERY_VALUE, &hEntryKey) == ERROR_SUCCESS) )
25 {
26 PQUERY_REGISTRY_KEYS_TABLE pTable = QueryTable;
27 while (pTable && pTable->QueryRoutine)
28 {
29 pTable->QueryRoutine(hRootKey, KeyName, szValueName, hEntryKey, Context, pTable->EntryContext);
30 ++pTable;
31 }
32
33 RegCloseKey(hEntryKey);
34 }
35
36 ++dwIndex;
37 dwValueLength = ARRAYSIZE(szValueName);
38 szValueName[0] = L'\0';
39 }
40
41 RegCloseKey(hSubKey);
42 }
43
44 return ERROR_SUCCESS;
45 }
46
47 //
48 // Idea taken from RtlQueryRegistryValues (see DDK).
49 //
50 LRESULT
RegQueryRegistryValues(IN HKEY hRootKey,IN LPCWSTR KeyName,IN PQUERY_REGISTRY_VALUES_TABLE QueryTable,IN PVOID Context)51 RegQueryRegistryValues(IN HKEY hRootKey,
52 IN LPCWSTR KeyName,
53 IN PQUERY_REGISTRY_VALUES_TABLE QueryTable,
54 IN PVOID Context)
55 {
56 LRESULT res = ERROR_SUCCESS;
57 HKEY hSubKey = NULL;
58
59 if ( (res = RegOpenKeyExW(hRootKey, KeyName, 0, KEY_QUERY_VALUE, &hSubKey)) == ERROR_SUCCESS )
60 {
61 DWORD dwIndex = 0, dwType = 0;
62 WCHAR szValueName[MAX_VALUE_NAME] = L"";
63 LPBYTE lpData = NULL;
64 DWORD dwValueLength = ARRAYSIZE(szValueName), dwDataLength = 0;
65
66 while (RegEnumValueW(hSubKey, dwIndex, szValueName, &dwValueLength, NULL, &dwType, NULL, &dwDataLength) != ERROR_NO_MORE_ITEMS)
67 {
68 ++dwValueLength;
69 lpData = (LPBYTE)MemAlloc(0, dwDataLength);
70
71 if (RegEnumValueW(hSubKey, dwIndex, szValueName, &dwValueLength, NULL, &dwType, lpData, &dwDataLength) == ERROR_SUCCESS)
72 {
73 PQUERY_REGISTRY_VALUES_TABLE pTable = QueryTable;
74 while (pTable && pTable->QueryRoutine)
75 {
76 pTable->QueryRoutine(hRootKey, KeyName, szValueName, dwType, lpData, dwDataLength, Context, pTable->EntryContext);
77 ++pTable;
78 }
79 }
80
81 MemFree(lpData); lpData = NULL;
82
83 ++dwIndex;
84 dwValueLength = ARRAYSIZE(szValueName), dwDataLength = 0;
85 szValueName[0] = L'\0';
86 }
87
88 RegCloseKey(hSubKey);
89 }
90
91 return res;
92 }
93
94 LONG
RegGetDWORDValue(IN HKEY hKey,IN LPCWSTR lpSubKey OPTIONAL,IN LPCWSTR lpValue OPTIONAL,OUT LPDWORD lpData OPTIONAL)95 RegGetDWORDValue(IN HKEY hKey,
96 IN LPCWSTR lpSubKey OPTIONAL,
97 IN LPCWSTR lpValue OPTIONAL,
98 OUT LPDWORD lpData OPTIONAL)
99 {
100 LONG lRet = ERROR_SUCCESS;
101 HKEY hEntryKey = NULL;
102
103 //
104 // Open the sub-key, if any. Otherwise,
105 // use the given registry key handle.
106 //
107 if (lpSubKey)
108 {
109 lRet = RegOpenKeyExW(hKey, lpSubKey, 0, KEY_QUERY_VALUE, &hEntryKey);
110 }
111 else
112 {
113 if (hKey != INVALID_HANDLE_VALUE)
114 {
115 // TODO: Ensure that hKey has the KEY_QUERY_VALUE right.
116 hEntryKey = hKey;
117 lRet = ERROR_SUCCESS;
118 }
119 else
120 {
121 lRet = ERROR_INVALID_HANDLE;
122 }
123 }
124
125 if (lRet == ERROR_SUCCESS)
126 {
127 DWORD dwType = 0,
128 dwRegData = 0,
129 dwBufSize = sizeof(dwRegData /* DWORD */);
130
131 lRet = RegQueryValueExW(hEntryKey, lpValue, NULL, &dwType, (LPBYTE)&dwRegData, &dwBufSize);
132
133 if (lRet == ERROR_SUCCESS)
134 {
135 if ( (dwType == REG_DWORD) && (dwBufSize == sizeof(DWORD)) )
136 {
137 if (lpData)
138 *lpData = dwRegData;
139 }
140 else
141 {
142 lRet = ERROR_UNSUPPORTED_TYPE;
143 }
144 }
145 else if (lRet == ERROR_MORE_DATA)
146 {
147 if (dwType != REG_DWORD)
148 {
149 lRet = ERROR_UNSUPPORTED_TYPE;
150 }
151 }
152
153 // Close the opened sub-key.
154 if (lpSubKey)
155 RegCloseKey(hEntryKey);
156 }
157
158 return lRet;
159 }
160
161 LONG
RegSetDWORDValue(IN HKEY hKey,IN LPCWSTR lpSubKey OPTIONAL,IN LPCWSTR lpValue OPTIONAL,IN BOOL bCreateKeyIfDoesntExist,IN DWORD dwData)162 RegSetDWORDValue(IN HKEY hKey,
163 IN LPCWSTR lpSubKey OPTIONAL,
164 IN LPCWSTR lpValue OPTIONAL,
165 IN BOOL bCreateKeyIfDoesntExist,
166 IN DWORD dwData)
167 {
168 LONG lRet = ERROR_SUCCESS;
169 HKEY hEntryKey = NULL;
170
171 //
172 // Open (or create) the sub-key, if any.
173 // Otherwise, use the given registry key handle.
174 //
175 if (lpSubKey)
176 {
177 if (bCreateKeyIfDoesntExist)
178 lRet = RegCreateKeyExW(hKey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hEntryKey, NULL);
179 else
180 lRet = RegOpenKeyExW(hKey, lpSubKey, 0, KEY_SET_VALUE, &hEntryKey);
181 }
182 else
183 {
184 if (hKey != INVALID_HANDLE_VALUE)
185 {
186 // TODO: Ensure that hKey has the KEY_QUERY_VALUE right.
187 hEntryKey = hKey;
188 lRet = ERROR_SUCCESS;
189 }
190 else
191 {
192 lRet = ERROR_INVALID_HANDLE;
193 }
194 }
195
196 //
197 // Opening successful, can set the value now.
198 //
199 if (lRet == ERROR_SUCCESS)
200 {
201 lRet = RegSetValueExW(hEntryKey, lpValue, 0, REG_DWORD, (LPBYTE)&dwData, sizeof(dwData /* DWORD */));
202
203 // Close the opened (or created) sub-key.
204 if (lpSubKey)
205 RegCloseKey(hEntryKey);
206 }
207
208 return lRet;
209 }
210