20#include <winpr/config.h>
22#include <winpr/registry.h>
30#if !defined(_WIN32) || defined(_UWP)
37#include <winpr/assert.h>
38#include <winpr/string.h>
40#include "registry_reg.h"
43#define TAG WINPR_TAG("registry")
45static Reg* instance = NULL;
47static size_t regsz_length(
const char* key,
const void* value,
bool unicode)
54 const size_t limit = 16383;
57 length = _wcsnlen((
const WCHAR*)value, limit);
59 length = strnlen((
const char*)value, limit);
61 WLog_WARN(TAG,
"REG_SZ[%s] truncated to size %" PRIuz, key, length);
65static Reg* RegGetInstance(
void)
68 instance = reg_open(1);
73LONG RegCloseKey(HKEY hKey)
79LONG RegCopyTreeW(WINPR_ATTR_UNUSED HKEY hKeySrc, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
80 WINPR_ATTR_UNUSED HKEY hKeyDest)
82 WLog_ERR(TAG,
"TODO: Implement");
86LONG RegCopyTreeA(WINPR_ATTR_UNUSED HKEY hKeySrc, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
87 WINPR_ATTR_UNUSED HKEY hKeyDest)
89 WLog_ERR(TAG,
"TODO: Implement");
93LONG RegCreateKeyExW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
94 WINPR_ATTR_UNUSED DWORD Reserved, WINPR_ATTR_UNUSED LPWSTR lpClass,
95 WINPR_ATTR_UNUSED DWORD dwOptions, WINPR_ATTR_UNUSED REGSAM samDesired,
96 WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpSecurityAttributes,
97 WINPR_ATTR_UNUSED PHKEY phkResult, WINPR_ATTR_UNUSED LPDWORD lpdwDisposition)
99 WLog_ERR(TAG,
"TODO: Implement");
103LONG RegCreateKeyExA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
104 WINPR_ATTR_UNUSED DWORD Reserved, WINPR_ATTR_UNUSED LPSTR lpClass,
105 WINPR_ATTR_UNUSED DWORD dwOptions, WINPR_ATTR_UNUSED REGSAM samDesired,
106 WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpSecurityAttributes,
107 WINPR_ATTR_UNUSED PHKEY phkResult, WINPR_ATTR_UNUSED LPDWORD lpdwDisposition)
109 WLog_ERR(TAG,
"TODO: Implement");
113LONG RegDeleteKeyExW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
114 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED DWORD Reserved)
116 WLog_ERR(TAG,
"TODO: Implement");
120LONG RegDeleteKeyExA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
121 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED DWORD Reserved)
123 WLog_ERR(TAG,
"TODO: Implement");
127LONG RegDeleteTreeW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey)
129 WLog_ERR(TAG,
"TODO: Implement");
133LONG RegDeleteTreeA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey)
135 WLog_ERR(TAG,
"TODO: Implement");
139LONG RegDeleteValueW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpValueName)
141 WLog_ERR(TAG,
"TODO: Implement");
145LONG RegDeleteValueA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpValueName)
147 WLog_ERR(TAG,
"TODO: Implement");
151LONG RegDisablePredefinedCacheEx(
void)
153 WLog_ERR(TAG,
"TODO: Implement");
157LONG RegEnumKeyExW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED DWORD dwIndex,
158 WINPR_ATTR_UNUSED LPWSTR lpName, WINPR_ATTR_UNUSED LPDWORD lpcName,
159 WINPR_ATTR_UNUSED LPDWORD lpReserved, WINPR_ATTR_UNUSED LPWSTR lpClass,
160 WINPR_ATTR_UNUSED LPDWORD lpcClass,
161 WINPR_ATTR_UNUSED PFILETIME lpftLastWriteTime)
163 WLog_ERR(TAG,
"TODO: Implement");
167LONG RegEnumKeyExA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED DWORD dwIndex,
168 WINPR_ATTR_UNUSED LPSTR lpName, WINPR_ATTR_UNUSED LPDWORD lpcName,
169 WINPR_ATTR_UNUSED LPDWORD lpReserved, WINPR_ATTR_UNUSED LPSTR lpClass,
170 WINPR_ATTR_UNUSED LPDWORD lpcClass,
171 WINPR_ATTR_UNUSED PFILETIME lpftLastWriteTime)
173 WLog_ERR(TAG,
"TODO: Implement");
177LONG RegEnumValueW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED DWORD dwIndex,
178 WINPR_ATTR_UNUSED LPWSTR lpValueName, WINPR_ATTR_UNUSED LPDWORD lpcchValueName,
179 WINPR_ATTR_UNUSED LPDWORD lpReserved, WINPR_ATTR_UNUSED LPDWORD lpType,
180 WINPR_ATTR_UNUSED LPBYTE lpData, WINPR_ATTR_UNUSED LPDWORD lpcbData)
182 WLog_ERR(TAG,
"TODO: Implement");
186LONG RegEnumValueA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED DWORD dwIndex,
187 WINPR_ATTR_UNUSED LPSTR lpValueName, WINPR_ATTR_UNUSED LPDWORD lpcchValueName,
188 WINPR_ATTR_UNUSED LPDWORD lpReserved, WINPR_ATTR_UNUSED LPDWORD lpType,
189 WINPR_ATTR_UNUSED LPBYTE lpData, WINPR_ATTR_UNUSED LPDWORD lpcbData)
191 WLog_ERR(TAG,
"TODO: Implement");
195LONG RegFlushKey(WINPR_ATTR_UNUSED HKEY hKey)
197 WLog_ERR(TAG,
"TODO: Implement");
201LONG RegGetKeySecurity(WINPR_ATTR_UNUSED HKEY hKey,
202 WINPR_ATTR_UNUSED SECURITY_INFORMATION SecurityInformation,
203 WINPR_ATTR_UNUSED PSECURITY_DESCRIPTOR pSecurityDescriptor,
204 WINPR_ATTR_UNUSED LPDWORD lpcbSecurityDescriptor)
206 WLog_ERR(TAG,
"TODO: Implement");
210LONG RegGetValueW(WINPR_ATTR_UNUSED HKEY hkey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
211 WINPR_ATTR_UNUSED LPCWSTR lpValue, WINPR_ATTR_UNUSED DWORD dwFlags,
212 WINPR_ATTR_UNUSED LPDWORD pdwType, WINPR_ATTR_UNUSED PVOID pvData,
213 WINPR_ATTR_UNUSED LPDWORD pcbData)
215 WLog_ERR(TAG,
"TODO: Implement");
219LONG RegGetValueA(WINPR_ATTR_UNUSED HKEY hkey, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
220 WINPR_ATTR_UNUSED LPCSTR lpValue, WINPR_ATTR_UNUSED DWORD dwFlags,
221 WINPR_ATTR_UNUSED LPDWORD pdwType, WINPR_ATTR_UNUSED PVOID pvData,
222 WINPR_ATTR_UNUSED LPDWORD pcbData)
224 WLog_ERR(TAG,
"TODO: Implement");
228LONG RegLoadAppKeyW(WINPR_ATTR_UNUSED LPCWSTR lpFile, WINPR_ATTR_UNUSED PHKEY phkResult,
229 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED DWORD dwOptions,
230 WINPR_ATTR_UNUSED DWORD Reserved)
232 WLog_ERR(TAG,
"TODO: Implement");
236LONG RegLoadAppKeyA(WINPR_ATTR_UNUSED LPCSTR lpFile, WINPR_ATTR_UNUSED PHKEY phkResult,
237 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED DWORD dwOptions,
238 WINPR_ATTR_UNUSED DWORD Reserved)
240 WLog_ERR(TAG,
"TODO: Implement");
244LONG RegLoadKeyW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
245 WINPR_ATTR_UNUSED LPCWSTR lpFile)
247 WLog_ERR(TAG,
"TODO: Implement");
251LONG RegLoadKeyA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
252 WINPR_ATTR_UNUSED LPCSTR lpFile)
254 WLog_ERR(TAG,
"TODO: Implement");
258LONG RegLoadMUIStringW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR pszValue,
259 WINPR_ATTR_UNUSED LPWSTR pszOutBuf, WINPR_ATTR_UNUSED DWORD cbOutBuf,
260 WINPR_ATTR_UNUSED LPDWORD pcbData, WINPR_ATTR_UNUSED DWORD Flags,
261 WINPR_ATTR_UNUSED LPCWSTR pszDirectory)
263 WLog_ERR(TAG,
"TODO: Implement");
267LONG RegLoadMUIStringA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR pszValue,
268 WINPR_ATTR_UNUSED LPSTR pszOutBuf, WINPR_ATTR_UNUSED DWORD cbOutBuf,
269 WINPR_ATTR_UNUSED LPDWORD pcbData, WINPR_ATTR_UNUSED DWORD Flags,
270 WINPR_ATTR_UNUSED LPCSTR pszDirectory)
272 WLog_ERR(TAG,
"TODO: Implement");
276LONG RegNotifyChangeKeyValue(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED BOOL bWatchSubtree,
277 WINPR_ATTR_UNUSED DWORD dwNotifyFilter,
278 WINPR_ATTR_UNUSED HANDLE hEvent, WINPR_ATTR_UNUSED BOOL fAsynchronous)
280 WLog_ERR(TAG,
"TODO: Implement");
284LONG RegOpenCurrentUser(WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED PHKEY phkResult)
286 WLog_ERR(TAG,
"TODO: Implement");
290LONG RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
293 char* str = ConvertWCharToUtf8Alloc(lpSubKey, NULL);
295 return ERROR_FILE_NOT_FOUND;
297 rc = RegOpenKeyExA(hKey, str, ulOptions, samDesired, phkResult);
302LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, WINPR_ATTR_UNUSED DWORD ulOptions,
303 WINPR_ATTR_UNUSED REGSAM samDesired, PHKEY phkResult)
305 Reg* reg = RegGetInstance();
310 if (hKey != HKEY_LOCAL_MACHINE)
312 WLog_WARN(TAG,
"Registry emulation only supports HKEY_LOCAL_MACHINE");
313 return ERROR_FILE_NOT_FOUND;
316 WINPR_ASSERT(reg->root_key);
317 RegKey* pKey = reg->root_key->subkeys;
321 WINPR_ASSERT(lpSubKey);
323 if (pKey->subname && (_stricmp(pKey->subname, lpSubKey) == 0))
325 *phkResult = (HKEY)pKey;
326 return ERROR_SUCCESS;
334 return ERROR_FILE_NOT_FOUND;
337LONG RegOpenUserClassesRoot(WINPR_ATTR_UNUSED HANDLE hToken, WINPR_ATTR_UNUSED DWORD dwOptions,
338 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED PHKEY phkResult)
340 WLog_ERR(TAG,
"TODO: Implement");
344LONG RegQueryInfoKeyW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPWSTR lpClass,
345 WINPR_ATTR_UNUSED LPDWORD lpcClass, WINPR_ATTR_UNUSED LPDWORD lpReserved,
346 WINPR_ATTR_UNUSED LPDWORD lpcSubKeys,
347 WINPR_ATTR_UNUSED LPDWORD lpcMaxSubKeyLen,
348 WINPR_ATTR_UNUSED LPDWORD lpcMaxClassLen, WINPR_ATTR_UNUSED LPDWORD lpcValues,
349 WINPR_ATTR_UNUSED LPDWORD lpcMaxValueNameLen,
350 WINPR_ATTR_UNUSED LPDWORD lpcMaxValueLen,
351 WINPR_ATTR_UNUSED LPDWORD lpcbSecurityDescriptor,
352 WINPR_ATTR_UNUSED PFILETIME lpftLastWriteTime)
354 WLog_ERR(TAG,
"TODO: Implement");
358LONG RegQueryInfoKeyA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPSTR lpClass,
359 WINPR_ATTR_UNUSED LPDWORD lpcClass, WINPR_ATTR_UNUSED LPDWORD lpReserved,
360 WINPR_ATTR_UNUSED LPDWORD lpcSubKeys,
361 WINPR_ATTR_UNUSED LPDWORD lpcMaxSubKeyLen,
362 WINPR_ATTR_UNUSED LPDWORD lpcMaxClassLen, WINPR_ATTR_UNUSED LPDWORD lpcValues,
363 WINPR_ATTR_UNUSED LPDWORD lpcMaxValueNameLen,
364 WINPR_ATTR_UNUSED LPDWORD lpcMaxValueLen,
365 WINPR_ATTR_UNUSED LPDWORD lpcbSecurityDescriptor,
366 WINPR_ATTR_UNUSED PFILETIME lpftLastWriteTime)
368 WLog_ERR(TAG,
"TODO: Implement");
372static LONG reg_read_int(
const RegVal* pValue, LPBYTE lpData, LPDWORD lpcbData)
374 const BYTE* ptr = NULL;
377 WINPR_ASSERT(pValue);
379 switch (pValue->type)
382 case REG_DWORD_BIG_ENDIAN:
383 required =
sizeof(DWORD);
384 ptr = (
const BYTE*)&pValue->data.dword;
387 required =
sizeof(UINT64);
388 ptr = (
const BYTE*)&pValue->data.qword;
391 return ERROR_INTERNAL_ERROR;
396 DWORD size = *lpcbData;
397 *lpcbData = required;
400 if (size < *lpcbData)
401 return ERROR_MORE_DATA;
408 WINPR_ASSERT(lpcbData);
411 *lpcbData = required;
413 return ERROR_MORE_DATA;
414 memcpy(lpData, ptr, required);
416 else if (lpcbData != NULL)
417 *lpcbData = required;
418 return ERROR_SUCCESS;
422LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
423 LPBYTE lpData, LPDWORD lpcbData)
426 LONG status = ERROR_FILE_NOT_FOUND;
428 RegVal* pValue = NULL;
429 char* valueName = NULL;
431 WINPR_UNUSED(lpReserved);
436 valueName = ConvertWCharToUtf8Alloc(lpValueName, NULL);
440 pValue = key->values;
442 while (pValue != NULL)
444 if (strcmp(pValue->name, valueName) == 0)
447 *lpType = pValue->type;
449 switch (pValue->type)
451 case REG_DWORD_BIG_ENDIAN:
454 status = reg_read_int(pValue, lpData, lpcbData);
458 const size_t length =
459 regsz_length(pValue->name, pValue->data.string, TRUE) *
sizeof(WCHAR);
461 status = ERROR_SUCCESS;
470 WINPR_ASSERT(lpcbData);
474 *lpcbData = (DWORD)length;
476 status = ERROR_MORE_DATA;
477 if (ConvertUtf8NToWChar(pValue->data.string, length, cnv.wc, length) < 0)
478 status = ERROR_OUTOFMEMORY;
481 *lpcbData = (UINT32)length;
487 "Registry emulation does not support value type %s [0x%08" PRIx32
"]",
488 reg_type_string(pValue->type), pValue->type);
493 pValue = pValue->next;
502LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
503 LPBYTE lpData, LPDWORD lpcbData)
507 RegVal* pValue = NULL;
509 WINPR_UNUSED(lpReserved);
514 pValue = key->values;
516 while (pValue != NULL)
518 if (strcmp(pValue->name, lpValueName) == 0)
521 *lpType = pValue->type;
523 switch (pValue->type)
525 case REG_DWORD_BIG_ENDIAN:
528 return reg_read_int(pValue, lpData, lpcbData);
531 const size_t length = regsz_length(pValue->name, pValue->data.string, FALSE);
533 char* pData = (
char*)lpData;
538 WINPR_ASSERT(lpcbData);
541 *lpcbData = (DWORD)length;
543 return ERROR_MORE_DATA;
544 memcpy(pData, pValue->data.string, length);
545 pData[length] =
'\0';
548 *lpcbData = (UINT32)length;
550 return ERROR_SUCCESS;
554 "Registry emulation does not support value type %s [0x%08" PRIx32
"]",
555 reg_type_string(pValue->type), pValue->type);
560 pValue = pValue->next;
563 return ERROR_FILE_NOT_FOUND;
566LONG RegRestoreKeyW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpFile,
567 WINPR_ATTR_UNUSED DWORD dwFlags)
569 WLog_ERR(TAG,
"TODO: Implement");
573LONG RegRestoreKeyA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpFile,
574 WINPR_ATTR_UNUSED DWORD dwFlags)
576 WLog_ERR(TAG,
"TODO: Implement");
580LONG RegSaveKeyExW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpFile,
581 WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpSecurityAttributes,
582 WINPR_ATTR_UNUSED DWORD Flags)
584 WLog_ERR(TAG,
"TODO: Implement");
588LONG RegSaveKeyExA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpFile,
589 WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpSecurityAttributes,
590 WINPR_ATTR_UNUSED DWORD Flags)
592 WLog_ERR(TAG,
"TODO: Implement");
596LONG RegSetKeySecurity(WINPR_ATTR_UNUSED HKEY hKey,
597 WINPR_ATTR_UNUSED SECURITY_INFORMATION SecurityInformation,
598 WINPR_ATTR_UNUSED PSECURITY_DESCRIPTOR pSecurityDescriptor)
600 WLog_ERR(TAG,
"TODO: Implement");
604LONG RegSetValueExW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpValueName,
605 WINPR_ATTR_UNUSED DWORD Reserved, WINPR_ATTR_UNUSED DWORD dwType,
606 WINPR_ATTR_UNUSED
const BYTE* lpData, WINPR_ATTR_UNUSED DWORD cbData)
608 WLog_ERR(TAG,
"TODO: Implement");
612LONG RegSetValueExA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpValueName,
613 WINPR_ATTR_UNUSED DWORD Reserved, WINPR_ATTR_UNUSED DWORD dwType,
614 WINPR_ATTR_UNUSED
const BYTE* lpData, WINPR_ATTR_UNUSED DWORD cbData)
616 WLog_ERR(TAG,
"TODO: Implement");
620LONG RegUnLoadKeyW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey)
622 WLog_ERR(TAG,
"TODO: Implement");
626LONG RegUnLoadKeyA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey)
628 WLog_ERR(TAG,
"TODO: Implement");