mycuti08
asked on
ACCESS_MASK
Hi,
How do I retrieve ACCESS_MASK from a file, or a file handle?
Thanks
How do I retrieve ACCESS_MASK from a file, or a file handle?
Thanks
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I got it. Thanks
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 ACL_size As ACL_SIZE_INFORMATION
Dim ACL_Rev As ACL_REVISION_INFORMATION
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"
Else
Ans(entry).ACE_Type = "Deny"
End If
' the permissions
If isFile Then
Ans(entry).ACE_Permission = FileMaskToString(Access_ACE.Mask)
Else
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
Else
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
Loop
' Free the memory we allocated.
'Marshal.FreeHGlobal(SD)
' Exit the routine.
If entry > 0 Then
ReDim Preserve Ans(entry - 1)
End If
Return Ans
End Function
ASKER
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.