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 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 */ 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 */ 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 */ 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 */ 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