AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

check write access?

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
ladiko



Joined: 14 Jul 2006
Posts: 190
Location: Berlin

PostPosted: Sat May 31, 2008 10:06 pm    Post subject: check write access? Reply with quote

Hello folks Smile

is there a simple way to check if the current user has write access to a file?

thank you in advance! ladiko
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5887

PostPosted: Sun Jun 01, 2008 1:24 am    Post subject: Reply with quote

Code:
MsgBox, % WriteAccess( A_AhkPath )
MsgBox, % WriteAccess( A_ScriptFullPath )

WriteAccess( F ) {
  Return ((h:=DllCall("_lopen",Str,F,Int,1)) > 0 ? 1 : 0) (DllCall("_lclose",Int,h)+NULL)
}

Smile
Back to top
View user's profile Send private message
ladiko



Joined: 14 Jul 2006
Posts: 190
Location: Berlin

PostPosted: Thu Jun 05, 2008 7:53 am    Post subject: Reply with quote

thank you skan Smile

Code:
Loop , %A_ScriptDir%\*.* , 1 , 1
   list .= A_LoopFileFullPath . " = " . WriteAccess( A_LoopFileFullPath ) . "`n"

Sort , list
list := A_ScriptName . "`n`n" . list
Msgbox , %list%

return

WriteAccess( F ) {
  Return ((h:=DllCall("_lopen",Str,F,Int,1)) > 0 ? 1 : 0) (DllCall("_lclose",Int,h)+NULL)
}

results in:
Code:
write_access.ahk

D:\NewFolder\NewFolder = 0
D:\NewFolder\NewFolder\Text Document (new).txt = 1
D:\NewFolder\write_access.ahk = 1
D:\NewFolder\write_access.exe = 1
and in:
Code:
write_access.exe

D:\NewFolder\NewFolder = 0
D:\NewFolder\NewFolder\Text Document (new).txt = 1
D:\NewFolder\write_access.ahk = 1
D:\NewFolder\write_access.exe = 0
so it is ok that the script has write access to the exe but the exe not to itself. it also has write access to the file inside of the folder, but not to the folder?!? that's wrong. the result for folders is always zero.

i want to know if i have write access to a folder, is it possible?
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5887

PostPosted: Thu Jun 05, 2008 8:42 am    Post subject: Reply with quote

The simplest way would be to write and check:

Code:
MsgBox, % FolderWriteAccess( A_ScriptDir )

