Option Explicit Private Const FOLDER_PATH = "f:/Test" ' Success status of high level access control APIs Private Const ERROR_SUCCESS = 0& ' Type of Securable Object we are operating in this sample code Private Const SE_FILE_OBJECT = 1& Const KEY_ALL_ACCESS = KEY_QUERY_VALUE + KEY_SET_VALUE + KEY_CREATE_SUB_KEY + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + KEY_CREATE_LINK + READ_CONTROL ' The Security Information constants required Private Const DACL_SECURITY_INFORMATION = 4& Private Const SET_ACCESS = 2& Private Enum SE_OBJECT_TYPE SE_UNKNOWN_OBJECT_TYPE = 0& SE_FILE_OBJECT = 1& SE_SERVICE = 2& SE_PRINTER = 3& SE_REGISTRY_KEY = 4& SE_LMSHARE = 5& SE_KERNEL_OBJECT = 6& SE_WINDOW_OBJECT = 7& End Enum ' Standard access rights extracted from WinNT.h Private Const SYNCHRONIZE = &H100000 Private Const READ_CONTROL = &H20000 Private Const WRITE_DAC = &H40000 Private Const WRITE_OWNER = &H80000 Private Const STANDARD_RIGHTS_READ = (READ_CONTROL) Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL) Private Const DELETE = &H10000 ' Generic access rights extracted from WinNT.h Private Const GENERIC_ALL = &H10000000 Private Const GENERIC_EXECUTE = &H20000000 Private Const GENERIC_READ = &H80000000 Private Const GENERIC_WRITE = &H40000000 ' Inheritance Flags Private Const CONTAINER_INHERIT_ACE = &H2 Private Const OBJECT_INHERIT_ACE = &H1 ' The TRUSTEE structure identifies the user account, group account, or logon session ' to which an ACE applies. The structure can use a name or a security identifier (SID) ' to identify the trustee. ' Access control APIs, such as SetEntriesInAcl and GetExplicitEntriesFromAcl, use this ' structure to identify the account associated with the access-control or audit-control ' information in an EXPLICIT_ACCESS structure. Private Type TRUSTEE pMultipleTrustee As Long MultipleTrusteeOperation As Long TrusteeForm As Long TrusteeType As Long ptstrName As String End Type ' EXPLICIT_ACCESS structure that specifies access-control information for a specified ' trustee such as access mask as well as inheritance flags Private Type EXPLICIT_ACCESS grfAccessPermissions As Long grfAccessMode As Long grfInheritance As Long pTRUSTEE As TRUSTEE End Type ' High Level access control API declarations Private Declare Sub BuildExplicitAccessWithName Lib "Advapi32.dll" Alias _ "BuildExplicitAccessWithNameA" _ (ea As Any, _ ByVal TrusteeName As String, _ ByVal AccessPermissions As Long, _ ByVal AccessMode As Integer, _ ByVal Inheritance As Long) Private Declare Function SetEntriesInAcl Lib "Advapi32.dll" Alias _ "SetEntriesInAclA" _ (ByVal CountofExplicitEntries As Long, _ ea As Any, _ ByVal OldAcl As Long, _ NewAcl As Long) As Long Private Declare Function GetNamedSecurityInfo Lib "Advapi32.dll" Alias _ "GetNamedSecurityInfoA" _ (ByVal ObjName As String, _ ByVal SE_OBJECT_TYPE As Long, _ ByVal SecInfo As Long, _ ByVal pSid As Long, _ ByVal pSidGroup As Long, _ pDacl As Long, _ ByVal pSacl As Long, _ pSecurityDescriptor As Long) As Long Private Declare Function SetNamedSecurityInfo Lib "Advapi32.dll" Alias _ "SetNamedSecurityInfoA" _ (ByVal ObjName As String, _ ByVal SE_OBJECT As Long, _ ByVal SecInfo As Long, _ ByVal pSid As Long, _ ByVal pSidGroup As Long, _ ByVal pDacl As Long, _ ByVal pSacl As Long) As Long Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long Private Sub Command1_Click() Dim result As Long Dim pSecDesc As Long Dim ea As EXPLICIT_ACCESS Dim pNewDACL As Long Dim pOldDACL As Long ' Get the DACL information of the folder using GetNamedSecurityInfo() API. ' SE_FILE_OBJECT constant says that the named securable object is a file or folder result = GetNamedSecurityInfo(FOLDER_PATH, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 0&, 0&, pOldDACL, 0&, pSecDesc) If result = ERROR_SUCCESS Then ' Construct an EXPLICIT_ACCESS structure for Everyone with GENERIC_ALL access that will apply for c:/test1 ' as well as subfolder and files using BuildExplicitAccessWithName() API BuildExplicitAccessWithName ea, "EVERYONE", GENERIC_ALL, SET_ACCESS, CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE ' Merge constructed EXPLICIT_ACCESS structure to the existing DACL and get an updated DACL in memory from ' SetEntriesInAcl() API result = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL) If result = ERROR_SUCCESS Then MsgBox "SetEntriesInAcl succeeded" ' Call SetNamedSecurityInfo() API with the updated DACL in memory to change the DACL of c:/test folder result = SetNamedSecurityInfo(FOLDER_PATH, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 0&, 0&, pNewDACL, 0&) If result = ERROR_SUCCESS Then MsgBox "SetNamedSecurityInfo succeeded" Else MsgBox "SetNamedSecurityInfo failed with error code : " & result End If ' Free the memory allocated for the new DACL by the SetEntriesInAcl() API, using LocalFree() API LocalFree pNewDACL Else MsgBox "SetEntriesInAcl failed with error code : " & result End If ' Free the memory allocated for the security descriptor by the GetNamedSecurityInfo() API, using LocalFree() API LocalFree pSecDesc Else MsgBox "GetNamedSecurityInfo failed with error code : " & result End If End Sub |