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
26 DEFINE_GUID(IID_CRegKeySecurity
, 0x965fc360, 0x16ff, 0x11d0, 0x0091, 0xcb,0x00,0xaa,0x00,0xbb,0xb7,0x23);
28 /******************************************************************************
29 Implementation of the CRegKeySecurity interface
30 ******************************************************************************/
32 static ifaceCRegKeySecurityVbtl efvt
=
34 /* IUnknown methods */
35 CRegKeySecurity_fnQueryInterface
,
36 CRegKeySecurity_fnAddRef
,
37 CRegKeySecurity_fnRelease
,
39 /* CRegKeySecurity methods */
40 CRegKeySecurity_fnGetObjectInformation
,
41 CRegKeySecurity_fnGetSecurity
,
42 CRegKeySecurity_fnSetSecurity
,
43 CRegKeySecurity_fnGetAccessRights
,
44 CRegKeySecurity_fnMapGeneric
,
45 CRegKeySecurity_fnGetInheritTypes
,
46 CRegKeySecurity_fnPropertySheetPageCallback
49 SI_ACCESS RegAccess
[] = {
50 {&GUID_NULL
, KEY_ALL_ACCESS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_FULLCONTROL
), SI_ACCESS_GENERAL
| SI_ACCESS_SPECIFIC
},
51 {&GUID_NULL
, KEY_READ
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READ
), SI_ACCESS_GENERAL
},
52 {&GUID_NULL
, KEY_QUERY_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_QUERYVALUE
), SI_ACCESS_SPECIFIC
},
53 {&GUID_NULL
, KEY_SET_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_SETVALUE
), SI_ACCESS_SPECIFIC
},
54 {&GUID_NULL
, KEY_CREATE_SUB_KEY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATESUBKEY
), SI_ACCESS_SPECIFIC
},
55 {&GUID_NULL
, KEY_ENUMERATE_SUB_KEYS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_ENUMERATESUBKEYS
), SI_ACCESS_SPECIFIC
},
56 {&GUID_NULL
, KEY_NOTIFY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_NOTIFY
), SI_ACCESS_SPECIFIC
},
57 {&GUID_NULL
, KEY_CREATE_LINK
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATELINK
), SI_ACCESS_SPECIFIC
},
58 {&GUID_NULL
, DELETE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_DELETE
), SI_ACCESS_SPECIFIC
},
59 {&GUID_NULL
, WRITE_DAC
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEDAC
), SI_ACCESS_SPECIFIC
},
60 {&GUID_NULL
, WRITE_OWNER
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEOWNER
), SI_ACCESS_SPECIFIC
},
61 {&GUID_NULL
, READ_CONTROL
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READCONTROL
), SI_ACCESS_SPECIFIC
},
64 DWORD RegDefaultAccess
= 1; /* KEY_READ */
66 GENERIC_MAPPING RegAccessMasks
= {
73 SI_INHERIT_TYPE RegInheritTypes
[] = {
74 {&GUID_NULL
, 0, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYONLY
)},
75 {&GUID_NULL
, CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYANDSUBKEYS
)},
76 {&GUID_NULL
, INHERIT_ONLY_ACE
| CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_SUBKEYSONLY
)},
80 static LPREGKEYSECURITY
CRegKeySecurity_fnConstructor(HANDLE Handle
, SI_OBJECT_INFO
*ObjectInfo
, BOOL
*Btn
)
84 obj
= (LPREGKEYSECURITY
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(REGKEYSECURITY
));
90 obj
->ObjectInfo
= *ObjectInfo
;
97 HRESULT STDMETHODCALLTYPE
98 CRegKeySecurity_fnQueryInterface(LPREGKEYSECURITY
this,
102 if(IsEqualGUID(iid
, &IID_IUnknown
) ||
103 IsEqualGUID(iid
, &IID_CRegKeySecurity
))
110 return E_NOINTERFACE
;
113 ULONG STDMETHODCALLTYPE
114 CRegKeySecurity_fnAddRef(LPREGKEYSECURITY
this)
116 return (ULONG
)InterlockedIncrement((LONG
*)&this->ref
);
119 ULONG STDMETHODCALLTYPE
120 CRegKeySecurity_fnRelease(LPREGKEYSECURITY
this)
124 rfc
= (ULONG
)InterlockedDecrement((LONG
*)&this->ref
);
127 HeapFree(GetProcessHeap(), 0, this);
132 HRESULT STDMETHODCALLTYPE
133 CRegKeySecurity_fnGetObjectInformation(LPREGKEYSECURITY
this,
134 PSI_OBJECT_INFO pObjectInfo
)
136 *pObjectInfo
= this->ObjectInfo
;
140 HRESULT STDMETHODCALLTYPE
141 CRegKeySecurity_fnGetSecurity(LPREGKEYSECURITY
this,
142 SECURITY_INFORMATION RequestedInformation
,
143 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
146 DWORD DescriptorSize
= 0;
147 PSECURITY_DESCRIPTOR SecurityDescriptor
;
150 /* find out how much memory we need to allocate */
151 ErrorCode
= RegGetKeySecurity(this->Handle
, RequestedInformation
, NULL
, &DescriptorSize
);
152 if(ErrorCode
== ERROR_INSUFFICIENT_BUFFER
)
154 SecurityDescriptor
= (PSECURITY_DESCRIPTOR
)LocalAlloc(LMEM_FIXED
, DescriptorSize
);
155 if (SecurityDescriptor
!= NULL
)
157 if (RegGetKeySecurity(this->Handle
, RequestedInformation
, SecurityDescriptor
, &DescriptorSize
) == ERROR_SUCCESS
)
159 *ppSecurityDescriptor
= SecurityDescriptor
;
164 LocalFree((HLOCAL
)SecurityDescriptor
);
165 return E_ACCESSDENIED
;
170 return E_OUTOFMEMORY
;
175 return E_ACCESSDENIED
;
179 HRESULT STDMETHODCALLTYPE
180 CRegKeySecurity_fnSetSecurity(LPREGKEYSECURITY
this,
181 SECURITY_INFORMATION RequestedInformation
,
182 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
189 HRESULT STDMETHODCALLTYPE
190 CRegKeySecurity_fnGetAccessRights(LPREGKEYSECURITY
this,
191 const GUID
* pguidObjectType
,
193 PSI_ACCESS
* ppAccess
,
195 ULONG
* piDefaultAccess
)
197 *ppAccess
= RegAccess
;
198 *pcAccesses
= sizeof(RegAccess
) / sizeof(SI_ACCESS
);
199 *piDefaultAccess
= RegDefaultAccess
;
203 HRESULT STDMETHODCALLTYPE
204 CRegKeySecurity_fnMapGeneric(LPREGKEYSECURITY
this,
205 const GUID
* pguidObjectType
,
209 MapGenericMask(pMask
, (PGENERIC_MAPPING
)&RegAccessMasks
);
210 *pMask
&= ~SYNCHRONIZE
;
214 HRESULT STDMETHODCALLTYPE
215 CRegKeySecurity_fnGetInheritTypes(LPREGKEYSECURITY
this,
216 PSI_INHERIT_TYPE
* ppInheritTypes
,
217 ULONG
* pcInheritTypes
)
220 if(this->ObjectInfo
.dwFlags
& SI_CONTAINER
)
222 *ppInheritTypes
= RegInheritTypes
;
223 *pcInheritTypes
= sizeof(RegInheritTypes
) / sizeof(SI_INHERIT_TYPE
);
229 HRESULT STDMETHODCALLTYPE
230 CRegKeySecurity_fnPropertySheetPageCallback(LPREGKEYSECURITY
this,
240 /******************************************************************************/
242 #define ACLUI_DLL _T("aclui.dll")
243 #define FN_EDITSECURITY "EditSecurity" /* no unicode, GetProcAddr doesn't accept unicode! */
245 typedef struct _CHANGE_CONTEXT
249 } CHANGE_CONTEXT
, *PCHANGE_CONTEXT
;
251 typedef BOOL (WINAPI
*PEDITSECURITY
)(HWND hwndOwner
,
252 LPREGKEYSECURITY psi
);
254 static PEDITSECURITY pfnEditSecurity
;
255 static HMODULE hAclUiDll
;
258 InitializeAclUiDll(VOID
)
260 if(!(hAclUiDll
= LoadLibrary(ACLUI_DLL
)))
264 if(!(pfnEditSecurity
= (PEDITSECURITY
)GetProcAddress(hAclUiDll
, FN_EDITSECURITY
)))
266 FreeLibrary(hAclUiDll
);
277 if(hAclUiDll
!= NULL
)
279 FreeLibrary(hAclUiDll
);
284 RegKeyEditPermissions(HWND hWndOwner
,
290 LPWSTR Machine
, KeyName
;
292 LPREGKEYSECURITY RegKeySecurity
;
293 SI_OBJECT_INFO ObjectInfo
;
295 if(pfnEditSecurity
== NULL
)
301 /* aclui.dll only accepts unicode strings, convert them */
302 if(lpMachine
!= NULL
)
304 int lnMachine
= lstrlen(lpMachine
);
305 if(!(Machine
= HeapAlloc(GetProcessHeap(), 0, (lnMachine
+ 1) * sizeof(WCHAR
))))
307 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
312 MultiByteToWideChar(CP_ACP
, 0, lpMachine
, -1, Machine
, lnMachine
+ 1);
320 if(lpKeyName
!= NULL
)
322 int lnKeyName
= lstrlen(lpKeyName
);
323 if(!(KeyName
= HeapAlloc(GetProcessHeap(), 0, (lnKeyName
+ 1) * sizeof(WCHAR
))))
327 HeapFree(GetProcessHeap(), 0, Machine
);
329 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
334 MultiByteToWideChar(CP_ACP
, 0, lpKeyName
, -1, KeyName
, lnKeyName
+ 1);
342 Machine
= (LPWSTR
)lpMachine
;
343 KeyName
= (LPWSTR
)lpKeyName
;
346 /* try to open the key again with more access rights */
347 if(RegOpenKeyEx(hKey
, NULL
, 0, READ_CONTROL
, &hInfoKey
) != ERROR_SUCCESS
)
349 /* FIXME - print error with FormatMessage */
353 ObjectInfo
.dwFlags
= SI_EDIT_ALL
| SI_ADVANCED
| SI_CONTAINER
| SI_OWNER_RECURSE
| SI_EDIT_PERMS
;
354 ObjectInfo
.hInstance
= hInst
;
355 ObjectInfo
.pszServerName
= Machine
;
356 ObjectInfo
.pszObjectName
= KeyName
;
357 ObjectInfo
.pszPageTitle
= KeyName
;
359 if(!(RegKeySecurity
= CRegKeySecurity_fnConstructor(hInfoKey
, &ObjectInfo
, &Result
)))
361 /* FIXME - print error with FormatMessage */
365 /* display the security editor dialog */
366 pfnEditSecurity(hWndOwner
, RegKeySecurity
);
368 /* dereference the interface, it should be destroyed here */
369 CRegKeySecurity_fnRelease(RegKeySecurity
);
371 RegCloseKey(hInfoKey
);
376 HeapFree(GetProcessHeap(), 0, Machine
);
380 HeapFree(GetProcessHeap(), 0, KeyName
);