2 * Regedit ACL Editor for Registry Keys
4 * Copyright (C) 2004 Thomas Weidenmueller <w3seek@reactos.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
35 /******************************************************************************
36 Implementation of the CRegKeySecurity interface
37 ******************************************************************************/
39 SI_ACCESS RegAccess
[] = {
40 {&GUID_NULL
, KEY_ALL_ACCESS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_FULLCONTROL
), SI_ACCESS_GENERAL
| SI_ACCESS_SPECIFIC
},
41 {&GUID_NULL
, KEY_READ
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READ
), SI_ACCESS_GENERAL
},
42 {&GUID_NULL
, KEY_QUERY_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_QUERYVALUE
), SI_ACCESS_SPECIFIC
},
43 {&GUID_NULL
, KEY_SET_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_SETVALUE
), SI_ACCESS_SPECIFIC
},
44 {&GUID_NULL
, KEY_CREATE_SUB_KEY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATESUBKEY
), SI_ACCESS_SPECIFIC
},
45 {&GUID_NULL
, KEY_ENUMERATE_SUB_KEYS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_ENUMERATESUBKEYS
), SI_ACCESS_SPECIFIC
},
46 {&GUID_NULL
, KEY_NOTIFY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_NOTIFY
), SI_ACCESS_SPECIFIC
},
47 {&GUID_NULL
, KEY_CREATE_LINK
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATELINK
), SI_ACCESS_SPECIFIC
},
48 {&GUID_NULL
, DELETE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_DELETE
), SI_ACCESS_SPECIFIC
},
49 {&GUID_NULL
, WRITE_DAC
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEDAC
), SI_ACCESS_SPECIFIC
},
50 {&GUID_NULL
, WRITE_OWNER
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEOWNER
), SI_ACCESS_SPECIFIC
},
51 {&GUID_NULL
, READ_CONTROL
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READCONTROL
), SI_ACCESS_SPECIFIC
},
54 DWORD RegDefaultAccess
= 1; /* KEY_READ */
56 GENERIC_MAPPING RegAccessMasks
= {
63 SI_INHERIT_TYPE RegInheritTypes
[] = {
64 {&GUID_NULL
, 0, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYONLY
)},
65 {&GUID_NULL
, CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYANDSUBKEYS
)},
66 {&GUID_NULL
, INHERIT_ONLY_ACE
| CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_SUBKEYSONLY
)},
70 LPREGKEYSECURITY
CRegKeySecurity_fnConstructor(HANDLE Handle
, SE_OBJECT_TYPE ObjectType
, SI_OBJECT_INFO
*ObjectInfo
, BOOL
*Btn
)
74 obj
= (LPREGKEYSECURITY
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(REGKEYSECURITY
));
80 obj
->ObjectType
= ObjectType
;
81 obj
->ObjectInfo
= *ObjectInfo
;
88 HRESULT STDMETHODCALLTYPE
89 CRegKeySecurity_fnQueryInterface(LPREGKEYSECURITY
this,
93 if(IsEqualGUID(iid
, &IID_IUnknown
) ||
94 IsEqualGUID(iid
, &IID_CRegKeySecurity
))
101 return E_NOINTERFACE
;
104 ULONG STDMETHODCALLTYPE
105 CRegKeySecurity_fnAddRef(LPREGKEYSECURITY
this)
107 return (ULONG
)InterlockedIncrement((LONG
*)&this->ref
);
110 ULONG STDMETHODCALLTYPE
111 CRegKeySecurity_fnRelease(LPREGKEYSECURITY
this)
115 rfc
= (ULONG
)InterlockedDecrement((LONG
*)&this->ref
);
118 HeapFree(GetProcessHeap(), 0, this);
123 HRESULT STDMETHODCALLTYPE
124 CRegKeySecurity_fnGetObjectInformation(LPREGKEYSECURITY
this,
125 PSI_OBJECT_INFO pObjectInfo
)
127 *pObjectInfo
= this->ObjectInfo
;
131 HRESULT STDMETHODCALLTYPE
132 CRegKeySecurity_fnGetSecurity(LPREGKEYSECURITY
this,
133 SECURITY_INFORMATION RequestedInformation
,
134 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
138 if(GetSecurityInfo(this->Handle
, this->ObjectType
, RequestedInformation
, 0, 0,
139 0, 0, ppSecurityDescriptor
) == ERROR_SUCCESS
)
145 return E_ACCESSDENIED
;
149 HRESULT STDMETHODCALLTYPE
150 CRegKeySecurity_fnSetSecurity(LPREGKEYSECURITY
this,
151 SECURITY_INFORMATION RequestedInformation
,
152 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
159 HRESULT STDMETHODCALLTYPE
160 CRegKeySecurity_fnGetAccessRights(LPREGKEYSECURITY
this,
161 const GUID
* pguidObjectType
,
163 PSI_ACCESS
* ppAccess
,
165 ULONG
* piDefaultAccess
)
167 *ppAccess
= RegAccess
;
168 *pcAccesses
= sizeof(RegAccess
) / sizeof(SI_ACCESS
);
169 *piDefaultAccess
= RegDefaultAccess
;
173 HRESULT STDMETHODCALLTYPE
174 CRegKeySecurity_fnMapGeneric(LPREGKEYSECURITY
this,
175 const GUID
* pguidObjectType
,
179 MapGenericMask(pMask
, (PGENERIC_MAPPING
)&RegAccessMasks
);
180 *pMask
&= ~SYNCHRONIZE
;
184 HRESULT STDMETHODCALLTYPE
185 CRegKeySecurity_fnGetInheritTypes(LPREGKEYSECURITY
this,
186 PSI_INHERIT_TYPE
* ppInheritTypes
,
187 ULONG
* pcInheritTypes
)
190 if(this->ObjectInfo
.dwFlags
& SI_CONTAINER
)
192 *ppInheritTypes
= RegInheritTypes
;
193 *pcInheritTypes
= sizeof(RegInheritTypes
) / sizeof(SI_INHERIT_TYPE
);
199 HRESULT STDMETHODCALLTYPE
200 CRegKeySecurity_fnPropertySheetPageCallback(LPREGKEYSECURITY
this,
210 /******************************************************************************/
212 #define ACLUI_DLL _T("aclui.dll")
213 #define FN_EDITSECURITY "EditSecurity" /* no unicode, GetProcAddr doesn't accept unicode! */
215 typedef struct _CHANGE_CONTEXT
219 } CHANGE_CONTEXT
, *PCHANGE_CONTEXT
;
221 typedef BOOL (WINAPI
*PEDITSECURITY
)(HWND hwndOwner
,
222 LPREGKEYSECURITY psi
);
224 static PEDITSECURITY pfnEditSecurity
;
225 static HMODULE hAclUiDll
;
228 InitializeAclUiDll(VOID
)
230 if(!(hAclUiDll
= LoadLibrary(ACLUI_DLL
)))
234 if(!(pfnEditSecurity
= (PEDITSECURITY
)GetProcAddress(hAclUiDll
, FN_EDITSECURITY
)))
236 FreeLibrary(hAclUiDll
);
247 if(hAclUiDll
!= NULL
)
249 FreeLibrary(hAclUiDll
);
254 RegKeyEditPermissions(HWND hWndOwner
,
261 LPWSTR Machine
, KeyName
;
263 LPREGKEYSECURITY RegKeySecurity
;
264 SI_OBJECT_INFO ObjectInfo
;
266 if(pfnEditSecurity
== NULL
)
272 /* aclui.dll only accepts unicode strings, convert them */
273 if(lpMachine
!= NULL
)
275 int lnMachine
= lstrlen(lpMachine
);
276 if(!(Machine
= HeapAlloc(GetProcessHeap(), 0, (lnMachine
+ 1) * sizeof(WCHAR
))))
278 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
283 MultiByteToWideChar(CP_ACP
, 0, lpMachine
, -1, Machine
, lnMachine
+ 1);
291 if(lpKeyName
!= NULL
)
293 int lnKeyName
= lstrlen(lpKeyName
);
294 if(!(KeyName
= HeapAlloc(GetProcessHeap(), 0, (lnKeyName
+ 1) * sizeof(WCHAR
))))
298 HeapFree(GetProcessHeap(), 0, Machine
);
300 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
305 MultiByteToWideChar(CP_ACP
, 0, lpKeyName
, -1, KeyName
, lnKeyName
+ 1);
313 Machine
= (LPWSTR
)lpMachine
;
314 KeyName
= (LPWSTR
)lpKeyName
;
317 /* try to open the key again with more access rights */
318 if(RegOpenKeyEx(hKey
, NULL
, 0, READ_CONTROL
, &hInfoKey
) != ERROR_SUCCESS
)
320 /* FIXME - print error with FormatMessage */
324 ObjectInfo
.dwFlags
= SI_EDIT_ALL
| SI_ADVANCED
| SI_CONTAINER
| SI_OWNER_RECURSE
| SI_EDIT_PERMS
;
325 ObjectInfo
.hInstance
= hInst
;
326 ObjectInfo
.pszServerName
= Machine
;
327 ObjectInfo
.pszObjectName
= KeyName
;
328 ObjectInfo
.pszPageTitle
= KeyName
;
330 if(!(RegKeySecurity
= CRegKeySecurity_fnConstructor(hInfoKey
, SE_REGISTRY_KEY
, &ObjectInfo
, &Result
)))
332 /* FIXME - print error with FormatMessage */
336 /* display the security editor dialog */
337 pfnEditSecurity(hWndOwner
, RegKeySecurity
);
339 /* dereference the interface, it should be destroyed here */
340 CRegKeySecurity_fnRelease(RegKeySecurity
);
342 RegCloseKey(hInfoKey
);
347 HeapFree(GetProcessHeap(), 0, Machine
);
351 HeapFree(GetProcessHeap(), 0, KeyName
);