KaFu Posted September 18, 2011 Share Posted September 18, 2011 (edited) HiHo Forum, as the topic title already says, I'm looking for a non-invasive way to check if a file or directory is writable / deletable. I drafted two methods which both work fine, but are invasive (file is changed). Method1 tries to set or unset the Archive attribute. This is invasive (file is changed) but works for both files and directories. Method2 tries to open files for write access (non-invasive!), but relies on creating files in directories (invasive again, *sigh*) to check the accessibility. What I want to do with this function is to check whether the current user could delete the file or directory in question (> UAC). Maybe someone else got an idea how to do this non-invasive for directories too ? expandcollapse popup#include <WinAPI.au3> Global $aFiles[4] = [@ScriptFullPath, @ScriptDir, @SystemDir, @SystemDir & "\user32.dll"] #region Method1 For $i = 0 To 3 ConsoleWrite(FileExists($aFiles[$i]) & @TAB & _FileWriteAccessible_Method1($aFiles[$i]) & @TAB & $aFiles[$i] & @CRLF) Next #endregion Method1 ConsoleWrite(@CRLF & @CRLF) #region Method2 For $i = 0 To 3 ConsoleWrite(FileExists($aFiles[$i]) & @TAB & _FileWriteAccessible_Method2($aFiles[$i]) & @TAB & $aFiles[$i] & @CRLF) Next #endregion Method2 Func _FileWriteAccessible_Method1($sFile) If Not FileExists($sFile) Then Return -1 Local $iSuccess = 0 Switch StringInStr(FileGetAttrib($sFile), "A", 2) Case False If FileSetAttrib($sFile, "+A") Then $iSuccess = 1 FileSetAttrib($sFile, "-A") EndIf Case Else If FileSetAttrib($sFile, "-A") Then $iSuccess = 1 FileSetAttrib($sFile, "+A") EndIf EndSwitch Return $iSuccess EndFunc ;==>_FileWriteAccessible_Method1 Func _FileWriteAccessible_Method2($sFile) If Not FileExists($sFile) Then Return -1 Local $iRes, $hFile, $sFile_Buf, $i = 0 Switch StringInStr(FileGetAttrib($sFile), "D", 2) Case True $sFile_Buf = $sFile While FileExists($sFile) $i += 1 $sFile = $sFile_Buf & "\Test_" & $i WEnd $hFile = _WinAPI_CreateFile($sFile, 0, 7) Switch _WinAPI_GetLastError() Case 0 ; ERROR_SUCCESS $iRes = 1 Case 5 ; ERROR_ACCESS_DENIED $iRes = 0 Case Else ; w000t? $iRes = _WinAPI_GetLastError() EndSwitch _WinAPI_CloseHandle($hFile) FileDelete($sFile) Case Else $hFile = _WinAPI_CreateFile($sFile, 2, 7) Switch _WinAPI_GetLastError() Case 0 ; ERROR_SUCCESS $iRes = 1 Case 5 ; ERROR_ACCESS_DENIED $iRes = 0 Case Else ; w000t? $iRes = _WinAPI_GetLastError() EndSwitch _WinAPI_CloseHandle($hFile) EndSwitch Return $iRes EndFunc ;==>_FileWriteAccessible_Method2 Edited February 20, 2013 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
kaotkbliss Posted September 18, 2011 Share Posted September 18, 2011 Does: FileGetAttrib ( "filename" ) Parameters filename Filename (or directory) to check. Return Value Success: Returns a code string representing a files attributes. Failure: Returns "" (blank string) and sets @error to 1. Remarks String returned could contain a combination of these letters "RASHNDOCT": "R" = READONLY "A" = ARCHIVE "S" = SYSTEM "H" = HIDDEN "N" = NORMAL "D" = DIRECTORY "O" = OFFLINE "C" = COMPRESSED (NTFS compression, not ZIP compression) "T" = TEMPORARY Not work? Check the results for an "R" or are you also checking to see if it's in use as well? 010101000110100001101001011100110010000001101001011100110010000 001101101011110010010000001110011011010010110011100100001 My Android cat and mouse gamehttps://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek We're gonna need another Timmy! Link to comment Share on other sites More sharing options...
KaFu Posted September 18, 2011 Author Share Posted September 18, 2011 (edited) Checking the file attributes for the R flag is not enough (see attached update), but of course should be added the the overall function, thanks for that hint ! What I'm looking for is to check whether the OS restricts the access to the file, like UAC does in Vista+ for system files, or files of other users for which the current user only has read but not modify rights. Edit: I skipped the first method setting the Archive attribute, just does not seem right to do this. expandcollapse popup#include <WinAPI.au3> Global $aFiles[5] = [@ScriptDir & "\_test.txt", @ScriptFullPath, @ScriptDir, @SystemDir, @SystemDir & "\user32.dll"] FileWriteLine($aFiles[0], "Test") FileSetAttrib($aFiles[0], "+R") For $i = 0 To 4 ConsoleWrite(_FileWriteAccessible($aFiles[$i]) & @TAB & StringInStr(FileGetAttrib($aFiles[$i]), "R", 2) & @TAB & $aFiles[$i] & @CRLF) Next FileSetAttrib($aFiles[0], "-R") FileDelete($aFiles[0]) Func _FileWriteAccessible($sFile) ; Returns ; 0 = Success, file is writeable and deletable ; -1 = File does not exist ; -2 = Other Error, check @extended ; 1 = File Attribute READONLY is set ; 2 = Access is restricted If Not FileExists($sFile) Then Return -1 If StringInStr(FileGetAttrib($aFiles[$i]), "R", 2) Then Return 1 Local $iSuccess = -2, $iSuccess_Extended = 0, $hFile, $sFile_Buf, $i = 0 Switch StringInStr(FileGetAttrib($sFile), "D", 2) Case True $sFile_Buf = $sFile While FileExists($sFile) $i += 1 $sFile = $sFile_Buf & "\Test_" & $i WEnd $hFile = _WinAPI_CreateFile($sFile, 0, 7) Switch _WinAPI_GetLastError() Case 0 ; ERROR_SUCCESS $iSuccess = 0 Case 5 ; ERROR_ACCESS_DENIED $iSuccess = 2 Case Else ; w000t? $iSuccess = -2 $iSuccess_Extended = _WinAPI_GetLastError() EndSwitch _WinAPI_CloseHandle($hFile) FileDelete($sFile) Case Else $hFile = _WinAPI_CreateFile($sFile, 2, 7) Switch _WinAPI_GetLastError() Case 0 ; ERROR_SUCCESS $iSuccess = 0 Case 5 ; ERROR_ACCESS_DENIED $iSuccess = 2 Case Else ; w000t? $iSuccess = -2 $iSuccess_Extended = _WinAPI_GetLastError() EndSwitch _WinAPI_CloseHandle($hFile) EndSwitch Return SetError(0, $iSuccess_Extended, $iSuccess) EndFunc ;==>_FileWriteAccessible Edited September 18, 2011 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
kaotkbliss Posted September 18, 2011 Share Posted September 18, 2011 Well, there's got to be some list or attribute or something recorded somewhere that tells windows which files and folders are locked due to UAC... 010101000110100001101001011100110010000001101001011100110010000 001101101011110010010000001110011011010010110011100100001 My Android cat and mouse gamehttps://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek We're gonna need another Timmy! Link to comment Share on other sites More sharing options...
KaFu Posted September 18, 2011 Author Share Posted September 18, 2011 Well, I guess this can be checked by accessing and parsing the ACL for each file (the hard way). As I don't need any detailed info I hoped there was some kind of work-around resulting in the same information I really need. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
KaFu Posted September 19, 2011 Author Share Posted September 19, 2011 (edited) Using the _WinAPI_CreateFileEx() function from Yashieds most excellent with the flag $FILE_FLAG_BACKUP_SEMANTICS to access directories seems to do the trick ... expandcollapse popup#include <WinAPIEx.au3> Global $aFiles[6] = [@ScriptDir & "\_test.txt", @ScriptFullPath, @ScriptDir, @SystemDir, @SystemDir & "\user32.dll", "c:\unkown.txt"] FileWriteLine($aFiles[0], "Test") FileSetAttrib($aFiles[0], "+R") For $i = 0 To 5 $iRes = _FileWriteAccessible($aFiles[$i]) ConsoleWrite($iRes & @TAB & @error & @TAB & @extended & @TAB & $aFiles[$i] & @CRLF) Next FileSetAttrib($aFiles[0], "-R") FileDelete($aFiles[0]) Func _FileWriteAccessible($sFile) ; Returns ; 1 = Success, file is writeable and deletable ; 0 = Failure ; @error ; 1 = Access Denied because of lacking access rights ; 2 = File is set "Read Only" by attribute ; 3 = File not found ; 4 = Unknown Api Error, check @extended Local $iSuccess = 0, $iError_Extended = 0, $iError = 0, $hFile ;$hFile = _WinAPI_CreateFileEx($sFile, $OPEN_EXISTING, $FILE_WRITE_DATA, BitOR($FILE_SHARE_DELETE, $FILE_SHARE_READ, $FILE_SHARE_WRITE), $FILE_FLAG_BACKUP_SEMANTICS) $hFile = _WinAPI_CreateFileEx($sFile, 3, 2, 7, 0x02000000) Switch _WinAPI_GetLastError() Case 0 ; ERROR_SUCCESS $iSuccess = 1 Case 5 ; ERROR_ACCESS_DENIED If StringInStr(FileGetAttrib($sFile), "R", 2) Then $iError = 2 Else $iError = 1 EndIf Case 2 ; ERROR_FILE_NOT_FOUND $iError = 3 Case Else ; w000t? $iError = 4 $iError_Extended = _WinAPI_GetLastError() EndSwitch _WinAPI_CloseHandle($hFile) Return SetError($iError, $iError_Extended, $iSuccess) EndFunc ;==>_FileWriteAccessible Edited September 19, 2011 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
VAN0 Posted February 20, 2013 Share Posted February 20, 2013 And old topic, but it doesn't seem to be working on AI 3.3.8.1All files return0 4 6Any ideas? Link to comment Share on other sites More sharing options...
KaFu Posted February 20, 2013 Author Share Posted February 20, 2013 (edited) I can't remember why I've changed it, but in the latest version of SMF the function looks like this, give it a try. #include <WinAPIEx.au3> Global $aFiles[6] = [@ScriptDir & "\_test.txt", @ScriptFullPath, @ScriptDir, @SystemDir, @SystemDir & "\user32.dll", "c:\unkown.txt"] FileWriteLine($aFiles[0], "Test") FileSetAttrib($aFiles[0], "+R") For $i = 0 To 5 $iRes = _FileWriteAccessible($aFiles[$i]) ConsoleWrite($iRes & @TAB & $aFiles[$i] & @CRLF) Next FileSetAttrib($aFiles[0], "-R") FileDelete($aFiles[0]) Func _FileWriteAccessible($sFile) ; Returns ; 1 = Success, file is writeable and deletable ; 2 = Access Denied because of lacking access rights OR because file is open by another process ; 3 = File is set "Read Only" by attribute ; 4 = File not found If Not FileExists("\\?\" & $sFile) Then Return 4 ; File not found If StringInStr(FileGetAttrib("\\?\" & $sFile), "R", 2) Then Return 3 ; Read-Only Flag set Local $hFile = _WinAPI_CreateFileEx("\\?\" & $sFile, 3, 2, 7, 0x02000000) If $hFile = 0 Then Return 2 ; File not accessible, UAC issue? _WinAPI_CloseHandle($hFile) Return 1 ; Success EndFunc ;==>_FileWriteAccessible Edited February 20, 2013 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
guinness Posted February 20, 2013 Share Posted February 20, 2013 Saving this one to my snippets. I've used _WinAPI_IsWritable for determining directories in the past. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
Nikolas92 Posted July 5, 2017 Share Posted July 5, 2017 (edited) Needed something like this recently, but for folders. In case someone else needs it: expandcollapse popup#NoTrayIcon #RequireAdmin #include <Constants.au3> #include <WinAPI.au3> #include <WinAPIFiles.au3> $path = @WindowsDir MsgBox(0, '', _GetTargetState($path)) Func _GetTargetState($FileOrFolder) Local $hFile = 0 If not StringInStr(FileGetAttrib($FileOrFolder), "D") Then $hFile = _WinAPI_CreateFile('\\.\' & $FileOrFolder, 2, 2+4, 2+4) Else _WinAPI_MoveFileEx($FileOrFolder, $FileOrFolder, BitOR($MOVE_FILE_COPY_ALLOWED, $MOVE_FILE_REPLACE_EXISTING)) EndIf $error = _WinAPI_GetLastError() If $hFile <> 0 Then _WinAPI_CloseHandle($hFile) Switch $error Case 0 ; writable Return 'writable' Case 2 ; doesnt exist Return 'not exist' Case 5 If StringInStr(FileGetAttrib($FileOrFolder), 'R') Then ; read only Return 'read only' Else ; denied access Return 'denied access' EndIf Case 32 ; in use Return 'in use' Case Else Return 'unknown' EndSwitch EndFunc Edited July 7, 2017 by Nikolas92 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now