Using security APIs you can set NTFS permissions in more technical term you can change ACL (Access Control List) for a user.
Here for demo purpose I have created a user called "tejuwala" and I have created a folder c:\test and two files c:\test\file_a.txt and c:\file_b.txt . User tejuwala dont have access to any of this file. In this example I will show you how you can set folder or file permissions using API.
Permissions on file_a.txt Before running this program

Permissions on file_a.txt After running this program

To Run this demo -> Create a Standard Exe Project (Project1) -> Add a Module file (Module1.bas)
Add following controls on the Form1 -> 5 checkbox rename them to chkFull, chkModify, chkReadAndExe, chkRead, chkWrite -> 2 textbox rename them to txtPath and txtUser -> 1 commandbutton rename it to cmdSet
Copy following code into Form1
Form1.frm |
Click here to copy the following block | Private Sub chkFull_Click() ResetPermissions End Sub Sub ResetPermissions() If chkFull.Value = 1 Then chkModify.Value = 1 chkReadandExe.Value = 1 chkRead.Value = 1 chkWrite.Value = 1 ElseIf chkModify.Value = 1 Then chkModify.Value = 1 chkReadandExe.Value = 1 chkRead.Value = 1 chkWrite.Value = 1 ElseIf chkReadandExe.Value = 1 Then chkReadandExe.Value = 1 chkRead.Value = 1 End If End Sub
Private Sub chkModify_Click() If chkModify.Value = 0 Then chkFull.Value = 0 End If
ResetPermissions End Sub
Private Sub chkRead_Click() If chkRead.Value = 0 Then chkFull.Value = 0 chkModify.Value = 0 chkReadandExe.Value = 0 End If ResetPermissions End Sub
Private Sub chkReadandExe_Click() If chkReadandExe.Value = 0 Then chkFull.Value = 0 End If ResetPermissions End Sub
Private Sub chkWrite_Click() If chkWrite.Value = 0 Then chkFull.Value = 0 chkModify.Value = 0 End If ResetPermissions End Sub
Private Sub cmdClose_Click() Unload Me End Sub
Private Sub cmdSet_Click() Dim sUserName As String Dim sPath As String Dim lPermission As Long
sUserName = Trim$(CStr(txtUser.Text)) sPath = Trim$(CStr(txtPath.Text))
If chkFull.Value = 1 Then lPermission = GENERIC_ALL SetAccess sUserName, sPath, lPermission ElseIf chkModify.Value = 1 Then lPermission = GENERIC_READ Or GENERIC_EXECUTE Or DELETE Or GENERIC_WRITE SetAccess sUserName, sPath, lPermission Else If chkReadandExe.Value = 1 Then lPermission = GENERIC_READ Or GENERIC_EXECUTE SetAccess sUserName, sPath, lPermission Else If chkRead.Value = 1 Then lPermission = GENERIC_READ SetAccess sUserName, sPath, lPermission End If If chkWrite.Value = 1 Then lPermission = GENERIC_WRITE SetAccess sUserName, sPath, lPermission End If End If End If End Sub |
Copy following code into Module1.bas
Module1.bas |
Click here to copy the following block |
Public Const GMEM_MOVEABLE = &H2 Public Const LMEM_FIXED = &H0 Public Const LMEM_ZEROINIT = &H40 Public Const LPTR = (LMEM_FIXED + LMEM_ZEROINIT) Public Const GENERIC_READ = &H80000000 Public Const GENERIC_ALL = &H10000000 Public Const GENERIC_EXECUTE = &H20000000 Public Const GENERIC_WRITE = &H40000000
Public Const DACL_SECURITY_INFORMATION = &H4 Public Const SECURITY_DESCRIPTOR_REVISION = 1 Public Const SECURITY_DESCRIPTOR_MIN_LENGTH = 20 Public Const SD_SIZE = (65536 + SECURITY_DESCRIPTOR_MIN_LENGTH) Public Const ACL_REVISION2 = 2 Public Const ACL_REVISION = 2 Public Const MAXDWORD = &HFFFFFFFF Public Const SidTypeUser = 1 Public Const AclSizeInformation = 2
Public Const OBJECT_INHERIT_ACE = &H1 Public Const CONTAINER_INHERIT_ACE = &H2 Public Const NO_PROPAGATE_INHERIT_ACE = &H4 Public Const INHERIT_ONLY_ACE = &H8 Public Const INHERITED_ACE = &H10 Public Const VALID_INHERIT_FLAGS = &H1F Public Const DELETE = &H10000
Type ACE_HEADER AceType As Byte AceFlags As Byte AceSize As Integer End Type
Public Type ACCESS_DENIED_ACE Header As ACE_HEADER Mask As Long SidStart As Long End Type
Type ACCESS_ALLOWED_ACE Header As ACE_HEADER Mask As Long SidStart As Long End Type
Type ACL AclRevision As Byte Sbz1 As Byte AclSize As Integer AceCount As Integer Sbz2 As Integer End Type
Type ACL_SIZE_INFORMATION AceCount As Long AclBytesInUse As Long AclBytesFree As Long End Type
Type SECURITY_DESCRIPTOR Revision As Byte Sbz1 As Byte Control As Long Owner As Long Group As Long sACL As ACL Dacl As ACL End Type
Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long Declare Function LookupAccountName Lib "advapi32.dll" Alias "LookupAccountNameA" (lpSystemName As String, ByVal lpAccountName As String, sid As Any, cbSid As Long, ByVal ReferencedDomainName As String, cbReferencedDomainName As Long, peUse As Long) As Long Declare Function InitializeSecurityDescriptor Lib "advapi32.dll" (pSecurityDescriptor As SECURITY_DESCRIPTOR, ByVal dwRevision As Long) As Long Declare Function GetSecurityDescriptorDacl Lib "advapi32.dll" (pSecurityDescriptor As Byte, lpbDaclPresent As Long, pDacl As Long, lpbDaclDefaulted As Long) As Long Declare Function GetFileSecurityN Lib "advapi32.dll" Alias "GetFileSecurityA" (ByVal lpFileName As String, ByVal RequestedInformation As Long, ByVal pSecurityDescriptor As Long, ByVal nLength As Long, lpnLengthNeeded As Long) As Long Declare Function GetFileSecurity Lib "advapi32.dll" Alias "GetFileSecurityA" (ByVal lpFileName As String, ByVal RequestedInformation As Long, pSecurityDescriptor As Byte, ByVal nLength As Long, lpnLengthNeeded As Long) As Long Declare Function GetAclInformation Lib "advapi32.dll" (ByVal pAcl As Long, pAclInformation As Any, ByVal nAclInformationLength As Long, ByVal dwAclInformationClass As Long) As Long Public Declare Function EqualSid Lib "advapi32.dll" (pSid1 As Byte, ByVal pSid2 As Long) As Long Declare Function GetLengthSid Lib "advapi32.dll" (pSid As Any) As Long Declare Function InitializeAcl Lib "advapi32.dll" (pAcl As Byte, ByVal nAclLength As Long, ByVal dwAclRevision As Long) As Long Declare Function GetAce Lib "advapi32.dll" (ByVal pAcl As Long, ByVal dwAceIndex As Long, pace As Any) As Long Declare Function AddAce Lib "advapi32.dll" (ByVal pAcl As Long, ByVal dwAceRevision As Long, ByVal dwStartingAceIndex As Long, ByVal pAceList As Long, ByVal nAceListLength As Long) As Long Declare Function AddAccessAllowedAce Lib "advapi32.dll" (pAcl As Byte, ByVal dwAceRevision As Long, ByVal AccessMask As Long, pSid As Byte) As Long Public Declare Function AddAccessDeniedAce Lib "advapi32.dll" (pAcl As Byte, ByVal dwAceRevision As Long, ByVal AccessMask As Long, pSid As Byte) As Long Declare Function SetSecurityDescriptorDacl Lib "advapi32.dll" (pSecurityDescriptor As SECURITY_DESCRIPTOR, ByVal bDaclPresent As Long, pDacl As Byte, ByVal bDaclDefaulted As Long) As Long Declare Function SetFileSecurity Lib "advapi32.dll" Alias "SetFileSecurityA" (ByVal lpFileName As String, ByVal SecurityInformation As Long, pSecurityDescriptor As SECURITY_DESCRIPTOR) As Long Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long) Public Sub SetAccess(sUserName As String, sFileName As String, lMask As Long) Dim lResult As Long Dim I As Integer Dim bUserSid(255) As Byte Dim bTempSid(255) As Byte Dim sSystemName As String
Dim lSystemNameLength As Long
Dim lLengthUserName As Long
Dim lUserSID As Long
Dim lTempSid As Long Dim lUserSIDSize As Long Dim sDomainName As String * 255 Dim lDomainNameLength As Long
Dim lSIDType As Long
Dim sFileSD As SECURITY_DESCRIPTOR
Dim bSDBuf() As Byte
Dim lFileSDSize As Long Dim lSizeNeeded As Long
Dim sNewSD As SECURITY_DESCRIPTOR
Dim sACL As ACL
Dim lDaclPresent As Long
Dim lDaclDefaulted As Long
Dim sACLInfo As ACL_SIZE_INFORMATION
Dim lACLSize As Long
Dim pAcl As Long Dim lNewACLSize As Long Dim bNewACL() As Byte
Dim sCurrentACE As ACCESS_ALLOWED_ACE Dim pCurrentAce As Long
Dim nRecordNumber As Long
lResult = LookupAccountName(vbNullString, sUserName, _ bUserSid(0), 255, sDomainName, lDomainNameLength, _ lSIDType)
sDomainName = Space(lDomainNameLength)
lResult = LookupAccountName(vbNullString, sUserName, _ bUserSid(0), 255, sDomainName, lDomainNameLength, _ lSIDType)
If (lResult = 0) Then MsgBox "Error: Unable to Lookup the Current User Account: " _ & sUserName Exit Sub End If
lResult = GetFileSecurityN(sFileName, DACL_SECURITY_INFORMATION, _ 0, 0, lSizeNeeded)
ReDim bSDBuf(lSizeNeeded)
lResult = GetFileSecurity(sFileName, DACL_SECURITY_INFORMATION, _ bSDBuf(0), lSizeNeeded, lSizeNeeded)
If (lResult = 0) Then MsgBox "Error: Unable to Get the File Security Descriptor" Exit Sub End If
lResult = InitializeSecurityDescriptor(sNewSD, _ SECURITY_DESCRIPTOR_REVISION)
If (lResult = 0) Then MsgBox "Error: Unable to Initialize New Security Descriptor" Exit Sub End If
lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, _ pAcl, lDaclDefaulted)
If (lResult = 0) Then MsgBox "Error: Unable to Get DACL from File Security " _ & "Descriptor" Exit Sub End If
If (lDaclPresent = False) Then MsgBox "Error: No ACL Information Available for this File" Exit Sub End If
lResult = GetAclInformation(pAcl, sACLInfo, Len(sACLInfo), 2&)
If (lResult = 0) Then MsgBox "Error: Unable to Get ACL from File Security Descriptor" Exit Sub End If
lNewACLSize = sACLInfo.AclBytesInUse + (Len(sCurrentACE) + _ GetLengthSid(bUserSid(0))) * 2 - 4
ReDim bNewACL(lNewACLSize)
lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION)
If (lResult = 0) Then MsgBox "Error: Unable to Initialize New ACL" Exit Sub End If
If (lDaclPresent) Then
If (sACLInfo.AceCount > 0) Then
nRecordNumber = 0 For I = 0 To (sACLInfo.AceCount - 1)
lResult = GetAce(pAcl, I, pCurrentAce)
If (lResult = 0) Then MsgBox "Error: Unable to Obtain ACE (" & I & ")" Exit Sub End If
CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
lTempSid = pCurrentAce + 8 If EqualSid(bUserSid(0), lTempSid) = 0 Then
lResult = AddAce(VarPtr(bNewACL(0)), ACL_REVISION, _ MAXDWORD, pCurrentAce, _ sCurrentACE.Header.AceSize)
If (lResult = 0) Then MsgBox "Error: Unable to Add ACE to New ACL" Exit Sub End If nRecordNumber = nRecordNumber + 1 End If
Next I
lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _ lMask, bUserSid(0))
If (lResult = 0) Then MsgBox "Error: Unable to Add ACL to DACL" Exit Sub End If
If GetAttr(sFileName) And vbDirectory Then
lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber, pCurrentAce)
If (lResult = 0) Then MsgBox "Error: Unable to Obtain ACE (" & I & ")" Exit Sub End If CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE) sCurrentACE.Header.AceFlags = OBJECT_INHERIT_ACE + INHERIT_ONLY_ACE CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE), LenB(sCurrentACE)
lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _ lMask, bUserSid(0))
If (lResult = 0) Then MsgBox "Error: Unable to Add ACL to DACL" Exit Sub End If
lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber + 1, pCurrentAce)
If (lResult = 0) Then MsgBox "Error: Unable to Obtain ACE (" & I & ")" Exit Sub End If
CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE) sCurrentACE.Header.AceFlags = CONTAINER_INHERIT_ACE CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE), LenB(sCurrentACE) End If
lResult = SetSecurityDescriptorDacl(sNewSD, 1, _ bNewACL(0), 0)
If (lResult = 0) Then MsgBox "Error: " & _ "Unable to Set New DACL to Security Descriptor" Exit Sub End If
lResult = SetFileSecurity(sFileName, _ DACL_SECURITY_INFORMATION, sNewSD)
If (lResult = 0) Then MsgBox "Error: Unable to Set New Security Descriptor " _ & " to File : " & sFileName MsgBox Err.LastDllError Else MsgBox "Updated Security Descriptor on File: " _ & sFileName End If End If End If End Sub |
|