1 /*
2  * PROJECT:     ReactOS api tests
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Tests for SHGetRestriction
5  * COPYRIGHT:   Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 
8 #include <apitest.h>
9 #include <shlwapi.h>
10 
11 #define REGKEY_POLICIES L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies"
12 #define REGKEY_POLICIES_EXPLORER  REGKEY_POLICIES L"\\Explorer"
13 
14 typedef DWORD (WINAPI *FN_SHGetRestriction)(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue);
15 typedef BOOL (WINAPI *FN_SHSettingsChanged)(LPCVOID unused, LPCVOID inpRegKey);
16 
17 static DWORD
18 Candidate_SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue)
19 {
20     WCHAR szPath[MAX_PATH];
21     DWORD cbValue, dwValue = 0;
22 
23     if (!lpSubKey)
24         lpSubKey = REGKEY_POLICIES;
25 
26     PathCombineW(szPath, lpSubKey, lpSubName);
27 
28     cbValue = sizeof(dwValue);
29     if (SHGetValueW(HKEY_LOCAL_MACHINE, szPath, lpValue, NULL, &dwValue, &cbValue) == ERROR_SUCCESS)
30         return dwValue;
31 
32     cbValue = sizeof(dwValue);
33     SHGetValueW(HKEY_CURRENT_USER, szPath, lpValue, NULL, &dwValue, &cbValue);
34     return dwValue;
35 }
36 
37 typedef struct tagTEST_ENTRY
38 {
39     LPCWSTR lpSubName;
40     LPCWSTR lpValue;
41 } TEST_ENTRY, *PTEST_ENTRY;
42 
43 static const TEST_ENTRY s_Entries[] =
44 {
45     { L"Explorer", L"NoRun" },
46     { L"Explorer", L"ForceActiveDesktopOn" },
47     { L"Explorer", L"NoActiveDesktop" },
48     { L"Explorer", L"NoDisconnect" },
49     { L"Explorer", L"NoRecentDocsHistory" },
50     { L"Explorer", L"NoDriveTypeAutoRun" },
51     { L"Explorer", L"NoSimpleStartMenu" },
52     { L"System", L"DontDisplayLastUserName" },
53     { L"System", L"ShutdownWithoutLogon" },
54     { L"System", L"UndockWithoutLogon" },
55 };
56 
57 static void
58 TEST_DoEntry(const TEST_ENTRY *entry, FN_SHGetRestriction fnSHGetRestriction)
59 {
60     DWORD value1 = fnSHGetRestriction(NULL, entry->lpSubName, entry->lpValue);
61     DWORD value2 = Candidate_SHGetRestriction(NULL, entry->lpSubName, entry->lpValue);
62     //trace("%ld vs %ld\n", value1, value2);
63     ok_long(value1, value2);
64 }
65 
66 #define DELETE_VALUE(hBaseKey) \
67     SHDeleteValueW((hBaseKey), REGKEY_POLICIES_EXPLORER, L"NoRun")
68 
69 #define SET_VALUE(hBaseKey, value) do { \
70     dwValue = (value); \
71     SHSetValueW((hBaseKey), REGKEY_POLICIES_EXPLORER, L"NoRun", \
72                 REG_DWORD, &dwValue, sizeof(dwValue)); \
73 } while (0)
74 
75 static void
76 TEST_SHGetRestriction_Stage(
77     INT iStage,
78     FN_SHGetRestriction fnSHGetRestriction)
79 {
80     size_t iItem;
81     DWORD dwValue;
82 
83     trace("Stage #%d\n", iStage);
84 
85     switch (iStage)
86     {
87         case 0:
88             DELETE_VALUE(HKEY_CURRENT_USER);
89             DELETE_VALUE(HKEY_LOCAL_MACHINE);
90             break;
91         case 1:
92             SET_VALUE(HKEY_CURRENT_USER, 0);
93             DELETE_VALUE(HKEY_LOCAL_MACHINE);
94             break;
95         case 2:
96             SET_VALUE(HKEY_CURRENT_USER, 1);
97             DELETE_VALUE(HKEY_LOCAL_MACHINE);
98             break;
99         case 3:
100             DELETE_VALUE(HKEY_CURRENT_USER);
101             SET_VALUE(HKEY_LOCAL_MACHINE, 0);
102             break;
103         case 4:
104             DELETE_VALUE(HKEY_CURRENT_USER);
105             SET_VALUE(HKEY_LOCAL_MACHINE, 1);
106             break;
107         case 5:
108             SET_VALUE(HKEY_CURRENT_USER, 0);
109             SET_VALUE(HKEY_LOCAL_MACHINE, 1);
110             break;
111         case 6:
112             SET_VALUE(HKEY_CURRENT_USER, 1);
113             SET_VALUE(HKEY_LOCAL_MACHINE, 0);
114             break;
115     }
116 
117     for (iItem = 0; iItem < _countof(s_Entries); ++iItem)
118     {
119         TEST_DoEntry(&s_Entries[iItem], fnSHGetRestriction);
120     }
121 }
122 
123 START_TEST(SHGetRestriction)
124 {
125     HMODULE hSHLWAPI = LoadLibraryW(L"shlwapi.dll");
126     FN_SHGetRestriction fn = (FN_SHGetRestriction)GetProcAddress(hSHLWAPI, MAKEINTRESOURCEA(271));
127     INT iStage;
128 
129     if (fn)
130     {
131         for (iStage = 0; iStage < 7; ++iStage)
132             TEST_SHGetRestriction_Stage(iStage, fn);
133 
134         DELETE_VALUE(HKEY_CURRENT_USER);
135         DELETE_VALUE(HKEY_LOCAL_MACHINE);
136     }
137     else
138     {
139         skip("SHGetRestriction not found\n");
140     }
141 
142     FreeLibrary(hSHLWAPI);
143 }
144