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