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