Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/advapi32/registry.c
4387 views
1
/*
2
* Registry management
3
*
4
* Copyright (C) 1999 Alexandre Julliard
5
* Copyright (C) 2017 Dmitry Timoshkov
6
*
7
* Based on misc/registry.c code
8
* Copyright (C) 1996 Marcus Meissner
9
* Copyright (C) 1998 Matthew Becker
10
* Copyright (C) 1999 Sylvain St-Germain
11
*
12
* This library is free software; you can redistribute it and/or
13
* modify it under the terms of the GNU Lesser General Public
14
* License as published by the Free Software Foundation; either
15
* version 2.1 of the License, or (at your option) any later version.
16
*
17
* This library is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
* Lesser General Public License for more details.
21
*
22
* You should have received a copy of the GNU Lesser General Public
23
* License along with this library; if not, write to the Free Software
24
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25
*/
26
27
#include <stdlib.h>
28
#include <stdarg.h>
29
#include <stdio.h>
30
31
#include "ntstatus.h"
32
#define WIN32_NO_STATUS
33
#include "windef.h"
34
#include "winbase.h"
35
#include "winreg.h"
36
#include "winerror.h"
37
#include "winternl.h"
38
39
#include "wine/debug.h"
40
#include "wine/list.h"
41
42
WINE_DEFAULT_DEBUG_CHANNEL(reg);
43
44
NTSTATUS WINAPI RemapPredefinedHandleInternal( HKEY hkey, HKEY override );
45
NTSTATUS WINAPI DisablePredefinedHandleTableInternal( HKEY hkey );
46
47
48
/******************************************************************************
49
* RegOverridePredefKey [ADVAPI32.@]
50
*/
51
LSTATUS WINAPI RegOverridePredefKey( HKEY hkey, HKEY override )
52
{
53
return RtlNtStatusToDosError( RemapPredefinedHandleInternal( hkey, override ));
54
}
55
56
57
/******************************************************************************
58
* RegCreateKeyW [ADVAPI32.@]
59
*
60
* Creates the specified reg key.
61
*
62
* PARAMS
63
* hKey [I] Handle to an open key.
64
* lpSubKey [I] Name of a key that will be opened or created.
65
* phkResult [O] Receives a handle to the opened or created key.
66
*
67
* RETURNS
68
* Success: ERROR_SUCCESS
69
* Failure: nonzero error code defined in Winerror.h
70
*/
71
LSTATUS WINAPI RegCreateKeyW( HKEY hkey, LPCWSTR lpSubKey, PHKEY phkResult )
72
{
73
if (!phkResult)
74
return ERROR_INVALID_PARAMETER;
75
76
return RegCreateKeyExW( hkey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE,
77
MAXIMUM_ALLOWED, NULL, phkResult, NULL );
78
}
79
80
81
/******************************************************************************
82
* RegCreateKeyA [ADVAPI32.@]
83
*
84
* See RegCreateKeyW.
85
*/
86
LSTATUS WINAPI RegCreateKeyA( HKEY hkey, LPCSTR lpSubKey, PHKEY phkResult )
87
{
88
if (!phkResult)
89
return ERROR_INVALID_PARAMETER;
90
91
return RegCreateKeyExA( hkey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE,
92
MAXIMUM_ALLOWED, NULL, phkResult, NULL );
93
}
94
95
96
/******************************************************************************
97
* RegCreateKeyTransactedW [ADVAPI32.@]
98
*/
99
LSTATUS WINAPI RegCreateKeyTransactedW( HKEY hkey, LPCWSTR name, DWORD reserved, LPWSTR class,
100
DWORD options, REGSAM access, SECURITY_ATTRIBUTES *sa,
101
PHKEY retkey, LPDWORD dispos, HANDLE transaction, PVOID reserved2 )
102
{
103
FIXME( "(%p,%s,%lu,%s,%lu,%lu,%p,%p,%p,%p,%p): stub\n", hkey, debugstr_w(name), reserved,
104
debugstr_w(class), options, access, sa, retkey, dispos, transaction, reserved2 );
105
return ERROR_CALL_NOT_IMPLEMENTED;
106
}
107
108
109
/******************************************************************************
110
* RegCreateKeyTransactedA [ADVAPI32.@]
111
*/
112
LSTATUS WINAPI RegCreateKeyTransactedA( HKEY hkey, LPCSTR name, DWORD reserved, LPSTR class,
113
DWORD options, REGSAM access, SECURITY_ATTRIBUTES *sa,
114
PHKEY retkey, LPDWORD dispos, HANDLE transaction, PVOID reserved2 )
115
{
116
FIXME( "(%p,%s,%lu,%s,%lu,%lu,%p,%p,%p,%p,%p): stub\n", hkey, debugstr_a(name), reserved,
117
debugstr_a(class), options, access, sa, retkey, dispos, transaction, reserved2 );
118
return ERROR_CALL_NOT_IMPLEMENTED;
119
}
120
121
122
/******************************************************************************
123
* RegOpenKeyW [ADVAPI32.@]
124
*
125
* See RegOpenKeyA.
126
*/
127
LSTATUS WINAPI RegOpenKeyW( HKEY hkey, LPCWSTR name, PHKEY retkey )
128
{
129
if (!retkey)
130
return ERROR_INVALID_PARAMETER;
131
132
if (!name || !*name)
133
{
134
*retkey = hkey;
135
return ERROR_SUCCESS;
136
}
137
return RegOpenKeyExW( hkey, name, 0, MAXIMUM_ALLOWED, retkey );
138
}
139
140
141
/******************************************************************************
142
* RegOpenKeyA [ADVAPI32.@]
143
*
144
* Open a registry key.
145
*
146
* PARAMS
147
* hkey [I] Handle of parent key to open the new key under
148
* name [I] Name of the key under hkey to open
149
* retkey [O] Destination for the resulting Handle
150
*
151
* RETURNS
152
* Success: ERROR_SUCCESS
153
* Failure: A standard Win32 error code. When retkey is valid, *retkey is set to 0.
154
*/
155
LSTATUS WINAPI RegOpenKeyA( HKEY hkey, LPCSTR name, PHKEY retkey )
156
{
157
if (!retkey)
158
return ERROR_INVALID_PARAMETER;
159
160
if (!name || !*name)
161
{
162
*retkey = hkey;
163
return ERROR_SUCCESS;
164
}
165
return RegOpenKeyExA( hkey, name, 0, MAXIMUM_ALLOWED, retkey );
166
}
167
168
169
/******************************************************************************
170
* RegEnumKeyW [ADVAPI32.@]
171
*
172
* Enumerates subkeys of the specified open reg key.
173
*
174
* PARAMS
175
* hKey [I] Handle to an open key.
176
* dwIndex [I] Index of the subkey of hKey to retrieve.
177
* lpName [O] Name of the subkey.
178
* cchName [I] Size of lpName in TCHARS.
179
*
180
* RETURNS
181
* Success: ERROR_SUCCESS
182
* Failure: system error code. If there are no more subkeys available, the
183
* function returns ERROR_NO_MORE_ITEMS.
184
*/
185
LSTATUS WINAPI RegEnumKeyW( HKEY hkey, DWORD index, LPWSTR name, DWORD name_len )
186
{
187
return RegEnumKeyExW( hkey, index, name, &name_len, NULL, NULL, NULL, NULL );
188
}
189
190
191
/******************************************************************************
192
* RegEnumKeyA [ADVAPI32.@]
193
*
194
* See RegEnumKeyW.
195
*/
196
LSTATUS WINAPI RegEnumKeyA( HKEY hkey, DWORD index, LPSTR name, DWORD name_len )
197
{
198
return RegEnumKeyExA( hkey, index, name, &name_len, NULL, NULL, NULL, NULL );
199
}
200
201
202
/******************************************************************************
203
* RegQueryMultipleValuesA [ADVAPI32.@]
204
*
205
* Retrieves the type and data for a list of value names associated with a key.
206
*
207
* PARAMS
208
* hKey [I] Handle to an open key.
209
* val_list [O] Array of VALENT structures that describes the entries.
210
* num_vals [I] Number of elements in val_list.
211
* lpValueBuf [O] Pointer to a buffer that receives the data for each value.
212
* ldwTotsize [I/O] Size of lpValueBuf.
213
*
214
* RETURNS
215
* Success: ERROR_SUCCESS. ldwTotsize contains num bytes copied.
216
* Failure: nonzero error code from Winerror.h ldwTotsize contains num needed
217
* bytes.
218
*/
219
LSTATUS WINAPI RegQueryMultipleValuesA( HKEY hkey, PVALENTA val_list, DWORD num_vals,
220
LPSTR lpValueBuf, LPDWORD ldwTotsize )
221
{
222
unsigned int i;
223
DWORD maxBytes = *ldwTotsize;
224
LSTATUS status;
225
LPSTR bufptr = lpValueBuf;
226
*ldwTotsize = 0;
227
228
TRACE("(%p,%p,%ld,%p,%p=%ld)\n", hkey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
229
230
for(i=0; i < num_vals; ++i)
231
{
232
233
val_list[i].ve_valuelen=0;
234
status = RegQueryValueExA(hkey, val_list[i].ve_valuename, NULL, NULL, NULL, &val_list[i].ve_valuelen);
235
if(status != ERROR_SUCCESS)
236
{
237
return status;
238
}
239
240
if(lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
241
{
242
status = RegQueryValueExA(hkey, val_list[i].ve_valuename, NULL, &val_list[i].ve_type,
243
(LPBYTE)bufptr, &val_list[i].ve_valuelen);
244
if(status != ERROR_SUCCESS)
245
{
246
return status;
247
}
248
249
val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
250
251
bufptr += val_list[i].ve_valuelen;
252
}
253
254
*ldwTotsize += val_list[i].ve_valuelen;
255
}
256
return lpValueBuf != NULL && *ldwTotsize <= maxBytes ? ERROR_SUCCESS : ERROR_MORE_DATA;
257
}
258
259
260
/******************************************************************************
261
* RegQueryMultipleValuesW [ADVAPI32.@]
262
*
263
* See RegQueryMultipleValuesA.
264
*/
265
LSTATUS WINAPI RegQueryMultipleValuesW( HKEY hkey, PVALENTW val_list, DWORD num_vals,
266
LPWSTR lpValueBuf, LPDWORD ldwTotsize )
267
{
268
unsigned int i;
269
DWORD maxBytes = *ldwTotsize;
270
LSTATUS status;
271
LPSTR bufptr = (LPSTR)lpValueBuf;
272
*ldwTotsize = 0;
273
274
TRACE("(%p,%p,%ld,%p,%p=%ld)\n", hkey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
275
276
for(i=0; i < num_vals; ++i)
277
{
278
val_list[i].ve_valuelen=0;
279
status = RegQueryValueExW(hkey, val_list[i].ve_valuename, NULL, NULL, NULL, &val_list[i].ve_valuelen);
280
if(status != ERROR_SUCCESS)
281
{
282
return status;
283
}
284
285
if(lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
286
{
287
status = RegQueryValueExW(hkey, val_list[i].ve_valuename, NULL, &val_list[i].ve_type,
288
(LPBYTE)bufptr, &val_list[i].ve_valuelen);
289
if(status != ERROR_SUCCESS)
290
{
291
return status;
292
}
293
294
val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
295
296
bufptr += val_list[i].ve_valuelen;
297
}
298
299
*ldwTotsize += val_list[i].ve_valuelen;
300
}
301
return lpValueBuf != NULL && *ldwTotsize <= maxBytes ? ERROR_SUCCESS : ERROR_MORE_DATA;
302
}
303
304
305
/******************************************************************************
306
* RegQueryReflectionKey [ADVAPI32.@]
307
*/
308
LONG WINAPI RegQueryReflectionKey( HKEY hkey, BOOL *is_reflection_disabled )
309
{
310
FIXME( "%p, %p stub\n", hkey, is_reflection_disabled );
311
*is_reflection_disabled = TRUE;
312
return ERROR_CALL_NOT_IMPLEMENTED;
313
}
314
315
316
/******************************************************************************
317
* RegDeleteKeyW [ADVAPI32.@]
318
*
319
* See RegDeleteKeyA.
320
*/
321
LSTATUS WINAPI RegDeleteKeyW( HKEY hkey, LPCWSTR name )
322
{
323
return RegDeleteKeyExW( hkey, name, 0, 0 );
324
}
325
326
327
/******************************************************************************
328
* RegDeleteKeyA [ADVAPI32.@]
329
*
330
* Delete a registry key.
331
*
332
* PARAMS
333
* hkey [I] Handle to parent key containing the key to delete
334
* name [I] Name of the key user hkey to delete
335
*
336
* NOTES
337
*
338
* MSDN is wrong when it says that hkey must be opened with the DELETE access
339
* right. In reality, it opens a new handle with DELETE access.
340
*
341
* RETURNS
342
* Success: ERROR_SUCCESS
343
* Failure: Error code
344
*/
345
LSTATUS WINAPI RegDeleteKeyA( HKEY hkey, LPCSTR name )
346
{
347
return RegDeleteKeyExA( hkey, name, 0, 0 );
348
}
349
350
351
/******************************************************************************
352
* RegSetValueW [ADVAPI32.@]
353
*
354
* Sets the data for the default or unnamed value of a reg key.
355
*
356
* PARAMS
357
* hkey [I] Handle to an open key.
358
* subkey [I] Name of a subkey of hKey.
359
* type [I] Type of information to store.
360
* data [I] String that contains the data to set for the default value.
361
* count [I] Ignored.
362
*
363
* RETURNS
364
* Success: ERROR_SUCCESS
365
* Failure: nonzero error code from Winerror.h
366
*/
367
LSTATUS WINAPI RegSetValueW( HKEY hkey, LPCWSTR subkey, DWORD type, LPCWSTR data, DWORD count )
368
{
369
TRACE("(%p,%s,%ld,%s,%ld)\n", hkey, debugstr_w(subkey), type, debugstr_w(data), count );
370
371
if (type != REG_SZ || !data) return ERROR_INVALID_PARAMETER;
372
373
return RegSetKeyValueW( hkey, subkey, NULL, type, data, (lstrlenW(data) + 1)*sizeof(WCHAR) );
374
}
375
376
/******************************************************************************
377
* RegSetValueA [ADVAPI32.@]
378
*
379
* See RegSetValueW.
380
*/
381
LSTATUS WINAPI RegSetValueA( HKEY hkey, LPCSTR subkey, DWORD type, LPCSTR data, DWORD count )
382
{
383
TRACE("(%p,%s,%ld,%s,%ld)\n", hkey, debugstr_a(subkey), type, debugstr_a(data), count );
384
385
if (type != REG_SZ || !data) return ERROR_INVALID_PARAMETER;
386
387
return RegSetKeyValueA( hkey, subkey, NULL, type, data, strlen(data) + 1 );
388
}
389
390
391
/******************************************************************************
392
* RegQueryValueW [ADVAPI32.@]
393
*
394
* Retrieves the data associated with the default or unnamed value of a key.
395
*
396
* PARAMS
397
* hkey [I] Handle to an open key.
398
* name [I] Name of the subkey of hKey.
399
* data [O] Receives the string associated with the default value
400
* of the key.
401
* count [I/O] Size of lpValue in bytes.
402
*
403
* RETURNS
404
* Success: ERROR_SUCCESS
405
* Failure: nonzero error code from Winerror.h
406
*/
407
LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count )
408
{
409
DWORD ret;
410
HKEY subkey = hkey;
411
412
TRACE("(%p,%s,%p,%ld)\n", hkey, debugstr_w(name), data, count ? *count : 0 );
413
414
if (name && name[0])
415
{
416
if ((ret = RegOpenKeyW( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
417
}
418
ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
419
if (subkey != hkey) RegCloseKey( subkey );
420
if (ret == ERROR_FILE_NOT_FOUND)
421
{
422
/* return empty string if default value not found */
423
if (data) *data = 0;
424
if (count) *count = sizeof(WCHAR);
425
ret = ERROR_SUCCESS;
426
}
427
return ret;
428
}
429
430
431
/******************************************************************************
432
* RegQueryValueA [ADVAPI32.@]
433
*
434
* See RegQueryValueW.
435
*/
436
LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG count )
437
{
438
DWORD ret;
439
HKEY subkey = hkey;
440
441
TRACE("(%p,%s,%p,%ld)\n", hkey, debugstr_a(name), data, count ? *count : 0 );
442
443
if (name && name[0])
444
{
445
if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
446
}
447
ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
448
if (subkey != hkey) RegCloseKey( subkey );
449
if (ret == ERROR_FILE_NOT_FOUND)
450
{
451
/* return empty string if default value not found */
452
if (data) *data = 0;
453
if (count) *count = 1;
454
ret = ERROR_SUCCESS;
455
}
456
return ret;
457
}
458
459
460
/******************************************************************************
461
* RegSaveKeyW [ADVAPI32.@]
462
*
463
* Save a key and all of its subkeys and values to a new file in the standard format.
464
*
465
* PARAMS
466
* hkey [I] Handle of key where save begins
467
* lpFile [I] Address of filename to save to
468
* sa [I] Address of security structure
469
*
470
* RETURNS
471
* Success: ERROR_SUCCESS
472
* Failure: nonzero error code from Winerror.h
473
*/
474
LSTATUS WINAPI RegSaveKeyW( HKEY hkey, LPCWSTR file, LPSECURITY_ATTRIBUTES sa )
475
{
476
return RegSaveKeyExW(hkey, file, sa, 0);
477
}
478
479
480
/******************************************************************************
481
* RegSaveKeyA [ADVAPI32.@]
482
*
483
* See RegSaveKeyW.
484
*/
485
LSTATUS WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa )
486
{
487
return RegSaveKeyExA(hkey, file, sa, 0);
488
}
489
490
491
/******************************************************************************
492
* RegReplaceKeyW [ADVAPI32.@]
493
*
494
* Replace the file backing a registry key and all its subkeys with another file.
495
*
496
* PARAMS
497
* hkey [I] Handle of open key
498
* lpSubKey [I] Address of name of subkey
499
* lpNewFile [I] Address of filename for file with new data
500
* lpOldFile [I] Address of filename for backup file
501
*
502
* RETURNS
503
* Success: ERROR_SUCCESS
504
* Failure: nonzero error code from Winerror.h
505
*/
506
LSTATUS WINAPI RegReplaceKeyW( HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpNewFile,
507
LPCWSTR lpOldFile )
508
{
509
FIXME("(%p,%s,%s,%s): stub\n", hkey, debugstr_w(lpSubKey),
510
debugstr_w(lpNewFile),debugstr_w(lpOldFile));
511
return ERROR_SUCCESS;
512
}
513
514
515
/******************************************************************************
516
* RegRenameKey [ADVAPI32.@]
517
*
518
*/
519
LSTATUS WINAPI RegRenameKey( HKEY hkey, LPCWSTR subkey_name, LPCWSTR new_name )
520
{
521
UNICODE_STRING str;
522
LSTATUS ret;
523
HKEY subkey;
524
525
TRACE("%p, %s, %s.\n", hkey, debugstr_w(subkey_name), debugstr_w(new_name));
526
527
RtlInitUnicodeString(&str, new_name);
528
529
if (!subkey_name)
530
return RtlNtStatusToDosError( NtRenameKey( hkey, &str ));
531
532
if ((ret = RegOpenKeyExW( hkey, subkey_name, 0, KEY_WRITE, &subkey )))
533
return ret;
534
535
ret = RtlNtStatusToDosError( NtRenameKey( subkey, &str ));
536
RegCloseKey( subkey );
537
538
return ret;
539
}
540
541
542
/******************************************************************************
543
* RegReplaceKeyA [ADVAPI32.@]
544
*
545
* See RegReplaceKeyW.
546
*/
547
LSTATUS WINAPI RegReplaceKeyA( HKEY hkey, LPCSTR lpSubKey, LPCSTR lpNewFile,
548
LPCSTR lpOldFile )
549
{
550
UNICODE_STRING lpSubKeyW;
551
UNICODE_STRING lpNewFileW;
552
UNICODE_STRING lpOldFileW;
553
LONG ret;
554
555
RtlCreateUnicodeStringFromAsciiz( &lpSubKeyW, lpSubKey );
556
RtlCreateUnicodeStringFromAsciiz( &lpOldFileW, lpOldFile );
557
RtlCreateUnicodeStringFromAsciiz( &lpNewFileW, lpNewFile );
558
ret = RegReplaceKeyW( hkey, lpSubKeyW.Buffer, lpNewFileW.Buffer, lpOldFileW.Buffer );
559
RtlFreeUnicodeString( &lpOldFileW );
560
RtlFreeUnicodeString( &lpNewFileW );
561
RtlFreeUnicodeString( &lpSubKeyW );
562
return ret;
563
}
564
565
566
/******************************************************************************
567
* RegConnectRegistryW [ADVAPI32.@]
568
*
569
* Establish a connection to a predefined registry key on another computer.
570
*
571
* PARAMS
572
* lpMachineName [I] Address of name of remote computer
573
* hHey [I] Predefined registry handle
574
* phkResult [I] Address of buffer for remote registry handle
575
*
576
* RETURNS
577
* Success: ERROR_SUCCESS
578
* Failure: nonzero error code from Winerror.h
579
*/
580
LSTATUS WINAPI RegConnectRegistryW( LPCWSTR lpMachineName, HKEY hKey,
581
PHKEY phkResult )
582
{
583
LONG ret;
584
585
TRACE("(%s,%p,%p)\n",debugstr_w(lpMachineName), hKey, phkResult);
586
587
if (!lpMachineName || !*lpMachineName) {
588
/* Use the local machine name */
589
ret = RegOpenKeyW( hKey, NULL, phkResult );
590
}
591
else {
592
WCHAR compName[MAX_COMPUTERNAME_LENGTH + 1];
593
DWORD len = ARRAY_SIZE( compName );
594
595
/* MSDN says lpMachineName must start with \\ : not so */
596
if( lpMachineName[0] == '\\' && lpMachineName[1] == '\\')
597
lpMachineName += 2;
598
if (GetComputerNameW(compName, &len))
599
{
600
if (!wcsicmp(lpMachineName, compName))
601
ret = RegOpenKeyW(hKey, NULL, phkResult);
602
else
603
{
604
FIXME("Connect to %s is not supported.\n",debugstr_w(lpMachineName));
605
ret = ERROR_BAD_NETPATH;
606
}
607
}
608
else
609
ret = GetLastError();
610
}
611
return ret;
612
}
613
614
615
/******************************************************************************
616
* RegConnectRegistryA [ADVAPI32.@]
617
*
618
* See RegConnectRegistryW.
619
*/
620
LSTATUS WINAPI RegConnectRegistryA( LPCSTR machine, HKEY hkey, PHKEY reskey )
621
{
622
UNICODE_STRING machineW;
623
LONG ret;
624
625
RtlCreateUnicodeStringFromAsciiz( &machineW, machine );
626
ret = RegConnectRegistryW( machineW.Buffer, hkey, reskey );
627
RtlFreeUnicodeString( &machineW );
628
return ret;
629
}
630
631
632
/******************************************************************************
633
* RegDisablePredefinedCache [ADVAPI32.@]
634
*
635
* Disables the caching of the HKEY_CURRENT_USER key for the process.
636
*
637
* PARAMS
638
* None.
639
*
640
* RETURNS
641
* Success: ERROR_SUCCESS
642
* Failure: nonzero error code from Winerror.h
643
*
644
* NOTES
645
* This is useful for services that use impersonation.
646
*/
647
LSTATUS WINAPI RegDisablePredefinedCache(void)
648
{
649
return RtlNtStatusToDosError( DisablePredefinedHandleTableInternal( HKEY_CURRENT_USER ));
650
}
651
652
653
/******************************************************************************
654
* RegCopyTreeA [ADVAPI32.@]
655
*
656
*/
657
LONG WINAPI RegCopyTreeA( HKEY hsrc, const char *subkey, HKEY hdst )
658
{
659
UNICODE_STRING subkeyW;
660
LONG ret;
661
662
if (subkey) RtlCreateUnicodeStringFromAsciiz( &subkeyW, subkey );
663
else subkeyW.Buffer = NULL;
664
ret = RegCopyTreeW( hsrc, subkeyW.Buffer, hdst );
665
RtlFreeUnicodeString( &subkeyW );
666
return ret;
667
}
668
669
670
/******************************************************************************
671
* RegEnableReflectionKey [ADVAPI32.@]
672
*
673
*/
674
LONG WINAPI RegEnableReflectionKey(HKEY base)
675
{
676
FIXME("%p: stub\n", base);
677
return ERROR_CALL_NOT_IMPLEMENTED;
678
}
679
680
681
/******************************************************************************
682
* RegDisableReflectionKey [ADVAPI32.@]
683
*
684
*/
685
LONG WINAPI RegDisableReflectionKey(HKEY base)
686
{
687
FIXME("%p: stub\n", base);
688
return ERROR_SUCCESS;
689
}
690
691