Option Explicit ' ******************************************** ' * © 2000 Sergey Merzlikin * ' ******************************************** ' Desired access rights constants Public Const MAXIMUM_ALLOWED As Long = &H2000000 Public Const DELETE As Long = &H10000 Public Const READ_CONTROL As Long = &H20000 Public Const WRITE_DAC As Long = &H40000 Public Const WRITE_OWNER As Long = &H80000 Public Const SYNCHRONIZE As Long = &H100000 Public Const STANDARD_RIGHTS_READ As Long = READ_CONTROL Public Const STANDARD_RIGHTS_WRITE As Long = READ_CONTROL Public Const STANDARD_RIGHTS_EXECUTE As Long = READ_CONTROL Public Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000 Public Const FILE_READ_DATA As Long = &H1 ' file & pipe Public Const FILE_LIST_DIRECTORY As Long = &H1 ' directory Public Const FILE_ADD_FILE As Long = &H2 ' directory Public Const FILE_WRITE_DATA As Long = &H2 ' file & pipe Public Const FILE_CREATE_PIPE_INSTANCE As Long = &H4 ' named pipe Public Const FILE_ADD_SUBDIRECTORY As Long = &H4 ' directory Public Const FILE_APPEND_DATA As Long = &H4 ' file Public Const FILE_READ_EA As Long = &H8 ' file & directory Public Const FILE_READ_PROPERTIES As Long = FILE_READ_EA Public Const FILE_WRITE_EA As Long = &H10 ' file & directory Public Const FILE_WRITE_PROPERTIES As Long = FILE_WRITE_EA Public Const FILE_EXECUTE As Long = &H20 ' file Public Const FILE_TRAVERSE As Long = &H20 ' directory Public Const FILE_DELETE_CHILD As Long = &H40 ' directory Public Const FILE_READ_ATTRIBUTES As Long = &H80 ' all Public Const FILE_WRITE_ATTRIBUTES As Long = &H100 ' all Public Const FILE_GENERIC_READ As Long = (STANDARD_RIGHTS_READ _ Or FILE_READ_DATA Or FILE_READ_ATTRIBUTES _ Or FILE_READ_EA Or SYNCHRONIZE) Public Const FILE_GENERIC_WRITE As Long = (STANDARD_RIGHTS_WRITE _ Or FILE_WRITE_DATA Or FILE_WRITE_ATTRIBUTES _ Or FILE_WRITE_EA Or FILE_APPEND_DATA Or SYNCHRONIZE) Public Const FILE_GENERIC_EXECUTE As Long = (STANDARD_RIGHTS_EXECUTE _ Or FILE_READ_ATTRIBUTES Or FILE_EXECUTE Or SYNCHRONIZE) Public Const FILE_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED _ Or SYNCHRONIZE Or &H1FF&) Public Const GENERIC_READ As Long = &H80000000 Public Const GENERIC_WRITE As Long = &H40000000 Public Const GENERIC_EXECUTE As Long = &H20000000 Public Const GENERIC_ALL As Long = &H10000000 ' Types, constants and functions ' to work with access rights Private Const OWNER_SECURITY_INFORMATION As Long = &H1 Private Const GROUP_SECURITY_INFORMATION As Long = &H2 Private Const DACL_SECURITY_INFORMATION As Long = &H4 Private Const TOKEN_QUERY As Long = 8 Private Const SecurityImpersonation As Integer = 3 Private Const ANYSIZE_ARRAY = 1 Private Type GENERIC_MAPPING GenericRead As Long GenericWrite As Long GenericExecute As Long GenericAll As Long End Type Private Type LUID LowPart As Long HighPart As Long End Type Private Type LUID_AND_ATTRIBUTES pLuid As LUID Attributes As Long End Type Private Type PRIVILEGE_SET PrivilegeCount As Long Control As Long Privilege(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES End Type Private 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 Private Declare Function AccessCheck Lib "advapi32.dll" _ (pSecurityDescriptor As Byte, ByVal ClientToken As Long, _ ByVal DesiredAccess As Long, GenericMapping As GENERIC_MAPPING, _ PrivilegeSet As PRIVILEGE_SET, PrivilegeSetLength As Long, _ GrantedAccess As Long, Status As Long) As Long Private Declare Function ImpersonateSelf Lib "advapi32.dll" _ (ByVal ImpersonationLevel As Integer) As Long Private Declare Function RevertToSelf Lib "advapi32.dll" () As Long Private Declare Sub MapGenericMask Lib "advapi32.dll" (AccessMask As Long, _ GenericMapping As GENERIC_MAPPING) Private Declare Function OpenThreadToken Lib "advapi32.dll" _ (ByVal ThreadHandle As Long, ByVal DesiredAccess As Long, _ ByVal OpenAsSelf As Long, TokenHandle As Long) As Long Private Declare Function GetCurrentThread Lib "kernel32" () As Long Private Declare Function CloseHandle Lib "kernel32" _ (ByVal hObject As Long) As Long ' Types, constants and functions for OS version detection Private Type OSVERSIONINFO dwOSVersionInfoSize As Long dwMajorVersion As Long dwMinorVersion As Long dwBuildNumber As Long dwPlatformId As Long szCSDVersion As String * 128 End Type Private Const VER_PLATFORM_WIN32_NT As Long = 2 Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _ (lpVersionInformation As OSVERSIONINFO) As Long ' Constant and function for detection of support ' of access rights by file system Private Const FS_PERSISTENT_ACLS As Long = &H8 Private Declare Function GetVolumeInformation Lib "kernel32" _ Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, _ ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, _ lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, _ lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, _ ByVal nFileSystemNameSize As Long) As Long ' *-----------------------------------------------------------------------* ' CheckFileAccess function checks access rights to given file. ' DesiredAccess - bitmask of desired access rights. ' The function returns bitmask, which contains those bits of desired bitmask, ' which correspond with existing access rights. Private Function CheckFileAccess(Filename As String, _ ByVal DesiredAccess As Long) As Long Dim r As Long, SecDesc() As Byte, SDSize As Long, hToken As Long Dim PrivSet As PRIVILEGE_SET, GenMap As GENERIC_MAPPING Dim Volume As String, FSFlags As Long ' Checking OS type If Not IsNT() Then ' Rights not supported. Returning -1. CheckFileAccess = -1 Exit Function End If ' Checking access rights support by file system If Left$(Filename, 2) = "\\" Then ' Path in UNC format. Extracting share name from it r = InStr(3, Filename, "\") If r = 0 Then Volume = Filename & "\" Else Volume = Left$(Filename, r) End If ElseIf Mid$(Filename, 2, 2) = ":\" Then ' Path begins with drive letter Volume = Left$(Filename, 3) 'Else ' If path not set, we are leaving Volume blank. ' It retutns information about current drive. End If ' Getting information about drive GetVolumeInformation Volume, vbNullString, 0, ByVal 0&, _ ByVal 0&, FSFlags, vbNullString, 0 If (FSFlags And FS_PERSISTENT_ACLS) = 0 Then ' Rights not supported. Returning -1. CheckFileAccess = -1 Exit Function End If ' Determination of buffer size GetFileSecurity Filename, OWNER_SECURITY_INFORMATION _ Or GROUP_SECURITY_INFORMATION _ Or DACL_SECURITY_INFORMATION, 0, 0, SDSize If Err.LastDllError <> 122 Then ' Rights not supported. Returning -1. CheckFileAccess = -1 Exit Function End If If SDSize = 0 Then Exit Function ' Buffer allocation ReDim SecDesc(1 To SDSize) ' Once more call of function ' to obtain Security Descriptor If GetFileSecurity(Filename, OWNER_SECURITY_INFORMATION _ Or GROUP_SECURITY_INFORMATION _ Or DACL_SECURITY_INFORMATION, _ SecDesc(1), SDSize, SDSize) = 0 Then ' Error. We must return no access rights. Exit Function End If ' Adding Impersonation Token for thread ImpersonateSelf SecurityImpersonation ' Opening of Token of current thread OpenThreadToken GetCurrentThread(), TOKEN_QUERY, 0, hToken If hToken <> 0 Then ' Filling GenericMask type GenMap.GenericRead = FILE_GENERIC_READ GenMap.GenericWrite = FILE_GENERIC_WRITE GenMap.GenericExecute = FILE_GENERIC_EXECUTE GenMap.GenericAll = FILE_ALL_ACCESS ' Conversion of generic rights ' to specific file access rights MapGenericMask DesiredAccess, GenMap ' Checking access AccessCheck SecDesc(1), hToken, DesiredAccess, GenMap, _ PrivSet, Len(PrivSet), CheckFileAccess, r CloseHandle hToken End If ' Deleting Impersonation Token RevertToSelf End Function ' *-----------------------------------------------------------------------* ' IsNT() function returns True, if the program works ' in Windows NT or Windows 2000 operating system, and False ' otherwise. Private Function IsNT() As Boolean Dim OSVer As OSVERSIONINFO OSVer.dwOSVersionInfoSize = Len(OSVer) GetVersionEx OSVer IsNT = (OSVer.dwPlatformId = VER_PLATFORM_WIN32_NT) End Function ' *-----------------------------------------------------------------------*
Tuesday, March 3, 2015
Source code of CheckFileAccess function (VBA)
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment