4

ユーザーがデバイスをイジェクトするのを妨げHANDLEに、一部のデバイスのファイル* にアクセスするにはどうすればよいですか?

私が考えることができる最も自由なアクセス権、つまりアクセス権と共有権限で呼び出してCreateFile(さらには) しようとしましたが、それでも機能しません。NtCreateFileFILE_READ_ATTRIBUTESFILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE

( FileTestは、プログラムを作成せずにこれをテストするための優れたツールです。)


*アップデート:

(ファイルだけでなく)ボリュームまたはドライブへのハンドルでも機能するソリューションが本当に好きです-つまり、 または. しかし、そのような解決策がない場合は、ファイルへのハンドルも役立ちます。\\.\D:\\.\PhysicalDrive0

4

2 に答える 2

2

ボリュームがマウントされている間にファイル ハンドルを取得するのは簡単なことです。

ボリュームが強制的にマウント解除されるとどうなりますか? すべてのファイル ハンドルが無効になります。それらを使用しようとすると、エラーが返されます。

これらのコード スニペットは、ボリュームを強制的にマウント解除して、後続のコードがボリュームに対して直接 i/o を実行できるようにします。これは、私が数年前に書いたディスク クリーナー ユーティリティ (大量消費者向け製品) からの抜粋です。

char    fn [20];

sprintf (fn, "\\\\.\\%s:", vol -> GetVolName ());
vol_lock_handle = CreateFile (fn, GENERIC_READ,
                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                OPEN_EXISTING,
                FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS,
                NULL);

fprintf (stderr,
 "Warning:  volume dismount will disrupt or kill all processes with open files!\n"
 "Before confirming, verify no critical processes have open files on volume %s:\n"
 "   Are you sure you want to dismount this volume? ('YES' to proceed)? ",
         g_vol -> GetVolName ());

char    buf [30];
if (!fgets (buf, sizeof buf, stdin)  ||  stricmp (buf, "yes\n"))
{
    fprintf (stderr, " Volume dismount not confirmed--canceled.\n");
    continue;
}
DWORD   status;
if (!DeviceIoControl (vol_lock_handle, FSCTL_DISMOUNT_VOLUME,
                        NULL, 0, NULL, 0, &status, NULL))
{
    DWORD err = GetLastError ();
    fprintf (stderr, "Error %d attempting to dismount volume: %s\n",
            err, w32errtxt (err));
}

私は、このコードがいかに間違っているかを完全に認識しています。マウント解除のために GENERIC_READ ハンドルが取得され、ボリューム ロックが取得されてから書き込まれます。できます!

于 2012-07-02T05:46:41.730 に答える
2

それはいけません。

ただし、できることは、デバイスの取り出しメッセージを監視してから、持っているすべてのハンドルを閉じることです。

デバイス イベント (MSDN)

于 2012-07-02T08:01:03.780 に答える