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 static HANDLE 82 SHELL_GetCachedGlobalCounter(_Inout_ HANDLE *phGlobalCounter, _In_ REFGUID rguid) 83 { 84 HANDLE hGlobalCounter; 85 if (*phGlobalCounter) 86 return *phGlobalCounter; 87 hGlobalCounter = SHGlobalCounterCreate(rguid); 88 if (InterlockedCompareExchangePointer(phGlobalCounter, hGlobalCounter, NULL)) 89 CloseHandle(hGlobalCounter); 90 return *phGlobalCounter; 91 } 92 93 /**************************************************************************** 94 * SHELL_GetRestrictionsCounter 95 * 96 * Retrieves the global counter for GUID_Restrictions using caching in a 97 * thread-safe manner. The variable g_hRestGlobalCounter is used for caching. 98 * 99 * @return The handle of the global counter. 100 * @see SHELL_GetCachedGlobalCounter 101 * @implemented 102 */ 103 static HANDLE SHELL_GetRestrictionsCounter(VOID) 104 { 105 return SHELL_GetCachedGlobalCounter(&g_hRestGlobalCounter, &GUID_Restrictions); 106 } 107 108 /**************************************************************************** 109 * SHELL_QueryRestrictionsChanged 110 * 111 * @return The value of the global counter for GUID_Restrictions. 112 * @see SHELL_GetRestrictionsCounter 113 * @implemented 114 */ 115 static BOOL SHELL_QueryRestrictionsChanged(VOID) 116 { 117 LONG Value = SHGlobalCounterGetValue(SHELL_GetRestrictionsCounter()); 118 if (g_nRestCountValue == Value) 119 return FALSE; 120 121 g_nRestCountValue = Value; 122 return TRUE; 123 } 124 125 /************************************************************************* 126 * SHRestricted [SHELL32.100] 127 * 128 * Get the value associated with a policy Id. 129 * 130 * PARAMS 131 * pol [I] Policy Id 132 * 133 * RETURNS 134 * The queried value for the policy. 135 * 136 * NOTES 137 * Exported by ordinal. 138 * This function caches the retrieved values to prevent unnecessary registry access, 139 * if SHSettingsChanged() was previously called. 140 * 141 * REFERENCES 142 * a: MS System Policy Editor. 143 * b: 98Lite 2.0 (which uses many of these policy keys) http://www.98lite.net/ 144 * c: 'The Windows 95 Registry', by John Woram, 1996 MIS: Press 145 */ 146 DWORD WINAPI SHRestricted (RESTRICTIONS rest) 147 { 148 TRACE("(0x%08lX)\n", rest); 149 150 /* If restrictions from registry have changed, reset all cached values to SHELL_NO_POLICY */ 151 if (SHELL_QueryRestrictionsChanged()) 152 FillMemory(&g_RestValues, sizeof(g_RestValues), 0xFF); 153 154 return SHRestrictionLookup(rest, NULL, s_PolicyTable, g_RestValues); 155 } 156 157 /************************************************************************* 158 * SHSettingsChanged [SHELL32.244] 159 * 160 * Initialise the policy cache to speed up calls to SHRestricted(). 161 * 162 * PARAMS 163 * unused [I] Reserved. 164 * pszKey [I] Registry key to scan. 165 * 166 * RETURNS 167 * Success: -1. The policy cache is initialised. 168 * Failure: 0, if inpRegKey is any value other than NULL, "Policy", or 169 * "Software\Microsoft\Windows\CurrentVersion\Policies". 170 * 171 * NOTES 172 * Exported by ordinal. Introduced in Win98. 173 */ 174 BOOL WINAPI SHSettingsChanged(LPCVOID unused, LPCWSTR pszKey) 175 { 176 TRACE("(%p, %s)\n", unused, debugstr_w(pszKey)); 177 178 if (pszKey && 179 lstrcmpiW(L"Policy", pszKey) != 0 && 180 lstrcmpiW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies", pszKey) != 0) 181 { 182 return FALSE; 183 } 184 185 return SHGlobalCounterIncrement(SHELL_GetRestrictionsCounter()); 186 } 187