FolderWriteAccess( Folder ) {
If InStr( FileExist(Folder), "D" ) {
  FileAppend,,%Folder%\fa.tmp
  rval := ! ErrorLevel
  FileDelete,,%Folder%\fa.tmp
  Return rval
} Return - 1 


Not-So-Elegant.. I am already googling to check if there is an API to do this. Will post again if I find one.

Smile
Back to top
View user's profile Send private message
ladiko



Joined: 14 Jul 2006
Posts: 190
Location: Berlin

PostPosted: Thu Jun 05, 2008 9:48 am    Post subject: Reply with quote

what about
Code:
FileCreateDir , %A_ScriptDir%\existing_folder
Msgbox , %ErrorLevel%
FileCreateDir , %A_WinDir%
Msgbox , %ErrorLevel%

but it doesnt work on vista, cause vista redirects the created folder to the users VirtualStore >.<

your last example has the same problem - vista's explorer creates the file in the VirtualStore folder =/


Last edited by ladiko on Thu Jun 05, 2008 3:04 pm; edited 1 time in total
Back to top
View user's profile Send private message
Rhys



Joined: 17 Apr 2007
Posts: 722
Location: Florida

PostPosted: Thu Jun 05, 2008 1:24 pm    Post subject: Reply with quote

Interesting topic, please excuse me tagging it for later review Embarassed
_________________
[Join IRC!]
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1353

PostPosted: Thu Jun 05, 2008 6:20 pm    Post subject: Reply with quote

I'm not sure where your confusion lies with folders skan. just use the same method that you did for files...

Code:

MsgBox, % FolderWriteAccess("C:\Program Files")
Return

FolderWriteAccess(Folder)
{
   h := DllCall("CreateFile", "Str", Folder "\tmp.tmp"
   , "UInt", 0x40000000, "UInt", 0, "UInt", 0, "UInt", 4, "UInt", 0, "UInt", 0)
   DllCall("CloseHandle", "UInt", h)
   Return, (h = -1) ? 0 : h
}

FileWriteAccess(File)
{
   h := DllCall("CreateFile", "Str", File
   , "UInt", 0x40000000, "UInt", 0, "UInt", 0, "UInt", 4, "UInt", 0, "UInt", 0)
   DllCall("CloseHandle", "UInt", h)
   Return, (h = -1) ? 0 : h
}
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5887

PostPosted: Thu Jun 05, 2008 7:55 pm    Post subject: Reply with quote

tic wrote:
where your confusion lies with folders skan


No confusion.. did not have enough time to chck CreateFile !.. I am upgrading my machine and hence been very limited on net for past one week.

Smile
Back to top
View user's profile Send private message
ladiko



Joined: 14 Jul 2006
Posts: 190
Location: Berlin

PostPosted: Fri Jun 06, 2008 9:00 am    Post subject: Reply with quote

on xp i get the correct result with tic's version but the folder method is almost the same as the FileAppend try from SKAN, isnt it?

so there is no other way than to create a file and delete it? isnt it possible to get all groups/users that have write permissions and check if the user is in one of this groups?

under vista it might not work cause it always creates a file but in a different virtual folder. you also cannot check if the file exist after creation cause vista does it overlay seemless and so the file exist in this write protected folder...
Back to top
View user's profile Send private message
n-l-i-d
Guest





PostPosted: Fri Jun 06, 2008 10:13 am    Post subject: Reply with quote

ladiko wrote:
... isnt it possible to get all groups/users that have write permissions and check if the user is in one of this groups?


If the AHK "solution" doesn't satisfy you, there are external tools which can, like perms/cacls/xcacls or others.

HTH
Back to top
tic



Joined: 22 Apr 2007
Posts: 1353

PostPosted: Fri Jun 06, 2008 10:46 am    Post subject: Reply with quote

ladiko wrote:
on xp i get the correct result with tic's version but the folder method is almost the same as the FileAppend try from SKAN, isnt it?


Well no.....it doesnt actually create a file. it attempts to get a handle to a file of specific location. no file is actually created. i see no problem with using this method. it is fast, efficient, simple and effective...
Back to top
View user's profile Send private message
ladiko



Joined: 14 Jul 2006
Posts: 190
Location: Berlin

PostPosted: Fri Jun 06, 2008 11:11 am    Post subject: Reply with quote

i changed your msgbox to:
MsgBox, % "Admin: " . A_IsAdmin . " Access: " . FolderWriteAccess(A_ProgramFiles)
and i get:
Admin: 0 Access: 0
and
Admin: 1 Access: 124
and in the second case, a file named tmp.tmp is created in A_ProgramFiles
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1353

PostPosted: Fri Jun 06, 2008 11:23 am    Post subject: Reply with quote

really? mmm. how did you see a file being created? this has surprised me Confused
Back to top
View user's profile Send private message
ladiko



Joined: 14 Jul 2006
Posts: 190
Location: Berlin

PostPosted: Fri Jun 06, 2008 11:32 am    Post subject: Reply with quote

with my eyes in the explorer of windows xp. what should createfile does instead?

my first unfinished try to get the folder rights. now i have to get the current users membership in the groups and compare this.
Code:
folder1 := A_ProgramFiles
folder2 := A_AppData

Loop , 2
{
   access := 0
   LoopFolder := folder%A_Index%
   cacls := CMDret_RunReturn("cacls """ . LoopFolder . """")
   Loop , Parse , cacls , `n , `r
   {
      Length := InStr(A_LoopField,":",false,0) - InStr(A_LoopField,"\",false,0) - 1
      StartPos := InStr(A_LoopField,"\",false,0) + 1
      LoopUser := SubStr(A_LoopField, StartPos , Length)
      LoopRight := SubStr(A_LoopField,-1,1)
      If LoopRight in F,W,C
         Msgbox , %LoopUser% has %LoopRight% rights for %LoopFolder%`nF= Full`nW= Write`nC = Change
   }
}

return


CMDret_RunReturn(CMDin, WorkingDir=0)
{
  Global cmdretPID
  tcWrk := WorkingDir=0 ? "Int" : "Str"
  idltm := A_TickCount + 20
  CMsize = 1
  VarSetCapacity(CMDout, 1, 32)
  VarSetCapacity(sui,68, 0)
  VarSetCapacity(pi, 16, 0)
  VarSetCapacity(pa, 12, 0)
  Loop, 4 {
    DllCall("RtlFillMemory", UInt,&pa+A_Index-1, UInt,1, UChar,12 >> 8*A_Index-8)
    DllCall("RtlFillMemory", UInt,&pa+8+A_Index-1, UInt,1, UChar,1 >> 8*A_Index-8)
  }
  IF (DllCall("CreatePipe", "UInt*",hRead, "UInt*",hWrite, "UInt",&pa, "Int",0) <> 0) {
    Loop, 4
      DllCall("RtlFillMemory", UInt,&sui+A_Index-1, UInt,1, UChar,68 >> 8*A_Index-8)
    DllCall("GetStartupInfo", "UInt", &sui)
    Loop, 4 {
      DllCall("RtlFillMemory", UInt,&sui+44+A_Index-1, UInt,1, UChar,257 >> 8*A_Index-8)
      DllCall("RtlFillMemory", UInt,&sui+60+A_Index-1, UInt,1, UChar,hWrite >> 8*A_Index-8)
      DllCall("RtlFillMemory", UInt,&sui+64+A_Index-1, UInt,1, UChar,hWrite >> 8*A_Index-8)
      DllCall("RtlFillMemory", UInt,&sui+48+A_Index-1, UInt,1, UChar,0 >> 8*A_Index-8)
    }
    IF (DllCall("CreateProcess", Int,0, Str,CMDin, Int,0, Int,0, Int,1, "UInt",0, Int,0, tcWrk, WorkingDir, UInt,&sui, UInt,&pi) <> 0) {
      Loop, 4
        cmdretPID += *(&pi+8+A_Index-1) << 8*A_Index-8
      Loop {
        idltm2 := A_TickCount - idltm
        If (idltm2 < 10) {
          DllCall("Sleep", Int, 10)
          Continue
        }
        IF (DllCall("PeekNamedPipe", "uint", hRead, "uint", 0, "uint", 0, "uint", 0, "uint*", bSize, "uint", 0 ) <> 0 ) {
          Process, Exist, %cmdretPID%
          IF (ErrorLevel OR bSize > 0) {
            IF (bSize > 0) {
              VarSetCapacity(lpBuffer, bSize+1)
              IF (DllCall("ReadFile", "UInt",hRead, "Str", lpBuffer, "Int",bSize, "UInt*",bRead, "Int",0) > 0) {
                IF (bRead > 0) {
                  TRead += bRead
                  VarSetCapacity(CMcpy, (bRead+CMsize+1), 0)
                  CMcpy = a
                  DllCall("RtlMoveMemory", "UInt", &CMcpy, "UInt", &CMDout, "Int", CMsize)
                  DllCall("RtlMoveMemory", "UInt", &CMcpy+CMsize, "UInt", &lpBuffer, "Int", bRead)
                  CMsize += bRead
                  VarSetCapacity(CMDout, (CMsize + 1), 0)
                  CMDout=a   
                  DllCall("RtlMoveMemory", "UInt", &CMDout, "UInt", &CMcpy, "Int", CMsize)
                  VarSetCapacity(CMDout, -1)   ; fix required by change in autohotkey v1.0.44.14
                }
              }
            }
          }
          ELSE
            break
        }
        ELSE
          break
        idltm := A_TickCount
      }
      cmdretPID=
      DllCall("CloseHandle", UInt, hWrite)
      DllCall("CloseHandle", UInt, hRead)
    }
  }
  IF (StrLen(CMDout) < TRead) {
    VarSetCapacity(CMcpy, TRead, 32)
    TRead2 = %TRead%
    Loop {
      DllCall("RtlZeroMemory", "UInt", &CMcpy, Int, TRead)
      NULLptr := StrLen(CMDout)
      cpsize := Tread - NULLptr
      DllCall("RtlMoveMemory", "UInt", &CMcpy, "UInt", (&CMDout + NULLptr + 2), "Int", (cpsize - 1))
      DllCall("RtlZeroMemory", "UInt", (&CMDout + NULLptr), Int, cpsize)
      DllCall("RtlMoveMemory", "UInt", (&CMDout + NULLptr), "UInt", &CMcpy, "Int", cpsize)
      TRead2 --
      IF (StrLen(CMDout) > TRead2)
        break
    }
  }
  StringTrimLeft, CMDout, CMDout, 1
  Return, CMDout
}
Back to top
View user's profile Send private message
tic



Joined: 22 Apr 2007
Posts: 1353

PostPosted: Fri Jun 06, 2008 12:38 pm    Post subject: Reply with quote

if all you want to see is if its been set to read only, then perhaps just do:

Code:
FolderWriteAccess(Folder)
{
   Attr := FileExist(Folder)
   Return, (!InStr(Attr, "D") || InStr(Attr, "R")) ? 0 : 1
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group