2012-10-14 12 views
8

ファイル/フォルダを特定のパスに書き込むことができるかどうかを示す関数をコーディングしたいと思います。私は実際にディスクにファイルを書き込むことなくそれをしたいと思います。そのためのWINAPI機能はありますか? ありがとうございます。ファイルシステムの制限を取得する

+3

それを行います単一の機能はありませんと、その後

。セキュリティAPIをナビゲートすることができれば、事前にこれを確認することができます。これまでに の場所に書き込むことができるかどうかを確認する最も簡単な方法は、そうしようとすることです。 –

+4

私はこのような状況にも対処しました。最初に私はACL権限のチェックに基づいて解決しましたが、まもなく、実際にGetTempFileName APIを使用して一時ファイルを実際に試して作成することが唯一の信頼できる方法であることに気づきました。 – kobik

+2

さて、私はCD-ROMを挿入し、あなたのプログラムはACLをチェックします。あなたはファイルを作成する権利が与えられますが、メディアはそれをサポートしていません。ライトプロテクトされたフロッピー、SDカードなどの場合も同様です。ACLだけでは不十分です。より良い試み。エラーが発生したときに生きているゴミを恐れている場合は、Windowsのフラグを自動的にファイルを閉じるように設定します。 –

答えて

12

GetFileSecurity()AccessCheck()機能を使用できます。 Aaron Ballmanの記事How to Check Access Rightsを読んでください。彼はCanAccessFolder()機能をあなたが尋ねたことをするために提供しました。

+0

ありがとうございます。それは私が探していたものです! –

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; 

は、あなたはこのように使用します。 場合(CheckFileAccess(SysteemGegevens.DFImportPath、FILE_ALL_ACCESS)<> FILE_ALL_ACCESS)

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

この関数が何をしているのか、入力パラメータは何か、そして結果は何ですか? Btw。Windows API関数呼び出しの結果を確認する必要があります。 – TLama

+0

これは、上記の答えから、移植されたCanAccessFolder関数のようです。 –

+1

TLama:申し訳ありませんが、追加されました。ベンジャミン:私は知らないだろう、私たちのコードベースからそれをつかんだ –

関連する問題