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