FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
registry.c
1
20#include <winpr/config.h>
21
22#include <winpr/registry.h>
23
24/*
25 * Windows registry MSDN pages:
26 * Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724880/
27 * Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724875/
28 */
29
30#if !defined(_WIN32) || defined(_UWP)
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include <winpr/crt.h>
37#include <winpr/assert.h>
38#include <winpr/string.h>
39
40#include "registry_reg.h"
41
42#include "../log.h"
43#define TAG WINPR_TAG("registry")
44
45static Reg* instance = NULL;
46
47static size_t regsz_length(const char* key, const void* value, bool unicode)
48{
49 /* https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-element-size-limits
50 *
51 * while not strictly limited to this size larger values should be stored to a
52 * file.
53 */
54 const size_t limit = 16383;
55 size_t length = 0;
56 if (unicode)
57 length = _wcsnlen((const WCHAR*)value, limit);
58 else
59 length = strnlen((const char*)value, limit);
60 if (length >= limit)
61 WLog_WARN(TAG, "REG_SZ[%s] truncated to size %" PRIuz, key, length);
62 return length;
63}
64
65static Reg* RegGetInstance(void)
66{
67 if (!instance)
68 instance = reg_open(1);
69
70 return instance;
71}
72
73LONG RegCloseKey(HKEY hKey)
74{
75 WINPR_UNUSED(hKey);
76 return 0;
77}
78
79LONG RegCopyTreeW(WINPR_ATTR_UNUSED HKEY hKeySrc, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
80 WINPR_ATTR_UNUSED HKEY hKeyDest)
81{
82 WLog_ERR(TAG, "TODO: Implement");
83 return -1;
84}
85
86LONG RegCopyTreeA(WINPR_ATTR_UNUSED HKEY hKeySrc, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
87 WINPR_ATTR_UNUSED HKEY hKeyDest)
88{
89 WLog_ERR(TAG, "TODO: Implement");
90 return -1;
91}
92
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)
98{
99 WLog_ERR(TAG, "TODO: Implement");
100 return -1;
101}
102
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)
108{
109 WLog_ERR(TAG, "TODO: Implement");
110 return -1;
111}
112
113LONG RegDeleteKeyExW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
114 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED DWORD Reserved)
115{
116 WLog_ERR(TAG, "TODO: Implement");
117 return -1;
118}
119
120LONG RegDeleteKeyExA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
121 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED DWORD Reserved)
122{
123 WLog_ERR(TAG, "TODO: Implement");
124 return -1;
125}
126
127LONG RegDeleteTreeW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey)
128{
129 WLog_ERR(TAG, "TODO: Implement");
130 return -1;
131}
132
133LONG RegDeleteTreeA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey)
134{
135 WLog_ERR(TAG, "TODO: Implement");
136 return -1;
137}
138
139LONG RegDeleteValueW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpValueName)
140{
141 WLog_ERR(TAG, "TODO: Implement");
142 return -1;
143}
144
145LONG RegDeleteValueA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpValueName)
146{
147 WLog_ERR(TAG, "TODO: Implement");
148 return -1;
149}
150
151LONG RegDisablePredefinedCacheEx(void)
152{
153 WLog_ERR(TAG, "TODO: Implement");
154 return -1;
155}
156
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)
162{
163 WLog_ERR(TAG, "TODO: Implement");
164 return -1;
165}
166
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)
172{
173 WLog_ERR(TAG, "TODO: Implement");
174 return -1;
175}
176
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)
181{
182 WLog_ERR(TAG, "TODO: Implement");
183 return -1;
184}
185
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)
190{
191 WLog_ERR(TAG, "TODO: Implement");
192 return -1;
193}
194
195LONG RegFlushKey(WINPR_ATTR_UNUSED HKEY hKey)
196{
197 WLog_ERR(TAG, "TODO: Implement");
198 return -1;
199}
200
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)
205{
206 WLog_ERR(TAG, "TODO: Implement");
207 return -1;
208}
209
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)
214{
215 WLog_ERR(TAG, "TODO: Implement");
216 return -1;
217}
218
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)
223{
224 WLog_ERR(TAG, "TODO: Implement");
225 return -1;
226}
227
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)
231{
232 WLog_ERR(TAG, "TODO: Implement");
233 return -1;
234}
235
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)
239{
240 WLog_ERR(TAG, "TODO: Implement");
241 return -1;
242}
243
244LONG RegLoadKeyW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey,
245 WINPR_ATTR_UNUSED LPCWSTR lpFile)
246{
247 WLog_ERR(TAG, "TODO: Implement");
248 return -1;
249}
250
251LONG RegLoadKeyA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey,
252 WINPR_ATTR_UNUSED LPCSTR lpFile)
253{
254 WLog_ERR(TAG, "TODO: Implement");
255 return -1;
256}
257
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)
262{
263 WLog_ERR(TAG, "TODO: Implement");
264 return -1;
265}
266
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)
271{
272 WLog_ERR(TAG, "TODO: Implement");
273 return -1;
274}
275
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)
279{
280 WLog_ERR(TAG, "TODO: Implement");
281 return -1;
282}
283
284LONG RegOpenCurrentUser(WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED PHKEY phkResult)
285{
286 WLog_ERR(TAG, "TODO: Implement");
287 return -1;
288}
289
290LONG RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
291{
292 LONG rc = 0;
293 char* str = ConvertWCharToUtf8Alloc(lpSubKey, NULL);
294 if (!str)
295 return ERROR_FILE_NOT_FOUND;
296
297 rc = RegOpenKeyExA(hKey, str, ulOptions, samDesired, phkResult);
298 free(str);
299 return rc;
300}
301
302LONG RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, WINPR_ATTR_UNUSED DWORD ulOptions,
303 WINPR_ATTR_UNUSED REGSAM samDesired, PHKEY phkResult)
304{
305 Reg* reg = RegGetInstance();
306
307 if (!reg)
308 return -1;
309
310 if (hKey != HKEY_LOCAL_MACHINE)
311 {
312 WLog_WARN(TAG, "Registry emulation only supports HKEY_LOCAL_MACHINE");
313 return ERROR_FILE_NOT_FOUND;
314 }
315
316 WINPR_ASSERT(reg->root_key);
317 RegKey* pKey = reg->root_key->subkeys;
318
319 while (pKey != NULL)
320 {
321 WINPR_ASSERT(lpSubKey);
322
323 if (pKey->subname && (_stricmp(pKey->subname, lpSubKey) == 0))
324 {
325 *phkResult = (HKEY)pKey;
326 return ERROR_SUCCESS;
327 }
328
329 pKey = pKey->next;
330 }
331
332 *phkResult = NULL;
333
334 return ERROR_FILE_NOT_FOUND;
335}
336
337LONG RegOpenUserClassesRoot(WINPR_ATTR_UNUSED HANDLE hToken, WINPR_ATTR_UNUSED DWORD dwOptions,
338 WINPR_ATTR_UNUSED REGSAM samDesired, WINPR_ATTR_UNUSED PHKEY phkResult)
339{
340 WLog_ERR(TAG, "TODO: Implement");
341 return -1;
342}
343
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)
353{
354 WLog_ERR(TAG, "TODO: Implement");
355 return -1;
356}
357
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)
367{
368 WLog_ERR(TAG, "TODO: Implement");
369 return -1;
370}
371
372static LONG reg_read_int(const RegVal* pValue, LPBYTE lpData, LPDWORD lpcbData)
373{
374 const BYTE* ptr = NULL;
375 DWORD required = 0;
376
377 WINPR_ASSERT(pValue);
378
379 switch (pValue->type)
380 {
381 case REG_DWORD:
382 case REG_DWORD_BIG_ENDIAN:
383 required = sizeof(DWORD);
384 ptr = (const BYTE*)&pValue->data.dword;
385 break;
386 case REG_QWORD:
387 required = sizeof(UINT64);
388 ptr = (const BYTE*)&pValue->data.qword;
389 break;
390 default:
391 return ERROR_INTERNAL_ERROR;
392 }
393
394 if (lpcbData)
395 {
396 DWORD size = *lpcbData;
397 *lpcbData = required;
398 if (lpData)
399 {
400 if (size < *lpcbData)
401 return ERROR_MORE_DATA;
402 }
403 }
404
405 if (lpData != NULL)
406 {
407 DWORD size = 0;
408 WINPR_ASSERT(lpcbData);
409
410 size = *lpcbData;
411 *lpcbData = required;
412 if (size < required)
413 return ERROR_MORE_DATA;
414 memcpy(lpData, ptr, required);
415 }
416 else if (lpcbData != NULL)
417 *lpcbData = required;
418 return ERROR_SUCCESS;
419}
420
421// NOLINTBEGIN(readability-non-const-parameter)
422LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
423 LPBYTE lpData, LPDWORD lpcbData)
424// NOLINTEND(readability-non-const-parameter)
425{
426 LONG status = ERROR_FILE_NOT_FOUND;
427 RegKey* key = NULL;
428 RegVal* pValue = NULL;
429 char* valueName = NULL;
430
431 WINPR_UNUSED(lpReserved);
432
433 key = (RegKey*)hKey;
434 WINPR_ASSERT(key);
435
436 valueName = ConvertWCharToUtf8Alloc(lpValueName, NULL);
437 if (!valueName)
438 goto end;
439
440 pValue = key->values;
441
442 while (pValue != NULL)
443 {
444 if (strcmp(pValue->name, valueName) == 0)
445 {
446 if (lpType)
447 *lpType = pValue->type;
448
449 switch (pValue->type)
450 {
451 case REG_DWORD_BIG_ENDIAN:
452 case REG_QWORD:
453 case REG_DWORD:
454 status = reg_read_int(pValue, lpData, lpcbData);
455 goto end;
456 case REG_SZ:
457 {
458 const size_t length =
459 regsz_length(pValue->name, pValue->data.string, TRUE) * sizeof(WCHAR);
460
461 status = ERROR_SUCCESS;
462 if (lpData != NULL)
463 {
464 DWORD size = 0;
465 union
466 {
467 WCHAR* wc;
468 BYTE* b;
469 } cnv;
470 WINPR_ASSERT(lpcbData);
471
472 cnv.b = lpData;
473 size = *lpcbData;
474 *lpcbData = (DWORD)length;
475 if (size < length)
476 status = ERROR_MORE_DATA;
477 if (ConvertUtf8NToWChar(pValue->data.string, length, cnv.wc, length) < 0)
478 status = ERROR_OUTOFMEMORY;
479 }
480 else if (lpcbData)
481 *lpcbData = (UINT32)length;
482
483 goto end;
484 }
485 default:
486 WLog_WARN(TAG,
487 "Registry emulation does not support value type %s [0x%08" PRIx32 "]",
488 reg_type_string(pValue->type), pValue->type);
489 break;
490 }
491 }
492
493 pValue = pValue->next;
494 }
495
496end:
497 free(valueName);
498 return status;
499}
500
501// NOLINTBEGIN(readability-non-const-parameter)
502LONG RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
503 LPBYTE lpData, LPDWORD lpcbData)
504// NOLINTEND(readability-non-const-parameter)
505{
506 RegKey* key = NULL;
507 RegVal* pValue = NULL;
508
509 WINPR_UNUSED(lpReserved);
510
511 key = (RegKey*)hKey;
512 WINPR_ASSERT(key);
513
514 pValue = key->values;
515
516 while (pValue != NULL)
517 {
518 if (strcmp(pValue->name, lpValueName) == 0)
519 {
520 if (lpType)
521 *lpType = pValue->type;
522
523 switch (pValue->type)
524 {
525 case REG_DWORD_BIG_ENDIAN:
526 case REG_QWORD:
527 case REG_DWORD:
528 return reg_read_int(pValue, lpData, lpcbData);
529 case REG_SZ:
530 {
531 const size_t length = regsz_length(pValue->name, pValue->data.string, FALSE);
532
533 char* pData = (char*)lpData;
534
535 if (pData != NULL)
536 {
537 DWORD size = 0;
538 WINPR_ASSERT(lpcbData);
539
540 size = *lpcbData;
541 *lpcbData = (DWORD)length;
542 if (size < length)
543 return ERROR_MORE_DATA;
544 memcpy(pData, pValue->data.string, length);
545 pData[length] = '\0';
546 }
547 else if (lpcbData)
548 *lpcbData = (UINT32)length;
549
550 return ERROR_SUCCESS;
551 }
552 default:
553 WLog_WARN(TAG,
554 "Registry emulation does not support value type %s [0x%08" PRIx32 "]",
555 reg_type_string(pValue->type), pValue->type);
556 break;
557 }
558 }
559
560 pValue = pValue->next;
561 }
562
563 return ERROR_FILE_NOT_FOUND;
564}
565
566LONG RegRestoreKeyW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpFile,
567 WINPR_ATTR_UNUSED DWORD dwFlags)
568{
569 WLog_ERR(TAG, "TODO: Implement");
570 return -1;
571}
572
573LONG RegRestoreKeyA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpFile,
574 WINPR_ATTR_UNUSED DWORD dwFlags)
575{
576 WLog_ERR(TAG, "TODO: Implement");
577 return -1;
578}
579
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)
583{
584 WLog_ERR(TAG, "TODO: Implement");
585 return -1;
586}
587
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)
591{
592 WLog_ERR(TAG, "TODO: Implement");
593 return -1;
594}
595
596LONG RegSetKeySecurity(WINPR_ATTR_UNUSED HKEY hKey,
597 WINPR_ATTR_UNUSED SECURITY_INFORMATION SecurityInformation,
598 WINPR_ATTR_UNUSED PSECURITY_DESCRIPTOR pSecurityDescriptor)
599{
600 WLog_ERR(TAG, "TODO: Implement");
601 return -1;
602}
603
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)
607{
608 WLog_ERR(TAG, "TODO: Implement");
609 return -1;
610}
611
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)
615{
616 WLog_ERR(TAG, "TODO: Implement");
617 return -1;
618}
619
620LONG RegUnLoadKeyW(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCWSTR lpSubKey)
621{
622 WLog_ERR(TAG, "TODO: Implement");
623 return -1;
624}
625
626LONG RegUnLoadKeyA(WINPR_ATTR_UNUSED HKEY hKey, WINPR_ATTR_UNUSED LPCSTR lpSubKey)
627{
628 WLog_ERR(TAG, "TODO: Implement");
629 return -1;
630}
631
632#endif