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 static ifaceCRegKeySecurityVbtl efvt
=
41 /* IUnknown methods */
42 CRegKeySecurity_fnQueryInterface
,
43 CRegKeySecurity_fnAddRef
,
44 CRegKeySecurity_fnRelease
,
46 /* CRegKeySecurity methods */
47 CRegKeySecurity_fnGetObjectInformation
,
48 CRegKeySecurity_fnGetSecurity
,
49 CRegKeySecurity_fnSetSecurity
,
50 CRegKeySecurity_fnGetAccessRights
,
51 CRegKeySecurity_fnMapGeneric
,
52 CRegKeySecurity_fnGetInheritTypes
,
53 CRegKeySecurity_fnPropertySheetPageCallback
56 SI_ACCESS RegAccess
[] = {
57 {&GUID_NULL
, KEY_ALL_ACCESS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_FULLCONTROL
), SI_ACCESS_GENERAL
| SI_ACCESS_SPECIFIC
},
58 {&GUID_NULL
, KEY_READ
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READ
), SI_ACCESS_GENERAL
},
59 {&GUID_NULL
, KEY_QUERY_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_QUERYVALUE
), SI_ACCESS_SPECIFIC
},
60 {&GUID_NULL
, KEY_SET_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_SETVALUE
), SI_ACCESS_SPECIFIC
},
61 {&GUID_NULL
, KEY_CREATE_SUB_KEY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATESUBKEY
), SI_ACCESS_SPECIFIC
},
62 {&GUID_NULL
, KEY_ENUMERATE_SUB_KEYS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_ENUMERATESUBKEYS
), SI_ACCESS_SPECIFIC
},
63 {&GUID_NULL
, KEY_NOTIFY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_NOTIFY
), SI_ACCESS_SPECIFIC
},
64 {&GUID_NULL
, KEY_CREATE_LINK
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATELINK
), SI_ACCESS_SPECIFIC
},
65 {&GUID_NULL
, DELETE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_DELETE
), SI_ACCESS_SPECIFIC
},
66 {&GUID_NULL
, WRITE_DAC
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEDAC
), SI_ACCESS_SPECIFIC
},
67 {&GUID_NULL
, WRITE_OWNER
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEOWNER
), SI_ACCESS_SPECIFIC
},
68 {&GUID_NULL
, READ_CONTROL
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READCONTROL
), SI_ACCESS_SPECIFIC
},
71 DWORD RegDefaultAccess
= 1; /* KEY_READ */
73 GENERIC_MAPPING RegAccessMasks
= {
80 SI_INHERIT_TYPE RegInheritTypes
[] = {
81 {&GUID_NULL
, 0, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYONLY
)},
82 {&GUID_NULL
, CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYANDSUBKEYS
)},
83 {&GUID_NULL
, INHERIT_ONLY_ACE
| CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_SUBKEYSONLY
)},
87 LPREGKEYSECURITY
CRegKeySecurity_fnConstructor(HANDLE Handle
, SE_OBJECT_TYPE ObjectType
, SI_OBJECT_INFO
*ObjectInfo
, BOOL
*Btn
)
91 obj
= (LPREGKEYSECURITY
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(REGKEYSECURITY
));
97 obj
->ObjectType
= ObjectType
;
98 obj
->ObjectInfo
= *ObjectInfo
;
105 HRESULT STDMETHODCALLTYPE
106 CRegKeySecurity_fnQueryInterface(LPREGKEYSECURITY
this,
110 if(IsEqualGUID(iid
, &IID_IUnknown
) ||
111 IsEqualGUID(iid
, &IID_CRegKeySecurity
))
118 return E_NOINTERFACE
;
121 ULONG STDMETHODCALLTYPE
122 CRegKeySecurity_fnAddRef(LPREGKEYSECURITY
this)
124 return (ULONG
)InterlockedIncrement(&this->ref
);
127 ULONG STDMETHODCALLTYPE
128 CRegKeySecurity_fnRelease(LPREGKEYSECURITY
this)
132 rfc
= (ULONG
)InterlockedDecrement(&this->ref
);
135 HeapFree(GetProcessHeap(), 0, this);
140 HRESULT STDMETHODCALLTYPE
141 CRegKeySecurity_fnGetObjectInformation(LPREGKEYSECURITY
this,
142 PSI_OBJECT_INFO pObjectInfo
)
144 *pObjectInfo
= this->ObjectInfo
;
148 HRESULT STDMETHODCALLTYPE
149 CRegKeySecurity_fnGetSecurity(LPREGKEYSECURITY
this,
150 SECURITY_INFORMATION RequestedInformation
,
151 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
155 if(GetSecurityInfo(this->Handle
, this->ObjectType
, RequestedInformation
, 0, 0,
156 0, 0, ppSecurityDescriptor
) == ERROR_SUCCESS
)
162 return E_ACCESSDENIED
;
166 HRESULT STDMETHODCALLTYPE
167 CRegKeySecurity_fnSetSecurity(LPREGKEYSECURITY
this,
168 SECURITY_INFORMATION RequestedInformation
,
169 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
176 HRESULT STDMETHODCALLTYPE
177 CRegKeySecurity_fnGetAccessRights(LPREGKEYSECURITY
this,
178 const GUID
* pguidObjectType
,
180 PSI_ACCESS
* ppAccess
,
182 ULONG
* piDefaultAccess
)
184 *ppAccess
= RegAccess
;
185 *pcAccesses
= sizeof(RegAccess
) / sizeof(SI_ACCESS
);
186 *piDefaultAccess
= RegDefaultAccess
;
190 HRESULT STDMETHODCALLTYPE
191 CRegKeySecurity_fnMapGeneric(LPREGKEYSECURITY
this,
192 const GUID
* pguidObjectType
,
196 MapGenericMask(pMask
, (PGENERIC_MAPPING
)&RegAccessMasks
);
197 *pMask
&= ~SYNCHRONIZE
;
201 HRESULT STDMETHODCALLTYPE
202 CRegKeySecurity_fnGetInheritTypes(LPREGKEYSECURITY
this,
203 PSI_INHERIT_TYPE
* ppInheritTypes
,
204 ULONG
* pcInheritTypes
)
207 if(this->ObjectInfo
.dwFlags
& SI_CONTAINER
)
209 *ppInheritTypes
= RegInheritTypes
;
210 *pcInheritTypes
= sizeof(RegInheritTypes
) / sizeof(SI_INHERIT_TYPE
);
216 HRESULT STDMETHODCALLTYPE
217 CRegKeySecurity_fnPropertySheetPageCallback(LPREGKEYSECURITY
this,
227 /******************************************************************************/
229 #define ACLUI_DLL _T("aclui.dll")
230 #define FN_EDITSECURITY "EditSecurity" /* no unicode, GetProcAddr doesn't accept unicode! */
232 typedef struct _CHANGE_CONTEXT
236 } CHANGE_CONTEXT
, *PCHANGE_CONTEXT
;
238 typedef BOOL (WINAPI
*PEDITSECURITY
)(HWND hwndOwner
,
239 LPREGKEYSECURITY psi
);
241 static PEDITSECURITY pfnEditSecurity
;
242 static HMODULE hAclUiDll
;
245 InitializeAclUiDll(VOID
)
247 if(!(hAclUiDll
= LoadLibrary(ACLUI_DLL
)))
251 if(!(pfnEditSecurity
= (PEDITSECURITY
)GetProcAddress(hAclUiDll
, FN_EDITSECURITY
)))
253 FreeLibrary(hAclUiDll
);
264 if(hAclUiDll
!= NULL
)
266 FreeLibrary(hAclUiDll
);
271 RegKeyEditPermissions(HWND hWndOwner
,
277 LPWSTR Machine
, KeyName
;
279 LPREGKEYSECURITY RegKeySecurity
;
280 SI_OBJECT_INFO ObjectInfo
;
282 if(pfnEditSecurity
== NULL
)
288 /* aclui.dll only accepts unicode strings, convert them */
289 if(lpMachine
!= NULL
)
291 int lnMachine
= lstrlen(lpMachine
);
292 if(!(Machine
= HeapAlloc(GetProcessHeap(), 0, (lnMachine
+ 1) * sizeof(WCHAR
))))
294 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
299 MultiByteToWideChar(CP_ACP
, 0, lpMachine
, -1, Machine
, lnMachine
+ 1);
307 if(lpKeyName
!= NULL
)
309 int lnKeyName
= lstrlen(lpKeyName
);
310 if(!(KeyName
= HeapAlloc(GetProcessHeap(), 0, (lnKeyName
+ 1) * sizeof(WCHAR
))))
314 HeapFree(GetProcessHeap(), 0, Machine
);
316 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
321 MultiByteToWideChar(CP_ACP
, 0, lpKeyName
, -1, KeyName
, lnKeyName
+ 1);
329 Machine
= (LPWSTR
)lpMachine
;
330 KeyName
= (LPWSTR
)lpKeyName
;
333 /* try to open the key again with more access rights */
334 if(RegOpenKeyEx(hKey
, NULL
, 0, READ_CONTROL
, &hInfoKey
) != ERROR_SUCCESS
)
336 /* FIXME - print error with FormatMessage */
340 ObjectInfo
.dwFlags
= SI_EDIT_ALL
| SI_ADVANCED
| SI_CONTAINER
| SI_OWNER_RECURSE
| SI_EDIT_PERMS
;
341 ObjectInfo
.hInstance
= hInst
;
342 ObjectInfo
.pszServerName
= Machine
;
343 ObjectInfo
.pszObjectName
= KeyName
;
344 ObjectInfo
.pszPageTitle
= KeyName
;
346 if(!(RegKeySecurity
= CRegKeySecurity_fnConstructor(hInfoKey
, SE_REGISTRY_KEY
, &ObjectInfo
, &Result
)))
348 /* FIXME - print error with FormatMessage */
352 /* display the security editor dialog */
353 pfnEditSecurity(hWndOwner
, RegKeySecurity
);
355 /* dereference the interface, it should be destroyed here */
356 CRegKeySecurity_fnRelease(RegKeySecurity
);
358 RegCloseKey(hInfoKey
);
363 HeapFree(GetProcessHeap(), 0, Machine
);
367 HeapFree(GetProcessHeap(), 0, KeyName
);