Code: Select all
; Desired access rights constants
#MAXIMUM_ALLOWED = $2000000
#DELETE = $10000
#READ_CONTROL = $20000
#WRITE_DAC = $40000
#WRITE_OWNER = $80000
#SYNCHRONIZE = $100000
#STANDARD_RIGHTS_READ = #READ_CONTROL
#STANDARD_RIGHTS_WRITE = #READ_CONTROL
#STANDARD_RIGHTS_EXECUTE = #READ_CONTROL
#STANDARD_RIGHTS_REQUIRED = $F0000
#FILE_READ_DATA = $1 ; file & pipe
#FILE_LIST_DIRECTORY = $1 ; directory
#FILE_ADD_FILE = $2 ; directory
#FILE_WRITE_DATA = $2 ; file & pipe
#FILE_CREATE_PIPE_INSTANCE = $4 ; named pipe
#FILE_ADD_SUBDIRECTORY = $4 ; directory
#FILE_APPEND_DATA = $4 ; file
#FILE_READ_EA = $8 ; file & directory
#FILE_READ_PROPERTIES = #FILE_READ_EA
#FILE_WRITE_EA = $10 ; file & directory
#FILE_WRITE_PROPERTIES = #FILE_WRITE_EA
#FILE_EXECUTE = $20 ; file
#FILE_TRAVERSE = $20 ; directory
#FILE_DELETE_CHILD = $40 ; directory
#FILE_READ_ATTRIBUTES = $80 ; all
#FILE_WRITE_ATTRIBUTES = $100 ; all
#FILE_GENERIC_READ = #STANDARD_RIGHTS_READ | #FILE_READ_DATA | #FILE_READ_ATTRIBUTES | #FILE_READ_EA | #SYNCHRONIZE
#FILE_GENERIC_WRITE = #STANDARD_RIGHTS_WRITE | #FILE_WRITE_DATA | #FILE_WRITE_ATTRIBUTES | #FILE_WRITE_EA | #FILE_APPEND_DATA | #SYNCHRONIZE
#FILE_GENERIC_EXECUTE = #STANDARD_RIGHTS_EXECUTE | #FILE_READ_ATTRIBUTES | #FILE_EXECUTE | #SYNCHRONIZE
#FILE_ALL_ACCESS = #STANDARD_RIGHTS_REQUIRED | #SYNCHRONIZE | $1FF
#GENERIC_READ = $80000000
#GENERIC_WRITE = $40000000
#GENERIC_EXECUTE = $20000000
#GENERIC_ALL = $10000000
; Types, constants And functions
; To work With access rights
#OWNER_SECURITY_INFORMATION = $1
#GROUP_SECURITY_INFORMATION = $2
#DACL_SECURITY_INFORMATION = $4
#TOKEN_QUERY = 8
#SecurityImpersonation = 3
#ANYSIZE_ARRAY = 1
; Constant And function For detection of support
; of access rights by file system
#FS_PERSISTENT_ACLS = $8
; 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.
Procedure.l CheckFileAccess(Filename.s, DesiredAccess.l)
Protected.l r, SDSize, FSFlags, Volume.s, hToken.i
; Checking access rights support by file system
If Left(Filename, 2) = "\\"
; Path in UNC format. Extracting share name from it
r = FindString(Filename, "\", 3)
If r = 0
Volume = Filename + "\"
Else
Volume = Left(Filename, r)
EndIf
ElseIf Mid(Filename, 2, 2) = ":\"
; Path begins With drive letter
Volume = Left(Filename, 3)
;Else
; If path Not set, we are leaving Volume blank.
; It returns information about current drive.
EndIf
; Getting information about drive
GetVolumeInformation_(Volume, #Null, 0, 0, 0, @FSFlags, #Null, 0)
If FSFlags And #FS_PERSISTENT_ACLS = 0
; Rights Not supported.
ProcedureReturn -1
EndIf
RequestedInformation = #OWNER_SECURITY_INFORMATION | #GROUP_SECURITY_INFORMATION | #DACL_SECURITY_INFORMATION
; Determination of buffer size
Retr = GetFileSecurity_(@Filename, RequestedInformation, 0, 0, @SDSize)
If Not Retr
If GetLastError_() <> 122
; Rights Not supported.
ProcedureReturn -1
EndIf
EndIf
If SDSize = 0 : ProcedureReturn -1 : EndIf
; Buffer allocation
*SecDesc = AllocateMemory(SDSize)
If Not *SecDesc
ProcedureReturn -1
EndIf
; Once more call of function
; To obtain Security Descriptor
If GetFileSecurity_(@Filename, RequestedInformation, *SecDesc, SDSize, @SDSize) = 0
; Error. We must Return no access rights.
ProcedureReturn 0
EndIf
; Adding Impersonation Token For thread
ImpersonateSelf_(#SecurityImpersonation)
; Opening of Token of current thread
OpenThreadToken_(GetCurrentThread_(), #TOKEN_QUERY, 0, @hToken)
If hToken <> 0
; Filling GenericMask type
GenMap.GENERIC_MAPPING
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
MapGenericMask_(@DesiredAccess, GenMap)
PrivSet.PRIVILEGE_SET
; Checking access
Size = SizeOf(PrivSet)
AccessCheck_(*SecDesc, hToken, DesiredAccess, GenMap, PrivSet.PRIVILEGE_SET, @Size, @CheckFileAccess, @r)
CloseHandle_(hToken)
EndIf
; Deleting Impersonation Token
RevertToSelf_()
;Free memory allocation
FreeMemory(*SecDesc)
ProcedureReturn CheckFileAccess
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
FileOrFolderName$ = GetEnvironmentVariable("SystemRoot")+"\notepad.exe"
If CheckFileAccess(FileOrFolderName$, #FILE_GENERIC_READ) = #FILE_GENERIC_READ
AccessRead2$ = "#FILE_GENERIC_READ"
Else
AccessRead2$ = "NO"
EndIf
If CheckFileAccess(FileOrFolderName$, #FILE_GENERIC_WRITE) = #FILE_GENERIC_WRITE
AccessWrite2$ = "#FILE_GENERIC_WRITE"
Else
AccessWrite2$ = "NO"
EndIf
MessageRequester("File Or Folder: Permissions", FileOrFolderName$+#LF$+#LF$+"Write permission is " + AccessWrite2$ + #CRLF$+#CRLF$+
"Read permission is " + AccessRead2$, #PB_MessageRequester_Ok)
FileOrFolderName$ = GetEnvironmentVariable("LocalAppData")
If CheckFileAccess(FileOrFolderName$, #FILE_GENERIC_READ) = #FILE_GENERIC_READ
AccessRead2$ = "#FILE_GENERIC_READ"
Else
AccessRead2$ = "NO"
EndIf
If CheckFileAccess(FileOrFolderName$, #FILE_GENERIC_WRITE) = #FILE_GENERIC_WRITE
AccessWrite2$ = "#FILE_GENERIC_WRITE"
Else
AccessWrite2$ = "NO"
EndIf
MessageRequester("File Or Folder: Permissions", FileOrFolderName$+#LF$+#LF$+"Write permission is " + AccessWrite2$ + #CRLF$+#CRLF$+
"Read permission is " + AccessRead2$, #PB_MessageRequester_Ok)
CompilerEndIf