Home All Groups Group Topic Archive Search About

File Security Descriptor

Author
17 Oct 2005 9:06 AM
Chris
I'm working with VB6 SP6.
I need to change rights on a directory.

When VB runs the GetFileSecurity function, It returns 0 and I get the
"Unable to Get the File Security Descriptor" message box.

Could you tell me what's wrong ?
Many thanks.
Chris

I'm using the following code from Microsoft :


Public Sub SetAccess(sUserName As String, sFileName As String, lMask As Long)
    Dim strError As String, strComputerName As String
    strError = String$(1024, Chr$(0))
   Dim lResult As Long            ' Result of various API calls.
   Dim i As Integer               ' Used in looping.
   Dim bUserSid(255) As Byte      ' This will contain your SID.
   Dim bTempSid(255) As Byte      ' This will contain the Sid of each ACE in
the ACL .
   Dim sSystemName As String      ' Name of this computer system.

   Dim lSystemNameLength As Long  ' Length of string that contains
                                  ' the name of this system.

   Dim lLengthUserName As Long    ' Max length of user name.

   'Dim sUserName As String * 255  ' String to hold the current user
                                  ' name.


   Dim lUserSID As Long           ' Used to hold the SID of the
                                  ' current user.

   Dim lTempSid As Long            ' Used to hold the SID of each ACE in the
ACL
   Dim lUserSIDSize As Long          ' Size of the SID.
   Dim sDomainName As String * 255   ' Domain the user belongs to.
   Dim lDomainNameLength As Long     ' Length of domain name needed.

   Dim lSIDType As Long              ' The type of SID info we are
                                     ' getting back.

   Dim sFileSD As SECURITY_DESCRIPTOR   ' SD of the file we want.

   Dim bSDBuf() As Byte           ' Buffer that holds the security
                                  ' descriptor for this file.

   Dim lFileSDSize As Long           ' Size of the File SD.
   Dim lSizeNeeded As Long           ' Size needed for SD for file.


   Dim sNewSD As SECURITY_DESCRIPTOR ' New security descriptor.

   Dim sACL As ACL                   ' Used in grabbing the DACL from
                                     ' the File SD.

   Dim lDaclPresent As Long          ' Used in grabbing the DACL from
                                     ' the File SD.

   Dim lDaclDefaulted As Long        ' Used in grabbing the DACL from
                                     ' the File SD.

   Dim sACLInfo As ACL_SIZE_INFORMATION  ' Used in grabbing the ACL
                                         ' from the File SD.

   Dim lACLSize As Long           ' Size of the ACL structure used
                                  ' to get the ACL from the File SD.

   Dim pAcl As Long               ' Current ACL for this file.
   Dim lNewACLSize As Long        ' Size of new ACL to create.
   Dim bNewACL() As Byte          ' Buffer to hold new ACL.

   Dim sCurrentACE As ACCESS_ALLOWED_ACE    ' Current ACE.
   Dim pCurrentAce As Long                  ' Our current ACE.

   Dim nRecordNumber As Long
   Dim strdw As String

   ' Get the SID of the user. (Refer to the MSDN for more information on SIDs
   ' and their function/purpose in the operating system.) Get the SID of this
   ' user by using the LookupAccountName API. In order to use the SID
   ' of the current user account, call the LookupAccountName API
   ' twice. The first time is to get the required sizes of the SID
   ' and the DomainName string. The second call is to actually get
   ' the desired information.
   lResult = LookupAccountName(strComputerName, sUserName, _
      bUserSid(0), 255, sDomainName, lDomainNameLength, _
      lSIDType)

   ' Now set the sDomainName string buffer to its proper size before
   ' calling the API again.
   sDomainName = Space(lDomainNameLength)

   ' Call the LookupAccountName again to get the actual SID for user.
   lResult = LookupAccountName(strComputerName, sUserName, _
      bUserSid(0), 255, sDomainName, lDomainNameLength, _
      lSIDType)

   ' Return value of zero means the call to LookupAccountName failed;
   ' test for this before you continue.
     If (lResult = 0) Then
        strdw = Err.LastDllError
        lResult = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, strdw,
