2 * Regedit ACL Editor for Registry Keys
4 * Copyright (C) 2004 - 2006 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 /* FIXME - shouldn't be defined here... */
27 DEFINE_GUID(IID_IRegKeySecurity
, 0x965fc360, 0x16ff, 0x11d0, 0x0091, 0xcb,0x00,0xaa,0x00,0xbb,0xb7,0x23);
28 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
29 DEFINE_GUID(IID_IRegKeySecurity2
, 0xc3ccfdb4, 0x6f88, 0x11d2, 0x00a3, 0xce,0x00,0xc0,0x4f,0xb1,0x78,0x2a);
32 /* FIXME: already defined in aclui.h - causing problems when compiling with MSVC/PSDK*/
34 DEFINE_GUID(IID_IEffectivePermission
, 0x3853dc76, 0x9f35, 0x407c, 0x0088, 0xa1,0xd1,0x93,0x44,0x36,0x5f,0xbc);
35 DEFINE_GUID(IID_ISecurityObjectTypeInfo
, 0xfc3066eb, 0x79ef, 0x444b, 0x0091, 0x11,0xd1,0x8a,0x75,0xeb,0xf2,0xfa);
38 /******************************************************************************
39 Implementation of the IUnknown methods of CRegKeySecurity
40 ******************************************************************************/
42 static __inline PCRegKeySecurity
43 impl_from_ISecurityInformation(struct ISecurityInformation
*iface
)
45 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
46 lpISecurityInformationVtbl
));
49 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
50 static __inline PCRegKeySecurity
51 impl_from_ISecurityInformation2(struct ISecurityInformation2
*iface
)
53 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
54 lpISecurityInformation2Vtbl
));
58 static __inline PCRegKeySecurity
59 impl_from_ISecurityObjectTypeInfo(struct ISecurityObjectTypeInfo
*iface
)
61 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
62 lpISecurityObjectTypeInfoVtbl
));
65 static __inline PCRegKeySecurity
66 impl_from_IEffectivePermission(struct IEffectivePermission
*iface
)
68 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
69 lpIEffectivePermissionVtbl
));
72 #define impl_to_interface(impl,iface) (struct iface *)(&(impl)->lp##iface##Vtbl)
75 CRegKeySecurity_fnAddRef(PCRegKeySecurity obj
)
77 return (ULONG
)InterlockedIncrement((LONG
*)&obj
->ref
);
81 CRegKeySecurity_fnRelease(PCRegKeySecurity obj
)
85 Ret
= (ULONG
)InterlockedDecrement((LONG
*)&obj
->ref
);
88 HeapFree(GetProcessHeap(),
96 static __inline HRESULT
97 CRegKeySecurity_fnQueryInterface(PCRegKeySecurity obj
,
104 &IID_IRegKeySecurity
))
106 pvObj
= (PVOID
)impl_to_interface(obj
,
107 ISecurityInformation
);
109 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
110 else if (IsEqualGUID(iid
,
111 &IID_IRegKeySecurity2
))
113 pvObj
= (PVOID
)impl_to_interface(obj
,
114 ISecurityInformation2
);
117 else if (IsEqualGUID(iid
,
118 &IID_IEffectivePermission
))
120 pvObj
= (PVOID
)impl_to_interface(obj
,
121 IEffectivePermission
);
123 else if (IsEqualGUID(iid
,
124 &IID_ISecurityObjectTypeInfo
))
126 pvObj
= (PVOID
)impl_to_interface(obj
,
127 ISecurityObjectTypeInfo
);
132 return E_NOINTERFACE
;
136 CRegKeySecurity_fnAddRef(obj
);
142 /******************************************************************************
143 Definition of the ISecurityInformation interface
144 ******************************************************************************/
147 static HRESULT STDMETHODCALLTYPE
148 ISecurityInformation_fnQueryInterface(struct ISecurityInformation
*this,
152 static ULONG STDMETHODCALLTYPE
153 ISecurityInformation_fnAddRef(struct ISecurityInformation
*this);
155 static ULONG STDMETHODCALLTYPE
156 ISecurityInformation_fnRelease(struct ISecurityInformation
*this);
158 /* ISecurityInformation */
159 static HRESULT STDMETHODCALLTYPE
160 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation
*this,
161 PSI_OBJECT_INFO pObjectInfo
);
163 static HRESULT STDMETHODCALLTYPE
164 ISecurityInformation_fnGetSecurity(struct ISecurityInformation
*this,
165 SECURITY_INFORMATION RequestedInformation
,
166 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
169 static HRESULT STDMETHODCALLTYPE
170 ISecurityInformation_fnSetSecurity(struct ISecurityInformation
*this,
171 SECURITY_INFORMATION RequestedInformation
,
172 PSECURITY_DESCRIPTOR pSecurityDescriptor
);
174 static HRESULT STDMETHODCALLTYPE
175 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation
*this,
176 const GUID
* pguidObjectType
,
178 PSI_ACCESS
* ppAccess
,
180 ULONG
* piDefaultAccess
);
182 static HRESULT STDMETHODCALLTYPE
183 ISecurityInformation_fnMapGeneric(struct ISecurityInformation
*this,
184 const GUID
* pguidObjectType
,
188 static HRESULT STDMETHODCALLTYPE
189 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation
*this,
190 PSI_INHERIT_TYPE
* ppInheritTypes
,
191 ULONG
* pcInheritTypes
);
192 static HRESULT STDMETHODCALLTYPE
193 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation
*this,
198 static const struct ifaceISecurityInformationVbtl vtblISecurityInformation
=
200 /* IUnknown methods */
201 ISecurityInformation_fnQueryInterface
,
202 ISecurityInformation_fnAddRef
,
203 ISecurityInformation_fnRelease
,
205 /* ISecurityInformation methods */
206 ISecurityInformation_fnGetObjectInformation
,
207 ISecurityInformation_fnGetSecurity
,
208 ISecurityInformation_fnSetSecurity
,
209 ISecurityInformation_fnGetAccessRights
,
210 ISecurityInformation_fnMapGeneric
,
211 ISecurityInformation_fnGetInheritTypes
,
212 ISecurityInformation_fnPropertySheetPageCallback
,
215 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
216 /******************************************************************************
217 Definition of the ISecurityInformation2 interface
218 ******************************************************************************/
221 static HRESULT STDMETHODCALLTYPE
222 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2
*this,
226 static ULONG STDMETHODCALLTYPE
227 ISecurityInformation2_fnAddRef(struct ISecurityInformation2
*this);
229 static ULONG STDMETHODCALLTYPE
230 ISecurityInformation2_fnRelease(struct ISecurityInformation2
*this);
232 /* ISecurityInformation2 */
233 static BOOL STDMETHODCALLTYPE
234 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2
*this,
237 static HRESULT STDMETHODCALLTYPE
238 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2
*this,
243 static const struct ifaceISecurityInformation2Vbtl vtblISecurityInformation2
=
245 /* IUnknown methods */
246 ISecurityInformation2_fnQueryInterface
,
247 ISecurityInformation2_fnAddRef
,
248 ISecurityInformation2_fnRelease
,
250 /* ISecurityInformation2 methods */
251 ISecurityInformation2_fnIsDaclCanonical
,
252 ISecurityInformation2_fnLookupSids
256 /******************************************************************************
257 Definition of the IEffectivePermission interface
258 ******************************************************************************/
261 static HRESULT STDMETHODCALLTYPE
262 IEffectivePermission_fnQueryInterface(struct IEffectivePermission
*this,
266 static ULONG STDMETHODCALLTYPE
267 IEffectivePermission_fnAddRef(struct IEffectivePermission
*this);
269 static ULONG STDMETHODCALLTYPE
270 IEffectivePermission_fnRelease(struct IEffectivePermission
*this);
272 /* IEffectivePermission */
273 static HRESULT STDMETHODCALLTYPE
274 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission
*this,
275 const GUID
* pguidObjectType
,
277 LPCWSTR pszServerName
,
278 PSECURITY_DESCRIPTOR pSD
,
279 POBJECT_TYPE_LIST
* ppObjectTypeList
,
280 ULONG
* pcObjectTypeListLength
,
281 PACCESS_MASK
* ppGrantedAccessList
,
282 ULONG
* pcGrantedAccessListLength
);
284 static const struct ifaceIEffectivePermissionVbtl vtblIEffectivePermission
=
286 /* IUnknown methods */
287 IEffectivePermission_fnQueryInterface
,
288 IEffectivePermission_fnAddRef
,
289 IEffectivePermission_fnRelease
,
291 /* IEffectivePermissions methods */
292 IEffectivePermission_fnGetEffectivePermission
295 /******************************************************************************
296 Definition of the ISecurityObjectTypeInfo interface
297 ******************************************************************************/
300 static HRESULT STDMETHODCALLTYPE
301 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo
*this,
305 static ULONG STDMETHODCALLTYPE
306 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo
*this);
308 static ULONG STDMETHODCALLTYPE
309 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo
*this);
311 /* ISecurityObjectTypeInfo */
312 static HRESULT STDMETHODCALLTYPE
313 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo
*this,
314 SECURITY_INFORMATION si
,
316 PINHERITED_FROM
* ppInheritArray
);
318 static const struct ifaceISecurityObjectTypeInfoVbtl vtblISecurityObjectTypeInfo
=
320 /* IUnknown methods */
321 ISecurityObjectTypeInfo_fnQueryInterface
,
322 ISecurityObjectTypeInfo_fnAddRef
,
323 ISecurityObjectTypeInfo_fnRelease
,
325 /* ISecurityObjectTypeInfo methods */
326 ISecurityObjectTypeInfo_fnGetInheritSource
330 /******************************************************************************
331 Implementation of the ISecurityInformation interface
332 ******************************************************************************/
334 static SI_ACCESS RegAccess
[] = {
335 {&GUID_NULL
, KEY_ALL_ACCESS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_FULLCONTROL
), SI_ACCESS_GENERAL
| SI_ACCESS_SPECIFIC
},
336 {&GUID_NULL
, KEY_READ
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READ
), SI_ACCESS_GENERAL
},
337 {&GUID_NULL
, KEY_QUERY_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_QUERYVALUE
), SI_ACCESS_SPECIFIC
},
338 {&GUID_NULL
, KEY_SET_VALUE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_SETVALUE
), SI_ACCESS_SPECIFIC
},
339 {&GUID_NULL
, KEY_CREATE_SUB_KEY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATESUBKEY
), SI_ACCESS_SPECIFIC
},
340 {&GUID_NULL
, KEY_ENUMERATE_SUB_KEYS
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_ENUMERATESUBKEYS
), SI_ACCESS_SPECIFIC
},
341 {&GUID_NULL
, KEY_NOTIFY
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_NOTIFY
), SI_ACCESS_SPECIFIC
},
342 {&GUID_NULL
, KEY_CREATE_LINK
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_CREATELINK
), SI_ACCESS_SPECIFIC
},
343 {&GUID_NULL
, DELETE
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_DELETE
), SI_ACCESS_SPECIFIC
},
344 {&GUID_NULL
, WRITE_DAC
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEDAC
), SI_ACCESS_SPECIFIC
},
345 {&GUID_NULL
, WRITE_OWNER
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_WRITEOWNER
), SI_ACCESS_SPECIFIC
},
346 {&GUID_NULL
, READ_CONTROL
, (LPWSTR
)MAKEINTRESOURCE(IDS_ACCESS_READCONTROL
), SI_ACCESS_SPECIFIC
},
349 static const DWORD RegDefaultAccess
= 1; /* KEY_READ */
351 static GENERIC_MAPPING RegAccessMasks
= {
358 static SI_INHERIT_TYPE RegInheritTypes
[] = {
359 {&GUID_NULL
, 0, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYONLY
)},
360 {&GUID_NULL
, CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_THISKEYANDSUBKEYS
)},
361 {&GUID_NULL
, INHERIT_ONLY_ACE
| CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCE(IDS_INHERIT_SUBKEYSONLY
)},
364 static HRESULT STDMETHODCALLTYPE
365 ISecurityInformation_fnQueryInterface(struct ISecurityInformation
*this,
372 *pvObject
= (PVOID
)this;
373 ISecurityInformation_fnAddRef(this);
377 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation(this),
382 static ULONG STDMETHODCALLTYPE
383 ISecurityInformation_fnAddRef(struct ISecurityInformation
*this)
385 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation(this));
388 static ULONG STDMETHODCALLTYPE
389 ISecurityInformation_fnRelease(struct ISecurityInformation
*this)
391 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation(this));
394 static HRESULT STDMETHODCALLTYPE
395 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation
*this,
396 PSI_OBJECT_INFO pObjectInfo
)
398 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
400 *pObjectInfo
= obj
->ObjectInfo
;
404 static HRESULT STDMETHODCALLTYPE
405 ISecurityInformation_fnGetSecurity(struct ISecurityInformation
*this,
406 SECURITY_INFORMATION RequestedInformation
,
407 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
410 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
413 ErrorCode
= GetNamedSecurityInfo(obj
->szRegKey
,
415 RequestedInformation
,
420 ppSecurityDescriptor
);
422 return HRESULT_FROM_WIN32(ErrorCode
);
425 static HRESULT STDMETHODCALLTYPE
426 ISecurityInformation_fnSetSecurity(struct ISecurityInformation
*this,
427 SECURITY_INFORMATION RequestedInformation
,
428 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
430 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
437 static HRESULT STDMETHODCALLTYPE
438 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation
*this,
439 const GUID
* pguidObjectType
,
441 PSI_ACCESS
* ppAccess
,
443 ULONG
* piDefaultAccess
)
445 *ppAccess
= RegAccess
;
446 *pcAccesses
= sizeof(RegAccess
) / sizeof(RegAccess
[0]);
447 *piDefaultAccess
= RegDefaultAccess
;
451 static HRESULT STDMETHODCALLTYPE
452 ISecurityInformation_fnMapGeneric(struct ISecurityInformation
*this,
453 const GUID
* pguidObjectType
,
457 MapGenericMask(pMask
,
459 *pMask
&= ~SYNCHRONIZE
;
463 static HRESULT STDMETHODCALLTYPE
464 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation
*this,
465 PSI_INHERIT_TYPE
* ppInheritTypes
,
466 ULONG
* pcInheritTypes
)
468 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
471 if (obj
->ObjectInfo
.dwFlags
& SI_CONTAINER
)
473 *ppInheritTypes
= RegInheritTypes
;
474 *pcInheritTypes
= sizeof(RegInheritTypes
) / sizeof(RegInheritTypes
[0]);
481 static HRESULT STDMETHODCALLTYPE
482 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation
*this,
490 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
491 /******************************************************************************
492 Implementation of the ISecurityInformation2 interface
493 ******************************************************************************/
495 static HRESULT STDMETHODCALLTYPE
496 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2
*this,
503 *pvObject
= (PVOID
)this;
504 ISecurityInformation2_fnAddRef(this);
508 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation2(this),
513 static ULONG STDMETHODCALLTYPE
514 ISecurityInformation2_fnAddRef(struct ISecurityInformation2
*this)
516 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation2(this));
519 static ULONG STDMETHODCALLTYPE
520 ISecurityInformation2_fnRelease(struct ISecurityInformation2
*this)
522 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation2(this));
525 static BOOL STDMETHODCALLTYPE
526 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2
*this,
533 static HRESULT STDMETHODCALLTYPE
534 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2
*this,
544 /******************************************************************************
545 Implementation of the IEffectivePermission interface
546 ******************************************************************************/
548 static HRESULT STDMETHODCALLTYPE
549 IEffectivePermission_fnQueryInterface(struct IEffectivePermission
*this,
556 *pvObject
= (PVOID
)this;
557 IEffectivePermission_fnAddRef(this);
561 return CRegKeySecurity_fnQueryInterface(impl_from_IEffectivePermission(this),
566 static ULONG STDMETHODCALLTYPE
567 IEffectivePermission_fnAddRef(struct IEffectivePermission
*this)
569 return CRegKeySecurity_fnAddRef(impl_from_IEffectivePermission(this));
572 static ULONG STDMETHODCALLTYPE
573 IEffectivePermission_fnRelease(struct IEffectivePermission
*this)
575 return CRegKeySecurity_fnRelease(impl_from_IEffectivePermission(this));
578 static HRESULT STDMETHODCALLTYPE
579 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission
*this,
580 const GUID
* pguidObjectType
,
582 LPCWSTR pszServerName
,
583 PSECURITY_DESCRIPTOR pSD
,
584 POBJECT_TYPE_LIST
* ppObjectTypeList
,
585 ULONG
* pcObjectTypeListLength
,
586 PACCESS_MASK
* ppGrantedAccessList
,
587 ULONG
* pcGrantedAccessListLength
)
590 BOOL DaclPresent
, DaclDefaulted
;
591 PACCESS_MASK GrantedAccessList
;
592 DWORD ErrorCode
= ERROR_SUCCESS
;
593 TRUSTEE Trustee
= {0};
594 static OBJECT_TYPE_LIST DefObjTypeList
= {0};
596 *ppObjectTypeList
= &DefObjTypeList
;
597 *pcObjectTypeListLength
= 1;
599 BuildTrusteeWithSid(&Trustee
,
602 if (GetSecurityDescriptorDacl(pSD
,
605 &DaclDefaulted
) && DaclPresent
)
607 GrantedAccessList
= (PACCESS_MASK
)LocalAlloc(LMEM_FIXED
,
608 sizeof(ACCESS_MASK
));
609 if (GrantedAccessList
== NULL
)
614 ErrorCode
= GetEffectiveRightsFromAcl(Dacl
,
617 if (ErrorCode
== ERROR_SUCCESS
)
619 *ppGrantedAccessList
= GrantedAccessList
;
620 *pcGrantedAccessListLength
= 1;
623 LocalFree((HLOCAL
)GrantedAccessList
);
627 ErrorCode
= GetLastError();
629 return HRESULT_FROM_WIN32(ErrorCode
);
632 /******************************************************************************
633 Implementation of the ISecurityObjectTypeInfo interface
634 ******************************************************************************/
636 static HRESULT STDMETHODCALLTYPE
637 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo
*this,
644 *pvObject
= (PVOID
)this;
645 ISecurityObjectTypeInfo_fnAddRef(this);
649 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityObjectTypeInfo(this),
654 static ULONG STDMETHODCALLTYPE
655 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo
*this)
657 return CRegKeySecurity_fnAddRef(impl_from_ISecurityObjectTypeInfo(this));
660 static ULONG STDMETHODCALLTYPE
661 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo
*this)
663 return CRegKeySecurity_fnRelease(impl_from_ISecurityObjectTypeInfo(this));
666 static HRESULT STDMETHODCALLTYPE
667 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo
*this,
668 SECURITY_INFORMATION si
,
670 PINHERITED_FROM
* ppInheritArray
)
672 PCRegKeySecurity obj
= impl_from_ISecurityObjectTypeInfo(this);
673 PINHERITED_FROM pif
, pif2
;
678 pifSize
= pACL
->AceCount
* sizeof(INHERITED_FROM
);
679 pif
= (PINHERITED_FROM
)HeapAlloc(GetProcessHeap(),
684 return E_OUTOFMEMORY
;
687 ErrorCode
= GetInheritanceSource(obj
->szRegKey
,
690 (obj
->ObjectInfo
.dwFlags
& SI_CONTAINER
) != 0,
698 if (ErrorCode
== ERROR_SUCCESS
)
700 /* Calculate the size of the buffer to return */
705 if (pif
[i
].AncestorName
!= NULL
)
707 pifSize
+= (_tcslen(pif
[i
].AncestorName
) + 1) * sizeof(TCHAR
);
711 /* Allocate enough space for the array and the strings */
712 pif2
= (PINHERITED_FROM
)LocalAlloc(LMEM_FIXED
,
716 ErrorCode
= GetLastError();
720 /* copy the array and strings to the buffer */
721 lpBuf
= (LPTSTR
)((ULONG_PTR
)pif2
+ (pACL
->AceCount
* sizeof(INHERITED_FROM
)));
726 pif2
[i
].GenerationGap
= pif
[i
].GenerationGap
;
727 if (pif
[i
].AncestorName
!= NULL
)
729 pif2
[i
].AncestorName
= lpBuf
;
731 pif
[i
].AncestorName
);
732 lpBuf
+= _tcslen(pif
[i
].AncestorName
) + 1;
735 pif2
[i
].AncestorName
= NULL
;
738 /* return the newly allocated array */
739 *ppInheritArray
= pif2
;
743 FreeInheritedFromArray(pif
,
746 HeapFree(GetProcessHeap(),
750 return HRESULT_FROM_WIN32(ErrorCode
);
753 /******************************************************************************
754 Implementation of the CRegKeySecurity constructor
755 ******************************************************************************/
757 static PCRegKeySecurity
758 CRegKeySecurity_fnConstructor(LPTSTR lpRegKey
,
760 SI_OBJECT_INFO
*ObjectInfo
,
763 PCRegKeySecurity obj
;
765 obj
= (PCRegKeySecurity
)HeapAlloc(GetProcessHeap(),
767 FIELD_OFFSET(CRegKeySecurity
,
768 szRegKey
[_tcslen(lpRegKey
) + 1]));
772 obj
->lpISecurityInformationVtbl
= &vtblISecurityInformation
;
773 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
774 obj
->lpISecurityInformation2Vtbl
= &vtblISecurityInformation2
;
776 obj
->lpIEffectivePermissionVtbl
= &vtblIEffectivePermission
;
777 obj
->lpISecurityObjectTypeInfoVtbl
= &vtblISecurityObjectTypeInfo
;
778 obj
->ObjectInfo
= *ObjectInfo
;
780 obj
->hRootKey
= hRootKey
;
781 _tcscpy(obj
->szRegKey
,
785 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
790 /******************************************************************************/
791 /******************************************************************************/
792 /******************************************************************************/
794 typedef struct _CHANGE_CONTEXT
798 } CHANGE_CONTEXT
, *PCHANGE_CONTEXT
;
800 typedef BOOL (WINAPI
*PEDITSECURITY
)(HWND hwndOwner
,
801 struct ISecurityInformation
*psi
);
803 static PEDITSECURITY pfnEditSecurity
;
804 static HMODULE hAclUiDll
;
807 InitializeAclUiDll(VOID
)
809 if (!(hAclUiDll
= LoadLibrary(_T("aclui.dll"))))
814 if (!(pfnEditSecurity
= (PEDITSECURITY
)GetProcAddress(hAclUiDll
,
817 FreeLibrary(hAclUiDll
);
828 if (hAclUiDll
!= NULL
)
830 FreeLibrary(hAclUiDll
);
835 RegKeyEditPermissions(HWND hWndOwner
,
841 LPWSTR Machine
= NULL
, KeyName
= NULL
;
842 LPCTSTR lphKey
= NULL
;
843 LPTSTR lpKeyPath
= NULL
;
844 PCRegKeySecurity RegKeySecurity
;
845 SI_OBJECT_INFO ObjectInfo
;
846 size_t lnMachine
= 0, lnKeyName
= 0;
848 if (pfnEditSecurity
== NULL
)
854 /* aclui.dll only accepts unicode strings, convert them */
855 if (lpMachine
!= NULL
)
857 lnMachine
= lstrlen(lpMachine
);
858 if (!(Machine
= HeapAlloc(GetProcessHeap(),
860 (lnMachine
+ 1) * sizeof(WCHAR
))))
862 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
868 MultiByteToWideChar(CP_ACP
,
881 if (lpKeyName
!= NULL
)
883 lnKeyName
= lstrlen(lpKeyName
);
884 if (!(KeyName
= HeapAlloc(GetProcessHeap(),
886 (lnKeyName
+ 1) * sizeof(WCHAR
))))
888 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
894 MultiByteToWideChar(CP_ACP
,
907 Machine
= (LPWSTR
)lpMachine
;
908 KeyName
= (LPWSTR
)lpKeyName
;
911 lnMachine
= wcslen(lpMachine
);
913 lnKeyName
= wcslen(KeyName
);
916 /* build registry path */
917 if (lpMachine
!= NULL
&&
918 (lpMachine
[0] == _T('\0') ||
919 (lpMachine
[0] == _T('.') && lpMachine
[1] == _T('.'))))
924 if (hKey
== HKEY_CLASSES_ROOT
)
925 lphKey
= TEXT("CLASSES_ROOT");
926 else if (hKey
== HKEY_CURRENT_USER
)
927 lphKey
= TEXT("CURRENT_USER");
928 else if (hKey
== HKEY_LOCAL_MACHINE
)
929 lphKey
= TEXT("MACHINE");
930 else if (hKey
== HKEY_USERS
)
931 lphKey
= TEXT("USERS");
932 else if (hKey
== HKEY_CURRENT_CONFIG
)
933 lphKey
= TEXT("CONFIG");
937 lpKeyPath
= HeapAlloc(GetProcessHeap(),
939 (2 + lnMachine
+ 1 + _tcslen(lphKey
) + 1 + lnKeyName
) * sizeof(TCHAR
));
940 if (lpKeyPath
== NULL
)
942 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
945 lpKeyPath
[0] = _T('\0');
959 if (lpKeyName
!= NULL
&& lpKeyName
[0] != _T('\0'))
961 if (lpKeyName
[0] != _T('\\'))
971 ObjectInfo
.dwFlags
= SI_EDIT_ALL
| SI_ADVANCED
| SI_CONTAINER
| SI_EDIT_EFFECTIVE
| SI_EDIT_PERMS
|
972 SI_OWNER_RECURSE
| SI_RESET_DACL_TREE
| SI_RESET_SACL_TREE
;
973 ObjectInfo
.hInstance
= hInst
;
974 ObjectInfo
.pszServerName
= Machine
;
975 ObjectInfo
.pszObjectName
= KeyName
; /* FIXME */
976 ObjectInfo
.pszPageTitle
= KeyName
; /* FIXME */
978 if (!(RegKeySecurity
= CRegKeySecurity_fnConstructor(lpKeyPath
,
986 /* display the security editor dialog */
987 pfnEditSecurity(hWndOwner
,
988 impl_to_interface(RegKeySecurity
,
989 ISecurityInformation
));
991 /* dereference the interface, it should be destroyed here */
992 CRegKeySecurity_fnRelease(RegKeySecurity
);
998 HeapFree(GetProcessHeap(),
1003 if (KeyName
!= NULL
)
1005 HeapFree(GetProcessHeap(),
1011 if (lpKeyPath
!= NULL
)
1013 HeapFree(GetProcessHeap(),