2012-10-14 11 views
8

Ich möchte eine Funktion, die mir sagt, wenn es möglich ist, eine Datei/Ordner zu einem bestimmten Pfad zu schreiben oder nicht. Ich möchte das tun, OHNE tatsächlich irgendwelche Dateien auf den Datenträger zu schreiben. Gibt es dafür eine WINAPI-Funktion? Vielen Dank für Ihre Hilfe.Get FileSystem Einschränkungen

+3

Es gibt keine einzige Funktion, die das tun wird. Wenn Sie in der Sicherheits-API navigieren können, können Sie dies im Voraus überprüfen. Mit Abstand der einfachste Weg, um zu wissen, ob Sie an einige Ort schreiben können, ist dies zu versuchen. –

+4

Ich habe mich auch mit dieser Art von Situation beschäftigt. Zuerst basierte ich meine Lösung auf ACL-Berechtigungen überprüfen, aber bald erkannte ich, dass die einzige zuverlässige Möglichkeit ist, tatsächlich versuchen, eine temporäre Datei mit 'GetTempFileName' API (oder was auch immer) zu erstellen. – kobik

+2

Nun, ich füge CD-ROM ein, dann überprüft Ihr Programm ACL. Sie haben das Recht, Ihre Dateien zu erstellen - aber die Medien unterstützen das nicht. Dito für schreibgeschützte Disketten, SD-Karten, etc. ACL ist einfach nicht genug. Besser versuchen. Legen Sie Windows-Flags fest, um die Datei beim Schließen automatisch zu löschen, wenn Sie im Falle von Fehlern Angst haben, Müll zu leben. –

Antwort

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; 

Sie verwenden diese wie: if (CheckFileAccess (SysteemGegevens.DFImportPath, FILE_ALL_ACCESS) <> FILE_ALL_ACCESS) dann

mit

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; 
+3

Können Sie erklären, was diese Funktion macht, was sind die Eingabeparameter und was ist das Ergebnis, bitte? Btw., Sollten Sie die Ergebnisse der Windows-API-Funktionsaufrufe überprüfen ... – TLama

+0

Dies ist offenbar die portierte CanAccessFolder-Funktion aus der obigen Antwort. –

+1

TLama: Sorry, hinzugefügt. Benjamin: Ich würde es nicht wissen, ergriff es von unserer Code-Basis –