GetUserDefaultLangID, strError, 1024, "0")
        MsgBox "Erreur " & strdw & " : " & Left$(strError, lResult)
        Exit Sub
     End If

   ' You now have the SID for the user who is logged on.
   ' The SID is of interest since it will get the security descriptor
   ' for the file that the user is interested in.
   ' The GetFileSecurity API will retrieve the Security Descriptor
   ' for the file. However, you must call this API twice: once to get
   ' the proper size for the Security Descriptor and once to get the
   ' actual Security Descriptor information.

   lResult = GetFileSecurityN(sFileName, DACL_SECURITY_INFORMATION, _
      0, 0, lSizeNeeded)

   ' Redimension the Security Descriptor buffer to the proper size.
   ReDim bSDBuf(lSizeNeeded)

   ' Now get the actual Security Descriptor for the file.
   lResult = GetFileSecurity(sFileName, DACL_SECURITY_INFORMATION, _
      bSDBuf(0), lSizeNeeded, lSizeNeeded)

   ' A return code of zero means the call failed; test for this
   ' before continuing.
   If (lResult = 0) Then
      MsgBox "Error: Unable to Get the File Security Descriptor"
      Exit Sub
   End If

   ' Call InitializeSecurityDescriptor to build a new SD for the
   ' file.
   lResult = InitializeSecurityDescriptor(sNewSD, _
      SECURITY_DESCRIPTOR_REVISION)

   ' A return code of zero means the call failed; test for this
   ' before continuing.
   If (lResult = 0) Then
      MsgBox "Error: Unable to Initialize New Security Descriptor"
      Exit Sub
   End If

   ' You now have the file's SD and a new Security Descriptor
   ' that will replace the current one. Next, pull the DACL from
   ' the SD. To do so, call the GetSecurityDescriptorDacl API
   ' function.

   lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, _
      pAcl, lDaclDefaulted)

   ' A return code of zero means the call failed; test for this
   ' before continuing.
   If (lResult = 0) Then
      MsgBox "Error: Unable to Get DACL from File Security " _
         & "Descriptor"
      Exit Sub
   End If

   ' You have the file's SD, and want to now pull the ACL from the
   ' SD. To do so, call the GetACLInformation API function.
   ' See if ACL exists for this file before getting the ACL
   ' information.
   If (lDaclPresent = False) Then
      MsgBox "Error: No ACL Information Available for this File"
      Exit Sub
   End If

   ' Attempt to get the ACL from the file's Security Descriptor.
   lResult = GetAclInformation(pAcl, sACLInfo, Len(sACLInfo), 2&)

   ' A return code of zero means the call failed; test for this
   ' before continuing.
   If (lResult = 0) Then
      MsgBox "Error: Unable to Get ACL from File Security Descriptor"
      Exit Sub
   End If

   ' Now that you have the ACL information, compute the new ACL size
   ' requirements.
   lNewACLSize = sACLInfo.AclBytesInUse + (Len(sCurrentACE) + _
      GetLengthSid(bUserSid(0))) * 2 - 4

   ' Resize our new ACL buffer to its proper size.
   ReDim bNewACL(lNewACLSize)

   ' Use the InitializeAcl API function call to initialize the new
   ' ACL.
   lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION)

   ' A return code of zero means the call failed; test for this
   ' before continuing.
   If (lResult = 0) Then
      MsgBox "Error: Unable to Initialize New ACL"
      Exit Sub
   End If

   ' If a DACL is present, copy it to a new DACL.
   If (lDaclPresent) Then

      ' Copy the ACEs from the file to the new ACL.
      If (sACLInfo.AceCount > 0) Then

         ' Grab each ACE and stuff them into the new ACL.
         nRecordNumber = 0
         For i = 0 To (sACLInfo.AceCount - 1)

            ' Attempt to grab the next ACE.
            lResult = GetAce(pAcl, i, pCurrentAce)

            ' Make sure you have the current ACE under question.
            If (lResult = 0) Then
               MsgBox "Error: Unable to Obtain ACE (" & i & ")"
               Exit Sub
            End If

            ' You have a pointer to the ACE. Place it
            ' into a structure, so you can get at its size.
            CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)

            'Skip adding the ACE to the ACL if this is same usersid
            lTempSid = pCurrentAce + 8
            If EqualSid(bUserSid(0), lTempSid) = 0 Then

                ' Now that you have the ACE, add it to the new ACL.
                lResult = AddAce(VarPtr(bNewACL(0)), ACL_REVISION, _
                  MAXDWORD, pCurrentAce, _
                  sCurrentACE.Header.AceSize)

                 ' Make sure you have the current ACE under question.
                 If (lResult = 0) Then
                   MsgBox "Error: Unable to Add ACE to New ACL"
                    Exit Sub
                 End If
                 nRecordNumber = nRecordNumber + 1
            End If

         Next i

         ' You have now rebuilt a new ACL and want to add it to
         ' the newly created DACL.
         lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
            lMask, bUserSid(0))

         ' Make sure added the ACL to the DACL.
         If (lResult = 0) Then
            MsgBox "Error: Unable to Add ACL to DACL"
            Exit Sub
         End If

         'If it's directory, we need to add inheritance staff.
         If GetAttr(sFileName) And vbDirectory Then

            ' Attempt to grab the next ACE which is what we just added.
            lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber, pCurrentAce)

            ' Make sure you have the current ACE under question.
            If (lResult = 0) Then
               MsgBox "Error: Unable to Obtain ACE (" & i & ")"
               Exit Sub
            End If
            ' You have a pointer to the ACE. Place it
            ' into a structure, so you can get at its size.
            CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
            sCurrentACE.Header.AceFlags = OBJECT_INHERIT_ACE +
INHERIT_ONLY_ACE
            CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE),
LenB(sCurrentACE)

            'add another ACE for files
            lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
               lMask, bUserSid(0))

            ' Make sure added the ACL to the DACL.
            If (lResult = 0) Then
               MsgBox "Error: Unable to Add ACL to DACL"
               Exit Sub
            End If

            ' Attempt to grab the next ACE.
            lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber + 1,
pCurrentAce)

            ' Make sure you have the current ACE under question.
            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


         ' Set the file's Security Descriptor to the new DACL.
         lResult = SetSecurityDescriptorDacl(sNewSD, 1, _
            bNewACL(0), 0)

         ' Make sure you set the SD to the new DACL.
         If (lResult = 0) Then
            MsgBox "Error: " & _
                "Unable to Set New DACL to Security Descriptor"
            Exit Sub
         End If

         ' The final step is to add the Security Descriptor back to
         ' the file!
         lResult = SetFileSecurity(sFileName, _
            DACL_SECURITY_INFORMATION, sNewSD)

         ' Make sure you added the Security Descriptor to the file!
         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

Author
17 Oct 2005 9:22 AM
A. Ahola
"Chris" wrote:

> I'm working with VB6 SP6.
> I need to change rights on a directory.
>
> When VB runs the GetFileSecurity function, It returns 0 and I get the
> "Unable to Get the File Security Descriptor" message box.
>
> Could you tell me what's wrong ?
> Many thanks.
> Chris

I recommend using SetACL activex component, a very handy tool for permission
management, you can grab it @ http://setacl.sourceforge.net/

-Amos


