1 /* 2 * PROJECT: ReactOS Service Host 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: base/services/svchost/registry.c 5 * PURPOSE: Helper functions for accessing the registry 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES ******************************************************************/ 10 11 #include "svchost.h" 12 13 /* FUNCTIONS *****************************************************************/ 14 15 DWORD 16 WINAPI 17 RegQueryValueWithAlloc ( 18 _In_ HKEY hKey, 19 _In_ LPCWSTR pszValueName, 20 _In_ DWORD dwExpectedType, 21 _Out_ PBYTE* ppbData, 22 _Out_ PDWORD pdwSize 23 ) 24 { 25 DWORD dwError, dwType, dwBytes; 26 PBYTE pbData; 27 ASSERT(hKey); 28 ASSERT(pszValueName); 29 ASSERT(ppbData); 30 ASSERT(pdwSize); 31 32 /* Assume failure */ 33 *ppbData = NULL; 34 *pdwSize = 0; 35 36 /* Query how big and what type the registry data is */ 37 dwBytes = 0; 38 dwError = RegQueryValueExW(hKey, 39 pszValueName, 40 NULL, 41 &dwType, 42 NULL, 43 &dwBytes); 44 if (dwError != ERROR_SUCCESS) return dwError; 45 46 /* It if's not the right type, or it's sero bytes, fail*/ 47 if ((dwType != dwExpectedType) || (dwBytes == 0)) return ERROR_INVALID_DATA; 48 49 /* Allocate space to hold the data */ 50 pbData = MemAlloc(0, dwBytes); 51 if (pbData == NULL) return ERROR_OUTOFMEMORY; 52 53 /* Now get the real registry data */ 54 dwError = RegQueryValueExW(hKey, 55 pszValueName, 56 NULL, 57 &dwType, 58 pbData, 59 &dwBytes); 60 if (dwError != ERROR_SUCCESS) 61 { 62 /* We failed, free the data since it won't be needed */ 63 MemFree(pbData); 64 } 65 else 66 { 67 /* It worked, return the data and size back to the caller */ 68 *ppbData = pbData; 69 *pdwSize = dwBytes; 70 } 71 72 /* All done */ 73 return dwError; 74 } 75 76 DWORD 77 WINAPI 78 RegQueryDword ( 79 _In_ HKEY hKey, 80 _In_ LPCWSTR pszValueName, 81 _Out_ PDWORD pdwValue 82 ) 83 { 84 DWORD dwError, cbData, dwType; 85 ASSERT(hKey); 86 ASSERT(pszValueName); 87 ASSERT(pdwValue); 88 89 /* Attempt to read 4 bytes */ 90 cbData = sizeof(DWORD); 91 dwError = RegQueryValueExW(hKey, pszValueName, 0, &dwType, 0, &cbData); 92 93 /* If we didn't get back a DWORD... */ 94 if ((dwError == ERROR_SUCCESS) && (dwType != REG_DWORD)) 95 { 96 /* Zero out the output and fail */ 97 *pdwValue = 0; 98 dwError = ERROR_INVALID_DATATYPE; 99 } 100 101 /* All done! */ 102 return dwError; 103 } 104 105 DWORD 106 WINAPI 107 RegQueryString ( 108 _In_ HKEY hKey, 109 _In_ LPCWSTR pszValueName, 110 _In_ DWORD dwExpectedType, 111 _Out_ PBYTE* ppbData 112 ) 113 { 114 DWORD dwSize; 115 ASSERT(hKey); 116 ASSERT(pszValueName); 117 118 /* Call the helper function */ 119 return RegQueryValueWithAlloc(hKey, 120 pszValueName, 121 dwExpectedType, 122 ppbData, 123 &dwSize); 124 } 125 126 DWORD 127 WINAPI 128 RegQueryStringA ( 129 _In_ HKEY hKey, 130 _In_ LPCWSTR pszValueName, 131 _In_ DWORD dwExpectedType, 132 _Out_ LPCSTR* ppszData 133 ) 134 { 135 DWORD dwError; 136 LPWSTR pbLocalData; 137 DWORD cchValueName, cbMultiByte; 138 LPSTR pszData; 139 ASSERT(hKey); 140 ASSERT(pszValueName); 141 ASSERT(ppszData); 142 143 /* Assume failure */ 144 *ppszData = NULL; 145 146 /* Query the string in Unicode first */ 147 dwError = RegQueryString(hKey, 148 pszValueName, 149 dwExpectedType, 150 (PBYTE*)&pbLocalData); 151 if (dwError != ERROR_SUCCESS) return dwError; 152 153 /* Get the length of the Unicode string */ 154 cchValueName = lstrlenW(pbLocalData); 155 156 /* See how much space it would take to convert to ANSI */ 157 cbMultiByte = WideCharToMultiByte(CP_ACP, 158 0, 159 pbLocalData, 160 cchValueName + 1, 161 NULL, 162 0, 163 NULL, 164 NULL); 165 if (cbMultiByte != 0) 166 { 167 /* Allocate the space, assuming failure */ 168 dwError = ERROR_OUTOFMEMORY; 169 pszData = MemAlloc(0, cbMultiByte); 170 if (pszData != NULL) 171 { 172 /* What do you know, it worked! */ 173 dwError = ERROR_SUCCESS; 174 175 /* Now do the real conversion */ 176 if (WideCharToMultiByte(CP_ACP, 177 0, 178 pbLocalData, 179 cchValueName + 1, 180 pszData, 181 cbMultiByte, 182 NULL, 183 NULL) != 0) 184 { 185 /* It worked, return the data back to the caller */ 186 *ppszData = pszData; 187 } 188 else 189 { 190 /* It failed, free our buffer and get the error code */ 191 MemFree(pszData); 192 dwError = GetLastError(); 193 } 194 } 195 } 196 197 /* Free the original Unicode string and return the error */ 198 MemFree(pbLocalData); 199 return dwError; 200 } 201 202