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 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 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 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 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 66 CRegKeySecurity_fnAddRef(PCRegKeySecurity obj) 67 { 68 return (ULONG)InterlockedIncrement((LONG*)&obj->ref); 69 } 70 71 static __inline ULONG 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 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 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 363 ISecurityInformation_fnAddRef(struct ISecurityInformation *this) 364 { 365 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation(this)); 366 } 367 368 static ULONG STDMETHODCALLTYPE 369 ISecurityInformation_fnRelease(struct ISecurityInformation *this) 370 { 371 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation(this)); 372 } 373 374 static HRESULT STDMETHODCALLTYPE 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 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 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 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 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 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 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 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 492 ISecurityInformation2_fnAddRef(struct ISecurityInformation2 *this) 493 { 494 return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation2(this)); 495 } 496 497 static ULONG STDMETHODCALLTYPE 498 ISecurityInformation2_fnRelease(struct ISecurityInformation2 *this) 499 { 500 return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation2(this)); 501 } 502 503 static BOOL STDMETHODCALLTYPE 504 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2 *this, 505 PACL pDacl) 506 { 507 /* FIXME */ 508 return TRUE; 509 } 510 511 static HRESULT STDMETHODCALLTYPE 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 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 544 IEffectivePermission_fnAddRef(struct IEffectivePermission *this) 545 { 546 return CRegKeySecurity_fnAddRef(impl_from_IEffectivePermission(this)); 547 } 548 549 static ULONG STDMETHODCALLTYPE 550 IEffectivePermission_fnRelease(struct IEffectivePermission *this) 551 { 552 return CRegKeySecurity_fnRelease(impl_from_IEffectivePermission(this)); 553 } 554 555 static HRESULT STDMETHODCALLTYPE 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 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 630 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo *this) 631 { 632 return CRegKeySecurity_fnAddRef(impl_from_ISecurityObjectTypeInfo(this)); 633 } 634 635 static ULONG STDMETHODCALLTYPE 636 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo *this) 637 { 638 return CRegKeySecurity_fnRelease(impl_from_ISecurityObjectTypeInfo(this)); 639 } 640 641 static HRESULT STDMETHODCALLTYPE 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 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 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 784 UnloadAclUiDll(VOID) 785 { 786 if (hAclUiDll != NULL) 787 { 788 FreeLibrary(hAclUiDll); 789 } 790 } 791 792 BOOL 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