Show quoteHide quote
>
> I'm using the following code from Microsoft :
>
>
> Public Sub SetAccess(sUserName As String, sFileName As String, lMask As Long)
>     Dim strError As String, strComputerName As String
>     strError = String$(1024, Chr$(0))
>    Dim lResult As Long            ' Result of various API calls.
>    Dim i As Integer               ' Used in looping.
>    Dim bUserSid(255) As Byte      ' This will contain your SID.
>    Dim bTempSid(255) As Byte      ' This will contain the Sid of each ACE in
> the ACL .
>    Dim sSystemName As String      ' Name of this computer system.
>
>    Dim lSystemNameLength As Long  ' Length of string that contains
>                                   ' the name of this system.
>
>    Dim lLengthUserName As Long    ' Max length of user name.
>
>    'Dim sUserName As String * 255  ' String to hold the current user
>                                   ' name.
>
>   
>    Dim lUserSID As Long           ' Used to hold the SID of the
>                                   ' current user.
>
>    Dim lTempSid As Long            ' Used to hold the SID of each ACE in the
> ACL
>    Dim lUserSIDSize As Long          ' Size of the SID.
>    Dim sDomainName As String * 255   ' Domain the user belongs to.
>    Dim lDomainNameLength As Long     ' Length of domain name needed.
>
>    Dim lSIDType As Long              ' The type of SID info we are
>                                      ' getting back.
>
>    Dim sFileSD As SECURITY_DESCRIPTOR   ' SD of the file we want.
>
>    Dim bSDBuf() As Byte           ' Buffer that holds the security
>                                   ' descriptor for this file.
>
>    Dim lFileSDSize As Long           ' Size of the File SD.
>    Dim lSizeNeeded As Long           ' Size needed for SD for file.
>
>
>    Dim sNewSD As SECURITY_DESCRIPTOR ' New security descriptor.
>
>    Dim sACL As ACL                   ' Used in grabbing the DACL from
>                                      ' the File SD.
>
>    Dim lDaclPresent As Long          ' Used in grabbing the DACL from
>                                      ' the File SD.
>
>    Dim lDaclDefaulted As Long        ' Used in grabbing the DACL from
>                                      ' the File SD.
>
>    Dim sACLInfo As ACL_SIZE_INFORMATION  ' Used in grabbing the ACL
>                                          ' from the File SD.
>
>    Dim lACLSize As Long           ' Size of the ACL structure used
>                                   ' to get the ACL from the File SD.
>
>    Dim pAcl As Long               ' Current ACL for this file.
>    Dim lNewACLSize As Long        ' Size of new ACL to create.
>    Dim bNewACL() As Byte          ' Buffer to hold new ACL.
>
>    Dim sCurrentACE As ACCESS_ALLOWED_ACE    ' Current ACE.
>    Dim pCurrentAce As Long                  ' Our current ACE.
>
>    Dim nRecordNumber As Long
>    Dim strdw As String
>   
>    ' Get the SID of the user. (Refer to the MSDN for more information on SIDs
>    ' and their function/purpose in the operating system.) Get the SID of this
>    ' user by using the LookupAccountName API. In order to use the SID
>    ' of the current user account, call the LookupAccountName API
>    ' twice. The first time is to get the required sizes of the SID
>    ' and the DomainName string. The second call is to actually get
>    ' the desired information.
>    lResult = LookupAccountName(strComputerName, sUserName, _
>       bUserSid(0), 255, sDomainName, lDomainNameLength, _
>       lSIDType)
>
>    ' Now set the sDomainName string buffer to its proper size before
>    ' calling the API again.
>    sDomainName = Space(lDomainNameLength)
>
>    ' Call the LookupAccountName again to get the actual SID for user.
>    lResult = LookupAccountName(strComputerName, sUserName, _
>       bUserSid(0), 255, sDomainName, lDomainNameLength, _
>       lSIDType)
>
>    ' Return value of zero means the call to LookupAccountName failed;
>    ' test for this before you continue.
>      If (lResult = 0) Then
>         strdw = Err.LastDllError
>         lResult = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, strdw,
> GetUserDefaultLangID, strError, 1024, "0")
>         MsgBox "Erreur " & strdw & " : " & Left$(strError, lResult)
>         Exit Sub
>      End If
>
>    ' You now have the SID for the user who is logged on.
>    ' The SID is of interest since it will get the security descriptor
>    ' for the file that the user is interested in.
>    ' The GetFileSecurity API will retrieve the Security Descriptor
>    ' for the file. However, you must call this API twice: once to get
>    ' the proper size for the Security Descriptor and once to get the
>    ' actual Security Descriptor information.
>
>    lResult = GetFileSecurityN(sFileName, DACL_SECURITY_INFORMATION, _
>       0, 0, lSizeNeeded)
>
>    ' Redimension the Security Descriptor buffer to the proper size.
>    ReDim bSDBuf(lSizeNeeded)
>
>    ' Now get the actual Security Descriptor for the file.
>    lResult = GetFileSecurity(sFileName, DACL_SECURITY_INFORMATION, _
>       bSDBuf(0), lSizeNeeded, lSizeNeeded)
>
>    ' A return code of zero means the call failed; test for this
>    ' before continuing.
>    If (lResult = 0) Then
>       MsgBox "Error: Unable to Get the File Security Descriptor"
>       Exit Sub
>    End If
>
>    ' Call InitializeSecurityDescriptor to build a new SD for the
>    ' file.
>    lResult = InitializeSecurityDescriptor(sNewSD, _
>       SECURITY_DESCRIPTOR_REVISION)
>
>    ' A return code of zero means the call failed; test for this
>    ' before continuing.
>    If (lResult = 0) Then
>       MsgBox "Error: Unable to Initialize New Security Descriptor"
>       Exit Sub
>    End If
>
>    ' You now have the file's SD and a new Security Descriptor
>    ' that will replace the current one. Next, pull the DACL from
>    ' the SD. To do so, call the GetSecurityDescriptorDacl API
>    ' function.
>
>    lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, _
>       pAcl, lDaclDefaulted)
>
>    ' A return code of zero means the call failed; test for this
>    ' before continuing.
>    If (lResult = 0) Then
>       MsgBox "Error: Unable to Get DACL from File Security " _
>          & "Descriptor"
>       Exit Sub
>    End If
>
>    ' You have the file's SD, and want to now pull the ACL from the
>    ' SD. To do so, call the GetACLInformation API function.
>    ' See if ACL exists for this file before getting the ACL
>    ' information.
>    If (lDaclPresent = False) Then
>       MsgBox "Error: No ACL Information Available for this File"
>       Exit Sub
>    End If
>
>    ' Attempt to get the ACL from the file's Security Descriptor.
>    lResult = GetAclInformation(pAcl, sACLInfo, Len(sACLInfo), 2&)
>
>    ' A return code of zero means the call failed; test for this
>    ' before continuing.
>    If (lResult = 0) Then
>       MsgBox "Error: Unable to Get ACL from File Security Descriptor"
>       Exit Sub
>    End If
>
>    ' Now that you have the ACL information, compute the new ACL size
>    ' requirements.
>    lNewACLSize = sACLInfo.AclBytesInUse + (Len(sCurrentACE) + _
>       GetLengthSid(bUserSid(0))) * 2 - 4
>
>    ' Resize our new ACL buffer to its proper size.
>    ReDim bNewACL(lNewACLSize)
>
>    ' Use the InitializeAcl API function call to initialize the new
>    ' ACL.
>    lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION)
>
>    ' A return code of zero means the call failed; test for this
>    ' before continuing.
>    If (lResult = 0) Then
>       MsgBox "Error: Unable to Initialize New ACL"
>       Exit Sub
>    End If
>
>    ' If a DACL is present, copy it to a new DACL.
>    If (lDaclPresent) Then
>
>       ' Copy the ACEs from the file to the new ACL.
>       If (sACLInfo.AceCount > 0) Then
>
>          ' Grab each ACE and stuff them into the new ACL.
>          nRecordNumber = 0
>          For i = 0 To (sACLInfo.AceCount - 1)
>
>             ' Attempt to grab the next ACE.
>             lResult = GetAce(pAcl, i, pCurrentAce)
>
>             ' Make sure you have the current ACE under question.
>             If (lResult = 0) Then
>                MsgBox "Error: Unable to Obtain ACE (" & i & ")"
>                Exit Sub
>             End If
>
>             ' You have a pointer to the ACE. Place it
>             ' into a structure, so you can get at its size.
>             CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
>            
>             'Skip adding the ACE to the ACL if this is same usersid
>             lTempSid = pCurrentAce + 8
>             If EqualSid(bUserSid(0), lTempSid) = 0 Then
>                                 
>                 ' Now that you have the ACE, add it to the new ACL.
>                 lResult = AddAce(VarPtr(bNewACL(0)), ACL_REVISION, _
>                   MAXDWORD, pCurrentAce, _
>                   sCurrentACE.Header.AceSize)
>                
>                  ' Make sure you have the current ACE under question.
>                  If (lResult = 0) Then
>                    MsgBox "Error: Unable to Add ACE to New ACL"
>                     Exit Sub
>                  End If
>                  nRecordNumber = nRecordNumber + 1
>             End If
>             
>          Next i
>
>          ' You have now rebuilt a new ACL and want to add it to
>          ' the newly created DACL.
>          lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
>             lMask, bUserSid(0))
>
>          ' Make sure added the ACL to the DACL.
>          If (lResult = 0) Then
>             MsgBox "Error: Unable to Add ACL to DACL"
>             Exit Sub
>          End If
>
>          'If it's directory, we need to add inheritance staff.
>          If GetAttr(sFileName) And vbDirectory Then
>             
>             ' Attempt to grab the next ACE which is what we just added.
>             lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber, pCurrentAce)
>            
>             ' Make sure you have the current ACE under question.
>             If (lResult = 0) Then
>                MsgBox "Error: Unable to Obtain ACE (" & i & ")"
>                Exit Sub
>             End If
>             ' You have a pointer to the ACE. Place it
>             ' into a structure, so you can get at its size.
>             CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
>             sCurrentACE.Header.AceFlags = OBJECT_INHERIT_ACE +
> INHERIT_ONLY_ACE
>             CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE),
> LenB(sCurrentACE)
>
>             'add another ACE for files
>             lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
>                lMask, bUserSid(0))
>            
>             ' Make sure added the ACL to the DACL.
>             If (lResult = 0) Then
>                MsgBox "Error: Unable to Add ACL to DACL"
>                Exit Sub
>             End If
>        
>             ' Attempt to grab the next ACE.
>             lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber + 1,
> pCurrentAce)
>    
>             ' Make sure you have the current ACE under question.
>             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
>
>
Author
17 Oct 2005 11:51 AM
Chris
Thanks Amos for your help.
I have tried the SetACL ActiveX, and it works fine for adding users
permissions on a directory.
But I also have to delete permissions for a group of users and I'm unable to
do it with SetACL.

