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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 #pragma message ("INVESTIGATE ME")
37 #if 1 //#ifndef _MSC_VER
38 DEFINE_GUID(IID_IEffectivePermission
, 0x3853dc76, 0x9f35, 0x407c, 0x0088, 0xa1,0xd1,0x93,0x44,0x36,0x5f,0xbc);
39 DEFINE_GUID(IID_ISecurityObjectTypeInfo
, 0xfc3066eb, 0x79ef, 0x444b, 0x0091, 0x11,0xd1,0x8a,0x75,0xeb,0xf2,0xfa);
42 /******************************************************************************
43 Implementation of the IUnknown methods of CRegKeySecurity
44 ******************************************************************************/
46 static __inline PCRegKeySecurity
47 impl_from_ISecurityInformation(struct ISecurityInformation
*iface
)
49 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
50 lpISecurityInformationVtbl
));
53 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
54 static __inline PCRegKeySecurity
55 impl_from_ISecurityInformation2(struct ISecurityInformation2
*iface
)
57 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
58 lpISecurityInformation2Vtbl
));
62 static __inline PCRegKeySecurity
63 impl_from_ISecurityObjectTypeInfo(struct ISecurityObjectTypeInfo
*iface
)
65 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
66 lpISecurityObjectTypeInfoVtbl
));
69 static __inline PCRegKeySecurity
70 impl_from_IEffectivePermission(struct IEffectivePermission
*iface
)
72 return (PCRegKeySecurity
)((ULONG_PTR
)iface
- FIELD_OFFSET(CRegKeySecurity
,
73 lpIEffectivePermissionVtbl
));
76 #define impl_to_interface(impl,iface) (struct iface *)(&(impl)->lp##iface##Vtbl)
79 CRegKeySecurity_fnAddRef(PCRegKeySecurity obj
)
81 return (ULONG
)InterlockedIncrement((LONG
*)&obj
->ref
);
85 CRegKeySecurity_fnRelease(PCRegKeySecurity obj
)
89 Ret
= (ULONG
)InterlockedDecrement((LONG
*)&obj
->ref
);
92 HeapFree(GetProcessHeap(),
100 static __inline HRESULT
101 CRegKeySecurity_fnQueryInterface(PCRegKeySecurity obj
,
108 &IID_IRegKeySecurity
))
110 pvObj
= (PVOID
)impl_to_interface(obj
,
111 ISecurityInformation
);
113 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
114 else if (IsEqualGUID(iid
,
115 &IID_IRegKeySecurity2
))
117 pvObj
= (PVOID
)impl_to_interface(obj
,
118 ISecurityInformation2
);
121 else if (IsEqualGUID(iid
,
122 &IID_IEffectivePermission
))
124 pvObj
= (PVOID
)impl_to_interface(obj
,
125 IEffectivePermission
);
127 else if (IsEqualGUID(iid
,
128 &IID_ISecurityObjectTypeInfo
))
130 pvObj
= (PVOID
)impl_to_interface(obj
,
131 ISecurityObjectTypeInfo
);
136 return E_NOINTERFACE
;
140 CRegKeySecurity_fnAddRef(obj
);
146 /******************************************************************************
147 Definition of the ISecurityInformation interface
148 ******************************************************************************/
151 static HRESULT STDMETHODCALLTYPE
152 ISecurityInformation_fnQueryInterface(struct ISecurityInformation
*this,
156 static ULONG STDMETHODCALLTYPE
157 ISecurityInformation_fnAddRef(struct ISecurityInformation
*this);
159 static ULONG STDMETHODCALLTYPE
160 ISecurityInformation_fnRelease(struct ISecurityInformation
*this);
162 /* ISecurityInformation */
163 static HRESULT STDMETHODCALLTYPE
164 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation
*this,
165 PSI_OBJECT_INFO pObjectInfo
);
167 static HRESULT STDMETHODCALLTYPE
168 ISecurityInformation_fnGetSecurity(struct ISecurityInformation
*this,
169 SECURITY_INFORMATION RequestedInformation
,
170 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
173 static HRESULT STDMETHODCALLTYPE
174 ISecurityInformation_fnSetSecurity(struct ISecurityInformation
*this,
175 SECURITY_INFORMATION RequestedInformation
,
176 PSECURITY_DESCRIPTOR pSecurityDescriptor
);
178 static HRESULT STDMETHODCALLTYPE
179 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation
*this,
180 const GUID
* pguidObjectType
,
182 PSI_ACCESS
* ppAccess
,
184 ULONG
* piDefaultAccess
);
186 static HRESULT STDMETHODCALLTYPE
187 ISecurityInformation_fnMapGeneric(struct ISecurityInformation
*this,
188 const GUID
* pguidObjectType
,
192 static HRESULT STDMETHODCALLTYPE
193 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation
*this,
194 PSI_INHERIT_TYPE
* ppInheritTypes
,
195 ULONG
* pcInheritTypes
);
196 static HRESULT STDMETHODCALLTYPE
197 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation
*this,
202 static const struct ifaceISecurityInformationVbtl vtblISecurityInformation
=
204 /* IUnknown methods */
205 ISecurityInformation_fnQueryInterface
,
206 ISecurityInformation_fnAddRef
,
207 ISecurityInformation_fnRelease
,
209 /* ISecurityInformation methods */
210 ISecurityInformation_fnGetObjectInformation
,
211 ISecurityInformation_fnGetSecurity
,
212 ISecurityInformation_fnSetSecurity
,
213 ISecurityInformation_fnGetAccessRights
,
214 ISecurityInformation_fnMapGeneric
,
215 ISecurityInformation_fnGetInheritTypes
,
216 ISecurityInformation_fnPropertySheetPageCallback
,
219 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
220 /******************************************************************************
221 Definition of the ISecurityInformation2 interface
222 ******************************************************************************/
225 static HRESULT STDMETHODCALLTYPE
226 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2
*this,
230 static ULONG STDMETHODCALLTYPE
231 ISecurityInformation2_fnAddRef(struct ISecurityInformation2
*this);
233 static ULONG STDMETHODCALLTYPE
234 ISecurityInformation2_fnRelease(struct ISecurityInformation2
*this);
236 /* ISecurityInformation2 */
237 static BOOL STDMETHODCALLTYPE
238 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2
*this,
241 static HRESULT STDMETHODCALLTYPE
242 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2
*this,
247 static const struct ifaceISecurityInformation2Vbtl vtblISecurityInformation2
=
249 /* IUnknown methods */
250 ISecurityInformation2_fnQueryInterface
,
251 ISecurityInformation2_fnAddRef
,
252 ISecurityInformation2_fnRelease
,
254 /* ISecurityInformation2 methods */
255 ISecurityInformation2_fnIsDaclCanonical
,
256 ISecurityInformation2_fnLookupSids
260 /******************************************************************************
261 Definition of the IEffectivePermission interface
262 ******************************************************************************/
265 static HRESULT STDMETHODCALLTYPE
266 IEffectivePermission_fnQueryInterface(struct IEffectivePermission
*this,
270 static ULONG STDMETHODCALLTYPE
271 IEffectivePermission_fnAddRef(struct IEffectivePermission
*this);
273 static ULONG STDMETHODCALLTYPE
274 IEffectivePermission_fnRelease(struct IEffectivePermission
*this);
276 /* IEffectivePermission */
277 static HRESULT STDMETHODCALLTYPE
278 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission
*this,
279 const GUID
* pguidObjectType
,
281 LPCWSTR pszServerName
,
282 PSECURITY_DESCRIPTOR pSD
,
283 POBJECT_TYPE_LIST
* ppObjectTypeList
,
284 ULONG
* pcObjectTypeListLength
,
285 PACCESS_MASK
* ppGrantedAccessList
,
286 ULONG
* pcGrantedAccessListLength
);
288 static const struct ifaceIEffectivePermissionVbtl vtblIEffectivePermission
=
290 /* IUnknown methods */
291 IEffectivePermission_fnQueryInterface
,
292 IEffectivePermission_fnAddRef
,
293 IEffectivePermission_fnRelease
,
295 /* IEffectivePermissions methods */
296 IEffectivePermission_fnGetEffectivePermission
299 /******************************************************************************
300 Definition of the ISecurityObjectTypeInfo interface
301 ******************************************************************************/
304 static HRESULT STDMETHODCALLTYPE
305 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo
*this,
309 static ULONG STDMETHODCALLTYPE
310 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo
*this);
312 static ULONG STDMETHODCALLTYPE
313 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo
*this);
315 /* ISecurityObjectTypeInfo */
316 static HRESULT STDMETHODCALLTYPE
317 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo
*this,
318 SECURITY_INFORMATION si
,
320 PINHERITED_FROM
* ppInheritArray
);
322 static const struct ifaceISecurityObjectTypeInfoVbtl vtblISecurityObjectTypeInfo
=
324 /* IUnknown methods */
325 ISecurityObjectTypeInfo_fnQueryInterface
,
326 ISecurityObjectTypeInfo_fnAddRef
,
327 ISecurityObjectTypeInfo_fnRelease
,
329 /* ISecurityObjectTypeInfo methods */
330 ISecurityObjectTypeInfo_fnGetInheritSource
334 /******************************************************************************
335 Implementation of the ISecurityInformation interface
336 ******************************************************************************/
338 static SI_ACCESS RegAccess
[] = {
339 {&GUID_NULL
, KEY_ALL_ACCESS
, MAKEINTRESOURCEW(IDS_ACCESS_FULLCONTROL
), SI_ACCESS_GENERAL
| SI_ACCESS_SPECIFIC
},
340 {&GUID_NULL
, KEY_READ
, MAKEINTRESOURCEW(IDS_ACCESS_READ
), SI_ACCESS_GENERAL
},
341 {&GUID_NULL
, KEY_QUERY_VALUE
, MAKEINTRESOURCEW(IDS_ACCESS_QUERYVALUE
), SI_ACCESS_SPECIFIC
},
342 {&GUID_NULL
, KEY_SET_VALUE
, MAKEINTRESOURCEW(IDS_ACCESS_SETVALUE
), SI_ACCESS_SPECIFIC
},
343 {&GUID_NULL
, KEY_CREATE_SUB_KEY
, MAKEINTRESOURCEW(IDS_ACCESS_CREATESUBKEY
), SI_ACCESS_SPECIFIC
},
344 {&GUID_NULL
, KEY_ENUMERATE_SUB_KEYS
, MAKEINTRESOURCEW(IDS_ACCESS_ENUMERATESUBKEYS
), SI_ACCESS_SPECIFIC
},
345 {&GUID_NULL
, KEY_NOTIFY
, MAKEINTRESOURCEW(IDS_ACCESS_NOTIFY
), SI_ACCESS_SPECIFIC
},
346 {&GUID_NULL
, KEY_CREATE_LINK
, MAKEINTRESOURCEW(IDS_ACCESS_CREATELINK
), SI_ACCESS_SPECIFIC
},
347 {&GUID_NULL
, DELETE
, MAKEINTRESOURCEW(IDS_ACCESS_DELETE
), SI_ACCESS_SPECIFIC
},
348 {&GUID_NULL
, WRITE_DAC
, MAKEINTRESOURCEW(IDS_ACCESS_WRITEDAC
), SI_ACCESS_SPECIFIC
},
349 {&GUID_NULL
, WRITE_OWNER
, MAKEINTRESOURCEW(IDS_ACCESS_WRITEOWNER
), SI_ACCESS_SPECIFIC
},
350 {&GUID_NULL
, READ_CONTROL
, MAKEINTRESOURCEW(IDS_ACCESS_READCONTROL
), SI_ACCESS_SPECIFIC
},
353 static const DWORD RegDefaultAccess
= 1; /* KEY_READ */
355 static GENERIC_MAPPING RegAccessMasks
= {
362 static SI_INHERIT_TYPE RegInheritTypes
[] = {
363 {&GUID_NULL
, 0, (LPWSTR
)MAKEINTRESOURCEW(IDS_INHERIT_THISKEYONLY
)},
364 {&GUID_NULL
, CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCEW(IDS_INHERIT_THISKEYANDSUBKEYS
)},
365 {&GUID_NULL
, INHERIT_ONLY_ACE
| CONTAINER_INHERIT_ACE
, (LPWSTR
)MAKEINTRESOURCEW(IDS_INHERIT_SUBKEYSONLY
)},
368 static HRESULT STDMETHODCALLTYPE
369 ISecurityInformation_fnQueryInterface(struct ISecurityInformation
*this,
376 *pvObject
= (PVOID
)this;
377 ISecurityInformation_fnAddRef(this);
381 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation(this),
386 static ULONG STDMETHODCALLTYPE
387 ISecurityInformation_fnAddRef(struct ISecurityInformation
*this)
389 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation(this));
392 static ULONG STDMETHODCALLTYPE
393 ISecurityInformation_fnRelease(struct ISecurityInformation
*this)
395 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation(this));
398 static HRESULT STDMETHODCALLTYPE
399 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation
*this,
400 PSI_OBJECT_INFO pObjectInfo
)
402 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
404 *pObjectInfo
= obj
->ObjectInfo
;
408 static HRESULT STDMETHODCALLTYPE
409 ISecurityInformation_fnGetSecurity(struct ISecurityInformation
*this,
410 SECURITY_INFORMATION RequestedInformation
,
411 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
,
414 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
417 ErrorCode
= GetNamedSecurityInfoW(obj
->szRegKey
,
419 RequestedInformation
,
424 ppSecurityDescriptor
);
426 return HRESULT_FROM_WIN32(ErrorCode
);
429 static HRESULT STDMETHODCALLTYPE
430 ISecurityInformation_fnSetSecurity(struct ISecurityInformation
*this,
431 SECURITY_INFORMATION RequestedInformation
,
432 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
434 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
441 static HRESULT STDMETHODCALLTYPE
442 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation
*this,
443 const GUID
* pguidObjectType
,
445 PSI_ACCESS
* ppAccess
,
447 ULONG
* piDefaultAccess
)
449 *ppAccess
= RegAccess
;
450 *pcAccesses
= COUNT_OF(RegAccess
);
451 *piDefaultAccess
= RegDefaultAccess
;
455 static HRESULT STDMETHODCALLTYPE
456 ISecurityInformation_fnMapGeneric(struct ISecurityInformation
*this,
457 const GUID
* pguidObjectType
,
461 MapGenericMask(pMask
,
463 *pMask
&= ~SYNCHRONIZE
;
467 static HRESULT STDMETHODCALLTYPE
468 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation
*this,
469 PSI_INHERIT_TYPE
* ppInheritTypes
,
470 ULONG
* pcInheritTypes
)
472 PCRegKeySecurity obj
= impl_from_ISecurityInformation(this);
475 if (obj
->ObjectInfo
.dwFlags
& SI_CONTAINER
)
477 *ppInheritTypes
= RegInheritTypes
;
478 *pcInheritTypes
= COUNT_OF(RegInheritTypes
);
485 static HRESULT STDMETHODCALLTYPE
486 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation
*this,
494 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
495 /******************************************************************************
496 Implementation of the ISecurityInformation2 interface
497 ******************************************************************************/
499 static HRESULT STDMETHODCALLTYPE
500 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2
*this,
507 *pvObject
= (PVOID
)this;
508 ISecurityInformation2_fnAddRef(this);
512 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation2(this),
517 static ULONG STDMETHODCALLTYPE
518 ISecurityInformation2_fnAddRef(struct ISecurityInformation2
*this)
520 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation2(this));
523 static ULONG STDMETHODCALLTYPE
524 ISecurityInformation2_fnRelease(struct ISecurityInformation2
*this)
526 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation2(this));
529 static BOOL STDMETHODCALLTYPE
530 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2
*this,
537 static HRESULT STDMETHODCALLTYPE
538 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2
*this,
548 /******************************************************************************
549 Implementation of the IEffectivePermission interface
550 ******************************************************************************/
552 static HRESULT STDMETHODCALLTYPE
553 IEffectivePermission_fnQueryInterface(struct IEffectivePermission
*this,
560 *pvObject
= (PVOID
)this;
561 IEffectivePermission_fnAddRef(this);
565 return CRegKeySecurity_fnQueryInterface(impl_from_IEffectivePermission(this),
570 static ULONG STDMETHODCALLTYPE
571 IEffectivePermission_fnAddRef(struct IEffectivePermission
*this)
573 return CRegKeySecurity_fnAddRef(impl_from_IEffectivePermission(this));
576 static ULONG STDMETHODCALLTYPE
577 IEffectivePermission_fnRelease(struct IEffectivePermission
*this)
579 return CRegKeySecurity_fnRelease(impl_from_IEffectivePermission(this));
582 static HRESULT STDMETHODCALLTYPE
583 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission
*this,
584 const GUID
* pguidObjectType
,
586 LPCWSTR pszServerName
,
587 PSECURITY_DESCRIPTOR pSD
,
588 POBJECT_TYPE_LIST
* ppObjectTypeList
,
589 ULONG
* pcObjectTypeListLength
,
590 PACCESS_MASK
* ppGrantedAccessList
,
591 ULONG
* pcGrantedAccessListLength
)
594 BOOL DaclPresent
, DaclDefaulted
;
595 PACCESS_MASK GrantedAccessList
;
596 DWORD ErrorCode
= ERROR_SUCCESS
;
597 TRUSTEE Trustee
= {0};
598 static OBJECT_TYPE_LIST DefObjTypeList
= {0};
600 *ppObjectTypeList
= &DefObjTypeList
;
601 *pcObjectTypeListLength
= 1;
603 BuildTrusteeWithSid(&Trustee
,
606 if (GetSecurityDescriptorDacl(pSD
,
609 &DaclDefaulted
) && DaclPresent
)
611 GrantedAccessList
= (PACCESS_MASK
)LocalAlloc(LMEM_FIXED
,
612 sizeof(ACCESS_MASK
));
613 if (GrantedAccessList
== NULL
)
618 ErrorCode
= GetEffectiveRightsFromAcl(Dacl
,
621 if (ErrorCode
== ERROR_SUCCESS
)
623 *ppGrantedAccessList
= GrantedAccessList
;
624 *pcGrantedAccessListLength
= 1;
627 LocalFree((HLOCAL
)GrantedAccessList
);
631 ErrorCode
= GetLastError();
633 return HRESULT_FROM_WIN32(ErrorCode
);
636 /******************************************************************************
637 Implementation of the ISecurityObjectTypeInfo interface
638 ******************************************************************************/
640 static HRESULT STDMETHODCALLTYPE
641 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo
*this,
648 *pvObject
= (PVOID
)this;
649 ISecurityObjectTypeInfo_fnAddRef(this);
653 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityObjectTypeInfo(this),
658 static ULONG STDMETHODCALLTYPE
659 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo
*this)
661 return CRegKeySecurity_fnAddRef(impl_from_ISecurityObjectTypeInfo(this));
664 static ULONG STDMETHODCALLTYPE
665 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo
*this)
667 return CRegKeySecurity_fnRelease(impl_from_ISecurityObjectTypeInfo(this));
670 static HRESULT STDMETHODCALLTYPE
671 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo
*this,
672 SECURITY_INFORMATION si
,
674 PINHERITED_FROM
* ppInheritArray
)
676 PCRegKeySecurity obj
= impl_from_ISecurityObjectTypeInfo(this);
677 PINHERITED_FROM pif
, pif2
;
682 pifSize
= pACL
->AceCount
* sizeof(INHERITED_FROM
);
683 pif
= (PINHERITED_FROM
)HeapAlloc(GetProcessHeap(),
688 return E_OUTOFMEMORY
;
691 ErrorCode
= GetInheritanceSourceW(obj
->szRegKey
,
694 (obj
->ObjectInfo
.dwFlags
& SI_CONTAINER
) != 0,
702 if (ErrorCode
== ERROR_SUCCESS
)
704 /* Calculate the size of the buffer to return */
709 if (pif
[i
].AncestorName
!= NULL
)
711 pifSize
+= (wcslen(pif
[i
].AncestorName
) + 1) * sizeof(WCHAR
);
715 /* Allocate enough space for the array and the strings */
716 pif2
= (PINHERITED_FROM
)LocalAlloc(LMEM_FIXED
,
720 ErrorCode
= GetLastError();
724 /* copy the array and strings to the buffer */
725 lpBuf
= (LPWSTR
)((ULONG_PTR
)pif2
+ (pACL
->AceCount
* sizeof(INHERITED_FROM
)));
730 pif2
[i
].GenerationGap
= pif
[i
].GenerationGap
;
731 if (pif
[i
].AncestorName
!= NULL
)
733 pif2
[i
].AncestorName
= lpBuf
;
735 pif
[i
].AncestorName
);
736 lpBuf
+= wcslen(pif
[i
].AncestorName
) + 1;
739 pif2
[i
].AncestorName
= NULL
;
742 /* return the newly allocated array */
743 *ppInheritArray
= pif2
;
747 FreeInheritedFromArray(pif
,
750 HeapFree(GetProcessHeap(),
754 return HRESULT_FROM_WIN32(ErrorCode
);
757 /******************************************************************************
758 Implementation of the CRegKeySecurity constructor
759 ******************************************************************************/
761 static PCRegKeySecurity
762 CRegKeySecurity_fnConstructor(LPWSTR lpRegKey
,
764 SI_OBJECT_INFO
*ObjectInfo
,
767 PCRegKeySecurity obj
;
769 obj
= (PCRegKeySecurity
)HeapAlloc(GetProcessHeap(),
771 FIELD_OFFSET(CRegKeySecurity
,
772 szRegKey
[wcslen(lpRegKey
) + 1]));
776 obj
->lpISecurityInformationVtbl
= &vtblISecurityInformation
;
777 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
778 obj
->lpISecurityInformation2Vtbl
= &vtblISecurityInformation2
;
780 obj
->lpIEffectivePermissionVtbl
= &vtblIEffectivePermission
;
781 obj
->lpISecurityObjectTypeInfoVtbl
= &vtblISecurityObjectTypeInfo
;
782 obj
->ObjectInfo
= *ObjectInfo
;
784 obj
->hRootKey
= hRootKey
;
785 wcscpy(obj
->szRegKey
,
789 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
794 /******************************************************************************/
795 /******************************************************************************/
796 /******************************************************************************/
798 typedef struct _CHANGE_CONTEXT
802 } CHANGE_CONTEXT
, *PCHANGE_CONTEXT
;
804 typedef BOOL (WINAPI
*PEDITSECURITY
)(HWND hwndOwner
,
805 struct ISecurityInformation
*psi
);
807 static PEDITSECURITY pfnEditSecurity
;
808 static HMODULE hAclUiDll
;
811 InitializeAclUiDll(VOID
)
813 if (!(hAclUiDll
= LoadLibraryW(L
"aclui.dll")))
818 if (!(pfnEditSecurity
= (PEDITSECURITY
)GetProcAddress(hAclUiDll
,
821 FreeLibrary(hAclUiDll
);
832 if (hAclUiDll
!= NULL
)
834 FreeLibrary(hAclUiDll
);
839 RegKeyEditPermissions(HWND hWndOwner
,
845 LPCWSTR lphKey
= NULL
;
846 LPWSTR lpKeyPath
= NULL
;
847 PCRegKeySecurity RegKeySecurity
;
848 SI_OBJECT_INFO ObjectInfo
;
849 size_t lnMachine
= 0, lnKeyName
= 0;
851 if (pfnEditSecurity
== NULL
)
856 if (lpMachine
!= NULL
)
857 lnMachine
= wcslen(lpMachine
);
858 if (lpKeyName
!= NULL
)
859 lnKeyName
= wcslen(lpKeyName
);
861 /* build registry path */
862 if (lpMachine
!= NULL
&&
863 (lpMachine
[0] == L
'\0' ||
864 (lpMachine
[0] == L
'.' && lpMachine
[1] == L
'.')))
869 if (hKey
== HKEY_CLASSES_ROOT
)
870 lphKey
= L
"CLASSES_ROOT";
871 else if (hKey
== HKEY_CURRENT_USER
)
872 lphKey
= L
"CURRENT_USER";
873 else if (hKey
== HKEY_LOCAL_MACHINE
)
875 else if (hKey
== HKEY_USERS
)
877 else if (hKey
== HKEY_CURRENT_CONFIG
)
882 lpKeyPath
= HeapAlloc(GetProcessHeap(),
884 (2 + lnMachine
+ 1 + wcslen(lphKey
) + 1 + lnKeyName
) * sizeof(WCHAR
));
885 if (lpKeyPath
== NULL
)
887 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
890 lpKeyPath
[0] = L
'\0';
904 if (lpKeyName
!= NULL
&& lpKeyName
[0] != L
'\0')
906 if (lpKeyName
[0] != L
'\\')
916 ObjectInfo
.dwFlags
= SI_EDIT_ALL
| SI_ADVANCED
| SI_CONTAINER
| SI_EDIT_EFFECTIVE
| SI_EDIT_PERMS
|
917 SI_OWNER_RECURSE
| SI_RESET_DACL_TREE
| SI_RESET_SACL_TREE
;
918 ObjectInfo
.hInstance
= hInst
;
919 ObjectInfo
.pszServerName
= (LPWSTR
)lpMachine
;
920 ObjectInfo
.pszObjectName
= (LPWSTR
)lpKeyName
; /* FIXME */
921 ObjectInfo
.pszPageTitle
= (LPWSTR
)lpKeyName
; /* FIXME */
923 if (!(RegKeySecurity
= CRegKeySecurity_fnConstructor(lpKeyPath
,
931 /* display the security editor dialog */
932 pfnEditSecurity(hWndOwner
,
933 impl_to_interface(RegKeySecurity
,
934 ISecurityInformation
));
936 /* dereference the interface, it should be destroyed here */
937 CRegKeySecurity_fnRelease(RegKeySecurity
);
940 if (lpKeyPath
!= NULL
)
942 HeapFree(GetProcessHeap(),