1 #include "precomp.h" 2 #include "utils.h" 3 #include "regutils.h" 4 5 LRESULT 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 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 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 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