Do you know how can I do that?
thanks.
chris

Show quoteHide quote
"A. Ahola" wrote:

>
>
> "Chris" wrote:
>
> > I'm working with VB6 SP6.
> > I need to change rights on a directory.
> >
> > When VB runs the GetFileSecurity function, It returns 0 and I get the
> > "Unable to Get the File Security Descriptor" message box.
> >
> > Could you tell me what's wrong ?
> > Many thanks.
> > Chris
>
> I recommend using SetACL activex component, a very handy tool for permission
> management, you can grab it @ http://setacl.sourceforge.net/
>
> -Amos
>
>
> >
> > I'm using the following code from Microsoft :
> >
> >
> > Public Sub SetAccess(sUserName As String, sFileName As String, lMask As Long)
> >     Dim strError As String, strComputerName As String
> >     strError = String$(1024, Chr$(0))
> >    Dim lResult As Long            ' Result of various API calls.
> >    Dim i As Integer               ' Used in looping.
> >    Dim bUserSid(255) As Byte      ' This will contain your SID.
> >    Dim bTempSid(255) As Byte      ' This will contain the Sid of each ACE in
> > the ACL .
> >    Dim sSystemName As String      ' Name of this computer system.
> >
> >    Dim lSystemNameLength As Long  ' Length of string that contains
> >                                   ' the name of this system.
> >
> >    Dim lLengthUserName As Long    ' Max length of user name.
> >
> >    'Dim sUserName As String * 255  ' String to hold the current user
> >                                   ' name.
> >
> >   
> >    Dim lUserSID As Long           ' Used to hold the SID of the
> >                                   ' current user.
> >
> >    Dim lTempSid As Long            ' Used to hold the SID of each ACE in the
> > ACL
> >    Dim lUserSIDSize As Long          ' Size of the SID.
> >    Dim sDomainName As String * 255   ' Domain the user belongs to.
> >    Dim lDomainNameLength As Long     ' Length of domain name needed.
> >
> >    Dim lSIDType As Long              ' The type of SID info we are
> >                                      ' getting back.
> >
> >    Dim sFileSD As SECURITY_DESCRIPTOR   ' SD of the file we want.
> >
> >    Dim bSDBuf() As Byte           ' Buffer that holds the security
> >                                   ' descriptor for this file.
> >
> >    Dim lFileSDSize As Long           ' Size of the File SD.
> >    Dim lSizeNeeded As Long           ' Size needed for SD for file.
> >
> >
> >    Dim sNewSD As SECURITY_DESCRIPTOR ' New security descriptor.
> >
> >    Dim sACL As ACL                   ' Used in grabbing the DACL from
> >                                      ' the File SD.
> >
> >    Dim lDaclPresent As Long          ' Used in grabbing the DACL from
> >                                      ' the File SD.
> >
> >    Dim lDaclDefaulted As Long        ' Used in grabbing the DACL from
> >                                      ' the File SD.
> >
> >    Dim sACLInfo As ACL_SIZE_INFORMATION  ' Used in grabbing the ACL
> >                                          ' from the File SD.
> >
> >    Dim lACLSize As Long           ' Size of the ACL structure used
> >                                   ' to get the ACL from the File SD.
> >
> >    Dim pAcl As Long               ' Current ACL for this file.
> >    Dim lNewACLSize As Long        ' Size of new ACL to create.
> >    Dim bNewACL() As Byte          ' Buffer to hold new ACL.
> >
> >    Dim sCurrentACE As ACCESS_ALLOWED_ACE    ' Current ACE.
> >    Dim pCurrentAce As Long                  ' Our current ACE.
> >
> >    Dim nRecordNumber As Long
> >    Dim strdw As String
> >   
> >    ' Get the SID of the user. (Refer to the MSDN for more information on SIDs
> >    ' and their function/purpose in the operating system.) Get the SID of this
> >    ' user by using the LookupAccountName API. In order to use the SID
> >    ' of the current user account, call the LookupAccountName API
> >    ' twice. The first time is to get the required sizes of the SID
> >    ' and the DomainName string. The second call is to actually get
> >    ' the desired information.
> >    lResult = LookupAccountName(strComputerName, sUserName, _
> >       bUserSid(0), 255, sDomainName, lDomainNameLength, _
> >       lSIDType)
> >
> >    ' Now set the sDomainName string buffer to its proper size before
> >    ' calling the API again.
> >    sDomainName = Space(lDomainNameLength)
> >
> >    ' Call the LookupAccountName again to get the actual SID for user.
> >    lResult = LookupAccountName(strComputerName, sUserName, _
> >       bUserSid(0), 255, sDomainName, lDomainNameLength, _
> >       lSIDType)
> >
> >    ' Return value of zero means the call to LookupAccountName failed;
> >    ' test for this before you continue.
> >      If (lResult = 0) Then
> >         strdw = Err.LastDllError
> >         lResult = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, strdw,
> > GetUserDefaultLangID, strError, 1024, "0")
> >         MsgBox "Erreur " & strdw & " : " & Left$(strError, lResult)
> >         Exit Sub
> >      End If
> >
> >    ' You now have the SID for the user who is logged on.
> >    ' The SID is of interest since it will get the security descriptor
> >    ' for the file that the user is interested in.
> >    ' The GetFileSecurity API will retrieve the Security Descriptor
> >    ' for the file. However, you must call this API twice: once to get
> >    ' the proper size for the Security Descriptor and once to get the
> >    ' actual Security Descriptor information.
> >
> >    lResult = GetFileSecurityN(sFileName, DACL_SECURITY_INFORMATION, _
> >       0, 0, lSizeNeeded)
> >
> >    ' Redimension the Security Descriptor buffer to the proper size.
> >    ReDim bSDBuf(lSizeNeeded)
> >
> >    ' Now get the actual Security Descriptor for the file.
> >    lResult = GetFileSecurity(sFileName, DACL_SECURITY_INFORMATION, _
> >       bSDBuf(0), lSizeNeeded, lSizeNeeded)
> >
> >    ' A return code of zero means the call failed; test for this
> >    ' before continuing.
> >    If (lResult = 0) Then
> >       MsgBox "Error: Unable to Get the File Security Descriptor"
> >       Exit Sub
> >    End If
> >
> >    ' Call InitializeSecurityDescriptor to build a new SD for the
> >    ' file.
> >    lResult = InitializeSecurityDescriptor(sNewSD, _
> >       SECURITY_DESCRIPTOR_REVISION)
> >
> >    ' A return code of zero means the call failed; test for this
> >    ' before continuing.
> >    If (lResult = 0) Then
> >       MsgBox "Error: Unable to Initialize New Security Descriptor"
> >       Exit Sub
> >    End If
> >
> >    ' You now have the file's SD and a new Security Descriptor
> >    ' that will replace the current one. Next, pull the DACL from
> >    ' the SD. To do so, call the GetSecurityDescriptorDacl API
> >    ' function.
> >
> >    lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, _
> >       pAcl, lDaclDefaulted)
> >
> >    ' A return code of zero means the call failed; test for this
> >    ' before continuing.
> >    If (lResult = 0) Then
> >       MsgBox "Error: Unable to Get DACL from File Security " _
> >          & "Descriptor"
> >       Exit Sub
> >    End If
> >
> >    ' You have the file's SD, and want to now pull the ACL from the
> >    ' SD. To do so, call the GetACLInformation API function.
> >    ' See if ACL exists for this file before getting the ACL
> >    ' information.
> >    If (lDaclPresent = False) Then
> >       MsgBox "Error: No ACL Information Available for this File"
> >       Exit Sub
> >    End If
> >
> >    ' Attempt to get the ACL from the file's Security Descriptor.
> >    lResult = GetAclInformation(pAcl, sACLInfo, Len(sACLInfo), 2&)
> >
> >    ' A return code of zero means the call failed; test for this
> >    ' before continuing.
> >    If (lResult = 0) Then
> >       MsgBox "Error: Unable to Get ACL from File Security Descriptor"
> >       Exit Sub
> >    End If
> >
> >    ' Now that you have the ACL information, compute the new ACL size
> >    ' requirements.
> >    lNewACLSize = sACLInfo.AclBytesInUse + (Len(sCurrentACE) + _
> >       GetLengthSid(bUserSid(0))) * 2 - 4
> >
> >    ' Resize our new ACL buffer to its proper size.
> >    ReDim bNewACL(lNewACLSize)
> >
> >    ' Use the InitializeAcl API function call to initialize the new
> >    ' ACL.
> >    lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION)
> >
> >    ' A return code of zero means the call failed; test for this
> >    ' before continuing.
> >    If (lResult = 0) Then
> >       MsgBox "Error: Unable to Initialize New ACL"
> >       Exit Sub
> >    End If
> >
> >    ' If a DACL is present, copy it to a new DACL.
> >    If (lDaclPresent) Then
> >
> >       ' Copy the ACEs from the file to the new ACL.
> >       If (sACLInfo.AceCount > 0) Then
> >
> >          ' Grab each ACE and stuff them into the new ACL.
> >          nRecordNumber = 0
> >          For i = 0 To (sACLInfo.AceCount - 1)
> >
> >             ' Attempt to grab the next ACE.
> >             lResult = GetAce(pAcl, i, pCurrentAce)
> >
> >             ' Make sure you have the current ACE under question.
> >             If (lResult = 0) Then
> >                MsgBox "Error: Unable to Obtain ACE (" & i & ")"
> >                Exit Sub
> >             End If
> >
> >             ' You have a pointer to the ACE. Place it
> >             ' into a structure, so you can get at its size.
> >             CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
> >            
> >             'Skip adding the ACE to the ACL if this is same usersid
> >             lTempSid = pCurrentAce + 8
> >             If EqualSid(bUserSid(0), lTempSid) = 0 Then
> >                                 
> >                 ' Now that you have the ACE, add it to the new ACL.
> >                 lResult = AddAce(VarPtr(bNewACL(0)), ACL_REVISION, _
> >                   MAXDWORD, pCurrentAce, _
> >                   sCurrentACE.Header.AceSize)
> >                
> >                  ' Make sure you have the current ACE under question.
> >                  If (lResult = 0) Then
> >                    MsgBox "Error: Unable to Add ACE to New ACL"
> >                     Exit Sub
> >                  End If
> >                  nRecordNumber = nRecordNumber + 1
> >             End If
> >             
> >          Next i
> >
> >          ' You have now rebuilt a new ACL and want to add it to
> >          ' the newly created DACL.
> >          lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
> >             lMask, bUserSid(0))
> >
> >          ' Make sure added the ACL to the DACL.
> >          If (lResult = 0) Then
> >             MsgBox "Error: Unable to Add ACL to DACL"
> >             Exit Sub
> >          End If
> >
> >          'If it's directory, we need to add inheritance staff.
> >          If GetAttr(sFileName) And vbDirectory Then
> >             
> >             ' Attempt to grab the next ACE which is what we just added.
> >             lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber, pCurrentAce)
> >            
> >             ' Make sure you have the current ACE under question.
> >             If (lResult = 0) Then
> >                MsgBox "Error: Unable to Obtain ACE (" & i & ")"
> >                Exit Sub
> >             End If
> >             ' You have a pointer to the ACE. Place it
> >             ' into a structure, so you can get at its size.
> >             CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
> >             sCurrentACE.Header.AceFlags = OBJECT_INHERIT_ACE +
> > INHERIT_ONLY_ACE
> >             CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE),
> > LenB(sCurrentACE)
> >
> >             'add another ACE for files
> >             lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
> >                lMask, bUserSid(0))
> >            
> >             ' Make sure added the ACL to the DACL.
> >             If (lResult = 0) Then
> >                MsgBox "Error: Unable to Add ACL to DACL"
> >                Exit Sub
> >             End If
> >        
> >             ' Attempt to grab the next ACE.
> >             lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber + 1,
> > pCurrentAce)
> >    
> >             ' Make sure you have the current ACE under question.
> >             If (lResult = 0) Then
> >                MsgBox "Error: Unable to Obtain ACE (" & i & ")"
Author
17 Oct 2005 12:33 PM
A. Ahola
"Chris" wrote:

