xref: /reactos/dll/win32/shell32/wine/shpolicy.c (revision 71a3be24)
1 /*
2  * shpolicy.c - Data for shell/system policies.
3  *
4  * Copyright 1999 Ian Schmidt <ischmidt@cfl.rr.com>
5  * Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * NOTES:
22  *
23  * Some of these policies can be tweaked via the System Policy
24  * Editor which came with the Win95 Migration Guide, although
25  * there doesn't appear to be an updated Win98 version that
26  * would handle the many new policies introduced since then.
27  * You could easily write one with the information in
28  * this file...
29  */
30 
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #define WIN32_NO_STATUS
36 #define _INC_WINDOWS
37 
38 #include <windef.h>
39 #include <winbase.h>
40 #include <shlobj.h>
41 #include <initguid.h>
42 #include <shlwapi_undoc.h>
43 #include <wine/debug.h>
44 
45 #include "shell32_main.h"
46 
47 WINE_DEFAULT_DEBUG_CHANNEL(shell);
48 
49 DEFINE_GUID(GUID_Restrictions, 0xA48F1A32, 0xA340, 0x11D1, 0xBC, 0x6B, 0x00, 0xA0, 0xC9, 0x03, 0x12, 0xE1);
50 
51 #define DEFINE_POLICY(policy, appstr, keystr) \
52     { policy, L##appstr, L##keystr }
53 
54 static const POLICYDATA s_PolicyTable[] =
55 {
56 #include "PolicyData.h"
57     { 0, NULL, NULL }
58 };
59 
60 #undef DEFINE_POLICY
61 
62 /*
63  * The restriction-related variables
64  */
65 HANDLE g_hRestGlobalCounter = NULL;
66 LONG g_nRestCountValue = -1;
67 DWORD g_RestValues[_countof(s_PolicyTable)] = { 0 };
68 
69 /****************************************************************************
70  *                  SHELL_GetCachedGlobalCounter
71  *
72  * Retrieves the global counter using cache in a thread-safe manner.
73  * If a cache of global counter exists, the function returns it.
74  * If there is no cache, the function creates a global counter.
75  *
76  * @param[in,out]  phGlobalCounter  The pointer to the handle of global counter.
77  * @param[in]      rguid            The GUID of global counter.
78  * @return  The handle of the global counter.
79  * @implemented
80  */
81 #ifdef __REACTOS__
82 EXTERN_C HANDLE
83 #else
84 static HANDLE
85 #endif
SHELL_GetCachedGlobalCounter(_Inout_ HANDLE * phGlobalCounter,_In_ REFGUID rguid)86 SHELL_GetCachedGlobalCounter(_Inout_ HANDLE *phGlobalCounter, _In_ REFGUID rguid)
87 {
88     HANDLE hGlobalCounter;
89     if (*phGlobalCounter)
90         return *phGlobalCounter;
91     hGlobalCounter = SHGlobalCounterCreate(rguid);
92     if (InterlockedCompareExchangePointer(phGlobalCounter, hGlobalCounter, NULL))
93         CloseHandle(hGlobalCounter);
94     return *phGlobalCounter;
95 }
96 
97 /****************************************************************************
98  *                  SHELL_GetRestrictionsCounter
99  *
100  * Retrieves the global counter for GUID_Restrictions using caching in a
101  * thread-safe manner. The variable g_hRestGlobalCounter is used for caching.
102  *
103  * @return  The handle of the global counter.
104  * @see SHELL_GetCachedGlobalCounter
105  * @implemented
106  */
SHELL_GetRestrictionsCounter(VOID)107 static HANDLE SHELL_GetRestrictionsCounter(VOID)
108 {
109     return SHELL_GetCachedGlobalCounter(&g_hRestGlobalCounter, &GUID_Restrictions);
110 }
111 
112 /****************************************************************************
113  *                  SHELL_QueryRestrictionsChanged
114  *
115  * @return  The value of the global counter for GUID_Restrictions.
116  * @see SHELL_GetRestrictionsCounter
117  * @implemented
118  */
SHELL_QueryRestrictionsChanged(VOID)119 static BOOL SHELL_QueryRestrictionsChanged(VOID)
120 {
121     LONG Value = SHGlobalCounterGetValue(SHELL_GetRestrictionsCounter());
122     if (g_nRestCountValue == Value)
123         return FALSE;
124 
125     g_nRestCountValue = Value;
126     return TRUE;
127 }
128 
129 /*************************************************************************
130  * SHRestricted				 [SHELL32.100]
131  *
132  * Get the value associated with a policy Id.
133  *
134  * PARAMS
135  *     pol [I] Policy Id
136  *
137  * RETURNS
138  *     The queried value for the policy.
139  *
140  * NOTES
141  *     Exported by ordinal.
142  *     This function caches the retrieved values to prevent unnecessary registry access,
143  *     if SHSettingsChanged() was previously called.
144  *
145  * REFERENCES
146  *     a: MS System Policy Editor.
147  *     b: 98Lite 2.0 (which uses many of these policy keys) http://www.98lite.net/
148  *     c: 'The Windows 95 Registry', by John Woram, 1996 MIS: Press
149  */
SHRestricted(RESTRICTIONS rest)150 DWORD WINAPI SHRestricted (RESTRICTIONS rest)
151 {
152     TRACE("(0x%08lX)\n", rest);
153 
154     /* If restrictions from registry have changed, reset all cached values to SHELL_NO_POLICY */
155     if (SHELL_QueryRestrictionsChanged())
156         FillMemory(&g_RestValues, sizeof(g_RestValues), 0xFF);
157 
158     return SHRestrictionLookup(rest, NULL, s_PolicyTable, g_RestValues);
159 }
160 
161 /*************************************************************************
162  * SHSettingsChanged          [SHELL32.244]
163  *
164  * Initialise the policy cache to speed up calls to SHRestricted().
165  *
166  * PARAMS
167  *  unused    [I] Reserved.
168  *  pszKey    [I] Registry key to scan.
169  *
170  * RETURNS
171  *  Success: -1. The policy cache is initialised.
172  *  Failure: 0, if inpRegKey is any value other than NULL, "Policy", or
173  *           "Software\Microsoft\Windows\CurrentVersion\Policies".
174  *
175  * NOTES
176  *  Exported by ordinal. Introduced in Win98.
177  */
SHSettingsChanged(LPCVOID unused,LPCWSTR pszKey)178 BOOL WINAPI SHSettingsChanged(LPCVOID unused, LPCWSTR pszKey)
179 {
180     TRACE("(%p, %s)\n", unused, debugstr_w(pszKey));
181 
182     if (pszKey &&
183         lstrcmpiW(L"Policy", pszKey) != 0 &&
184         lstrcmpiW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies", pszKey) != 0)
185     {
186         return FALSE;
187     }
188 
189     return SHGlobalCounterIncrement(SHELL_GetRestrictionsCounter());
190 }
191