Posted on 2008-10-20
Last Modified: 2013-11-25

How do I retrieve ACCESS_MASK from a file, or a file handle?
Question by:mycuti08
  • 2
  • 2
LVL 41

Accepted Solution

graye earned 500 total points
ID: 22776451
The ACCESS_MASK is just the format for the Access Control Entries (ACE).
The ACE is inside the Discretionaly Access Control List (ACL).   You'd typically use GetNamedSecurityInfo to get the DACL, then "walk the DACL" to get each ACE.   There is an example that sets the ACE at the following link.   It not exactly what you're looking for, but it's a pretty good example of the technique required:

Author Comment

ID: 22777703
Thanks graye,

I got to the point where I can get the pointer to PDACL. But that pointer only points to the ACL header, not a list of ACEs. How do I access list of ACEs from this point.


Author Closing Comment

ID: 31507976
I got it. Thanks
LVL 41

Expert Comment

ID: 22778467
I've got a VB.Net example handy...   (Sorry, I don't have C++ version, but it still might be helpful)

    Public Function GetFileACL(ByVal file As String) As ACE_Entry()

        Dim SD As System.IntPtr

        Dim SDSizeNeeded, SDSize As Integer

        Dim LastError As Integer

        Dim Dacl_Present, Dacl_Defaulted As Boolean

        Dim DACL, ACE, SID_ptr, SID_String_ptr As System.IntPtr

        Dim ACE_Header As ACE_HEADER

        Dim Access_ACE As ACCESS_ACE



        Dim entry As Integer

        Dim isFile As Boolean

        Dim Win32Error As Win32Exception

        Dim name_len, domain_len, dUse, num As Integer

        Dim name, domain_name, UserName, MachineName, StringSID As String

        Dim Ans(0) As ACE_Entry

        ' Do a quick sanity check?

        isFile = True

        If System.IO.File.Exists(file) = False Then

            If System.IO.Directory.Exists(file) = False Then

                Throw New ApplicationException("Error: file doesn't exist!")

            End If

            isFile = False

        End If

        ' get the Security Descriptor and DACL

        If GetNamedSecurityInfo(file, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, Nothing, Nothing, DACL, Nothing, SD) <> 0 Then

            LastError = Marshal.GetLastWin32Error()

            Win32Error = New Win32Exception(LastError)

            Throw New ApplicationException("Error: " & Win32Error.Message)

        End If

        ' quick sanity check...

        If IsValidSecurityDescriptor(SD) = False Then

            Throw New ApplicationException("Error: invalid SD")

        End If

        ' one last check...

        If IsValidAcl(DACL) = False Then

            Throw New ApplicationException("Error: invalid ACL")

        End If

        ' how many ACEs are in the DACL?

        GetAclInformation(DACL, ACL_size, Len(ACL_size), ACL_INFORMATION_CLASS.AclSizeInformation)

        ReDim Ans(ACL_size.AceCount - 1)

        Debug.WriteLine("AceCount=" & ACL_size.AceCount)

        GetAclInformation(DACL, ACL_Rev, Len(ACL_Rev), ACL_INFORMATION_CLASS.AclRevisionInformation)

        Debug.WriteLine("ACL_Rev=" & ACL_Rev.AclRevision)

        ' loop thru all of the ACE's in the DACL

        entry = 0

        Do While GetAce(DACL, entry, ACE) = True

            ' start by copying just the header

            ACE_Header = Marshal.PtrToStructure(ACE, GetType(ACE_HEADER))

            ' we're really only interested in type=0 (allow) and type=1 (deny)

            If ACE_Header.AceType = 0 Or ACE_Header.AceType = 1 Then

                ' now that we know it's type... we do the copy over again

                Access_ACE = Marshal.PtrToStructure(ACE, GetType(ACCESS_ACE))

                Debug.WriteLine("AceSize=" & ACE_Header.AceSize & ", AceType=" & ACE_Header.AceType & ", Mask=" & Access_ACE.Mask & ", AceFlags=" & Access_ACE.Header.AceFlags)

                ' translate SID to Account Name

                SID_ptr = New IntPtr(ACE.ToInt32 + 8)

                UserName = TranslateSidToName("", SID_ptr)

                Ans(entry).ACE_Name = Left(UserName, 50)

                ' Type of ACE

                If ACE_Header.AceType = 0 Then

                    Ans(entry).ACE_Type = "Allow"


                    Ans(entry).ACE_Type = "Deny"

                End If

                ' the permissions

                If isFile Then

                    Ans(entry).ACE_Permission = FileMaskToString(Access_ACE.Mask)


                    Ans(entry).ACE_Permission = DirectoryMaskToString(Access_ACE.Mask)

                End If

                ' Inheritance

                If Access_ACE.Header.AceFlags And AceFlags.INHERITED_ACE Then

                    Ans(entry).ACE_Inherited = True


                    Ans(entry).ACE_Inherited = False

                End If

                ' Scope (directories only)

                If isFile = False Then

                    Ans(entry).ACE_Scope = ACEFlagToString(Access_ACE.Header.AceFlags)

                End If

            End If

            entry = entry + 1


        ' Free the memory we allocated.


        ' Exit the routine.

        If entry > 0 Then

            ReDim Preserve Ans(entry - 1)

        End If

        Return Ans

    End Function

Open in new window


Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

26 Experts available now in Live!

Get 1:1 Help Now