Check permissions of directory

Hi all,

I'm after a way to check the write access the user has to a particular directory. Pref. a way to do it that doesn't require non foxpro objects (ie wsh/fso).

doing an fcreate to create a dummy file then deleting it isn't suitable. It's not really elegant and there are instances where the user might have create rights but no delete rights & there'd be a bunch of dummy files in the dir.

any ideas? adir() doesn't give enough info (or any info in fact)

thanks

[490 byte] By [teeth777] at [2008-1-3]
# 1

i think u can use

!attrib > x.txt

convert x.txt to dbf programattically and check whether u have write permission or not.

LakshmiN at 2007-9-25 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 2
You may use API function, GetFileSecurity.
dni at 2007-9-25 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 4

Here is a code by Christof Wollenhaupt: (taken from a thread on for profit website):

==============================================

Here's the code. It's a bit more lengthy than the last one that just returns permissions for a file:
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

 
NaomiNosonovsky at 2007-9-25 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 5
Thanks everyone! The info has been very helpful, playing with it now... BUT, that function is returning .T. for directories that i know i don't have write access to.

Here's a simple test.

Create a new directory on your local drive, share it to everyone & only allow read access. Map the shared folder to a drive letter.

If you go to the share via the drive letter it won't let you save, but 'checkdirectoryrights' returns .T.

I've tried this on network directories that i only have read access to and it returns .T. as well... It
only returns false if i don't have any access to the directory or it doesn't exist.

I set up Z:\ as the map to my local dir

?CheckDirectoryRights("Z:\","W")
returns .T.

teeth777 at 2007-9-25 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 6

Yes, in my tests the results were not always as I expected. I'm not sure why, since this is not my code. I may ask Christof about it.

My own solution was with FSO, but you said you don't want FSO solution. Besides, it doesn't seem to be 100% reliable either.

Look closer at the posted function and at the link, may be you will be able to figure out translation of VB code at that link.

Also I didn't look close enough to this function, but I see it has lots of places it can fail. May be we need to output Last Error information, there is a possibility the function is failing.

NaomiNosonovsky at 2007-9-25 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 7

Look at http://home.hot.rr.com/graye/Articles/SetPermissions.htm I don't have enough API knowledge to translate this into VFP code, but I'll ask Christof and other developers.

I'm sorry, I found Christof explanation for the behavior we're seeing in the same thread. I don't want to re-post his answer here, but I asked this question on the other forum and also gave a reference to this thread.

NaomiNosonovsky at 2007-9-25 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...
# 8

> If you go to the share via the drive letter it won't let you save, but 'checkdirectoryrights' returns .T.

That's because you're mixing share permissions and folder permissions. The program queries only file and folder permissions. It's using what you see when you right-click on the directory and open the "Security" tab. It's not checking any additional restrictions that the share imposes. See

http://technet2.microsoft.com/windowsserver/en/library/d043701a-5a2e-4001-b659-0c23c90f76f61033.mspx?mfr=true
http://www.windowsecurity.com/articles/Share-Permissions.html


for more details on share and folder permissions.

--
Christof

ChristofWollenhaupt at 2007-9-25 > top of Msdn Tech,Visual FoxPro,Visual FoxPro General...