Code Snippet
*******************************************
* FUNCTION CheckDirectoryRights(tcName, tuAccess)
* Date : 05/17/2007, 09:33:00
* Author : Christof Wollenhaupt
* Description: Returns .t. or .f. if the user has rights for the specific directory
****** PARAMETERS **************
* Parameters : 2
* Parameter 1: Directory name
* Parameter 2: Which access permissions we want to return*******************************************
FUNCTION CheckDirectoryRights ( tcName, tuAccess )
*!* IF hasAccess("C:\directory\","W")
*!* ENDIF*========================================================================================
* Returns .T. if the current user has the requested privileges for a particular file or
* directory.
*========================================================================================
*--
* Build up the Access mask. You can specify a numeric value for other masks
*--
Local lnAccess
Do case
Case Vartype(m.tuAccess) == "C"
lnAccess = 0
If "R" $ Upper(m.tuAccess) && Read
lnAccess = m.lnAccess + 1
EndIf
If "W" $ Upper(m.tuAccess) && Write
lnAccess = m.lnAccess + 2
EndIf
If "A" $ Upper(m.tuAccess) && Append
lnAccess = m.lnAccess + 4
EndIf
If "D" $ Upper(m.tuAccess) && Delete
lnAccess = m.lnAccess + 0x40
EndIf
Case Vartype(m.tuAccess) == "N"
lnAccess = m.tuAccess
EndCase *--
* Declare API functions
*--
Declare Long GetFileSecurity in Win32API ;
String lpFileName, ;
Long RequestedInformation, ;
String @pSecurityDescriptor, ;
Long nLength, ;
Long @lpnLengthNeeded
Declare Long OpenProcessToken in Win32API ;
Long ThreadHandle, ;
Long DesiredAccess, ;
Long @TokenHandle
Declare Long AccessCheck in Win32API ;
String pSecurityDescriptor, ;
Long ClientToken, ;
Long DesiredAccess, ;
String GenericMapping, ;
String @PrivilegeSet, ;
Long @PrivilegeSetLength, ;
Long @GrantedAccess, ;
Long @AccessStatus
Declare MapGenericMask in Win32API ;
Long @AccessMask, ;
String @GenericMapping
Declare Long GetLastError in Win32API
Declare CloseHandle in Win32API Long
Declare Long DuplicateToken in Win32API ;
Long ExistingTokenHandle, ;
Long ImpersonationLevel, ;
Long @DuplicateTokenHandle *--
* Retrieve the DACL
*--
Local lcDACL, lnNeeded
lcDACL = Space(4096)
lnNeeded = 0
GetFileSecurity( ;
m.tcName, ;
0x7, ;
@lcDACL, ;
Len(m.lcDACL), ;
@lnNeeded ;
)
lcDACL = Left( m.lcDACL,m.lnNeeded) *--
* Get the Token for the current security context. That's the user which is logged onto
* the system or an impersonated user.
*--
Local lnToken, lnError
lnToken = 0
If OpenProcessToken( -1, 0x0008+0x0002, @lnToken ) == 0
lnError = GetLastError()
Return .F.
EndIf *--
* AccessCheck requires an impersonated token
*--
Local lnImpToken
lnImpToken = 0
If DuplicateToken( m.lnToken, 2, @lnImpToken ) == 0
lnError = GetLastError()
CloseHandle(m.lnToken)
Return .F.
EndIf *--
* Create a generic mapping for permissions
*--
Local lcMapping
lcMapping = Space(16)
MapGenericMask( @lnAccess, @lcMapping ) *--
* Check permissions
*--
Local lnStatus, lnGrant, lnPLength, lcPBuf, lnOK
lnStatus = 0
lnGrant = 0
lcPBuf = Space(4096)
lnPLength = Len(m.lcPBuf)
lnOK = AccessCheck( ;
m.lcDACL, ;
m.lnImpToken, ;
m.lnAccess, ;
m.lcMapping, ;
@lcPBuf, ;
@lnPLength, ;
@lnGrant, ;
@lnStatus ;
)
lnError = GetLastError() *--
* Close all handles
*--
CloseHandle(m.lnToken)
CloseHandle(m.lnImpToken)Return m.lnGrant != 0