20 #include <winpr/config.h>
22 #include <winpr/registry.h>
30 #if !defined(_WIN32) || defined(_UWP)
36 #include <winpr/crt.h>
37 #include <winpr/assert.h>
39 #include "registry_reg.h"
42 #define TAG WINPR_TAG("registry")
44 static Reg* instance = NULL;
46 static Reg* RegGetInstance(
void)
49 instance = reg_open(1);
54 LONG RegCloseKey(HKEY hKey)
60 LONG RegCopyTreeW(HKEY hKeySrc, LPCWSTR lpSubKey, HKEY hKeyDest)
62 WLog_ERR(TAG,
"TODO: Implement");
66 LONG RegCopyTreeA(HKEY hKeySrc, LPCSTR lpSubKey, HKEY hKeyDest)
68 WLog_ERR(TAG,
"TODO: Implement");
72 LONG RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions,
73 REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult,
74 LPDWORD lpdwDisposition)
76 WLog_ERR(TAG,
"TODO: Implement");
80 LONG RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions,
81 REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult,
82 LPDWORD lpdwDisposition)
84 WLog_ERR(TAG,
"TODO: Implement");
88 LONG RegDeleteKeyExW(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved)
90 WLog_ERR(TAG,
"TODO: Implement");
94 LONG RegDeleteKeyExA(HKEY hKey, LPCSTR lpSubKey, REGSAM samDesired, DWORD Reserved)
96 WLog_ERR(TAG,
"TODO: Implement");
100 LONG RegDeleteTreeW(HKEY hKey, LPCWSTR lpSubKey)
102 WLog_ERR(TAG,
"TODO: Implement");
106 LONG RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey)
108 WLog_ERR(TAG,
"TODO: Implement");
112 LONG RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
114 WLog_ERR(TAG,
"TODO: Implement");
118 LONG RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
120 WLog_ERR(TAG,
"TODO: Implement");
124 LONG RegDisablePredefinedCacheEx(
void)
126 WLog_ERR(TAG,
"TODO: Implement");
130 LONG RegEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcName, LPDWORD lpReserved,
131 LPWSTR lpClass, LPDWORD lpcClass, PFILETIME lpftLastWriteTime)
133 WLog_ERR(TAG,
"TODO: Implement");
137 LONG RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcName, LPDWORD lpReserved,
138 LPSTR lpClass, LPDWORD lpcClass, PFILETIME lpftLastWriteTime)
140 WLog_ERR(TAG,
"TODO: Implement");
144 LONG RegEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPDWORD lpcchValueName,
145 LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
147 WLog_ERR(TAG,
"TODO: Implement");
151 LONG RegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName, LPDWORD lpcchValueName,
152 LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
154 WLog_ERR(TAG,
"TODO: Implement");
158 LONG RegFlushKey(HKEY hKey)
160 WLog_ERR(TAG,
"TODO: Implement");
164 LONG RegGetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation,
165 PSECURITY_DESCRIPTOR pSecurityDescriptor, LPDWORD lpcbSecurityDescriptor)
167 WLog_ERR(TAG,
"TODO: Implement");
171 LONG RegGetValueW(HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType,
172 PVOID pvData, LPDWORD pcbData)
174 WLog_ERR(TAG,
"TODO: Implement");
178 LONG RegGetValueA(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType,
179 PVOID pvData, LPDWORD pcbData)
181 WLog_ERR(TAG,
"TODO: Implement");
185 LONG RegLoadAppKeyW(LPCWSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions,
188 WLog_ERR(TAG,
"TODO: Implement");
192 LONG RegLoadAppKeyA(LPCSTR lpFile, PHKEY phkResult, REGSAM samDesired, DWORD dwOptions,
195 WLog_ERR(TAG,
"TODO: Implement");
199 LONG RegLoadKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile)
201 WLog_ERR(TAG,
"TODO: Implement");
205 LONG RegLoadKeyA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpFile)
207 WLog_ERR(TAG,
"TODO: Implement");
211 LONG RegLoadMUIStringW(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf,
212 LPDWORD pcbData, DWORD Flags, LPCWSTR pszDirectory)
214 WLog_ERR(TAG,
"TODO: Implement");
218 LONG RegLoadMUIStringA(HKEY hKey, LPCSTR pszValue, LPSTR pszOutBuf, DWORD cbOutBuf, LPDWORD pcbData,
219 DWORD Flags, LPCSTR pszDirectory)
221 WLog_ERR(TAG,
"TODO: Implement");
225 LONG RegNotifyChangeKeyValue(HKEY hKey, BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent,
228 WLog_ERR(TAG,
"TODO: Implement");
232 LONG RegOpenCurrentUser(REGSAM samDesired, PHKEY phkResult)
234 WLog_ERR(TAG,
"TODO: Implement");
238 LONG RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
241 char* str = ConvertWCharToUtf8Alloc(lpSubKey, NULL);
243 return ERROR_FILE_NOT_FOUND;
245 rc = RegOpenKeyExA(hKey, str, ulOptions, samDesired, phkResult);
250 LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
252 Reg* reg = RegGetInstance();
257 if (hKey != HKEY_LOCAL_MACHINE)
259 WLog_WARN(TAG,
"Registry emulation only supports HKEY_LOCAL_MACHINE");
260 return ERROR_FILE_NOT_FOUND;
263 WINPR_ASSERT(reg->root_key);
264 RegKey* pKey = reg->root_key->subkeys;
268 WINPR_ASSERT(lpSubKey);
270 if (pKey->subname && (_stricmp(pKey->subname, lpSubKey) == 0))
272 *phkResult = (HKEY)pKey;
273 return ERROR_SUCCESS;
281 return ERROR_FILE_NOT_FOUND;
284 LONG RegOpenUserClassesRoot(HANDLE hToken, DWORD dwOptions, REGSAM samDesired, PHKEY phkResult)
286 WLog_ERR(TAG,
"TODO: Implement");
290 LONG RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved,
291 LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen,
292 LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen,
293 LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
295 WLog_ERR(TAG,
"TODO: Implement");
299 LONG RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved,
300 LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen,
301 LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen,
302 LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
304 WLog_ERR(TAG,
"TODO: Implement");
308 static LONG reg_read_int(
const RegVal* pValue, LPBYTE lpData, LPDWORD lpcbData)
310 const BYTE* ptr = NULL;
313 WINPR_ASSERT(pValue);
315 switch (pValue->type)
318 case REG_DWORD_BIG_ENDIAN:
319 required =
sizeof(DWORD);
320 ptr = (
const BYTE*)&pValue->data.dword;
323 required =
sizeof(UINT64);
324 ptr = (
const BYTE*)&pValue->data.qword;
327 return ERROR_INTERNAL_ERROR;
332 DWORD size = *lpcbData;
333 *lpcbData = required;
336 if (size < *lpcbData)
337 return ERROR_MORE_DATA;
344 WINPR_ASSERT(lpcbData);
347 *lpcbData = required;
349 return ERROR_MORE_DATA;
350 memcpy(lpData, ptr, required);
352 else if (lpcbData != NULL)
353 *lpcbData = required;
354 return ERROR_SUCCESS;
358 LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
359 LPBYTE lpData, LPDWORD lpcbData)
362 LONG status = ERROR_FILE_NOT_FOUND;
364 RegVal* pValue = NULL;
365 char* valueName = NULL;
367 WINPR_UNUSED(lpReserved);
372 valueName = ConvertWCharToUtf8Alloc(lpValueName, NULL);
376 pValue = key->values;
378 while (pValue != NULL)
380 if (strcmp(pValue->name, valueName) == 0)
383 *lpType = pValue->type;
385 switch (pValue->type)
387 case REG_DWORD_BIG_ENDIAN:
390 status = reg_read_int(pValue, lpData, lpcbData);
394 const size_t length = strnlen(pValue->data.string, UINT32_MAX) *
sizeof(WCHAR);
396 status = ERROR_SUCCESS;
405 WINPR_ASSERT(lpcbData);
409 *lpcbData = (DWORD)length;
411 status = ERROR_MORE_DATA;
412 if (ConvertUtf8NToWChar(pValue->data.string, length, cnv.wc, length) < 0)
413 status = ERROR_OUTOFMEMORY;
416 *lpcbData = (UINT32)length;
422 "Registry emulation does not support value type %s [0x%08" PRIx32
"]",
423 reg_type_string(pValue->type), pValue->type);
428 pValue = pValue->next;
437 LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
438 LPBYTE lpData, LPDWORD lpcbData)
442 RegVal* pValue = NULL;
444 WINPR_UNUSED(lpReserved);
449 pValue = key->values;
451 while (pValue != NULL)
453 if (strcmp(pValue->name, lpValueName) == 0)
456 *lpType = pValue->type;
458 switch (pValue->type)
460 case REG_DWORD_BIG_ENDIAN:
463 return reg_read_int(pValue, lpData, lpcbData);
466 const size_t length = strnlen(pValue->data.string, UINT32_MAX);
467 char* pData = (
char*)lpData;
472 WINPR_ASSERT(lpcbData);
475 *lpcbData = (DWORD)length;
477 return ERROR_MORE_DATA;
478 memcpy(pData, pValue->data.string, length);
479 pData[length] =
'\0';
482 *lpcbData = (UINT32)length;
484 return ERROR_SUCCESS;
488 "Registry emulation does not support value type %s [0x%08" PRIx32
"]",
489 reg_type_string(pValue->type), pValue->type);
494 pValue = pValue->next;
497 return ERROR_FILE_NOT_FOUND;
500 LONG RegRestoreKeyW(HKEY hKey, LPCWSTR lpFile, DWORD dwFlags)
502 WLog_ERR(TAG,
"TODO: Implement");
506 LONG RegRestoreKeyA(HKEY hKey, LPCSTR lpFile, DWORD dwFlags)
508 WLog_ERR(TAG,
"TODO: Implement");
512 LONG RegSaveKeyExW(HKEY hKey, LPCWSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
515 WLog_ERR(TAG,
"TODO: Implement");
519 LONG RegSaveKeyExA(HKEY hKey, LPCSTR lpFile, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
522 WLog_ERR(TAG,
"TODO: Implement");
526 LONG RegSetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecurityInformation,
527 PSECURITY_DESCRIPTOR pSecurityDescriptor)
529 WLog_ERR(TAG,
"TODO: Implement");
533 LONG RegSetValueExW(HKEY hKey, LPCWSTR lpValueName, DWORD Reserved, DWORD dwType,
534 const BYTE* lpData, DWORD cbData)
536 WLog_ERR(TAG,
"TODO: Implement");
540 LONG RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType,
const BYTE* lpData,
543 WLog_ERR(TAG,
"TODO: Implement");
547 LONG RegUnLoadKeyW(HKEY hKey, LPCWSTR lpSubKey)
549 WLog_ERR(TAG,
"TODO: Implement");
553 LONG RegUnLoadKeyA(HKEY hKey, LPCSTR lpSubKey)
555 WLog_ERR(TAG,
"TODO: Implement");