Recent

Author Topic: [SOLVED] Checking if a folder is read only in a TShellTreeView  (Read 2054 times)

petevick

  • Sr. Member
  • ****
  • Posts: 419
[SOLVED] Checking if a folder is read only in a TShellTreeView
« on: January 17, 2024, 06:53:23 pm »
I've cobbeled the following code from google searches, but it doesnt catch known read only folders, it always returns False. Can anyone see what might be wrong.....

Code: Pascal  [Select][+][-]
  1. function CheckIfFolderIsReadOnly(SelectedNode: TTreeNode): Boolean;
  2. var
  3.   FolderPath: String;
  4.   FolderInfo: TSearchRec;
  5. begin
  6.   Result:= True;
  7.   // Get the selected node
  8. //  SelectedNode := ShellTreeView1.Selected;
  9.   if Assigned(SelectedNode) then
  10.   begin
  11.     // Get the folder path from the selected node
  12.     FolderPath := Browser.myTreeView.Path;
  13.     // Check if the folder exists
  14.     if DirectoryExists(FolderPath) then
  15.     begin
  16.       // Check if the folder is read-only
  17.       if FindFirst(FolderPath, faDirectory, FolderInfo) = 0 then
  18.       begin
  19.         if (FolderInfo.Attr and faReadOnly) = faReadOnly then
  20.          Result:= True
  21.         else
  22.          Result:= False;;
  23.         FindClose(FolderInfo);
  24.       end;
  25.     end;
  26.   end;
  27. end;
« Last Edit: January 18, 2024, 12:36:52 pm by petevick »
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.2, FPC 3.2.2

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Checking if a folder is read only in a TShellTreeView
« Reply #1 on: January 17, 2024, 07:48:33 pm »
Your check is wrong. Here is a correct version:
Code: Pascal  [Select][+][-]
  1. uses SysUtils;
  2.  
  3. function IsDirectoryReadOnly(const DirName: string): Boolean;
  4. var
  5.  SR: TSearchRec;
  6. begin
  7.  if FindFirst(DirName, faAnyFile, SR) = 0 then
  8.  begin
  9.  Result := (SR.Attr and faReadOnly) <> 0;
  10.  FindClose(SR);
  11.  end
  12.  else
  13.  Result := False;
  14. end;

This here might help but I do not recommend that approach. It checks if its readonly by creating a test file, on success it aint readonly.
Code: Pascal  [Select][+][-]
  1. uses SysUtils;
  2.  
  3. function IsDirectoryReadOnly(const ADirName: string): Boolean;
  4. var
  5.  TempFile: string;
  6. begin
  7.  TempFile := IncludeTrailingPathDelimiter(ADirName) + 'tempfile';
  8.  try
  9.    AssignFile(TempFile);
  10.    Rewrite(TempFile);
  11.    CloseFile(TempFile);
  12.    DeleteFile(TempFile);
  13.    Result := False;
  14.  except
  15.    Result := True;
  16.  end;
  17. end;
« Last Edit: January 17, 2024, 08:20:53 pm by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

petevick

  • Sr. Member
  • ****
  • Posts: 419
Re: Checking if a folder is read only in a TShellTreeView
« Reply #2 on: January 18, 2024, 08:32:24 am »
Your check is wrong. Here is a correct version:
Code: Pascal  [Select][+][-]
  1. uses SysUtils;
  2.  
  3. function IsDirectoryReadOnly(const DirName: string): Boolean;
  4. var
  5.  SR: TSearchRec;
  6. begin
  7.  if FindFirst(DirName, faAnyFile, SR) = 0 then
  8.  begin
  9.  Result := (SR.Attr and faReadOnly) <> 0;
  10.  FindClose(SR);
  11.  end
  12.  else
  13.  Result := False;
  14. end;
Thanks for the help KodeZwerg. I'm getting a little bit closer I think. A problem with my original code was that Browser.myTreeView.Path has a delimiter at the end. The function is now passed Browser.myTreeView.Path and the last delimiter is removed. But it's still not giving consistent correct results, known read only folders are still returning false. The only folder that returns True is the root folder (in Linux) where obviosly the Node.Text value = ''. The FolderInfo.Attr data seems to be ok except I don't know what the Attr = 48; value indicates for a read only folder.
Revised function below based on your code above....

Code: Pascal  [Select][+][-]
  1. function CheckIfFolderIsReadOnly(FolderPath: String): Boolean;
  2. var
  3.   FolderInfo: TSearchRec;
  4.   SelectedNode: TTreeNode;
  5. begin
  6.   // Get the selected node
  7.   SelectedNode := Browser.myTreeView.Selected;
  8.   if Assigned(SelectedNode) then
  9.   begin
  10.     // remove last delimiter
  11.     LeftStr(FolderPath, (length(FolderPath)-1));
  12.     // Check if the folder exists
  13.     if DirectoryExists(FolderPath) then
  14.     begin
  15.       // Check if the folder is read-only
  16.       if FindFirst(FolderPath, faAnyFile, FolderInfo) = 0 then
  17.       begin
  18.         Result:= (FolderInfo.Attr and faReadOnly) <> 0;
  19.         FindClose(FolderInfo);
  20.       end else
  21.         Result:= False;
  22.     end;
  23.   end;
  24. end;
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.2, FPC 3.2.2

