1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Test for the HKEY_CLASSES_ROOT key
5  * PROGRAMMER:      Jérôme Gardou <jerome.gardou@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 #include <ndk/cmfuncs.h>
11 
12 #define IS_HKCR(hk) (((UINT_PTR)hk & 3) == 2)
13 
14 /* HKCU and HKLM system paths */
15 static UNICODE_STRING HKLM_ClassesPath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Classes");
16 static UNICODE_STRING HKCU_ClassesPath;
17 
18 static
19 LONG
20 DeleteSubKey(HKEY hKey, LPWSTR Root, LPWSTR SubKey)
21 {
22     HKEY RootKey;
23     LONG ErrorCode;
24 
25     ErrorCode = RegOpenKeyExW(
26         hKey,
27         Root,
28         0,
29         MAXIMUM_ALLOWED,
30         &RootKey);
31     ok_dec(ErrorCode, ERROR_SUCCESS);
32     ErrorCode = RegDeleteKeyW(RootKey, SubKey);
33     RegCloseKey(RootKey);
34 
35     return ErrorCode;
36 }
37 
38 static
39 void
40 GetKeyName(HKEY hKey, PUNICODE_STRING KeyName)
41 {
42     UNICODE_STRING InfoName;
43     PKEY_NAME_INFORMATION NameInformation;
44     ULONG InfoLength;
45     NTSTATUS Status;
46 
47     /* Get info length */
48     InfoLength = 0;
49     Status = NtQueryKey(hKey, KeyNameInformation, NULL, 0, &InfoLength);
50     ok_ntstatus(Status, STATUS_BUFFER_TOO_SMALL);
51 
52     /* Get it for real */
53     NameInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, InfoLength);
54     ok(NameInformation != NULL, "\n");
55 
56     Status = NtQueryKey(hKey, KeyNameInformation, NameInformation, InfoLength, &InfoLength);
57     ok_ntstatus(Status, STATUS_SUCCESS);
58 
59     InfoName.Buffer = NameInformation->Name;
60     InfoName.Length = NameInformation->NameLength;
61     InfoName.MaximumLength = InfoName.Length;
62 
63     RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, &InfoName, KeyName);
64 
65     RtlFreeHeap(RtlGetProcessHeap(), 0, NameInformation);
66 }
67 
68 static void _test_key_deleted(HKEY hKey, BOOL Deleted, ULONG LineNumber)
69 {
70     DWORD ErrorCode = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
71     if (Deleted)
72         ok_(__FILE__, LineNumber)(ErrorCode == ERROR_KEY_DELETED, "\n");
73     else
74         ok_(__FILE__, LineNumber)(ErrorCode == ERROR_SUCCESS, "\n");
75 }
76 #define ok_key_deleted(hKey) _test_key_deleted(hKey, TRUE, __LINE__)
77 #define ok_key_not_deleted(hKey) _test_key_deleted(hKey, FALSE, __LINE__)
78 
79 static void _test_key_name(HKEY hKey, PUNICODE_STRING Prefix, LPCWSTR Name, ULONG LineNumber)
80 {
81     UNICODE_STRING ExpectedName, KeyName;
82     WCHAR Buffer[1024];
83 
84     ExpectedName.Length = 0;
85     ExpectedName.MaximumLength = sizeof(Buffer);
86     ExpectedName.Buffer = Buffer;
87 
88     RtlAppendUnicodeStringToString(&ExpectedName, Prefix);
89     RtlAppendUnicodeToString(&ExpectedName, L"\\");
90     RtlAppendUnicodeToString(&ExpectedName, Name);
91 
92     GetKeyName(hKey, &KeyName);
93 
94     ok_(__FILE__, LineNumber)(RtlCompareUnicodeString(&KeyName, &ExpectedName, TRUE) == 0,
95             "Key name is %.*S, expected %.*S\n",
96             KeyName.Length, KeyName.Buffer,
97             ExpectedName.Length, ExpectedName.Buffer);
98 
99     RtlFreeUnicodeString(&KeyName);
100 }
101 
102 #define ok_key_name(hKey, Prefix, Name) _test_key_name(hKey, Prefix, Name, __LINE__)
103 
104 static
105 void
106 Test_CreateOpenKey(void)
107 {
108     HKEY MachineKey, MachineSubKey;
109     HKEY UserKey, UserSubKey;
110     HKEY ClassesRootKey, ClassesRootSubKey;
111     DWORD ErrorCode;
112     DWORD Disposition;
113 
114     /* First create a subkey in HKLM */
115     ErrorCode = RegCreateKeyExW(
116         HKEY_LOCAL_MACHINE,
117         L"Software\\Classes\\Apitest_HKLM",
118         0,
119         NULL,
120         0,
121         MAXIMUM_ALLOWED,
122         NULL,
123         &MachineKey,
124         NULL);
125 
126     if (ErrorCode == ERROR_ACCESS_DENIED)
127     {
128         win_skip("Please run those tests with Administrator rights\n");
129         return;
130     }
131 
132     ok_dec(ErrorCode, ERROR_SUCCESS);
133     ok(!IS_HKCR(MachineKey), "\n");
134 
135     /* Open it in HKCR */
136     ErrorCode = RegOpenKeyExW(
137         HKEY_CLASSES_ROOT,
138         L"Apitest_HKLM",
139         0,
140         MAXIMUM_ALLOWED,
141         &ClassesRootKey);
142     ok_dec(ErrorCode, ERROR_SUCCESS);
143     ok(IS_HKCR(ClassesRootKey), "\n");
144     ok_key_name(ClassesRootKey, &HKLM_ClassesPath, L"Apitest_HKLM");
145 
146     /* Try opening it in HKCU */
147     UserKey = (HKEY)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
148     ErrorCode = RegOpenKeyExW(
149         HKEY_CURRENT_USER,
150         L"Software\\Classes\\Apitest_HKLM",
151         0,
152         MAXIMUM_ALLOWED,
153         &UserKey);
154     ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND);
155     ok_hdl(UserKey, NULL);
156 
157     /* Cleanup */
158     RegCloseKey(ClassesRootKey);
159     RegCloseKey(MachineKey);
160     ErrorCode = DeleteSubKey(HKEY_LOCAL_MACHINE, L"Software\\Classes", L"Apitest_HKLM");
161     ok_dec(ErrorCode, ERROR_SUCCESS);
162 
163     /* Try creating in HKCR */
164     ErrorCode = RegCreateKeyExW(
165         HKEY_CLASSES_ROOT,
166         L"Apitest_HKCR",
167         0,
168         NULL,
169         0,
170         MAXIMUM_ALLOWED,
171         NULL,
172         &ClassesRootKey,
173         NULL);
174     ok_dec(ErrorCode, ERROR_SUCCESS);
175     ok(IS_HKCR(ClassesRootKey), "\n");
176     ok_key_name(ClassesRootKey, &HKLM_ClassesPath, L"Apitest_HKCR");
177 
178     /* It should be present in HKLM */
179     ErrorCode = RegOpenKeyExW(
180         HKEY_LOCAL_MACHINE,
181         L"Software\\Classes\\Apitest_HKCR",
182         0,
183         MAXIMUM_ALLOWED,
184         &MachineKey);
185     ok_dec(ErrorCode, ERROR_SUCCESS);
186     ok(!IS_HKCR(MachineKey), "\n");
187 
188     /* But not in HKCU */
189     UserKey = (HKEY)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
190     ErrorCode = RegOpenKeyExW(
191         HKEY_CURRENT_USER,
192         L"Software\\Classes\\Apitest_HKCR",
193         0,
194         MAXIMUM_ALLOWED,
195         &UserKey);
196     ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND);
197     ok_hdl(UserKey, NULL);
198 
199     /* This must delete the one in HKLM */
200     ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCR");
201     ok_dec(ErrorCode, ERROR_SUCCESS);
202     ok_key_deleted(ClassesRootKey);
203     ok_key_deleted(MachineKey);
204     RegCloseKey(ClassesRootKey);
205     RegCloseKey(MachineKey);
206 
207     /* Test that it is really not present anymore */
208     MachineKey = (HKEY)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
209     ErrorCode = RegOpenKeyExW(
210         HKEY_LOCAL_MACHINE,
211         L"Software\\Classes\\Apitest_HKCR",
212         0,
213         MAXIMUM_ALLOWED,
214         &MachineKey);
215     ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND);
216     ok_hdl(MachineKey, NULL);
217 
218     /* Try creating in HKCU */
219     ErrorCode = RegCreateKeyExW(
220         HKEY_CURRENT_USER,
221         L"Software\\Classes\\Apitest_HKCU",
222         0,
223         NULL,
224         0,
225         MAXIMUM_ALLOWED,
226         NULL,
227         &UserKey,
228         NULL);
229     ok_dec(ErrorCode, ERROR_SUCCESS);
230     ok(!IS_HKCR(UserKey), "\n");
231 
232     /* Try opening it in HKCR */
233     ErrorCode = RegOpenKeyExW(
234         HKEY_CLASSES_ROOT,
235         L"Apitest_HKCU",
236         0,
237         MAXIMUM_ALLOWED,
238         &ClassesRootKey);
239     ok_dec(ErrorCode, ERROR_SUCCESS);
240     ok(IS_HKCR(ClassesRootKey), "\n");
241     ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKCU");
242 
243     /* And in HKLM */
244     ErrorCode = RegOpenKeyExW(
245         HKEY_LOCAL_MACHINE,
246         L"Software\\Classes\\Apitest_HKCU",
247         0,
248         MAXIMUM_ALLOWED,
249         &MachineKey);
250     ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND);
251     ok_hdl(MachineKey, NULL);
252 
253     ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCU");
254     ok_dec(ErrorCode, ERROR_SUCCESS);
255     ok_key_deleted(ClassesRootKey);
256     ok_key_deleted(UserKey);
257     RegCloseKey(ClassesRootKey);
258     RegCloseKey(UserKey);
259 
260     /* Test that it is really not present anymore */
261     UserKey = (HKEY)(ULONG_PTR)0xCAFEF00DCAFEF00DULL;
262     ErrorCode = RegOpenKeyExW(
263         HKEY_CURRENT_USER,
264         L"Software\\Classes\\Apitest_HKCU",
265         0,
266         MAXIMUM_ALLOWED,
267         &UserKey);
268     ok_dec(ErrorCode, ERROR_FILE_NOT_FOUND);
269     ok_hdl(UserKey, NULL);
270 
271     /* Try creating in both HKLM and HKCU */
272     ErrorCode = RegCreateKeyExW(
273         HKEY_CURRENT_USER,
274         L"Software\\Classes\\Apitest_HKLM_HKCU",
275         0,
276         NULL,
277         0,
278         MAXIMUM_ALLOWED,
279         NULL,
280         &UserKey,
281         NULL);
282     ok_dec(ErrorCode, ERROR_SUCCESS);
283     ok(!IS_HKCR(UserKey), "\n");
284 
285     ErrorCode = RegCreateKeyExW(
286         HKEY_LOCAL_MACHINE,
287         L"Software\\Classes\\Apitest_HKLM_HKCU",
288         0,
289         NULL,
290         0,
291         MAXIMUM_ALLOWED,
292         NULL,
293         &MachineKey,
294         NULL);
295     ok_dec(ErrorCode, ERROR_SUCCESS);
296     ok(!IS_HKCR(MachineKey), "\n");
297 
298     /* Open it in HKCR */
299     ErrorCode = RegOpenKeyExW(
300         HKEY_CLASSES_ROOT,
301         L"Apitest_HKLM_HKCU",
302         0,
303         MAXIMUM_ALLOWED,
304         &ClassesRootKey);
305     ok_dec(ErrorCode, ERROR_SUCCESS);
306     ok(IS_HKCR(ClassesRootKey), "\n");
307     /* Verify it has opened the HKCU one */
308     ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKLM_HKCU");
309 
310     /* Try the same thing, but this time with RegCreateKeyEx API */
311     RegCloseKey(ClassesRootKey);
312     ErrorCode = RegCreateKeyExW(
313         HKEY_CLASSES_ROOT,
314         L"Apitest_HKLM_HKCU",
315         0,
316         NULL,
317         0,
318         MAXIMUM_ALLOWED,
319         NULL,
320         &ClassesRootKey,
321         &Disposition);
322     ok_dec(ErrorCode, ERROR_SUCCESS);
323     ok(IS_HKCR(ClassesRootKey), "\n");
324     /* Verify it has opened the HKCU one */
325     ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKLM_HKCU");
326     ok_hex(Disposition, REG_OPENED_EXISTING_KEY);
327 
328     /* Deleting it from HKCR first deletes the one in HKCU */
329     ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM_HKCU");
330     ok_dec(ErrorCode, ERROR_SUCCESS);
331     ok_key_deleted(UserKey);
332     ok_key_deleted(ClassesRootKey);
333     ok_key_not_deleted(MachineKey);
334 
335     RegCloseKey(UserKey);
336     RegCloseKey(ClassesRootKey);
337 
338     /* This deletes it from HKLM this time */
339     ErrorCode = RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM_HKCU");
340     ok_dec(ErrorCode, ERROR_SUCCESS);
341     ok_key_deleted(MachineKey);
342     RegCloseKey(MachineKey);
343 
344     /* See what happens with subkeys */
345     ErrorCode = RegCreateKeyExW(
346         HKEY_LOCAL_MACHINE,
347         L"Software\\Classes\\Apitest_HKLM",
348         0,
349         NULL,
350         0,
351         MAXIMUM_ALLOWED,
352         NULL,
353         &MachineKey,
354         NULL);
355     ok_dec(ErrorCode, ERROR_SUCCESS);
356     ok(!IS_HKCR(MachineKey), "\n");
357 
358     /* Open it in HKCR */
359     ErrorCode = RegOpenKeyExW(
360         HKEY_CLASSES_ROOT,
361         L"Apitest_HKLM",
362         0,
363         MAXIMUM_ALLOWED,
364         &ClassesRootKey);
365     ok_dec(ErrorCode, ERROR_SUCCESS);
366     ok(IS_HKCR(ClassesRootKey), "\n");
367     ok_key_name(ClassesRootKey, &HKLM_ClassesPath, L"Apitest_HKLM");
368 
369     /* Create a corresponding subkey in HKCU */
370     ErrorCode = RegCreateKeyExW(
371         HKEY_CURRENT_USER,
372         L"Software\\Classes\\Apitest_HKLM\\HKCU_Subkey",
373         0,
374         NULL,
375         0,
376         MAXIMUM_ALLOWED,
377         NULL,
378         &UserSubKey,
379         NULL);
380     ok_dec(ErrorCode, ERROR_SUCCESS);
381     ok(!IS_HKCR(UserSubKey), "\n");
382 
383     /* Open it as an HKCR subkey */
384     ErrorCode = RegOpenKeyExW(
385         ClassesRootKey,
386         L"HKCU_Subkey",
387         0,
388         MAXIMUM_ALLOWED,
389         &ClassesRootSubKey);
390     ok_dec(ErrorCode, ERROR_SUCCESS);
391     ok(IS_HKCR(ClassesRootSubKey), "\n");
392     ok_key_name(ClassesRootSubKey, &HKCU_ClassesPath, L"Apitest_HKLM\\HKCU_Subkey");
393 
394     /* Try the same thing, but this time with RegCreateKeyEx API */
395     RegCloseKey(ClassesRootSubKey);
396     ErrorCode = RegCreateKeyExW(
397         ClassesRootKey,
398         L"HKCU_Subkey",
399         0,
400         NULL,
401         0,
402         MAXIMUM_ALLOWED,
403         NULL,
404         &ClassesRootSubKey,
405         &Disposition);
406     ok_dec(ErrorCode, ERROR_SUCCESS);
407     ok(IS_HKCR(ClassesRootSubKey), "\n");
408     /* Verify it has opened the HKCU one */
409     ok_key_name(ClassesRootSubKey, &HKCU_ClassesPath, L"Apitest_HKLM\\HKCU_Subkey");
410     ok_hex(Disposition, REG_OPENED_EXISTING_KEY);
411 
412     /* This one now exists */
413     ErrorCode = RegOpenKeyExW(
414         HKEY_CURRENT_USER,
415         L"Software\\Classes\\Apitest_HKLM",
416         0,
417         MAXIMUM_ALLOWED,
418         &UserKey);
419     ok_dec(ErrorCode, ERROR_SUCCESS);
420     ok(!IS_HKCR(UserKey), "\n");
421 
422     /* Delete */
423     ErrorCode = RegDeleteKeyW(UserKey, L"HKCU_Subkey");
424     ok_dec(ErrorCode, ERROR_SUCCESS);
425     ok_key_deleted(UserSubKey);
426     ok_key_deleted(ClassesRootSubKey);
427     RegCloseKey(UserSubKey);
428     RegCloseKey(ClassesRootSubKey);
429 
430     /* See what this deletes */
431     RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM");
432     ok_key_deleted(UserKey);
433     RegCloseKey(UserKey);
434     ok_key_not_deleted(ClassesRootKey);
435     ok_key_not_deleted(MachineKey);
436 
437     /* Once again */
438     RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKLM");
439     ok_key_deleted(ClassesRootKey);
440     ok_key_deleted(MachineKey);
441     RegCloseKey(ClassesRootKey);
442     RegCloseKey(MachineKey);
443 
444     /* Same, but with HKCU first */
445     ErrorCode = RegCreateKeyExW(
446         HKEY_CURRENT_USER,
447         L"Software\\Classes\\Apitest_HKCU",
448         0,
449         NULL,
450         0,
451         MAXIMUM_ALLOWED,
452         NULL,
453         &UserKey,
454         NULL);
455     ok_dec(ErrorCode, ERROR_SUCCESS);
456     ok(!IS_HKCR(UserKey), "\n");
457 
458     /* Open it in HKCR */
459     ErrorCode = RegOpenKeyExW(
460         HKEY_CLASSES_ROOT,
461         L"Apitest_HKCU",
462         0,
463         MAXIMUM_ALLOWED,
464         &ClassesRootKey);
465     ok_dec(ErrorCode, ERROR_SUCCESS);
466     ok(IS_HKCR(ClassesRootKey), "\n");
467     ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKCU");
468 
469     /* Try creating a subkey with this HKCR handle, which points to a subkey in HKCU. */
470     ErrorCode = RegCreateKeyExW(
471         ClassesRootKey,
472         L"HKCR_Subkey",
473         0,
474         NULL,
475         0,
476         MAXIMUM_ALLOWED,
477         NULL,
478         &ClassesRootSubKey,
479         NULL);
480     ok_dec(ErrorCode, ERROR_SUCCESS);
481     ok(IS_HKCR(ClassesRootSubKey), "\n");
482     /* It is in fact created in HKLM */
483     ok_key_name(ClassesRootSubKey, &HKLM_ClassesPath, L"Apitest_HKCU\\HKCR_Subkey");
484     /* Let's see if we can delete it */
485     RegDeleteKeyW(ClassesRootKey, L"HKCR_Subkey");
486     ok_key_deleted(ClassesRootSubKey);
487     RegCloseKey(ClassesRootSubKey);
488 
489     /* Create a corresponding subkey in HKLM */
490     ErrorCode = RegCreateKeyExW(
491         HKEY_LOCAL_MACHINE,
492         L"Software\\Classes\\Apitest_HKCU\\HKLM_Subkey",
493         0,
494         NULL,
495         0,
496         MAXIMUM_ALLOWED,
497         NULL,
498         &MachineSubKey,
499         NULL);
500     ok_dec(ErrorCode, ERROR_SUCCESS);
501     ok(!IS_HKCR(MachineSubKey), "\n");
502 
503     /* Open it from the HKCR handle (which is still pointing to HKCU) */
504     ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKCU");
505     ErrorCode = RegOpenKeyExW(
506         ClassesRootKey,
507         L"HKLM_Subkey",
508         0,
509         MAXIMUM_ALLOWED,
510         &ClassesRootSubKey);
511     ok_dec(ErrorCode, ERROR_SUCCESS);
512     ok(IS_HKCR(ClassesRootSubKey), "\n");
513     ok_key_name(ClassesRootSubKey, &HKLM_ClassesPath, L"Apitest_HKCU\\HKLM_Subkey");
514 
515     /* This one now exists */
516     ErrorCode = RegOpenKeyExW(
517         HKEY_LOCAL_MACHINE,
518         L"Software\\Classes\\Apitest_HKCU",
519         0,
520         MAXIMUM_ALLOWED,
521         &MachineKey);
522     ok_dec(ErrorCode, ERROR_SUCCESS);
523     ok(!IS_HKCR(MachineKey), "\n");
524 
525     /* Delete this subkey */
526     ErrorCode = RegDeleteKeyW(MachineKey, L"HKLM_Subkey");
527     ok_dec(ErrorCode, ERROR_SUCCESS);
528     ok_key_deleted(MachineSubKey);
529     ok_key_deleted(ClassesRootSubKey);
530 
531     /* Create another subkey, this time from HKCU */
532     ErrorCode = RegCreateKeyExW(
533         HKEY_CURRENT_USER,
534         L"Software\\Classes\\Apitest_HKCU\\HKCU_Subkey",
535         0,
536         NULL,
537         0,
538         MAXIMUM_ALLOWED,
539         NULL,
540         &UserSubKey,
541         NULL);
542     ok_dec(ErrorCode, ERROR_SUCCESS);
543     ok(!IS_HKCR(UserSubKey), "\n");
544 
545     /* And try creating it again as a subkey of this HKCR handle (which points to HKCU). */
546     ok_key_name(ClassesRootKey, &HKCU_ClassesPath, L"Apitest_HKCU");
547     ErrorCode = RegCreateKeyExW(
548         ClassesRootKey,
549         L"HKCU_Subkey",
550         0,
551         NULL,
552         0,
553         MAXIMUM_ALLOWED,
554         NULL,
555         &ClassesRootSubKey,
556         &Disposition);
557     ok_dec(ErrorCode, ERROR_SUCCESS);
558     ok(IS_HKCR(ClassesRootSubKey), "\n");
559     /* This time the one in HKCU is opened */
560     ok_key_name(ClassesRootSubKey, &HKCU_ClassesPath, L"Apitest_HKCU\\HKCU_Subkey");
561     ok_hex(Disposition, REG_OPENED_EXISTING_KEY);
562     /* Let's see if we can delete it */
563     RegDeleteKeyW(ClassesRootKey, L"HKCU_Subkey");
564     ok_key_deleted(ClassesRootSubKey);
565     RegCloseKey(ClassesRootSubKey);
566     ok_key_deleted(UserSubKey);
567     RegCloseKey(UserSubKey);
568 
569     RegCloseKey(MachineSubKey);
570     RegCloseKey(ClassesRootSubKey);
571 
572     /* See what this deletes */
573     RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCU");
574     ok_key_deleted(UserKey);
575     RegCloseKey(UserKey);
576     ok_key_deleted(ClassesRootKey);
577     RegCloseKey(UserKey);
578     ok_key_not_deleted(MachineKey);
579 
580     /* Once again */
581     RegDeleteKeyW(HKEY_CLASSES_ROOT, L"Apitest_HKCU");
582     ok_key_deleted(MachineKey);
583     RegCloseKey(MachineKey);
584 }
585 
586 static
587 void
588 Test_DuplicateHandle(void)
589 {
590     HKEY KeyHandle, DupHandle;
591     DWORD ErrorCode;
592     BOOL Duplicated;
593 
594     ErrorCode = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &KeyHandle);
595     ok_dec(ErrorCode, ERROR_SUCCESS);
596     ok(IS_HKCR(KeyHandle), "\n");
597 
598     Duplicated = DuplicateHandle(GetCurrentProcess(), KeyHandle, GetCurrentProcess(), (PHANDLE)&DupHandle, 0, 0, DUPLICATE_SAME_ACCESS);
599     ok(Duplicated, "\n");
600     ok(DupHandle != NULL, "\n");
601     ok(!IS_HKCR(DupHandle), "\n");
602 
603     RegCloseKey(KeyHandle);
604     RegCloseKey(DupHandle);
605 }
606 
607 START_TEST(HKEY_CLASSES_ROOT)
608 {
609     HKEY UserKey;
610     LONG ErrorCode;
611 
612     /* Get HKCU real key name */
613     ErrorCode = RegOpenKeyExW(
614         HKEY_CURRENT_USER,
615         L"Software\\Classes",
616         0,
617         KEY_READ,
618         &UserKey);
619     ok_dec(ErrorCode, ERROR_SUCCESS);
620     GetKeyName(UserKey, &HKCU_ClassesPath);
621     RegCloseKey(UserKey);
622 
623     Test_CreateOpenKey();
624     Test_DuplicateHandle();
625 }
626