> Thanks Amos for your help.
> I have tried the SetACL ActiveX, and it works fine for adding users
> permissions on a directory.
> But I also have to delete permissions for a group of users and I'm unable to
> do it with SetACL.
>
> Do you know how can I do that?
> thanks.
> chris

SetACL isnt that well documented, I know :)
Anyway, heres the code I used:

'needed for setAcl.ocx
Dim nError As Integer

'changes permissions for folder strpath

Private Function setacl_kk(strpath, kayttajatunnus)

With Fpaa.SetACL2
    'removes inheritance
    nError = .SetObject(strpath, SE_FILE_OBJECT)
    nError = .SetAction(ACTN_SETINHFROMPAR)
    nError = .SetObjectFlags(INHPARCOPY, 0, False, False)
    nError = .Run

    ' "SOME\domain users" - remove all rights
    nError = .SetObject(strpath, SE_FILE_OBJECT)
    nError = .SetAction(ACTN_TRUSTEE)
    nError = .AddTrustee("SOME\domain users", "", False, False,
ACTN_REMOVETRUSTEE, True, False)
    nError = .Run

    '"SOME\Office" - edit
    nError = .SetObject(strpath, SE_FILE_OBJECT)
    nError = .SetAction(ACTN_ADDACE)
    nError = .AddACE("SOME\Office", False, "change", INHPARNOCHANGE, False,
GRANT_ACCESS, ACL_DACL)
    nError = .Run

    ' "SOME\Team" - read and execute
    nError = .SetObject(strpath, SE_FILE_OBJECT)
    nError = .SetAction(ACTN_ADDACE)
    nError = .AddACE("SOME\Team", False, "read_ex", INHPARNOCHANGE, False,
GRANT_ACCESS, ACL_DACL)
    nError = .Run

    ' "SOME\kayttajatunnus" - edit
    nError = .SetObject(strpath, SE_FILE_OBJECT)
    nError = .SetAction(ACTN_ADDACE)
    nError = .AddACE("SOME\" & kayttajatunnus, False, "change",
INHPARNOCHANGE, False, GRANT_ACCESS, ACL_DACL)
    nError = .Run