Zvoni

  • Hero Member
  • *****
  • Posts: 3195
Re: Checking if a folder is read only in a TShellTreeView
« Reply #3 on: January 18, 2024, 10:11:29 am »
Code: Pascal  [Select][+][-]
  1. function CheckIfFolderIsReadOnly(FolderPath: String): Boolean;
  2. var
  3.   FolderInfo: TSearchRec;
  4.   SelectedNode: TTreeNode;
  5. begin
  6.   // Get the selected node
  7.   SelectedNode := Browser.myTreeView.Selected;
  8.   if Assigned(SelectedNode) then
  9.   begin
  10.     // remove last delimiter
  11.     LeftStr(FolderPath, (length(FolderPath)-1));
  12.     // Check if the folder exists
  13.     if DirectoryExists(FolderPath) then
  14.     begin
  15.       // Check if the folder is read-only
  16.       if FindFirst(FolderPath, faAnyFile, FolderInfo) = 0 then
  17.       begin
  18.         Result:= (FolderInfo.Attr and faReadOnly) <> 0;
  19.         FindClose(FolderInfo);
  20.       end else
  21.         Result:= False;
  22.     end;
  23.   end;
  24. end;

This looks weird to me
Code: Pascal  [Select][+][-]
  1. Result:= (FolderInfo.Attr and faReadOnly) <> 0;
  2.  

Would have expected
Code: Pascal  [Select][+][-]
  1. Result:= (FolderInfo.Attr and faReadOnly) = faReadOnly;
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

petevick

  • Sr. Member
  • ****
  • Posts: 419
Re: Checking if a folder is read only in a TShellTreeView
« Reply #4 on: January 18, 2024, 10:23:01 am »
Well after all that I came across one of my own posts querying the DirectoryIsWritable() function which as leads to the my revised and simpler function that works (although I do have to try it in Windows yet) I switch the boolean result so it matches TShellTreeView.ReadOnly property......

Code: Pascal  [Select][+][-]
  1. function CheckIfFolderIsReadOnly(FolderPath: String): Boolean;
  2. var
  3.   SelectedNode: TTreeNode;
  4. begin
  5.   // Get the selected node
  6.   SelectedNode := Browser.myTreeView.Selected;
  7.   if Assigned(SelectedNode) then
  8.   begin
  9.     if DirectoryExists(FolderPath) then
  10.     begin
  11.       // Check if the folder is read-only
  12.       Result:= DirectoryIsWritable(FolderPath);
  13.       Result:= not Result;
  14.     end;
  15.   end;
  16. end;
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.2, FPC 3.2.2

wp

  • Hero Member
  • *****
  • Posts: 13270
Re: Checking if a folder is read only in a TShellTreeView
« Reply #5 on: January 18, 2024, 10:25:01 am »
This looks weird to me
Code: Pascal  [Select][+][-]
  1. Result:= (FolderInfo.Attr and faReadOnly) <> 0;
  2.  

Would have expected
Code: Pascal  [Select][+][-]
  1. Result:= (FolderInfo.Attr and faReadOnly) = faReadOnly;
Why? faReadOnly represents a single bit only (faReadOnly   = $00000001). Therefore both statements are correct.

petevick

  • Sr. Member
  • ****
  • Posts: 419
Re: Checking if a folder is read only in a TShellTreeView
« Reply #6 on: January 18, 2024, 10:26:05 am »
..........
Would have expected
Code: Pascal  [Select][+][-]
  1. Result:= (FolderInfo.Attr and faReadOnly) = faReadOnly;
That's what I had orginally which also didn't work.
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.2, FPC 3.2.2

Zvoni

  • Hero Member
  • *****
  • Posts: 3195
Re: Checking if a folder is read only in a TShellTreeView
« Reply #7 on: January 18, 2024, 10:40:41 am »
OK, noticed something "weird" (on Windows):
I declared a Test-Folder to be readonly. OK.
BUT..... This Folder inherits Attributes from its Parent-Folder, and that one removed the ReadOnly-Flag when i was reading it again.....
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Checking if a folder is read only in a TShellTreeView
« Reply #8 on: January 18, 2024, 11:01:10 am »
I am unsure about the problems you encounter but specific on windows i would do it in a similar way
Code: Pascal  [Select][+][-]
  1. var
  2.  attr: Integer;
  3. begin
  4.  attr := FileGetAttr('C:\SomeDirectory');
  5.  if (attr and faReadOnly) <> 0 then
And I always just test if a bit is included (<>0)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

petevick

  • Sr. Member
  • ****
  • Posts: 419
Re: Checking if a folder is read only in a TShellTreeView
« Reply #9 on: January 18, 2024, 12:36:31 pm »
Tested in Windows and works correctly.

Thanks to all for the help  ;)
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.2, FPC 3.2.2

 

TinyPortal © 2005-2018