1 /**
2  * WinPR: Windows Portable Runtime
3  * Windows Registry
4  *
5  * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <winpr/registry.h>
25 
26 /*
27  * Windows registry MSDN pages:
28  * Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724880/
29  * Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724875/
30  */
31 
32 #if !defined(_WIN32) || defined(_UWP)
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #include <winpr/crt.h>
39 #include <assert.h>
40 
41 #include "registry_reg.h"
42 
43 static Reg* instance = NULL;
44 
RegGetInstance(void)45 static Reg* RegGetInstance(void)
46 {
47 	if (!instance)
48 		instance = reg_open(1);
49 
50 	return instance;
51 }
52 
RegCloseKey(HKEY hKey)53 LONG RegCloseKey(HKEY hKey)
54 {
55 	return 0;
56 }
57 
RegCopyTreeW(HKEY hKeySrc,LPCWSTR lpSubKey,HKEY hKeyDest)58 LONG RegCopyTreeW(HKEY hKeySrc, LPCWSTR lpSubKey, HKEY hKeyDest)
59 {
60 	return 0;
61 }
62 
RegCopyTreeA(HKEY hKeySrc,LPCSTR lpSubKey,HKEY hKeyDest)63 LONG RegCopyTreeA(HKEY hKeySrc, LPCSTR lpSubKey, HKEY hKeyDest)
64 {
65 	return 0;
66 }
67 
RegCreateKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD Reserved,LPWSTR lpClass,DWORD dwOptions,REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecurityAttributes,PHKEY phkResult,LPDWORD lpdwDisposition)68 LONG RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions,
69                      REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult,
70                      LPDWORD lpdwDisposition)
71 {
72 	return 0;
73 }
74 
RegCreateKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD Reserved,LPSTR lpClass,DWORD dwOptions,REGSAM samDesired,LPSECURITY_ATTRIBUTES lpSecurityAttributes,PHKEY phkResult,LPDWORD lpdwDisposition)75 LONG RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions,
76                      REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult,
77                      LPDWORD lpdwDisposition)
78 {
79 	return 0;
80 }
81 
RegDeleteKeyExW(HKEY hKey,LPCWSTR lpSubKey,REGSAM samDesired,DWORD Reserved)82 LONG RegDeleteKeyExW(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved)
83 {
84 	return 0;
85 }
86 
RegDeleteKeyExA(HKEY hKey,LPCSTR lpSubKey,REGSAM samDesired,DWORD Reserved)87 LONG RegDeleteKeyExA(HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired, DWORD Reserved)
88 {
89 	return 0;
90 }
91 
RegDeleteTreeW(HKEY hKey,LPCWSTR lpSubKey)92 LONG RegDeleteTreeW(HKEY hKey, LPCWSTR lpSubKey)
93 {
94 	return 0;
95 }
96 
RegDeleteTreeA(HKEY hKey,LPCSTR lpSubKey)97 LONG RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey)
98 {
99 	return 0;
100 }
101 
RegDeleteValueW(HKEY hKey,LPCWSTR lpValueName)102 LONG RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
103 {
104 	return 0;
105 }
106 
RegDeleteValueA(HKEY hKey,LPCSTR lpValueName)107 LONG RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
108 {
109 	return 0;
110 }
111 
RegDisablePredefinedCacheEx(void)112 LONG RegDisablePredefinedCacheEx(void)
113 {
114 	return 0;
115 }
116 
RegEnumKeyExW(HKEY hKey,DWORD dwIndex,LPWSTR lpName,LPDWORD lpcName,LPDWORD lpReserved,LPWSTR lpClass,LPDWORD lpcClass,PFILETIME lpftLastWriteTime)117 LONG RegEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcName, LPDWORD lpReserved,
118                    LPWSTR lpClass, LPDWORD lpcClass, PFILETIME lpftLastWriteTime)
119 {
120 	return 0;
121 }
122 
RegEnumKeyExA(HKEY hKey,DWORD dwIndex,LPSTR lpName,LPDWORD lpcName,LPDWORD lpReserved,LPSTR lpClass,LPDWORD lpcClass,PFILETIME lpftLastWriteTime)123 LONG RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcName, LPDWORD lpReserved,
124                    LPSTR lpClass, LPDWORD lpcClass, PFILETIME lpftLastWriteTime)
125 {
126 	return 0;
127 }
128 
RegEnumValueW(HKEY hKey,DWORD dwIndex,LPWSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData)129 LONG RegEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPDWORD lpcchValueName,
130                    LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
131 {
132 	return 0;
133 }
134 
RegEnumValueA(HKEY hKey,DWORD dwIndex,LPSTR lpValueName,LPDWORD lpcchValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData)135 LONG RegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName, LPDWORD lpcchValueName,
136                    LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
137 {
138 	return 0;
139 }
140 
RegFlushKey(HKEY hKey)141 LONG RegFlushKey(HKEY hKey)
142 {
143 	return 0;
144 }
145 
RegGetKeySecurity(HKEY hKey,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,LPDWORD lpcbSecurityDescriptor)146 LONG RegGetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation,
147                        PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor)
148 {
149 	return 0;
150 }
151 
RegGetValueW(HKEY hkey,LPCWSTR lpSubKey,LPCWSTR lpValue,DWORD dwFlags,LPDWORD pdwType,PVOID pvData,LPDWORD pcbData)152 LONG RegGetValueW(HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType,
153                   PVOID pvData, LPDWORD pcbData)
154 {
155 	return 0;
156 }
157 
RegGetValueA(HKEY hkey,LPCSTR lpSubKey,LPCSTR lpValue,DWORD dwFlags,LPDWORD pdwType,PVOID pvData,LPDWORD pcbData)158 LONG RegGetValueA(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType,
159                   PVOID pvData, LPDWORD pcbData)
160 {
161 	return 0;
162 }
163 
RegLoadAppKeyW(LPCWSTR lpFile,PHKEY phkResult,REGSAM samDesired,DWORD dwOptions,DWORD Reserved)164 LONG RegLoadAppKeyW(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions,
165                     DWORD Reserved)
166 {
167 	return 0;
168 }
169 
RegLoadAppKeyA(LPCSTR lpFile,PHKEY phkResult,REGSAM samDesired,DWORD dwOptions,DWORD Reserved)170 LONG RegLoadAppKeyA(LPCSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions,
171                     DWORD Reserved)
172 {
173 	return 0;
174 }
175 
RegLoadKeyW(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpFile)176 LONG RegLoadKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile)
177 {
178 	return 0;
179 }
180 
RegLoadKeyA(HKEY hKey,LPCSTR lpSubKey,LPCSTR lpFile)181 LONG RegLoadKeyA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpFile)
182 {
183 	return 0;
184 }
185 
RegLoadMUIStringW(HKEY hKey,LPCWSTR pszValue,LPWSTR pszOutBuf,DWORD cbOutBuf,LPDWORD pcbData,DWORD Flags,LPCWSTR pszDirectory)186 LONG RegLoadMUIStringW(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf,
187                        LPDWORD pcbData, DWORD Flags, LPCWSTR pszDirectory)
188 {
189 	return 0;
190 }
191 
RegLoadMUIStringA(HKEY hKey,LPCSTR pszValue,LPSTR pszOutBuf,DWORD cbOutBuf,LPDWORD pcbData,DWORD Flags,LPCSTR pszDirectory)192 LONG RegLoadMUIStringA(HKEY hKey, LPCSTR pszValue, LPSTR pszOutBuf, DWORD cbOutBuf, LPDWORD pcbData,
193                        DWORD Flags, LPCSTR pszDirectory)
194 {
195 	return 0;
196 }
197 
RegNotifyChangeKeyValue(HKEY hKey,BOOL bWatchSubtree,DWORD dwNotifyFilter,HANDLE hEvent,BOOL fAsynchronous)198 LONG RegNotifyChangeKeyValue(HKEY hKey, BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent,
199                              BOOL fAsynchronous)
200 {
201 	return 0;
202 }
203 
RegOpenCurrentUser(REGSAM samDesired,PHKEY phkResult)204 LONG RegOpenCurrentUser(REGSAM samDesired, PHKEY phkResult)
205 {
206 	return 0;
207 }
208 
RegOpenKeyExW(HKEY hKey,LPCWSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult)209 LONG RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
210 {
211 	return 0;
212 }
213 
RegOpenKeyExA(HKEY hKey,LPCSTR lpSubKey,DWORD ulOptions,REGSAM samDesired,PHKEY phkResult)214 LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
215 {
216 	RegKey* pKey;
217 	Reg* reg = RegGetInstance();
218 
219 	if (!reg)
220 		return -1;
221 
222 	if (hKey != HKEY_LOCAL_MACHINE)
223 		return ERROR_FILE_NOT_FOUND;
224 
225 	assert(reg->root_key);
226 	pKey = reg->root_key->subkeys;
227 
228 	while (pKey != NULL)
229 	{
230 		assert(lpSubKey);
231 
232 		if (pKey->subname && (_stricmp(pKey->subname, lpSubKey) == 0))
233 		{
234 			*phkResult = (HKEY)pKey;
235 			return ERROR_SUCCESS;
236 		}
237 
238 		pKey = pKey->next;
239 	}
240 
241 	*phkResult = NULL;
242 
243 	return ERROR_FILE_NOT_FOUND;
244 }
245 
RegOpenUserClassesRoot(HANDLE hToken,DWORD dwOptions,REGSAM samDesired,PHKEY phkResult)246 LONG RegOpenUserClassesRoot(HANDLE hToken, DWORD dwOptions, REGSAM samDesired, PHKEY phkResult)
247 {
248 	return 0;
249 }
250 
RegQueryInfoKeyW(HKEY hKey,LPWSTR lpClass,LPDWORD lpcClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcMaxSubKeyLen,LPDWORD lpcMaxClassLen,LPDWORD lpcValues,LPDWORD lpcMaxValueNameLen,LPDWORD lpcMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime)251 LONG RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved,
252                       LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen,
253                       LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen,
254                       LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
255 {
256 	return 0;
257 }
258 
RegQueryInfoKeyA(HKEY hKey,LPSTR lpClass,LPDWORD lpcClass,LPDWORD lpReserved,LPDWORD lpcSubKeys,LPDWORD lpcMaxSubKeyLen,LPDWORD lpcMaxClassLen,LPDWORD lpcValues,LPDWORD lpcMaxValueNameLen,LPDWORD lpcMaxValueLen,LPDWORD lpcbSecurityDescriptor,PFILETIME lpftLastWriteTime)259 LONG RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved,
260                       LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen,
261                       LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen,
262                       LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
263 {
264 	return 0;
265 }
266 
RegQueryValueExW(HKEY hKey,LPCWSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData)267 LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
268                       LPBYTE lpData, LPDWORD lpcbData)
269 {
270 	return ERROR_FILE_NOT_FOUND;
271 }
272 
RegQueryValueExA(HKEY hKey,LPCSTR lpValueName,LPDWORD lpReserved,LPDWORD lpType,LPBYTE lpData,LPDWORD lpcbData)273 LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
274                       LPBYTE lpData, LPDWORD lpcbData)
275 {
276 	RegKey* key;
277 	RegVal* pValue;
278 
279 	WINPR_UNUSED(lpReserved);
280 
281 	key = (RegKey*)hKey;
282 	assert(key);
283 
284 	pValue = key->values;
285 
286 	while (pValue != NULL)
287 	{
288 		if (strcmp(pValue->name, lpValueName) == 0)
289 		{
290 			if (lpType)
291 				*lpType = pValue->type;
292 
293 			if (pValue->type == REG_DWORD)
294 			{
295 				DWORD* pData = (DWORD*)lpData;
296 
297 				if (lpcbData)
298 				{
299 					DWORD size = *lpcbData;
300 					*lpcbData = sizeof(DWORD);
301 					if (pData)
302 					{
303 						if (size < *lpcbData)
304 							return ERROR_MORE_DATA;
305 					}
306 				}
307 
308 				if (pData != NULL)
309 				{
310 					DWORD size;
311 					assert(lpcbData);
312 
313 					size = *lpcbData;
314 					*lpcbData = sizeof(DWORD);
315 					if (size < sizeof(DWORD))
316 						return ERROR_MORE_DATA;
317 					*pData = pValue->data.dword;
318 				}
319 				else if (lpcbData != NULL)
320 					*lpcbData = sizeof(DWORD);
321 				return ERROR_SUCCESS;
322 			}
323 			else if (pValue->type == REG_SZ)
324 			{
325 				size_t length;
326 				char* pData = (char*)lpData;
327 
328 				length = strnlen(pValue->data.string, INT_MAX);
329 
330 				if (pData != NULL)
331 				{
332 					DWORD size;
333 					assert(lpcbData);
334 
335 					size = *lpcbData;
336 					*lpcbData = length;
337 					if (size < length)
338 						return ERROR_MORE_DATA;
339 					memcpy(pData, pValue->data.string, length);
340 					pData[length] = '\0';
341 				}
342 				else if (lpcbData)
343 					*lpcbData = (UINT32)length;
344 
345 				return ERROR_SUCCESS;
346 			}
347 		}
348 
349 		pValue = pValue->next;
350 	}
351 
352 	return ERROR_FILE_NOT_FOUND;
353 }
354 
RegRestoreKeyW(HKEY hKey,LPCWSTR lpFile,DWORD dwFlags)355 LONG RegRestoreKeyW(HKEY hKey, LPCWSTR lpFile, DWORD dwFlags)
356 {
357 	return 0;
358 }
359 
RegRestoreKeyA(HKEY hKey,LPCSTR lpFile,DWORD dwFlags)360 LONG RegRestoreKeyA(HKEY hKey, LPCSTR lpFile, DWORD dwFlags)
361 {
362 	return 0;
363 }
364 
RegSaveKeyExW(HKEY hKey,LPCWSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD Flags)365 LONG RegSaveKeyExW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
366                    DWORD Flags)
367 {
368 	return 0;
369 }
370 
RegSaveKeyExA(HKEY hKey,LPCSTR lpFile,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD Flags)371 LONG RegSaveKeyExA(HKEY hKey, LPCSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
372                    DWORD Flags)
373 {
374 	return 0;
375 }
376 
RegSetKeySecurity(HKEY hKey,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor)377 LONG RegSetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation,
378                        PSECURITY_DESCRIPTOR pSecurityDescriptor)
379 {
380 	return 0;
381 }
382 
RegSetValueExW(HKEY hKey,LPCWSTR lpValueName,DWORD Reserved,DWORD dwType,const BYTE * lpData,DWORD cbData)383 LONG RegSetValueExW(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType,
384                     const BYTE* lpData, DWORD cbData)
385 {
386 	return 0;
387 }
388 
RegSetValueExA(HKEY hKey,LPCSTR lpValueName,DWORD Reserved,DWORD dwType,const BYTE * lpData,DWORD cbData)389 LONG RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE* lpData,
390                     DWORD cbData)
391 {
392 	return 0;
393 }
394 
RegUnLoadKeyW(HKEY hKey,LPCWSTR lpSubKey)395 LONG RegUnLoadKeyW(HKEY hKey, LPCWSTR lpSubKey)
396 {
397 	return 0;
398 }
399 
RegUnLoadKeyA(HKEY hKey,LPCSTR lpSubKey)400 LONG RegUnLoadKeyA(HKEY hKey, LPCSTR lpSubKey)
401 {
402 	return 0;
403 }
404 
405 #endif
406