ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

security.c
Go to the documentation of this file.
00001 /*
00002  * Regedit ACL Editor for Registry Keys
00003  *
00004  * Copyright (C) 2004 - 2006 Thomas Weidenmueller <w3seek@reactos.com>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <regedit.h>
00022 
00023 #define INITGUID
00024 #include <guiddef.h>
00025 
00026 /* FIXME - shouldn't be defined here... */
00027 DEFINE_GUID(IID_IRegKeySecurity, 0x965fc360, 0x16ff, 0x11d0, 0x0091, 0xcb,0x00,0xaa,0x00,0xbb,0xb7,0x23);
00028 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
00029 DEFINE_GUID(IID_IRegKeySecurity2, 0xc3ccfdb4, 0x6f88, 0x11d2, 0x00a3, 0xce,0x00,0xc0,0x4f,0xb1,0x78,0x2a);
00030 #endif
00031 
00032 /* FIXME: already defined in aclui.h - causing problems when compiling with MSVC/PSDK*/
00033 #ifdef _MSC_VER
00034 #pragma message ("INVESTIGATE ME")
00035 #endif
00036 
00037 #if 1 //#ifndef _MSC_VER
00038 DEFINE_GUID(IID_IEffectivePermission, 0x3853dc76, 0x9f35, 0x407c, 0x0088, 0xa1,0xd1,0x93,0x44,0x36,0x5f,0xbc);
00039 DEFINE_GUID(IID_ISecurityObjectTypeInfo, 0xfc3066eb, 0x79ef, 0x444b, 0x0091, 0x11,0xd1,0x8a,0x75,0xeb,0xf2,0xfa);
00040 #endif
00041 
00042 /******************************************************************************
00043    Implementation of the IUnknown methods of CRegKeySecurity
00044  ******************************************************************************/
00045 
00046 static __inline PCRegKeySecurity
00047 impl_from_ISecurityInformation(struct ISecurityInformation *iface)
00048 {
00049     return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
00050                                                               lpISecurityInformationVtbl));
00051 }
00052 
00053 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
00054 static __inline PCRegKeySecurity
00055 impl_from_ISecurityInformation2(struct ISecurityInformation2 *iface)
00056 {
00057     return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
00058                                                               lpISecurityInformation2Vtbl));
00059 }
00060 #endif
00061 
00062 static __inline PCRegKeySecurity
00063 impl_from_ISecurityObjectTypeInfo(struct ISecurityObjectTypeInfo *iface)
00064 {
00065     return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
00066                                                               lpISecurityObjectTypeInfoVtbl));
00067 }
00068 
00069 static __inline PCRegKeySecurity
00070 impl_from_IEffectivePermission(struct IEffectivePermission *iface)
00071 {
00072     return (PCRegKeySecurity)((ULONG_PTR)iface - FIELD_OFFSET(CRegKeySecurity,
00073                                                               lpIEffectivePermissionVtbl));
00074 }
00075 
00076 #define impl_to_interface(impl,iface) (struct iface *)(&(impl)->lp##iface##Vtbl)
00077 
00078 static __inline ULONG
00079 CRegKeySecurity_fnAddRef(PCRegKeySecurity obj)
00080 {
00081     return (ULONG)InterlockedIncrement((LONG*)&obj->ref);
00082 }
00083 
00084 static __inline ULONG
00085 CRegKeySecurity_fnRelease(PCRegKeySecurity obj)
00086 {
00087     ULONG Ret;
00088 
00089     Ret = (ULONG)InterlockedDecrement((LONG*)&obj->ref);
00090     if (Ret == 0)
00091     {
00092         HeapFree(GetProcessHeap(),
00093                  0,
00094                  obj);
00095     }
00096 
00097     return Ret;
00098 }
00099 
00100 static __inline HRESULT
00101 CRegKeySecurity_fnQueryInterface(PCRegKeySecurity obj,
00102                                  REFIID iid,
00103                                  PVOID *pvObject)
00104 {
00105     PVOID pvObj = NULL;
00106 
00107     if (IsEqualGUID(iid,
00108                     &IID_IRegKeySecurity))
00109     {
00110         pvObj = (PVOID)impl_to_interface(obj,
00111                                          ISecurityInformation);
00112     }
00113 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
00114     else if (IsEqualGUID(iid,
00115                          &IID_IRegKeySecurity2))
00116     {
00117         pvObj = (PVOID)impl_to_interface(obj,
00118                                          ISecurityInformation2);
00119     }
00120 #endif
00121     else if (IsEqualGUID(iid,
00122                          &IID_IEffectivePermission))
00123     {
00124         pvObj = (PVOID)impl_to_interface(obj,
00125                                          IEffectivePermission);
00126     }
00127     else if (IsEqualGUID(iid,
00128                          &IID_ISecurityObjectTypeInfo))
00129     {
00130         pvObj = (PVOID)impl_to_interface(obj,
00131                                          ISecurityObjectTypeInfo);
00132     }
00133 
00134     if (pvObj == NULL)
00135     {
00136         return E_NOINTERFACE;
00137     }
00138 
00139     *pvObject = pvObj;
00140     CRegKeySecurity_fnAddRef(obj);
00141 
00142     return S_OK;
00143 }
00144 
00145 
00146 /******************************************************************************
00147    Definition of the ISecurityInformation interface
00148  ******************************************************************************/
00149 
00150 /* IUnknown */
00151 static HRESULT STDMETHODCALLTYPE
00152 ISecurityInformation_fnQueryInterface(struct ISecurityInformation *this,
00153                                       REFIID iid,
00154                                       PVOID *pvObject);
00155 
00156 static ULONG STDMETHODCALLTYPE
00157 ISecurityInformation_fnAddRef(struct ISecurityInformation *this);
00158 
00159 static ULONG STDMETHODCALLTYPE
00160 ISecurityInformation_fnRelease(struct ISecurityInformation *this);
00161 
00162 /* ISecurityInformation */
00163 static HRESULT STDMETHODCALLTYPE
00164 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation *this,
00165                                             PSI_OBJECT_INFO pObjectInfo);
00166 
00167 static HRESULT STDMETHODCALLTYPE
00168 ISecurityInformation_fnGetSecurity(struct ISecurityInformation *this,
00169                                    SECURITY_INFORMATION RequestedInformation,
00170                                    PSECURITY_DESCRIPTOR* ppSecurityDescriptor,
00171                                    BOOL fDefault);
00172 
00173 static HRESULT STDMETHODCALLTYPE
00174 ISecurityInformation_fnSetSecurity(struct ISecurityInformation *this,
00175                                    SECURITY_INFORMATION RequestedInformation,
00176                                    PSECURITY_DESCRIPTOR pSecurityDescriptor);
00177 
00178 static HRESULT STDMETHODCALLTYPE
00179 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation *this,
00180                                        const GUID* pguidObjectType,
00181                                       DWORD dwFlags,
00182                                       PSI_ACCESS* ppAccess,
00183                                       ULONG* pcAccesses,
00184                                       ULONG* piDefaultAccess);
00185 
00186 static HRESULT STDMETHODCALLTYPE
00187 ISecurityInformation_fnMapGeneric(struct ISecurityInformation *this,
00188                                  const GUID* pguidObjectType,
00189                                  UCHAR* pAceFlags,
00190                                  ACCESS_MASK* pMask);
00191 
00192 static HRESULT STDMETHODCALLTYPE
00193 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation *this,
00194                                       PSI_INHERIT_TYPE* ppInheritTypes,
00195                                       ULONG* pcInheritTypes);
00196 static HRESULT STDMETHODCALLTYPE
00197 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation *this,
00198                                                 HWND hwnd,
00199                                                 UINT uMsg,
00200                                                 SI_PAGE_TYPE uPage);
00201 
00202 static const struct ifaceISecurityInformationVbtl vtblISecurityInformation =
00203 {
00204     /* IUnknown methods */
00205     ISecurityInformation_fnQueryInterface,
00206     ISecurityInformation_fnAddRef,
00207     ISecurityInformation_fnRelease,
00208 
00209     /* ISecurityInformation methods */
00210     ISecurityInformation_fnGetObjectInformation,
00211     ISecurityInformation_fnGetSecurity,
00212     ISecurityInformation_fnSetSecurity,
00213     ISecurityInformation_fnGetAccessRights,
00214     ISecurityInformation_fnMapGeneric,
00215     ISecurityInformation_fnGetInheritTypes,
00216     ISecurityInformation_fnPropertySheetPageCallback,
00217 };
00218 
00219 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
00220 /******************************************************************************
00221    Definition of the ISecurityInformation2 interface
00222  ******************************************************************************/
00223 
00224 /* IUnknown */
00225 static HRESULT STDMETHODCALLTYPE
00226 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2 *this,
00227                                        REFIID iid,
00228                                        PVOID *pvObject);
00229 
00230 static ULONG STDMETHODCALLTYPE
00231 ISecurityInformation2_fnAddRef(struct ISecurityInformation2 *this);
00232 
00233 static ULONG STDMETHODCALLTYPE
00234 ISecurityInformation2_fnRelease(struct ISecurityInformation2 *this);
00235 
00236 /* ISecurityInformation2 */
00237 static BOOL STDMETHODCALLTYPE
00238 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2 *this,
00239                                         PACL pDacl);
00240 
00241 static HRESULT STDMETHODCALLTYPE
00242 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2 *this,
00243                                    ULONG cSids,
00244                                    PSID* rgpSids,
00245                                    LPDATAOBJECT* ppdo);
00246 
00247 static const struct ifaceISecurityInformation2Vbtl vtblISecurityInformation2 =
00248 {
00249     /* IUnknown methods */
00250     ISecurityInformation2_fnQueryInterface,
00251     ISecurityInformation2_fnAddRef,
00252     ISecurityInformation2_fnRelease,
00253 
00254     /* ISecurityInformation2 methods */
00255     ISecurityInformation2_fnIsDaclCanonical,
00256     ISecurityInformation2_fnLookupSids
00257 };
00258 #endif
00259 
00260 /******************************************************************************
00261    Definition of the IEffectivePermission interface
00262  ******************************************************************************/
00263 
00264 /* IUnknown */
00265 static HRESULT STDMETHODCALLTYPE
00266 IEffectivePermission_fnQueryInterface(struct IEffectivePermission *this,
00267                                       REFIID iid,
00268                                       PVOID *pvObject);
00269 
00270 static ULONG STDMETHODCALLTYPE
00271 IEffectivePermission_fnAddRef(struct IEffectivePermission *this);
00272 
00273 static ULONG STDMETHODCALLTYPE
00274 IEffectivePermission_fnRelease(struct IEffectivePermission *this);
00275 
00276 /* IEffectivePermission */
00277 static HRESULT STDMETHODCALLTYPE
00278 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission *this,
00279                                               const GUID* pguidObjectType,
00280                                               PSID pUserSid,
00281                                               LPCWSTR pszServerName,
00282                                               PSECURITY_DESCRIPTOR pSD,
00283                                               POBJECT_TYPE_LIST* ppObjectTypeList,
00284                                               ULONG* pcObjectTypeListLength,
00285                                               PACCESS_MASK* ppGrantedAccessList,
00286                                               ULONG* pcGrantedAccessListLength);
00287 
00288 static const struct ifaceIEffectivePermissionVbtl vtblIEffectivePermission =
00289 {
00290     /* IUnknown methods */
00291     IEffectivePermission_fnQueryInterface,
00292     IEffectivePermission_fnAddRef,
00293     IEffectivePermission_fnRelease,
00294 
00295     /* IEffectivePermissions methods */
00296     IEffectivePermission_fnGetEffectivePermission
00297 };
00298 
00299 /******************************************************************************
00300    Definition of the ISecurityObjectTypeInfo interface
00301  ******************************************************************************/
00302 
00303 /* IUnknown */
00304 static HRESULT STDMETHODCALLTYPE
00305 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo *this,
00306                                          REFIID iid,
00307                                          PVOID *pvObject);
00308 
00309 static ULONG STDMETHODCALLTYPE
00310 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo *this);
00311 
00312 static ULONG STDMETHODCALLTYPE
00313 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo *this);
00314 
00315 /* ISecurityObjectTypeInfo */
00316 static HRESULT STDMETHODCALLTYPE
00317 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo *this,
00318                                            SECURITY_INFORMATION si,
00319                                            PACL pACL,
00320                                            PINHERITED_FROM* ppInheritArray);
00321 
00322 static const struct ifaceISecurityObjectTypeInfoVbtl vtblISecurityObjectTypeInfo =
00323 {
00324     /* IUnknown methods */
00325     ISecurityObjectTypeInfo_fnQueryInterface,
00326     ISecurityObjectTypeInfo_fnAddRef,
00327     ISecurityObjectTypeInfo_fnRelease,
00328 
00329     /* ISecurityObjectTypeInfo methods */
00330     ISecurityObjectTypeInfo_fnGetInheritSource
00331 };
00332 
00333 
00334 /******************************************************************************
00335    Implementation of the ISecurityInformation interface
00336  ******************************************************************************/
00337 
00338 static SI_ACCESS RegAccess[] = {
00339     {&GUID_NULL, KEY_ALL_ACCESS,         (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_FULLCONTROL),      SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC},
00340     {&GUID_NULL, KEY_READ,               (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_READ),             SI_ACCESS_GENERAL},
00341     {&GUID_NULL, KEY_QUERY_VALUE,        (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_QUERYVALUE),       SI_ACCESS_SPECIFIC},
00342     {&GUID_NULL, KEY_SET_VALUE,          (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_SETVALUE),         SI_ACCESS_SPECIFIC},
00343     {&GUID_NULL, KEY_CREATE_SUB_KEY,     (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_CREATESUBKEY),     SI_ACCESS_SPECIFIC},
00344     {&GUID_NULL, KEY_ENUMERATE_SUB_KEYS, (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_ENUMERATESUBKEYS), SI_ACCESS_SPECIFIC},
00345     {&GUID_NULL, KEY_NOTIFY,             (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_NOTIFY),           SI_ACCESS_SPECIFIC},
00346     {&GUID_NULL, KEY_CREATE_LINK,        (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_CREATELINK),       SI_ACCESS_SPECIFIC},
00347     {&GUID_NULL, DELETE,                 (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_DELETE),           SI_ACCESS_SPECIFIC},
00348     {&GUID_NULL, WRITE_DAC,              (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_WRITEDAC),         SI_ACCESS_SPECIFIC},
00349     {&GUID_NULL, WRITE_OWNER,            (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_WRITEOWNER),       SI_ACCESS_SPECIFIC},
00350     {&GUID_NULL, READ_CONTROL,           (LPWSTR)MAKEINTRESOURCE(IDS_ACCESS_READCONTROL),      SI_ACCESS_SPECIFIC},
00351 };
00352 
00353 static const DWORD RegDefaultAccess = 1; /* KEY_READ */
00354 
00355 static GENERIC_MAPPING RegAccessMasks = {
00356     KEY_READ,
00357     KEY_WRITE,
00358     KEY_EXECUTE,
00359     KEY_ALL_ACCESS
00360 };
00361 
00362 static SI_INHERIT_TYPE RegInheritTypes[] = {
00363     {&GUID_NULL, 0,                                        (LPWSTR)MAKEINTRESOURCE(IDS_INHERIT_THISKEYONLY)},
00364     {&GUID_NULL, CONTAINER_INHERIT_ACE,                    (LPWSTR)MAKEINTRESOURCE(IDS_INHERIT_THISKEYANDSUBKEYS)},
00365     {&GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, (LPWSTR)MAKEINTRESOURCE(IDS_INHERIT_SUBKEYSONLY)},
00366 };
00367 
00368 static HRESULT STDMETHODCALLTYPE
00369 ISecurityInformation_fnQueryInterface(struct ISecurityInformation *this,
00370                                       REFIID iid,
00371                                       PVOID *pvObject)
00372 {
00373     if (IsEqualGUID(iid,
00374                     &IID_IUnknown))
00375     {
00376         *pvObject = (PVOID)this;
00377         ISecurityInformation_fnAddRef(this);
00378         return S_OK;
00379     }
00380 
00381     return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation(this),
00382                                             iid,
00383                                             pvObject);
00384 }
00385 
00386 static ULONG STDMETHODCALLTYPE
00387 ISecurityInformation_fnAddRef(struct ISecurityInformation *this)
00388 {
00389     return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation(this));
00390 }
00391 
00392 static ULONG STDMETHODCALLTYPE
00393 ISecurityInformation_fnRelease(struct ISecurityInformation *this)
00394 {
00395     return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation(this));
00396 }
00397 
00398 static HRESULT STDMETHODCALLTYPE
00399 ISecurityInformation_fnGetObjectInformation(struct ISecurityInformation *this,
00400                                             PSI_OBJECT_INFO pObjectInfo)
00401 {
00402     PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
00403 
00404     *pObjectInfo = obj->ObjectInfo;
00405     return S_OK;
00406 }
00407 
00408 static HRESULT STDMETHODCALLTYPE
00409 ISecurityInformation_fnGetSecurity(struct ISecurityInformation *this,
00410                                    SECURITY_INFORMATION RequestedInformation,
00411                                    PSECURITY_DESCRIPTOR* ppSecurityDescriptor,
00412                                    BOOL fDefault)
00413 {
00414     PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
00415     LONG ErrorCode;
00416 
00417     ErrorCode = GetNamedSecurityInfo(obj->szRegKey,
00418                                      SE_REGISTRY_KEY,
00419                                      RequestedInformation,
00420                                      NULL,
00421                                      NULL,
00422                                      NULL,
00423                                      NULL,
00424                                      ppSecurityDescriptor);
00425 
00426     return HRESULT_FROM_WIN32(ErrorCode);
00427 }
00428 
00429 static HRESULT STDMETHODCALLTYPE
00430 ISecurityInformation_fnSetSecurity(struct ISecurityInformation *this,
00431                                    SECURITY_INFORMATION RequestedInformation,
00432                                    PSECURITY_DESCRIPTOR pSecurityDescriptor)
00433 {
00434     PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
00435 
00436     /* FIXME */
00437     *obj->Btn = TRUE;
00438     return S_OK;
00439 }
00440 
00441 static HRESULT STDMETHODCALLTYPE
00442 ISecurityInformation_fnGetAccessRights(struct ISecurityInformation *this,
00443                                        const GUID* pguidObjectType,
00444                                        DWORD dwFlags,
00445                                        PSI_ACCESS* ppAccess,
00446                                        ULONG* pcAccesses,
00447                                        ULONG* piDefaultAccess)
00448 {
00449     *ppAccess = RegAccess;
00450     *pcAccesses = sizeof(RegAccess) / sizeof(RegAccess[0]);
00451     *piDefaultAccess = RegDefaultAccess;
00452     return S_OK;
00453 }
00454 
00455 static HRESULT STDMETHODCALLTYPE
00456 ISecurityInformation_fnMapGeneric(struct ISecurityInformation *this,
00457                                   const GUID* pguidObjectType,
00458                                   UCHAR* pAceFlags,
00459                                   ACCESS_MASK* pMask)
00460 {
00461     MapGenericMask(pMask,
00462                    &RegAccessMasks);
00463     *pMask &= ~SYNCHRONIZE;
00464     return S_OK;
00465 }
00466 
00467 static HRESULT STDMETHODCALLTYPE
00468 ISecurityInformation_fnGetInheritTypes(struct ISecurityInformation *this,
00469                                        PSI_INHERIT_TYPE* ppInheritTypes,
00470                                        ULONG* pcInheritTypes)
00471 {
00472     PCRegKeySecurity obj = impl_from_ISecurityInformation(this);
00473 
00474     /* FIXME */
00475     if (obj->ObjectInfo.dwFlags & SI_CONTAINER)
00476     {
00477         *ppInheritTypes = RegInheritTypes;
00478         *pcInheritTypes = sizeof(RegInheritTypes) / sizeof(RegInheritTypes[0]);
00479         return S_OK;
00480     }
00481 
00482     return E_NOTIMPL;
00483 }
00484 
00485 static HRESULT STDMETHODCALLTYPE
00486 ISecurityInformation_fnPropertySheetPageCallback(struct ISecurityInformation *this,
00487                                             HWND hwnd,
00488                                             UINT uMsg,
00489                                             SI_PAGE_TYPE uPage)
00490 {
00491     return S_OK;
00492 }
00493 
00494 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
00495 /******************************************************************************
00496    Implementation of the ISecurityInformation2 interface
00497  ******************************************************************************/
00498 
00499 static HRESULT STDMETHODCALLTYPE
00500 ISecurityInformation2_fnQueryInterface(struct ISecurityInformation2 *this,
00501                                        REFIID iid,
00502                                        PVOID *pvObject)
00503 {
00504     if (IsEqualGUID(iid,
00505                     &IID_IUnknown))
00506     {
00507         *pvObject = (PVOID)this;
00508         ISecurityInformation2_fnAddRef(this);
00509         return S_OK;
00510     }
00511 
00512     return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityInformation2(this),
00513                                             iid,
00514                                             pvObject);
00515 }
00516 
00517 static ULONG STDMETHODCALLTYPE
00518 ISecurityInformation2_fnAddRef(struct ISecurityInformation2 *this)
00519 {
00520     return CRegKeySecurity_fnAddRef(impl_from_ISecurityInformation2(this));
00521 }
00522 
00523 static ULONG STDMETHODCALLTYPE
00524 ISecurityInformation2_fnRelease(struct ISecurityInformation2 *this)
00525 {
00526     return CRegKeySecurity_fnRelease(impl_from_ISecurityInformation2(this));
00527 }
00528 
00529 static BOOL STDMETHODCALLTYPE
00530 ISecurityInformation2_fnIsDaclCanonical(struct ISecurityInformation2 *this,
00531                                         PACL pDacl)
00532 {
00533     /* FIXME */
00534     return TRUE;
00535 }
00536 
00537 static HRESULT STDMETHODCALLTYPE
00538 ISecurityInformation2_fnLookupSids(struct ISecurityInformation2 *this,
00539                                    ULONG cSids,
00540                                    PSID* rgpSids,
00541                                    LPDATAOBJECT* ppdo)
00542 {
00543     /* FIXME */
00544     return E_NOTIMPL;
00545 }
00546 #endif
00547 
00548 /******************************************************************************
00549    Implementation of the IEffectivePermission interface
00550  ******************************************************************************/
00551 
00552 static HRESULT STDMETHODCALLTYPE
00553 IEffectivePermission_fnQueryInterface(struct IEffectivePermission *this,
00554                                       REFIID iid,
00555                                       PVOID *pvObject)
00556 {
00557     if (IsEqualGUID(iid,
00558                     &IID_IUnknown))
00559     {
00560         *pvObject = (PVOID)this;
00561         IEffectivePermission_fnAddRef(this);
00562         return S_OK;
00563     }
00564 
00565     return CRegKeySecurity_fnQueryInterface(impl_from_IEffectivePermission(this),
00566                                             iid,
00567                                             pvObject);
00568 }
00569 
00570 static ULONG STDMETHODCALLTYPE
00571 IEffectivePermission_fnAddRef(struct IEffectivePermission *this)
00572 {
00573     return CRegKeySecurity_fnAddRef(impl_from_IEffectivePermission(this));
00574 }
00575 
00576 static ULONG STDMETHODCALLTYPE
00577 IEffectivePermission_fnRelease(struct IEffectivePermission *this)
00578 {
00579     return CRegKeySecurity_fnRelease(impl_from_IEffectivePermission(this));
00580 }
00581 
00582 static HRESULT STDMETHODCALLTYPE
00583 IEffectivePermission_fnGetEffectivePermission(struct IEffectivePermission *this,
00584                                               const GUID* pguidObjectType,
00585                                               PSID pUserSid,
00586                                               LPCWSTR pszServerName,
00587                                               PSECURITY_DESCRIPTOR pSD,
00588                                               POBJECT_TYPE_LIST* ppObjectTypeList,
00589                                               ULONG* pcObjectTypeListLength,
00590                                               PACCESS_MASK* ppGrantedAccessList,
00591                                               ULONG* pcGrantedAccessListLength)
00592 {
00593     PACL Dacl = NULL;
00594     BOOL DaclPresent, DaclDefaulted;
00595     PACCESS_MASK GrantedAccessList;
00596     DWORD ErrorCode = ERROR_SUCCESS;
00597     TRUSTEE Trustee = {0};
00598     static OBJECT_TYPE_LIST DefObjTypeList = {0};
00599 
00600     *ppObjectTypeList = &DefObjTypeList;
00601     *pcObjectTypeListLength = 1;
00602 
00603     BuildTrusteeWithSid(&Trustee,
00604                         pUserSid);
00605 
00606     if (GetSecurityDescriptorDacl(pSD,
00607                                   &DaclPresent,
00608                                   &Dacl,
00609                                   &DaclDefaulted) && DaclPresent)
00610     {
00611         GrantedAccessList = (PACCESS_MASK)LocalAlloc(LMEM_FIXED,
00612                                                      sizeof(ACCESS_MASK));
00613         if (GrantedAccessList == NULL)
00614         {
00615             goto Fail;
00616         }
00617 
00618         ErrorCode = GetEffectiveRightsFromAcl(Dacl,
00619                                               &Trustee,
00620                                               GrantedAccessList);
00621         if (ErrorCode == ERROR_SUCCESS)
00622         {
00623             *ppGrantedAccessList = GrantedAccessList;
00624             *pcGrantedAccessListLength = 1;
00625         }
00626         else
00627             LocalFree((HLOCAL)GrantedAccessList);
00628     }
00629     else
00630 Fail:
00631         ErrorCode = GetLastError();
00632 
00633     return HRESULT_FROM_WIN32(ErrorCode);
00634 }
00635 
00636 /******************************************************************************
00637    Implementation of the ISecurityObjectTypeInfo interface
00638  ******************************************************************************/
00639 
00640 static HRESULT STDMETHODCALLTYPE
00641 ISecurityObjectTypeInfo_fnQueryInterface(struct ISecurityObjectTypeInfo *this,
00642                                          REFIID iid,
00643                                          PVOID *pvObject)
00644 {
00645     if (IsEqualGUID(iid,
00646                     &IID_IUnknown))
00647     {
00648         *pvObject = (PVOID)this;
00649         ISecurityObjectTypeInfo_fnAddRef(this);
00650         return S_OK;
00651     }
00652 
00653     return CRegKeySecurity_fnQueryInterface(impl_from_ISecurityObjectTypeInfo(this),
00654                                             iid,
00655                                             pvObject);
00656 }
00657 
00658 static ULONG STDMETHODCALLTYPE
00659 ISecurityObjectTypeInfo_fnAddRef(struct ISecurityObjectTypeInfo *this)
00660 {
00661     return CRegKeySecurity_fnAddRef(impl_from_ISecurityObjectTypeInfo(this));
00662 }
00663 
00664 static ULONG STDMETHODCALLTYPE
00665 ISecurityObjectTypeInfo_fnRelease(struct ISecurityObjectTypeInfo *this)
00666 {
00667     return CRegKeySecurity_fnRelease(impl_from_ISecurityObjectTypeInfo(this));
00668 }
00669 
00670 static HRESULT STDMETHODCALLTYPE
00671 ISecurityObjectTypeInfo_fnGetInheritSource(struct ISecurityObjectTypeInfo *this,
00672                                            SECURITY_INFORMATION si,
00673                                            PACL pACL,
00674                                            PINHERITED_FROM* ppInheritArray)
00675 {
00676     PCRegKeySecurity obj = impl_from_ISecurityObjectTypeInfo(this);
00677     PINHERITED_FROM pif, pif2;
00678     SIZE_T pifSize;
00679     DWORD ErrorCode, i;
00680     LPTSTR lpBuf;
00681 
00682     pifSize = pACL->AceCount * sizeof(INHERITED_FROM);
00683     pif = (PINHERITED_FROM)HeapAlloc(GetProcessHeap(),
00684                                      0,
00685                                      pifSize);
00686     if (pif == NULL)
00687     {
00688         return E_OUTOFMEMORY;
00689     }
00690 
00691     ErrorCode = GetInheritanceSource(obj->szRegKey,
00692                                      SE_REGISTRY_KEY,
00693                                      si,
00694                                      (obj->ObjectInfo.dwFlags & SI_CONTAINER) != 0,
00695                                      NULL,
00696                                      0,
00697                                      pACL,
00698                                      NULL,
00699                                      &RegAccessMasks,
00700                                      pif);
00701 
00702     if (ErrorCode == ERROR_SUCCESS)
00703     {
00704         /* Calculate the size of the buffer to return */
00705         for (i = 0;
00706              i < pACL->AceCount;
00707              i++)
00708         {
00709             if (pif[i].AncestorName != NULL)
00710             {
00711                 pifSize += (_tcslen(pif[i].AncestorName) + 1) * sizeof(TCHAR);
00712             }
00713         }
00714 
00715         /* Allocate enough space for the array and the strings */
00716         pif2 = (PINHERITED_FROM)LocalAlloc(LMEM_FIXED,
00717                                            pifSize);
00718         if (pif2 == NULL)
00719         {
00720             ErrorCode = GetLastError();
00721             goto Cleanup;
00722         }
00723 
00724         /* copy the array and strings to the buffer */
00725         lpBuf = (LPTSTR)((ULONG_PTR)pif2 + (pACL->AceCount * sizeof(INHERITED_FROM)));
00726         for (i = 0;
00727              i < pACL->AceCount;
00728              i++)
00729         {
00730             pif2[i].GenerationGap = pif[i].GenerationGap;
00731             if (pif[i].AncestorName != NULL)
00732             {
00733                 pif2[i].AncestorName = lpBuf;
00734                 _tcscpy(lpBuf,
00735                         pif[i].AncestorName);
00736                 lpBuf += _tcslen(pif[i].AncestorName) + 1;
00737             }
00738             else
00739                 pif2[i].AncestorName = NULL;
00740         }
00741 
00742         /* return the newly allocated array */
00743         *ppInheritArray = pif2;
00744     }
00745 
00746 Cleanup:
00747     FreeInheritedFromArray(pif,
00748                            pACL->AceCount,
00749                            NULL);
00750     HeapFree(GetProcessHeap(),
00751              0,
00752              pif);
00753 
00754     return HRESULT_FROM_WIN32(ErrorCode);
00755 }
00756 
00757 /******************************************************************************
00758    Implementation of the CRegKeySecurity constructor
00759  ******************************************************************************/
00760 
00761 static PCRegKeySecurity
00762 CRegKeySecurity_fnConstructor(LPTSTR lpRegKey,
00763                               HKEY hRootKey,
00764                               SI_OBJECT_INFO *ObjectInfo,
00765                               BOOL *Btn)
00766 {
00767     PCRegKeySecurity obj;
00768 
00769     obj = (PCRegKeySecurity)HeapAlloc(GetProcessHeap(),
00770                                       HEAP_ZERO_MEMORY,
00771                                       FIELD_OFFSET(CRegKeySecurity,
00772                                                    szRegKey[_tcslen(lpRegKey) + 1]));
00773     if (obj != NULL)
00774     {
00775         obj->ref = 1;
00776         obj->lpISecurityInformationVtbl = &vtblISecurityInformation;
00777 #if REGEDIT_IMPLEMENT_ISECURITYINFORMATION2
00778         obj->lpISecurityInformation2Vtbl = &vtblISecurityInformation2;
00779 #endif
00780         obj->lpIEffectivePermissionVtbl = &vtblIEffectivePermission;
00781         obj->lpISecurityObjectTypeInfoVtbl =  &vtblISecurityObjectTypeInfo;
00782         obj->ObjectInfo = *ObjectInfo;
00783         obj->Btn = Btn;
00784         obj->hRootKey = hRootKey;
00785         _tcscpy(obj->szRegKey,
00786                 lpRegKey);
00787     }
00788     else
00789         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00790 
00791     return obj;
00792 }
00793 
00794 /******************************************************************************/
00795 /******************************************************************************/
00796 /******************************************************************************/
00797 
00798 typedef struct _CHANGE_CONTEXT
00799 {
00800   HKEY hKey;
00801   LPTSTR KeyString;
00802 } CHANGE_CONTEXT, *PCHANGE_CONTEXT;
00803 
00804 typedef BOOL (WINAPI *PEDITSECURITY)(HWND hwndOwner,
00805                                      struct ISecurityInformation *psi);
00806 
00807 static PEDITSECURITY pfnEditSecurity;
00808 static HMODULE hAclUiDll;
00809 
00810 BOOL
00811 InitializeAclUiDll(VOID)
00812 {
00813     if (!(hAclUiDll = LoadLibrary(_T("aclui.dll"))))
00814     {
00815         return FALSE;
00816     }
00817 
00818     if (!(pfnEditSecurity = (PEDITSECURITY)GetProcAddress(hAclUiDll,
00819                                                          "EditSecurity")))
00820     {
00821         FreeLibrary(hAclUiDll);
00822         hAclUiDll = NULL;
00823         return FALSE;
00824     }
00825 
00826     return TRUE;
00827 }
00828 
00829 VOID
00830 UnloadAclUiDll(VOID)
00831 {
00832     if (hAclUiDll != NULL)
00833     {
00834         FreeLibrary(hAclUiDll);
00835     }
00836 }
00837 
00838 BOOL
00839 RegKeyEditPermissions(HWND hWndOwner,
00840                       HKEY hKey,
00841                       LPCTSTR lpMachine,
00842                       LPCTSTR lpKeyName)
00843 {
00844     BOOL Result = FALSE;
00845     LPWSTR Machine = NULL, KeyName = NULL;
00846     LPCTSTR lphKey = NULL;
00847     LPTSTR lpKeyPath = NULL;
00848     PCRegKeySecurity RegKeySecurity;
00849     SI_OBJECT_INFO ObjectInfo;
00850     size_t lnMachine = 0, lnKeyName = 0;
00851 
00852     if (pfnEditSecurity == NULL)
00853     {
00854         return FALSE;
00855     }
00856 
00857 #ifndef UNICODE
00858     /* aclui.dll only accepts unicode strings, convert them */
00859     if (lpMachine != NULL)
00860     {
00861         lnMachine = lstrlen(lpMachine);
00862         if (!(Machine = HeapAlloc(GetProcessHeap(),
00863                                   0,
00864                                   (lnMachine + 1) * sizeof(WCHAR))))
00865         {
00866             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00867             goto Cleanup;
00868         }
00869 
00870         if (lnMachine > 0)
00871         {
00872             MultiByteToWideChar(CP_ACP,
00873                                 0,
00874                                 lpMachine,
00875                                 -1,
00876                                 Machine,
00877                                 lnMachine + 1);
00878         }
00879         else
00880             *Machine = L'\0';
00881     }
00882     else
00883         Machine = NULL;
00884 
00885     if (lpKeyName != NULL)
00886     {
00887         lnKeyName = lstrlen(lpKeyName);
00888         if (!(KeyName = HeapAlloc(GetProcessHeap(),
00889                                   0,
00890                                   (lnKeyName + 1) * sizeof(WCHAR))))
00891         {
00892             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00893             goto Cleanup;
00894         }
00895 
00896         if (lnKeyName > 0)
00897         {
00898             MultiByteToWideChar(CP_ACP,
00899                                 0,
00900                                 lpKeyName,
00901                                 -1,
00902                                 KeyName,
00903                                 lnKeyName + 1);
00904         }
00905         else
00906             *KeyName = L'\0';
00907     }
00908     else
00909         KeyName = NULL;
00910 #else
00911     Machine = (LPWSTR)lpMachine;
00912     KeyName = (LPWSTR)lpKeyName;
00913 
00914     if (Machine != NULL)
00915         lnMachine = wcslen(lpMachine);
00916     if (KeyName != NULL)
00917         lnKeyName = wcslen(KeyName);
00918 #endif
00919 
00920     /* build registry path */
00921     if (lpMachine != NULL &&
00922         (lpMachine[0] == _T('\0') ||
00923          (lpMachine[0] == _T('.') && lpMachine[1] == _T('.'))))
00924     {
00925         lnMachine = 0;
00926     }
00927 
00928     if (hKey == HKEY_CLASSES_ROOT)
00929         lphKey = TEXT("CLASSES_ROOT");
00930     else if (hKey == HKEY_CURRENT_USER)
00931         lphKey = TEXT("CURRENT_USER");
00932     else if (hKey == HKEY_LOCAL_MACHINE)
00933         lphKey = TEXT("MACHINE");
00934     else if (hKey == HKEY_USERS)
00935         lphKey = TEXT("USERS");
00936     else if (hKey == HKEY_CURRENT_CONFIG)
00937         lphKey = TEXT("CONFIG");
00938     else
00939     goto Cleanup;
00940 
00941     lpKeyPath = HeapAlloc(GetProcessHeap(),
00942                           0,
00943                           (2 + lnMachine + 1 + _tcslen(lphKey) + 1 + lnKeyName) * sizeof(TCHAR));
00944     if (lpKeyPath == NULL)
00945     {
00946         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00947         goto Cleanup;
00948     }
00949     lpKeyPath[0] = _T('\0');
00950 
00951     if (lnMachine != 0)
00952     {
00953         _tcscat(lpKeyPath,
00954                 _T("\\\\"));
00955         _tcscat(lpKeyPath,
00956                 lpMachine);
00957         _tcscat(lpKeyPath,
00958                 _T("\\"));
00959     }
00960 
00961     _tcscat(lpKeyPath,
00962             lphKey);
00963     if (lpKeyName != NULL && lpKeyName[0] != _T('\0'))
00964     {
00965         if (lpKeyName[0] != _T('\\'))
00966         {
00967             _tcscat(lpKeyPath,
00968                     _T("\\"));
00969         }
00970 
00971         _tcscat(lpKeyPath,
00972                 lpKeyName);
00973     }
00974 
00975     ObjectInfo.dwFlags = SI_EDIT_ALL  | SI_ADVANCED | SI_CONTAINER | SI_EDIT_EFFECTIVE | SI_EDIT_PERMS |
00976                              SI_OWNER_RECURSE | SI_RESET_DACL_TREE | SI_RESET_SACL_TREE;
00977     ObjectInfo.hInstance = hInst;
00978     ObjectInfo.pszServerName = Machine;
00979     ObjectInfo.pszObjectName = KeyName; /* FIXME */
00980     ObjectInfo.pszPageTitle = KeyName; /* FIXME */
00981 
00982     if (!(RegKeySecurity = CRegKeySecurity_fnConstructor(lpKeyPath,
00983                                                          hKey,
00984                                                          &ObjectInfo,
00985                                                          &Result)))
00986     {
00987         goto Cleanup;
00988     }
00989 
00990     /* display the security editor dialog */
00991     pfnEditSecurity(hWndOwner,
00992                     impl_to_interface(RegKeySecurity,
00993                                       ISecurityInformation));
00994 
00995     /* dereference the interface, it should be destroyed here */
00996     CRegKeySecurity_fnRelease(RegKeySecurity);
00997 
00998 Cleanup:
00999 #ifndef UNICODE
01000     if (Machine != NULL)
01001     {
01002         HeapFree(GetProcessHeap(),
01003                  0,
01004                  Machine);
01005     }
01006 
01007     if (KeyName != NULL)
01008     {
01009         HeapFree(GetProcessHeap(),
01010                  0,
01011                  KeyName);
01012     }
01013 #endif
01014 
01015     if (lpKeyPath != NULL)
01016     {
01017         HeapFree(GetProcessHeap(),
01018                  0,
01019                  lpKeyPath);
01020     }
01021 
01022     return Result;
01023 }
01024 
01025 /* EOF */

Generated on Sat May 26 2012 04:16:24 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.