Get FileSystem Restrictions
Asked Answered
L

2

8

I would like to code a function that tells me if it's possible to WRITE a file/folder to a specific path or not. I would like to do that WITHOUT actually writing any file(s) to the disk. Is there a WINAPI function for that? Thank you for your help.

Lamaism answered 14/10, 2012 at 7:24 Comment(5)
There's no single function that will do that. If you can navigate the security API you can make a pretty good go at checking this in advance. By far the easiest way to know whether or not you can write to some location is to attempt to do so.Zonked
I've also dealt with this kind of situation. first I based my solution on checking ACL permissions, but soon I came to realize that the only reliable way is to actually try and create a temp file using GetTempFileName API (or whatever).Argentina
Well, i insert CD-ROM, then your program, checks ACL. You are granted the right to create your files - but the media just does not support it. Ditto for write-protected floppies, SD cards, etc. ACL is just not enough. Better try. Set Windows flags to auto-delete file on close, if you are afraid to live garbage in case of errors.Give
See also How can I use Delphi to test if a Directory is writeable?Argentina
@Argentina I wanted to do the same but without writing a temporary file.Lamaism
C
12

You can use GetFileSecurity() and AccessCheck() functions. Read the Aaron Ballman's article on How to Check Access Rights. He provided the CanAccessFolder() function to do what you asked.

Caty answered 14/10, 2012 at 8:14 Comment(0)
H
8
function CheckFileAccess(const FileName: string; const CheckedAccess: Cardinal): Cardinal;
var Token: THandle;
    Status: LongBool;
    Access: Cardinal;
    SecDescSize: Cardinal;
    PrivSetSize: Cardinal;
    PrivSet: PRIVILEGE_SET;
    Mapping: GENERIC_MAPPING;
    SecDesc: PSECURITY_DESCRIPTOR;
begin
  Result := 0;
  GetFileSecurity(PChar(Filename), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, nil, 0, SecDescSize);
  SecDesc := GetMemory(SecDescSize);

  if GetFileSecurity(PChar(Filename), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, SecDesc, SecDescSize, SecDescSize) then
  begin
    ImpersonateSelf(SecurityImpersonation);
    OpenThreadToken(GetCurrentThread, TOKEN_QUERY, False, Token);
    if Token <> 0 then
    begin
      Mapping.GenericRead := FILE_GENERIC_READ;
      Mapping.GenericWrite := FILE_GENERIC_WRITE;
      Mapping.GenericExecute := FILE_GENERIC_EXECUTE;
      Mapping.GenericAll := FILE_ALL_ACCESS;

      MapGenericMask(Access, Mapping);
      PrivSetSize := SizeOf(PrivSet);
      AccessCheck(SecDesc, Token, CheckedAccess, Mapping, PrivSet, PrivSetSize, Access, Status);
      CloseHandle(Token);
      if Status then
        Result := Access;
    end;
  end;

  FreeMem(SecDesc, SecDescSize);
end;

You use this like: if (CheckFileAccess(SysteemGegevens.DFImportPath, FILE_ALL_ACCESS) <> FILE_ALL_ACCESS) then

with

const
FILE_READ_DATA = $0001;
FILE_WRITE_DATA = $0002;
FILE_APPEND_DATA = $0004;
FILE_READ_EA = $0008;
FILE_WRITE_EA = $0010;
FILE_EXECUTE = $0020;
FILE_READ_ATTRIBUTES = $0080;
FILE_WRITE_ATTRIBUTES = $0100;
FILE_GENERIC_READ = (STANDARD_RIGHTS_READ or FILE_READ_DATA or
FILE_READ_ATTRIBUTES or FILE_READ_EA or SYNCHRONIZE);
FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE or FILE_WRITE_DATA or
FILE_WRITE_ATTRIBUTES or FILE_WRITE_EA or FILE_APPEND_DATA or SYNCHRONIZE);
FILE_GENERIC_EXECUTE = (STANDARD_RIGHTS_EXECUTE or FILE_READ_ATTRIBUTES or
FILE_EXECUTE or SYNCHRONIZE);
FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $1FF;
Haematite answered 15/10, 2012 at 7:15 Comment(4)
Could you explain what this function does, what are the input parameters and what is the result, please ? Btw., you should check results of the Windows API function calls...Sedan
This is seems to be the ported CanAccessFolder function from the answer above.Lamaism
TLama: Sorry, added. Benjamin: I would not know, grabbed it from our code baseHaematite
Hello, I used this function and started having printing related issues: #74229386Bacterin

© 2022 - 2024 — McMap. All rights reserved.