1 /*
2 * Regedit ACL Editor for Registry Keys
3 *
4 * Copyright (C) 2004-2006 Thomas Weidenmueller <w3seek@reactos.com>
5 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
6 */
7
8 #include "regedit.h"
9
10 #define INITGUID
11 #include <guiddef.h>
12
13 /* FIXME - shouldn't be defined here... */
14 DEFINE_GUID(IID_IRegKeySecurity, 0x965fc360, 0x16ff, 0x11d0, 0x0091, 0xcb,0x00,0xaa,0x00,0xbb,0xb7,0x23);
15 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
16 DEFINE_GUID(IID_IRegKeySecurity2, 0xc3ccfdb4, 0x6f88, 0x11d2, 0x00a3, 0xce,0x00,0xc0,0x4f,0xb1,0x78,0x2a);
17 #endif
18
19 /* FIXME: already defined in aclui.h - causing problems when compiling with MSVC/PSDK*/
20 #ifdef _MSC_VER
21 #pragma message ("INVESTIGATE ME")
22 #endif
23
24 #if 1 //#ifndef _MSC_VER
25 DEFINE_GUID(IID_IEffectivePermission, 0x3853dc76, 0x9f35, 0x407c, 0x0088, 0xa1,0xd1,0x93,0x44,0x36,0x5f,0xbc);
26 DEFINE_GUID(IID_ISecurityObjectTypeInfo, 0xfc3066eb, 0x79ef, 0x444b, 0x0091, 0x11,0xd1,0x8a,0x75,0xeb,0xf2,0xfa);
27 #endif
28
29 /******************************************************************************
30 Implementation of the IUnknown methods of CRegKeySecurity
31 ******************************************************************************/
32
33 static __inline PCRegKeySecurity
impl_from_ISecurityInformation(struct ISecurityInformation * iface)34 impl_from_ISecurityInformation(struct ISecurityInformation *iface)
35 {
36 return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
37 lpISecurityInformationVtbl));
38 }
39
40 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
41 static __inline PCRegKeySecurity
impl_from_ISecurityInformation2(struct ISecurityInformation2 * iface)42 impl_from_ISecurityInformation2(struct ISecurityInformation2 *iface)
43 {
44 return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
45 lpISecurityInformation2Vtbl));
46 }
47 #endif
48
49 static __inline PCRegKeySecurity
impl_from_ISecurityObjectTypeInfo(struct ISecurityObjectTypeInfo * iface)50 impl_from_ISecurityObjectTypeInfo(struct ISecurityObjectTypeInfo *iface)
51 {
52 return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
53 lpISecurityObjectTypeInfoVtbl));
54 }
55
56 static __inline PCRegKeySecurity
impl_from_IEffectivePermission(struct IEffectivePermission * iface)57 impl_from_IEffectivePermission(struct IEffectivePermission *iface)
58 {
59 return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
60 lpIEffectivePermissionVtbl));
61 }
62
63 #define impl_to_interface(impl,iface) (struct iface *)(&(impl)->lp##iface##Vtbl)
64
65 static __inline ULONG
CRegKeySecurity_fnAddRef(PCRegKeySecurity obj)66 CRegKeySecurity_fnAddRef(PCRegKeySecurity obj)
67 {
68 return (ULONG)InterlockedIncrement((LONG*)&obj->ref);
69 }
70
71 static __inline ULONG
CRegKeySecurity_fnRelease(PCRegKeySecurity obj)72 CRegKeySecurity_fnRelease(PCRegKeySecurity obj)
73 {
74 ULONG Ret;
75
76 Ret = (ULONG)InterlockedDecrement((LONG*)&obj->ref);
77 if (Ret == 0)
78 {
79 HeapFree(GetProcessHeap(), 0, obj);
80 }
81
82 return Ret;
83 }
84
85 static __inline HRESULT
CRegKeySecurity_fnQueryInterface(PCRegKeySecurity obj,REFIID iid,PVOID * pvObject)86 CRegKeySecurity_fnQueryInterface(PCRegKeySecurity obj,
87 REFIID iid,
88 PVOID *pvObject)
89 {
90 PVOID pvObj = NULL;
91
92 if (IsEqualGUID(iid, &IID_IRegKeySecurity))
93 {
94 pvObj = (PVOID)impl_to_interface(obj, ISecurityInformation);
95 }
96 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
97 else if (IsEqualGUID(iid, &IID_IRegKeySecurity2))
98 {
99 pvObj = (PVOID)impl_to_interface(obj, ISecurityInformation2);
100 }
101 #endif
102 else if (IsEqualGUID(iid, &IID_IEffectivePermission))
103 {
104 pvObj = (PVOID)impl_to_interface(obj, IEffectivePermission);
105 }
106 else if (IsEqualGUID(iid, &IID_ISecurityObjectTypeInfo))
107 {
108 pvObj = (PVOID)impl_to_interface(obj, ISecurityObjectTypeInfo);
109 }
110
111 if (pvObj == NULL)
112 {
113 return E_NOINTERFACE;
114 }
115
116 *pvObject = pvObj;
117 CRegKeySecurity_fnAddRef(obj);
118
119 return S_OK;
120 }
121
122
123 /******************************************************************************
124 Definition of the ISecurityInformation interface
125 ******************************************************************************/
126
127 /* IUnknown */
128 static HRESULT STDMETHODCALLTYPE
129 ISecurityInformation_fnQueryInterface(struct ISecurityInformation *this,
130 REFIID iid,
131 PVOID *pvObject);
132
133 static ULONG STDMETHODCALLTYPE
134 ISecurityInformation_fnAddRef(struct ISecurityInformation *this);
135
136 static ULONG STDMETHODCALLTYPE
137 ISecurityInformation_fnRelease(struct ISecurityInformation *this);
138
139 /* ISecurityInformation */
140 static HRESULT STDMETHODCALLTYPE
141 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation *this,
142 PSI_OBJECT_INFO pObjectInfo);
143
144 static HRESULT STDMETHODCALLTYPE
145 ISecurityInformation_fnGetSecurity(struct ISecurityInformation *this,
146 SECURITY_INFORMATION RequestedInformation,
147 PSECURITY_DESCRIPTOR* ppSecurityDescriptor,
148 BOOL fDefault);
149
150 static HRESULT STDMETHODCALLTYPE
151 ISecurityInformation_fnSetSecurity(struct ISecurityInformation *this,
152 SECURITY_INFORMATION RequestedInformation,
153 PSECURITY_DESCRIPTOR pSecurityDescriptor);
154
155 static HRESULT STDMETHODCALLTYPE
156 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation *this,
157 const GUID* pguidObjectType,
158 DWORD dwFlags,
159 PSI_ACCESS* ppAccess,
160 ULONG* pcAccesses,
161 ULONG* piDefaultAccess);
162
163 static HRESULT STDMETHODCALLTYPE
164 ISecurityInformation_fnMapGeneric(struct ISecurityInformation *this,
165 const GUID* pguidObjectType,
166 UCHAR* pAceFlags,
167 ACCESS_MASK* pMask);
168
169 static HRESULT STDMETHODCALLTYPE
170 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation *this,
171 PSI_INHERIT_TYPE* ppInheritTypes,
172 ULONG* pcInheritTypes);
173 static HRESULT STDMETHODCALLTYPE
174 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation *this,
175 HWND hwnd,
176 UINT uMsg,
177 SI_PAGE_TYPE uPage);
178
179 static const struct ifaceISecurityInformationVbtl vtblISecurityInformation =
180 {
181 /* IUnknown methods */
182 ISecurityInformation_fnQueryInterface,
183 ISecurityInformation_fnAddRef,
184 ISecurityInformation_fnRelease,
185
186 /* ISecurityInformation methods */
187 ISecurityInformation_fnGetObjectInformation,
188 ISecurityInformation_fnGetSecurity,
189 ISecurityInformation_fnSetSecurity,
190 ISecurityInformation_fnGetAccessRights,
191 ISecurityInformation_fnMapGeneric,
192 ISecurityInformation_fnGetInheritTypes,
193 ISecurityInformation_fnPropertySheetPageCallback,
194 };
195
196 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
197 /******************************************************************************
198 Definition of the ISecurityInformation2 interface
199 ******************************************************************************/
200
201 /* IUnknown */
202 static HRESULT STDMETHODCALLTYPE
203 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2 *this,
204 REFIID iid,
205 PVOID *pvObject);
206
207 static ULONG STDMETHODCALLTYPE
208 ISecurityInformation2_fnAddRef(struct ISecurityInformation2 *this);
209
210 static ULONG STDMETHODCALLTYPE
211 ISecurityInformation2_fnRelease(struct ISecurityInformation2 *this);
212
213 /* ISecurityInformation2 */
214 static BOOL STDMETHODCALLTYPE
215 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2 *this,
216 PACL pDacl);
217
218 static HRESULT STDMETHODCALLTYPE
219 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2 *this,
220 ULONG cSids,
221 PSID* rgpSids,
222 LPDATAOBJECT* ppdo);
223
224 static const struct ifaceISecurityInformation2Vbtl vtblISecurityInformation2 =
225 {
226 /* IUnknown methods */
227 ISecurityInformation2_fnQueryInterface,
228 ISecurityInformation2_fnAddRef,
229 ISecurityInformation2_fnRelease,
230
231 /* ISecurityInformation2 methods */
232 ISecurityInformation2_fnIsDaclCanonical,
233 ISecurityInformation2_fnLookupSids
234 };
235 #endif
236
237 /******************************************************************************
238 Definition of the IEffectivePermission interface
239 ******************************************************************************/
240
241 /* IUnknown */
242 static HRESULT STDMETHODCALLTYPE
243 IEffectivePermission_fnQueryInterface(struct IEffectivePermission *this,
244 REFIID iid,
245 PVOID *pvObject);
246
247 static ULONG STDMETHODCALLTYPE
248 IEffectivePermission_fnAddRef(struct IEffectivePermission *this);
249
250 static ULONG STDMETHODCALLTYPE
251 IEffectivePermission_fnRelease(struct IEffectivePermission *this);
252
253 /* IEffectivePermission */
254 static HRESULT STDMETHODCALLTYPE
255 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission *this,
256 const GUID* pguidObjectType,
257 PSID pUserSid,
258 LPCWSTR pszServerName,
259 PSECURITY_DESCRIPTOR pSD,
260 POBJECT_TYPE_LIST* ppObjectTypeList,
261 ULONG* pcObjectTypeListLength,
262 PACCESS_MASK* ppGrantedAccessList,
263 ULONG* pcGrantedAccessListLength);
264
265 static const struct ifaceIEffectivePermissionVbtl vtblIEffectivePermission =
266 {
267 /* IUnknown methods */
268 IEffectivePermission_fnQueryInterface,
269 IEffectivePermission_fnAddRef,
270 IEffectivePermission_fnRelease,
271
272 /* IEffectivePermissions methods */
273 IEffectivePermission_fnGetEffectivePermission
274 };
275
276 /******************************************************************************
277 Definition of the ISecurityObjectTypeInfo interface
278 ******************************************************************************/
279
280 /* IUnknown */
281 static HRESULT STDMETHODCALLTYPE
282 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo *this,
283 REFIID iid,
284 PVOID *pvObject);
285
286 static ULONG STDMETHODCALLTYPE
287 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo *this);
288
289 static ULONG STDMETHODCALLTYPE
290 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo *this);
291
292 /* ISecurityObjectTypeInfo */
293 static HRESULT STDMETHODCALLTYPE
294 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo *this,
295 SECURITY_INFORMATION si,
296 PACL pACL,
297 PINHERITED_FROM* ppInheritArray);
298
299 static const struct ifaceISecurityObjectTypeInfoVbtl vtblISecurityObjectTypeInfo =
300 {
301 /* IUnknown methods */
302 ISecurityObjectTypeInfo_fnQueryInterface,
303 ISecurityObjectTypeInfo_fnAddRef,
304 ISecurityObjectTypeInfo_fnRelease,
305
306 /* ISecurityObjectTypeInfo methods */
307 ISecurityObjectTypeInfo_fnGetInheritSource
308 };
309
310
311 /******************************************************************************
312 Implementation of the ISecurityInformation interface
313 ******************************************************************************/
314
315 static SI_ACCESS RegAccess[] = {
316 {&GUID_NULL, KEY_ALL_ACCESS, MAKEINTRESOURCEW(IDS_ACCESS_FULLCONTROL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC},
317 {&GUID_NULL, KEY_READ, MAKEINTRESOURCEW(IDS_ACCESS_READ), SI_ACCESS_GENERAL},
318 {&GUID_NULL, KEY_QUERY_VALUE, MAKEINTRESOURCEW(IDS_ACCESS_QUERYVALUE), SI_ACCESS_SPECIFIC},
319 {&GUID_NULL, KEY_SET_VALUE, MAKEINTRESOURCEW(IDS_ACCESS_SETVALUE), SI_ACCESS_SPECIFIC},
320 {&GUID_NULL, KEY_CREATE_SUB_KEY, MAKEINTRESOURCEW(IDS_ACCESS_CREATESUBKEY), SI_ACCESS_SPECIFIC},
321 {&GUID_NULL, KEY_ENUMERATE_SUB_KEYS, MAKEINTRESOURCEW(IDS_ACCESS_ENUMERATESUBKEYS), SI_ACCESS_SPECIFIC},
322 {&GUID_NULL, KEY_NOTIFY, MAKEINTRESOURCEW(IDS_ACCESS_NOTIFY), SI_ACCESS_SPECIFIC},
323 {&GUID_NULL, KEY_CREATE_LINK, MAKEINTRESOURCEW(IDS_ACCESS_CREATELINK), SI_ACCESS_SPECIFIC},
324 {&GUID_NULL, DELETE, MAKEINTRESOURCEW(IDS_ACCESS_DELETE), SI_ACCESS_SPECIFIC},
325 {&GUID_NULL, WRITE_DAC, MAKEINTRESOURCEW(IDS_ACCESS_WRITEDAC), SI_ACCESS_SPECIFIC},
326 {&GUID_NULL, WRITE_OWNER, MAKEINTRESOURCEW(IDS_ACCESS_WRITEOWNER), SI_ACCESS_SPECIFIC},
327 {&GUID_NULL, READ_CONTROL, MAKEINTRESOURCEW(IDS_ACCESS_READCONTROL), SI_ACCESS_SPECIFIC},
328 };
329
330 static const DWORD RegDefaultAccess = 1; /* KEY_READ */
331
332 static GENERIC_MAPPING RegAccessMasks = {
333 KEY_READ,
334 KEY_WRITE,
335 KEY_EXECUTE,
336 KEY_ALL_ACCESS
337 };
338
339 static SI_INHERIT_TYPE RegInheritTypes[] = {
340 {&GUID_NULL, 0, (LPWSTR)MAKEINTRESOURCEW(IDS_INHERIT_THISKEYONLY)},
341 {&GUID_NULL, CONTAINER_INHERIT_ACE, (LPWSTR)MAKEINTRESOURCEW(IDS_INHERIT_THISKEYANDSUBKEYS)},
342 {&GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, (LPWSTR)MAKEINTRESOURCEW(IDS_INHERIT_SUBKEYSONLY)},
343 };
344
345 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnQueryInterface(struct ISecurityInformation * this,REFIID iid,PVOID * pvObject)346 ISecurityInformation_fnQueryInterface(struct ISecurityInformation *this,
347 REFIID iid,
348 PVOID *pvObject)
349 {
350 if (IsEqualGUID(iid, &IID_IUnknown))
351 {
352 *pvObject = (PVOID)this;
353 ISecurityInformation_fnAddRef(this);
354 return S_OK;
355 }
356
357 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation(this),
358 iid,
359 pvObject);
360 }
361
362 static ULONG STDMETHODCALLTYPE
ISecurityInformation_fnAddRef(struct ISecurityInformation * this)363 ISecurityInformation_fnAddRef(struct ISecurityInformation *this)
364 {
365 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation(this));
366 }
367
368 static ULONG STDMETHODCALLTYPE
ISecurityInformation_fnRelease(struct ISecurityInformation * this)369 ISecurityInformation_fnRelease(struct ISecurityInformation *this)
370 {
371 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation(this));
372 }
373
374 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation * this,PSI_OBJECT_INFO pObjectInfo)375 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation *this,
376 PSI_OBJECT_INFO pObjectInfo)
377 {
378 PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
379
380 *pObjectInfo = obj->ObjectInfo;
381 return S_OK;
382 }
383
384 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnGetSecurity(struct ISecurityInformation * this,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR * ppSecurityDescriptor,BOOL fDefault)385 ISecurityInformation_fnGetSecurity(struct ISecurityInformation *this,
386 SECURITY_INFORMATION RequestedInformation,
387 PSECURITY_DESCRIPTOR* ppSecurityDescriptor,
388 BOOL fDefault)
389 {
390 PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
391 LONG ErrorCode;
392
393 ErrorCode = GetNamedSecurityInfoW(obj->szRegKey,
394 SE_REGISTRY_KEY,
395 RequestedInformation,
396 NULL,
397 NULL,
398 NULL,
399 NULL,
400 ppSecurityDescriptor);
401
402 return HRESULT_FROM_WIN32(ErrorCode);
403 }
404
405 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnSetSecurity(struct ISecurityInformation * this,SECURITY_INFORMATION RequestedInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor)406 ISecurityInformation_fnSetSecurity(struct ISecurityInformation *this,
407 SECURITY_INFORMATION RequestedInformation,
408 PSECURITY_DESCRIPTOR pSecurityDescriptor)
409 {
410 PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
411
412 /* FIXME */
413 *obj->Btn = TRUE;
414 return S_OK;
415 }
416
417 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnGetAccessRights(struct ISecurityInformation * this,const GUID * pguidObjectType,DWORD dwFlags,PSI_ACCESS * ppAccess,ULONG * pcAccesses,ULONG * piDefaultAccess)418 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation *this,
419 const GUID* pguidObjectType,
420 DWORD dwFlags,
421 PSI_ACCESS* ppAccess,
422 ULONG* pcAccesses,
423 ULONG* piDefaultAccess)
424 {
425 *ppAccess = RegAccess;
426 *pcAccesses = ARRAY_SIZE(RegAccess);
427 *piDefaultAccess = RegDefaultAccess;
428 return S_OK;
429 }
430
431 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnMapGeneric(struct ISecurityInformation * this,const GUID * pguidObjectType,UCHAR * pAceFlags,ACCESS_MASK * pMask)432 ISecurityInformation_fnMapGeneric(struct ISecurityInformation *this,
433 const GUID* pguidObjectType,
434 UCHAR* pAceFlags,
435 ACCESS_MASK* pMask)
436 {
437 MapGenericMask(pMask, &RegAccessMasks);
438 *pMask &= ~SYNCHRONIZE;
439 return S_OK;
440 }
441
442 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation * this,PSI_INHERIT_TYPE * ppInheritTypes,ULONG * pcInheritTypes)443 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation *this,
444 PSI_INHERIT_TYPE* ppInheritTypes,
445 ULONG* pcInheritTypes)
446 {
447 PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
448
449 /* FIXME */
450 if (obj->ObjectInfo.dwFlags & SI_CONTAINER)
451 {
452 *ppInheritTypes = RegInheritTypes;
453 *pcInheritTypes = ARRAY_SIZE(RegInheritTypes);
454 return S_OK;
455 }
456
457 return E_NOTIMPL;
458 }
459
460 static HRESULT STDMETHODCALLTYPE
ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation * this,HWND hwnd,UINT uMsg,SI_PAGE_TYPE uPage)461 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation *this,
462 HWND hwnd,
463 UINT uMsg,
464 SI_PAGE_TYPE uPage)
465 {
466 return S_OK;
467 }
468
469 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
470 /******************************************************************************
471 Implementation of the ISecurityInformation2 interface
472 ******************************************************************************/
473
474 static HRESULT STDMETHODCALLTYPE
ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2 * this,REFIID iid,PVOID * pvObject)475 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2 *this,
476 REFIID iid,
477 PVOID *pvObject)
478 {
479 if (IsEqualGUID(iid, &IID_IUnknown))
480 {
481 *pvObject = (PVOID)this;
482 ISecurityInformation2_fnAddRef(this);
483 return S_OK;
484 }
485
486 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation2(this),
487 iid,
488 pvObject);
489 }
490
491 static ULONG STDMETHODCALLTYPE
ISecurityInformation2_fnAddRef(struct ISecurityInformation2 * this)492 ISecurityInformation2_fnAddRef(struct ISecurityInformation2 *this)
493 {
494 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation2(this));
495 }
496
497 static ULONG STDMETHODCALLTYPE
ISecurityInformation2_fnRelease(struct ISecurityInformation2 * this)498 ISecurityInformation2_fnRelease(struct ISecurityInformation2 *this)
499 {
500 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation2(this));
501 }
502
503 static BOOL STDMETHODCALLTYPE
ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2 * this,PACL pDacl)504 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2 *this,
505 PACL pDacl)
506 {
507 /* FIXME */
508 return TRUE;
509 }
510
511 static HRESULT STDMETHODCALLTYPE
ISecurityInformation2_fnLookupSids(struct ISecurityInformation2 * this,ULONG cSids,PSID * rgpSids,LPDATAOBJECT * ppdo)512 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2 *this,
513 ULONG cSids,
514 PSID* rgpSids,
515 LPDATAOBJECT* ppdo)
516 {
517 /* FIXME */
518 return E_NOTIMPL;
519 }
520 #endif
521
522 /******************************************************************************
523 Implementation of the IEffectivePermission interface
524 ******************************************************************************/
525
526 static HRESULT STDMETHODCALLTYPE
IEffectivePermission_fnQueryInterface(struct IEffectivePermission * this,REFIID iid,PVOID * pvObject)527 IEffectivePermission_fnQueryInterface(struct IEffectivePermission *this,
528 REFIID iid,
529 PVOID *pvObject)
530 {
531 if (IsEqualGUID(iid, &IID_IUnknown))
532 {
533 *pvObject = (PVOID)this;
534 IEffectivePermission_fnAddRef(this);
535 return S_OK;
536 }
537
538 return CRegKeySecurity_fnQueryInterface(impl_from_IEffectivePermission(this),
539 iid,
540 pvObject);
541 }
542
543 static ULONG STDMETHODCALLTYPE
IEffectivePermission_fnAddRef(struct IEffectivePermission * this)544 IEffectivePermission_fnAddRef(struct IEffectivePermission *this)
545 {
546 return CRegKeySecurity_fnAddRef(impl_from_IEffectivePermission(this));
547 }
548
549 static ULONG STDMETHODCALLTYPE
IEffectivePermission_fnRelease(struct IEffectivePermission * this)550 IEffectivePermission_fnRelease(struct IEffectivePermission *this)
551 {
552 return CRegKeySecurity_fnRelease(impl_from_IEffectivePermission(this));
553 }
554
555 static HRESULT STDMETHODCALLTYPE
IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission * this,const GUID * pguidObjectType,PSID pUserSid,LPCWSTR pszServerName,PSECURITY_DESCRIPTOR pSD,POBJECT_TYPE_LIST * ppObjectTypeList,ULONG * pcObjectTypeListLength,PACCESS_MASK * ppGrantedAccessList,ULONG * pcGrantedAccessListLength)556 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission *this,
557 const GUID* pguidObjectType,
558 PSID pUserSid,
559 LPCWSTR pszServerName,
560 PSECURITY_DESCRIPTOR pSD,
561 POBJECT_TYPE_LIST* ppObjectTypeList,
562 ULONG* pcObjectTypeListLength,
563 PACCESS_MASK* ppGrantedAccessList,
564 ULONG* pcGrantedAccessListLength)
565 {
566 PACL Dacl = NULL;
567 BOOL DaclPresent, DaclDefaulted;
568 PACCESS_MASK GrantedAccessList;
569 DWORD ErrorCode = ERROR_SUCCESS;
570 TRUSTEE Trustee = {0};
571 static OBJECT_TYPE_LIST DefObjTypeList = {0};
572
573 *ppObjectTypeList = &DefObjTypeList;
574 *pcObjectTypeListLength = 1;
575
576 BuildTrusteeWithSid(&Trustee, pUserSid);
577
578 if (GetSecurityDescriptorDacl(pSD,
579 &DaclPresent,
580 &Dacl,
581 &DaclDefaulted) && DaclPresent)
582 {
583 GrantedAccessList = (PACCESS_MASK)LocalAlloc(LMEM_FIXED,
584 sizeof(ACCESS_MASK));
585 if (GrantedAccessList == NULL)
586 {
587 goto Fail;
588 }
589
590 ErrorCode = GetEffectiveRightsFromAcl(Dacl,
591 &Trustee,
592 GrantedAccessList);
593 if (ErrorCode == ERROR_SUCCESS)
594 {
595 *ppGrantedAccessList = GrantedAccessList;
596 *pcGrantedAccessListLength = 1;
597 }
598 else
599 LocalFree((HLOCAL)GrantedAccessList);
600 }
601 else
602 Fail:
603 ErrorCode = GetLastError();
604
605 return HRESULT_FROM_WIN32(ErrorCode);
606 }
607
608 /******************************************************************************
609 Implementation of the ISecurityObjectTypeInfo interface
610 ******************************************************************************/
611
612 static HRESULT STDMETHODCALLTYPE
ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo * this,REFIID iid,PVOID * pvObject)613 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo *this,
614 REFIID iid,
615 PVOID *pvObject)
616 {
617 if (IsEqualGUID(iid, &IID_IUnknown))
618 {
619 *pvObject = (PVOID)this;
620 ISecurityObjectTypeInfo_fnAddRef(this);
621 return S_OK;
622 }
623
624 return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityObjectTypeInfo(this),
625 iid,
626 pvObject);
627 }
628
629 static ULONG STDMETHODCALLTYPE
ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo * this)630 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo *this)
631 {
632 return CRegKeySecurity_fnAddRef(impl_from_ISecurityObjectTypeInfo(this));
633 }
634
635 static ULONG STDMETHODCALLTYPE
ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo * this)636 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo *this)
637 {
638 return CRegKeySecurity_fnRelease(impl_from_ISecurityObjectTypeInfo(this));
639 }
640
641 static HRESULT STDMETHODCALLTYPE
ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo * this,SECURITY_INFORMATION si,PACL pACL,PINHERITED_FROM * ppInheritArray)642 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo *this,
643 SECURITY_INFORMATION si,
644 PACL pACL,
645 PINHERITED_FROM* ppInheritArray)
646 {
647 PCRegKeySecurity obj = impl_from_ISecurityObjectTypeInfo(this);
648 PINHERITED_FROM pif, pif2;
649 SIZE_T pifSize;
650 DWORD ErrorCode, i;
651 LPWSTR lpBuf;
652
653 pifSize = pACL->AceCount * sizeof(INHERITED_FROM);
654 pif = (PINHERITED_FROM)HeapAlloc(GetProcessHeap(), 0, pifSize);
655 if (pif == NULL)
656 return E_OUTOFMEMORY;
657
658 ErrorCode = GetInheritanceSourceW(obj->szRegKey,
659 SE_REGISTRY_KEY,
660 si,
661 (obj->ObjectInfo.dwFlags & SI_CONTAINER) != 0,
662 NULL,
663 0,
664 pACL,
665 NULL,
666 &RegAccessMasks,
667 pif);
668 if (ErrorCode == ERROR_SUCCESS)
669 {
670 /* Calculate the size of the buffer to return */
671 for (i = 0; i < pACL->AceCount; i++)
672 {
673 if (pif[i].AncestorName != NULL)
674 pifSize += (wcslen(pif[i].AncestorName) + 1) * sizeof(WCHAR);
675 }
676
677 /* Allocate enough space for the array and the strings */
678 pif2 = (PINHERITED_FROM)LocalAlloc(LMEM_FIXED, pifSize);
679 if (pif2 == NULL)
680 {
681 ErrorCode = GetLastError();
682 goto Cleanup;
683 }
684
685 /* copy the array and strings to the buffer */
686 lpBuf = (LPWSTR)((ULONG_PTR)pif2 + (pACL->AceCount * sizeof(INHERITED_FROM)));
687 for (i = 0; i < pACL->AceCount; i++)
688 {
689 pif2[i].GenerationGap = pif[i].GenerationGap;
690 if (pif[i].AncestorName != NULL)
691 {
692 pif2[i].AncestorName = lpBuf;
693 wcscpy(lpBuf,
694 pif[i].AncestorName);
695 lpBuf += wcslen(pif[i].AncestorName) + 1;
696 }
697 else
698 pif2[i].AncestorName = NULL;
699 }
700
701 /* return the newly allocated array */
702 *ppInheritArray = pif2;
703 }
704
705 Cleanup:
706 FreeInheritedFromArray(pif, pACL->AceCount, NULL);
707 HeapFree(GetProcessHeap(), 0, pif);
708
709 return HRESULT_FROM_WIN32(ErrorCode);
710 }
711
712 /******************************************************************************
713 Implementation of the CRegKeySecurity constructor
714 ******************************************************************************/
715
716 static PCRegKeySecurity
CRegKeySecurity_fnConstructor(LPWSTR lpRegKey,HKEY hRootKey,SI_OBJECT_INFO * ObjectInfo,BOOL * Btn)717 CRegKeySecurity_fnConstructor(LPWSTR lpRegKey,
718 HKEY hRootKey,
719 SI_OBJECT_INFO *ObjectInfo,
720 BOOL *Btn)
721 {
722 PCRegKeySecurity obj;
723
724 obj = (PCRegKeySecurity)HeapAlloc(GetProcessHeap(),
725 HEAP_ZERO_MEMORY,
726 FIELD_OFFSET(CRegKeySecurity,
727 szRegKey[wcslen(lpRegKey) + 1]));
728 if (obj != NULL)
729 {
730 obj->ref = 1;
731 obj->lpISecurityInformationVtbl = &vtblISecurityInformation;
732 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
733 obj->lpISecurityInformation2Vtbl = &vtblISecurityInformation2;
734 #endif
735 obj->lpIEffectivePermissionVtbl = &vtblIEffectivePermission;
736 obj->lpISecurityObjectTypeInfoVtbl = &vtblISecurityObjectTypeInfo;
737 obj->ObjectInfo = *ObjectInfo;
738 obj->Btn = Btn;
739 obj->hRootKey = hRootKey;
740 StringCbCopyW(obj->szRegKey, sizeof(obj->szRegKey), lpRegKey);
741 }
742 else
743 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
744
745 return obj;
746 }
747
748 /******************************************************************************/
749 /******************************************************************************/
750 /******************************************************************************/
751
752 typedef struct _CHANGE_CONTEXT
753 {
754 HKEY hKey;
755 LPWSTR KeyString;
756 } CHANGE_CONTEXT, *PCHANGE_CONTEXT;
757
758 typedef BOOL (WINAPI *PEDITSECURITY)(HWND hwndOwner,
759 struct ISecurityInformation *psi);
760
761 static PEDITSECURITY pfnEditSecurity;
762 static HMODULE hAclUiDll;
763
764 BOOL
InitializeAclUiDll(VOID)765 InitializeAclUiDll(VOID)
766 {
767 if (!(hAclUiDll = LoadLibraryW(L"aclui.dll")))
768 {
769 return FALSE;
770 }
771
772 if (!(pfnEditSecurity = (PEDITSECURITY)GetProcAddress(hAclUiDll,
773 "EditSecurity")))
774 {
775 FreeLibrary(hAclUiDll);
776 hAclUiDll = NULL;
777 return FALSE;
778 }
779
780 return TRUE;
781 }
782
783 VOID
UnloadAclUiDll(VOID)784 UnloadAclUiDll(VOID)
785 {
786 if (hAclUiDll != NULL)
787 {
788 FreeLibrary(hAclUiDll);
789 }
790 }
791
792 BOOL
RegKeyEditPermissions(HWND hWndOwner,HKEY hKey,LPCWSTR lpMachine,LPCWSTR lpKeyName)793 RegKeyEditPermissions(HWND hWndOwner,
794 HKEY hKey,
795 LPCWSTR lpMachine,
796 LPCWSTR lpKeyName)
797 {
798 BOOL Result = FALSE;
799 LPCWSTR lphKey = NULL;
800 LPWSTR lpKeyPath = NULL;
801 PCRegKeySecurity RegKeySecurity;
802 SI_OBJECT_INFO ObjectInfo;
803 size_t lnMachine = 0, lnKeyName = 0;
804
805 if (pfnEditSecurity == NULL)
806 {
807 return FALSE;
808 }
809
810 if (lpMachine != NULL)
811 lnMachine = wcslen(lpMachine);
812 if (lpKeyName != NULL)
813 lnKeyName = wcslen(lpKeyName);
814
815 /* build registry path */
816 if (lpMachine != NULL &&
817 (lpMachine[0] == L'\0' ||
818 (lpMachine[0] == L'.' && lpMachine[1] == L'.')))
819 {
820 lnMachine = 0;
821 }
822
823 if (hKey == HKEY_CLASSES_ROOT)
824 lphKey = L"CLASSES_ROOT";
825 else if (hKey == HKEY_CURRENT_USER)
826 lphKey = L"CURRENT_USER";
827 else if (hKey == HKEY_LOCAL_MACHINE)
828 lphKey = L"MACHINE";
829 else if (hKey == HKEY_USERS)
830 lphKey = L"USERS";
831 else if (hKey == HKEY_CURRENT_CONFIG)
832 lphKey = L"CONFIG";
833 else
834 goto Cleanup;
835
836 lpKeyPath = HeapAlloc(GetProcessHeap(),
837 0,
838 (2 + lnMachine + 1 + wcslen(lphKey) + 1 + lnKeyName) * sizeof(WCHAR));
839 if (lpKeyPath == NULL)
840 {
841 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
842 goto Cleanup;
843 }
844 lpKeyPath[0] = L'\0';
845
846 if (lnMachine != 0)
847 {
848 wcscat(lpKeyPath, L"\\\\");
849 wcscat(lpKeyPath, lpMachine);
850 wcscat(lpKeyPath, L"\\");
851 }
852
853 wcscat(lpKeyPath, lphKey);
854 if (lpKeyName != NULL && lpKeyName[0] != L'\0')
855 {
856 if (lpKeyName[0] != L'\\')
857 wcscat(lpKeyPath, L"\\");
858
859 wcscat(lpKeyPath, lpKeyName);
860 }
861
862 ObjectInfo.dwFlags = SI_EDIT_ALL | SI_ADVANCED | SI_CONTAINER | SI_EDIT_EFFECTIVE | SI_EDIT_PERMS |
863 SI_OWNER_RECURSE | SI_RESET_DACL_TREE | SI_RESET_SACL_TREE;
864 ObjectInfo.hInstance = hInst;
865 ObjectInfo.pszServerName = (LPWSTR)lpMachine;
866 ObjectInfo.pszObjectName = (LPWSTR)lpKeyName; /* FIXME */
867 ObjectInfo.pszPageTitle = (LPWSTR)lpKeyName; /* FIXME */
868
869 if (!(RegKeySecurity = CRegKeySecurity_fnConstructor(lpKeyPath,
870 hKey,
871 &ObjectInfo,
872 &Result)))
873 {
874 goto Cleanup;
875 }
876
877 /* display the security editor dialog */
878 pfnEditSecurity(hWndOwner, impl_to_interface(RegKeySecurity, ISecurityInformation));
879
880 /* dereference the interface, it should be destroyed here */
881 CRegKeySecurity_fnRelease(RegKeySecurity);
882
883 Cleanup:
884 if (lpKeyPath != NULL)
885 HeapFree(GetProcessHeap(), 0, lpKeyPath);
886
887 return Result;
888 }
889
890 /* EOF */
891