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 */
37 /******************************************************************************
38 Implementation of the CRegKeySecurity interface
39 ******************************************************************************/
41 static ifaceCRegKeySecurityVbtl efvt
=
43 /* IUnknown methods */
44 CRegKeySecurity_fnQueryInterface
,
45 CRegKeySecurity_fnAddRef
,
46 CRegKeySecurity_fnRelease
,
48 /* CRegKeySecurity methods */
49 CRegKeySecurity_fnGetObjectInformation
,
50 CRegKeySecurity_fnGetSecurity
,
51 CRegKeySecurity_fnSetSecurity
,
52 CRegKeySecurity_fnGetAccessRights
,
53 CRegKeySecurity_fnMapGeneric
,
54 CRegKeySecurity_fnGetInheritTypes
,
55 CRegKeySecurity_fnPropertySheetPageCallback
58 SI_ACCESS RegAccess
[] = {
59 {&GUID_NULL
, KEY_ALL_ACCESS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_FULLCONTROL
), SI_ACCESS_GENERAL
| SI_ACCESS_SPECIFIC
},
60 {&GUID_NULL
, KEY_READ
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READ
), SI_ACCESS_GENERAL
},
61 {&GUID_NULL
, KEY_QUERY_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_QUERYVALUE
), SI_ACCESS_SPECIFIC
},
62 {&GUID_NULL
, KEY_SET_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_SETVALUE
), SI_ACCESS_SPECIFIC
},
63 {&GUID_NULL
, KEY_CREATE_SUB_KEY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATESUBKEY
), SI_ACCESS_SPECIFIC
},
64 {&GUID_NULL
, KEY_ENUMERATE_SUB_KEYS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_ENUMERATESUBKEYS
), SI_ACCESS_SPECIFIC
},
65 {&GUID_NULL
, KEY_NOTIFY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_NOTIFY
), SI_ACCESS_SPECIFIC
},
66 {&GUID_NULL
, KEY_CREATE_LINK
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATELINK
), SI_ACCESS_SPECIFIC
},
67 {&GUID_NULL
, DELETE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_DELETE
), SI_ACCESS_SPECIFIC
},
68 {&GUID_NULL
, WRITE_DAC
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEDAC
), SI_ACCESS_SPECIFIC
},
69 {&GUID_NULL
, WRITE_OWNER
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEOWNER
), SI_ACCESS_SPECIFIC
},
70 {&GUID_NULL
, READ_CONTROL
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READCONTROL
), SI_ACCESS_SPECIFIC
},
73 DWORD RegDefaultAccess
= 1; /* KEY_READ */
75 GENERIC_MAPPING RegAccessMasks
= {
82 SI_INHERIT_TYPE RegInheritTypes
[] = {
83 {&GUID_NULL
, 0, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYONLY
)},
84 {&GUID_NULL
, CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYANDSUBKEYS
)},
85 {&GUID_NULL
, INHERIT_ONLY_ACE
| CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_SUBKEYSONLY
)},
89 LPREGKEYSECURITY
CRegKeySecurity_fnConstructor(HANDLE Handle
, SE_OBJECT_TYPE ObjectType
, SI_OBJECT_INFO
*ObjectInfo
, BOOL
*Btn
)
93 obj
= (LPREGKEYSECURITY
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(REGKEYSECURITY
));
99 obj
->ObjectType
= ObjectType
;
100 obj
->ObjectInfo
= *ObjectInfo
;
107 HRESULT STDMETHODCALLTYPE
108 CRegKeySecurity_fnQueryInterface(LPREGKEYSECURITY
this,
112 if(IsEqualGUID(iid
, &IID_IUnknown
) ||
113 IsEqualGUID(iid
, &IID_CRegKeySecurity
))
120 return E_NOINTERFACE
;
123 ULONG STDMETHODCALLTYPE
124 CRegKeySecurity_fnAddRef(LPREGKEYSECURITY
this)
126 return (ULONG
)InterlockedIncrement((LONG
*)&this->ref
);
129 ULONG STDMETHODCALLTYPE
130 CRegKeySecurity_fnRelease(LPREGKEYSECURITY
this)
134 rfc
= (ULONG
)InterlockedDecrement((LONG
*)&this->ref
);
137 HeapFree(GetProcessHeap(), 0, this);
142 HRESULT STDMETHODCALLTYPE
143 CRegKeySecurity_fnGetObjectInformation(LPREGKEYSECURITY
this,
144 PSI_OBJECT_INFO pObjectInfo
)
146 *pObjectInfo
= this->ObjectInfo
;
150 HRESULT STDMETHODCALLTYPE
151 CRegKeySecurity_fnGetSecurity(LPREGKEYSECURITY
this,
152 SECURITY_INFORMATION RequestedInformation
,
153 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
157 if(GetSecurityInfo(this->Handle
, this->ObjectType
, RequestedInformation
, 0, 0,
158 0, 0, ppSecurityDescriptor
) == ERROR_SUCCESS
)
164 return E_ACCESSDENIED
;
168 HRESULT STDMETHODCALLTYPE
169 CRegKeySecurity_fnSetSecurity(LPREGKEYSECURITY
this,
170 SECURITY_INFORMATION RequestedInformation
,
171 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
178 HRESULT STDMETHODCALLTYPE
179 CRegKeySecurity_fnGetAccessRights(LPREGKEYSECURITY
this,
180 const GUID
* pguidObjectType
,
182 PSI_ACCESS
* ppAccess
,
184 ULONG
* piDefaultAccess
)
186 *ppAccess
= RegAccess
;
187 *pcAccesses
= sizeof(RegAccess
) / sizeof(SI_ACCESS
);
188 *piDefaultAccess
= RegDefaultAccess
;
192 HRESULT STDMETHODCALLTYPE
193 CRegKeySecurity_fnMapGeneric(LPREGKEYSECURITY
this,
194 const GUID
* pguidObjectType
,
198 MapGenericMask(pMask
, (PGENERIC_MAPPING
)&RegAccessMasks
);
199 *pMask
&= ~SYNCHRONIZE
;
203 HRESULT STDMETHODCALLTYPE
204 CRegKeySecurity_fnGetInheritTypes(LPREGKEYSECURITY
this,
205 PSI_INHERIT_TYPE
* ppInheritTypes
,
206 ULONG
* pcInheritTypes
)
209 if(this->ObjectInfo
.dwFlags
& SI_CONTAINER
)
211 *ppInheritTypes
= RegInheritTypes
;
212 *pcInheritTypes
= sizeof(RegInheritTypes
) / sizeof(SI_INHERIT_TYPE
);
218 HRESULT STDMETHODCALLTYPE
219 CRegKeySecurity_fnPropertySheetPageCallback(LPREGKEYSECURITY
this,
229 /******************************************************************************/
231 #define ACLUI_DLL _T("aclui.dll")
232 #define FN_EDITSECURITY "EditSecurity" /* no unicode, GetProcAddr doesn't accept unicode! */
234 typedef struct _CHANGE_CONTEXT
238 } CHANGE_CONTEXT
, *PCHANGE_CONTEXT
;
240 typedef BOOL (WINAPI
*PEDITSECURITY
)(HWND hwndOwner
,
241 LPREGKEYSECURITY psi
);
243 static PEDITSECURITY pfnEditSecurity
;
244 static HMODULE hAclUiDll
;
247 InitializeAclUiDll(VOID
)
249 if(!(hAclUiDll
= LoadLibrary(ACLUI_DLL
)))
253 if(!(pfnEditSecurity
= (PEDITSECURITY
)GetProcAddress(hAclUiDll
, FN_EDITSECURITY
)))
255 FreeLibrary(hAclUiDll
);
266 if(hAclUiDll
!= NULL
)
268 FreeLibrary(hAclUiDll
);
273 RegKeyEditPermissions(HWND hWndOwner
,
279 LPWSTR Machine
, KeyName
;
281 LPREGKEYSECURITY RegKeySecurity
;
282 SI_OBJECT_INFO ObjectInfo
;
284 if(pfnEditSecurity
== NULL
)
290 /* aclui.dll only accepts unicode strings, convert them */
291 if(lpMachine
!= NULL
)
293 int lnMachine
= lstrlen(lpMachine
);
294 if(!(Machine
= HeapAlloc(GetProcessHeap(), 0, (lnMachine
+ 1) * sizeof(WCHAR
))))
296 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
301 MultiByteToWideChar(CP_ACP
, 0, lpMachine
, -1, Machine
, lnMachine
+ 1);
309 if(lpKeyName
!= NULL
)
311 int lnKeyName
= lstrlen(lpKeyName
);
312 if(!(KeyName
= HeapAlloc(GetProcessHeap(), 0, (lnKeyName
+ 1) * sizeof(WCHAR
))))
316 HeapFree(GetProcessHeap(), 0, Machine
);
318 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
323 MultiByteToWideChar(CP_ACP
, 0, lpKeyName
, -1, KeyName
, lnKeyName
+ 1);
331 Machine
= (LPWSTR
)lpMachine
;
332 KeyName
= (LPWSTR
)lpKeyName
;
335 /* try to open the key again with more access rights */
336 if(RegOpenKeyEx(hKey
, NULL
, 0, READ_CONTROL
, &hInfoKey
) != ERROR_SUCCESS
)
338 /* FIXME - print error with FormatMessage */
342 ObjectInfo
.dwFlags
= SI_EDIT_ALL
| SI_ADVANCED
| SI_CONTAINER
| SI_OWNER_RECURSE
| SI_EDIT_PERMS
;
343 ObjectInfo
.hInstance
= hInst
;
344 ObjectInfo
.pszServerName
= Machine
;
345 ObjectInfo
.pszObjectName
= KeyName
;
346 ObjectInfo
.pszPageTitle
= KeyName
;
348 if(!(RegKeySecurity
= CRegKeySecurity_fnConstructor(hInfoKey
, SE_REGISTRY_KEY
, &ObjectInfo
, &Result
)))
350 /* FIXME - print error with FormatMessage */
354 /* display the security editor dialog */
355 pfnEditSecurity(hWndOwner
, RegKeySecurity
);
357 /* dereference the interface, it should be destroyed here */
358 CRegKeySecurity_fnRelease(RegKeySecurity
);
360 RegCloseKey(hInfoKey
);
365 HeapFree(GetProcessHeap(), 0, Machine
);
369 HeapFree(GetProcessHeap(), 0, KeyName
);