2012-10-14 23 views
8

Vorrei scrivere una funzione che indichi se è possibile scrivere un file o una cartella su un percorso specifico oppure no. Mi piacerebbe farlo SENZA scrivere effettivamente qualsiasi file sul disco. Esiste una funzione WINAPI per questo? Grazie per il vostro aiuto.Ottieni restrizioni file system

+3

Non esiste un'unica funzione che lo farà. Se riesci a navigare nell'API di sicurezza, puoi fare un bel tentativo di controllarlo in anticipo. Di gran lunga il modo più semplice per sapere se è possibile o meno scrivere in qualche posizione è tentare di farlo. –

+4

Ho anche affrontato questo tipo di situazione. per prima cosa ho basato la mia soluzione sul controllo delle autorizzazioni ACL, ma presto ho capito che l'unico modo affidabile è provare e creare un file temporaneo utilizzando l'API 'GetTempFileName' (o qualsiasi altra cosa). – kobik

+2

Bene, inserisco il CD-ROM, quindi il tuo programma, controlla ACL. Hai il diritto di creare i tuoi file - ma il supporto non lo supporta. Idem per i floppy protetti da scrittura, le schede SD, ecc. ACL non è sufficiente. Meglio provare. Imposta i flag di Windows per eliminare automaticamente il file alla chiusura, se hai paura di vivere la spazzatura in caso di errori. –

risposta

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; 

si utilizza questo tipo: se (CheckFileAccess (SysteemGegevens.DFImportPath, FILE_ALL_ACCESS) <> FILE_ALL_ACCESS) poi

con

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

Puoi spiegare cosa fa questa funzione, quali sono i parametri di input e qual è il risultato, per favore? Btw., È necessario verificare i risultati delle chiamate della funzione API di Windows ... – TLama

+0

Questa sembra essere la funzione CanAccessFolder trasferita dalla risposta sopra riportata. –

+1

TLama: Siamo spiacenti, aggiunto. Benjamin: non lo saprei, l'ho preso dalla nostra base di codice –