End With

End Function

I tried using cacls before, but it messed up the inheritance, so I gave it
up. In the end setACL worked like charm.

Hope this helps,

Amos




Show quoteHide quote
>
> "A. Ahola" wrote:
>
> >
> >
> > "Chris" wrote:
> >
> > > I'm working with VB6 SP6.
> > > I need to change rights on a directory.
> > >
> > > When VB runs the GetFileSecurity function, It returns 0 and I get the
> > > "Unable to Get the File Security Descriptor" message box.
> > >
> > > Could you tell me what's wrong ?
> > > Many thanks.
> > > Chris
> >
> > I recommend using SetACL activex component, a very handy tool for permission
> > management, you can grab it @ http://setacl.sourceforge.net/
> >
> > -Amos
> >
> >
> > >
> > > I'm using the following code from Microsoft :
> > >
> > >
> > > Public Sub SetAccess(sUserName As String, sFileName As String, lMask As Long)
> > >     Dim strError As String, strComputerName As String
> > >     strError = String$(1024, Chr$(0))
> > >    Dim lResult As Long            ' Result of various API calls.
> > >    Dim i As Integer               ' Used in looping.
> > >    Dim bUserSid(255) As Byte      ' This will contain your SID.
> > >    Dim bTempSid(255) As Byte      ' This will contain the Sid of each ACE in
> > > the ACL .
> > >    Dim sSystemName As String      ' Name of this computer system.
> > >
> > >    Dim lSystemNameLength As Long  ' Length of string that contains
> > >                                   ' the name of this system.
> > >
> > >    Dim lLengthUserName As Long    ' Max length of user name.
> > >
> > >    'Dim sUserName As String * 255  ' String to hold the current user
> > >                                   ' name.
> > >
> > >   
> > >    Dim lUserSID As Long           ' Used to hold the SID of the
> > >                                   ' current user.
> > >
> > >    Dim lTempSid As Long            ' Used to hold the SID of each ACE in the
> > > ACL
> > >    Dim lUserSIDSize As Long          ' Size of the SID.
> > >    Dim sDomainName As String * 255   ' Domain the user belongs to.
> > >    Dim lDomainNameLength As Long     ' Length of domain name needed.
> > >
> > >    Dim lSIDType As Long              ' The type of SID info we are
> > >                                      ' getting back.
> > >
> > >    Dim sFileSD As SECURITY_DESCRIPTOR   ' SD of the file we want.
> > >
> > >    Dim bSDBuf() As Byte           ' Buffer that holds the security
> > >                                   ' descriptor for this file.
> > >
> > >    Dim lFileSDSize As Long           ' Size of the File SD.
> > >    Dim lSizeNeeded As Long           ' Size needed for SD for file.
> > >
> > >
> > >    Dim sNewSD As SECURITY_DESCRIPTOR ' New security descriptor.
> > >
> > >    Dim sACL As ACL                   ' Used in grabbing the DACL from
> > >                                      ' the File SD.
> > >
> > >    Dim lDaclPresent As Long          ' Used in grabbing the DACL from
> > >                                      ' the File SD.
> > >
> > >    Dim lDaclDefaulted As Long        ' Used in grabbing the DACL from
> > >                                      ' the File SD.
> > >
> > >    Dim sACLInfo As ACL_SIZE_INFORMATION  ' Used in grabbing the ACL
> > >                                          ' from the File SD.
> > >
> > >    Dim lACLSize As Long           ' Size of the ACL structure used
> > >                                   ' to get the ACL from the File SD.
> > >
> > >    Dim pAcl As Long               ' Current ACL for this file.
> > >    Dim lNewACLSize As Long        ' Size of new ACL to create.
> > >    Dim bNewACL() As Byte          ' Buffer to hold new ACL.
> > >
> > >    Dim sCurrentACE As ACCESS_ALLOWED_ACE    ' Current ACE.
> > >    Dim pCurrentAce As Long                  ' Our current ACE.
> > >
> > >    Dim nRecordNumber As Long
> > >    Dim strdw As String
> > >   
> > >    ' Get the SID of the user. (Refer to the MSDN for more information on SIDs
> > >    ' and their function/purpose in the operating system.) Get the SID of this
> > >    ' user by using the LookupAccountName API. In order to use the SID
> > >    ' of the current user account, call the LookupAccountName API
> > >    ' twice. The first time is to get the required sizes of the SID
> > >    ' and the DomainName string. The second call is to actually get
> > >    ' the desired information.
> > >    lResult = LookupAccountName(strComputerName, sUserName, _
> > >       bUserSid(0), 255, sDomainName, lDomainNameLength, _
> > >       lSIDType)
> > >
> > >    ' Now set the sDomainName string buffer to its proper size before
> > >    ' calling the API again.
> > >    sDomainName = Space(lDomainNameLength)
> > >
> > >    ' Call the LookupAccountName again to get the actual SID for user.
> > >    lResult = LookupAccountName(strComputerName, sUserName, _
> > >       bUserSid(0), 255, sDomainName, lDomainNameLength, _
> > >       lSIDType)
> > >
> > >    ' Return value of zero means the call to LookupAccountName failed;
> > >    ' test for this before you continue.
> > >      If (lResult = 0) Then
> > >         strdw = Err.LastDllError
> > >         lResult = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, strdw,
> > > GetUserDefaultLangID, strError, 1024, "0")
> > >         MsgBox "Erreur " & strdw & " : " & Left$(strError, lResult)
> > >         Exit Sub
> > >      End If
> > >
> > >    ' You now have the SID for the user who is logged on.
> > >    ' The SID is of interest since it will get the security descriptor
> > >    ' for the file that the user is interested in.
> > >    ' The GetFileSecurity API will retrieve the Security Descriptor
> > >    ' for the file. However, you must call this API twice: once to get
> > >    ' the proper size for the Security Descriptor and once to get the
> > >    ' actual Security Descriptor information.
> > >
> > >    lResult = GetFileSecurityN(sFileName, DACL_SECURITY_INFORMATION, _
> > >       0, 0, lSizeNeeded)
> > >
> > >    ' Redimension the Security Descriptor buffer to the proper size.
> > >    ReDim bSDBuf(lSizeNeeded)
> > >
> > >    ' Now get the actual Security Descriptor for the file.
> > >    lResult = GetFileSecurity(sFileName, DACL_SECURITY_INFORMATION, _
> > >       bSDBuf(0), lSizeNeeded, lSizeNeeded)
> > >
> > >    ' A return code of zero means the call failed; test for this
> > >    ' before continuing.
> > >    If (lResult = 0) Then
> > >       MsgBox "Error: Unable to Get the File Security Descriptor"
> > >       Exit Sub
> > >    End If
> > >
> > >    ' Call InitializeSecurityDescriptor to build a new SD for the
> > >    ' file.
> > >    lResult = InitializeSecurityDescriptor(sNewSD, _
> > >       SECURITY_DESCRIPTOR_REVISION)
> > >
> > >    ' A return code of zero means the call failed; test for this
> > >    ' before continuing.
> > >    If (lResult = 0) Then
> > >       MsgBox "Error: Unable to Initialize New Security Descriptor"
> > >       Exit Sub
> > >    End If
> > >
> > >    ' You now have the file's SD and a new Security Descriptor
> > >    ' that will replace the current one. Next, pull the DACL from
> > >    ' the SD. To do so, call the GetSecurityDescriptorDacl API
> > >    ' function.
> > >
> > >    lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, _
> > >       pAcl, lDaclDefaulted)
> > >
> > >    ' A return code of zero means the call failed; test for this
> > >    ' before continuing.
> > >    If (lResult = 0) Then
> > >       MsgBox "Error: Unable to Get DACL from File Security " _
> > >          & "Descriptor"
> > >       Exit Sub
> > >    End If
> > >
> > >    ' You have the file's SD, and want to now pull the ACL from the
> > >    ' SD. To do so, call the GetACLInformation API function.
> > >    ' See if ACL exists for this file before getting the ACL
> > >    ' information.
> > >    If (lDaclPresent = False) Then
> > >       MsgBox "Error: No ACL Information Available for this File"
> > >       Exit Sub
> > >    End If
> > >
> > >    ' Attempt to get the ACL from the file's Security Descriptor.
> > >    lResult = GetAclInformation(pAcl, sACLInfo, Len(sACLInfo), 2&)
> > >
> > >    ' A return code of zero means the call failed; test for this
> > >    ' before continuing.
> > >    If (lResult = 0) Then
> > >       MsgBox "Error: Unable to Get ACL from File Security Descriptor"
> > >       Exit Sub
> > >    End If
> > >
> > >    ' Now that you have the ACL information, compute the new ACL size
> > >    ' requirements.
> > >    lNewACLSize = sACLInfo.AclBytesInUse + (Len(sCurrentACE) + _
> > >       GetLengthSid(bUserSid(0))) * 2 - 4
> > >
> > >    ' Resize our new ACL buffer to its proper size.
> > >    ReDim bNewACL(lNewACLSize)
> > >
> > >    ' Use the InitializeAcl API function call to initialize the new
> > >    ' ACL.
> > >    lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION)
> > >
> > >    ' A return code of zero means the call failed; test for this
> > >    ' before continuing.
> > >    If (lResult = 0) Then
> > >       MsgBox "Error: Unable to Initialize New ACL"
> > >       Exit Sub
> > >    End If
> > >
> > >    ' If a DACL is present, copy it to a new DACL.
> > >    If (lDaclPresent) Then
> > >
> > >       ' Copy the ACEs from the file to the new ACL.
> > >       If (sACLInfo.AceCount > 0) Then
> > >
> > >          ' Grab each ACE and stuff them into the new ACL.
> > >          nRecordNumber = 0
> > >          For i = 0 To (sACLInfo.AceCount - 1)
> > >
> > >             ' Attempt to grab the next ACE.
> > >             lResult = GetAce(pAcl, i, pCurrentAce)
> > >
> > >             ' Make sure you have the current ACE under question.
> > >             If (lResult = 0) Then
> > >                MsgBox "Error: Unable to Obtain ACE (" & i & ")"
> > >                Exit Sub
> > >             End If
> > >
> > >             ' You have a pointer to the ACE. Place it
> > >             ' into a structure, so you can get at its size.
> > >             CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
> > >            
> > >             'Skip adding the ACE to the ACL if this is same usersid
> > >             lTempSid = pCurrentAce + 8
> > >             If EqualSid(bUserSid(0), lTempSid) = 0 Then
> > >                                 
> > >                 ' Now that you have the ACE, add it to the new ACL.
> > >                 lResult = AddAce(VarPtr(bNewACL(0)), ACL_REVISION, _
> > >                   MAXDWORD, pCurrentAce, _
> > >                   sCurrentACE.Header.AceSize)
> > >                
> > >                  ' Make sure you have the current ACE under question.
> > >                  If (lResult = 0) Then
> > >                    MsgBox "Error: Unable to Add ACE to New ACL"
> > >                     Exit Sub
> > >                  End If
> > >                  nRecordNumber = nRecordNumber + 1
> > >             End If
> > >             
> > >          Next i
> > >
> > >          ' You have now rebuilt a new ACL and want to add it to
> > >          ' the newly created DACL.
> > >          lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
> > >             lMask, bUserSid(0))
> > >
> > >          ' Make sure added the ACL to the DACL.
> > >          If (lResult = 0) Then
> > >             MsgBox "Error: Unable to Add ACL to DACL"
> > >             Exit Sub
> > >          End If
> > >
> > >          'If it's directory, we need to add inheritance staff.
> > >          If GetAttr(sFileName) And vbDirectory Then
> > >             
> > >             ' Attempt to grab the next ACE which is what we just added.
> > >             lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber, pCurrentAce)
> > >            
> > >             ' Make sure you have the current ACE under question.
> > >             If (lResult = 0) Then
> > >                MsgBox "Error: Unable to Obtain ACE (" & i & ")"
> > >                Exit Sub
> > >             End If
> > >             ' You have a pointer to the ACE. Place it
> > >             ' into a structure, so you can get at its size.
> > >             CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
> > >             sCurrentACE.Header.AceFlags = OBJECT_INHERIT_ACE +
> > > INHERIT_ONLY_ACE
> > >             CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE),
> > > LenB(sCurrentACE)
> > >
> > >             'add another ACE for files
> > >             lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
> > >                lMask, bUserSid(0))
> > >
Author
17 Oct 2005 2:07 PM
Chris
Thanks Amos for your help.
Everything works fine now.

Chris