1

「クイック削除用に最適化」ポリシーが設定されたループ内のファイルを USB スティックにコピーするバックグラウンド アプリケーションを作成しています。ただし、このプロセスの途中でスティックが取り外された場合 (具体的には、以下の WriteFile() 呼び出しで、ERROR FILE NOT FOUND が返されます)、アプリケーションがハングし、他のアプリケーションからドライブに永久にアクセスできなくなり、PC をシャットダウンできなくなります。ログオフ/再起動など。結果として、Windows Explorer の実行中のすべてのインスタンスもハングします。

スティックが取り外され、上記のエラーが発生した後に行われた CloseHandle() 呼び出しに問題を追跡しました。スティックがなくなったため、CloseHandle() がドライバーのどこかで無期限にブロックされているように見えますか? とにかく、WriteFile() が ERROR FILE NOT FOUND を返す場合、CloseHandle() 呼び出しをスキップするだけで、この問題を回避できました。ただし、これにより別の問題が発生し、ファイルが修復不可能なほど壊れてしまい、それを修正する唯一の方法が chkdsk を使用するか、スティックを再フォーマットすることになります。

これは XP (SP2 および 3) でのみ発生することに注意してください。Vista ではこの問題は発生しないようです。コードのスニペットは次のとおりです。

HANDLE hFile = CreateFile(szFile, 
                          GENERIC_WRITE, 
                          FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
                          NULL,
                          CREATE_ALWAYS,
                          FILE_FLAG_WRITE_THROUGH,
                          NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
    if (!WriteFile(hFile, pBuffer, dwBufferSize, &dwWritten))
    {
        int nLastError = GetLastError();
    }

    // If usb stick is removed during WriteFile(), ERROR_FILE_NOT_FOUND usually      results.
    // If handle is closed at this point then drive is inaccessible.
    // If CloseHandle() is skipped, then file corruption occurs instead
    if (nLastError != ERROR_FILE_NOT_FOUND)
    {
        CloseHandle(hFile);
    }
}

CreateFile() のフラグのほとんどすべての組み合わせを試しましたが、すべて役に立ちませんでした。誰かがこれを以前に見たことがありますか、または発生する2つの問題のいずれかを回避する方法について良いアイデアを持っています. 私が見ているのは、vista で黙って修正されたドライバーの問題ですか?

助けてくれてありがとう。

4

4 に答える 4

2

スティックがなくなったため、CloseHandle() がドライバーのどこかで無期限にブロックされているように見えますか?

合理的に聞こえます。CloseHandle() は最終的にファイル システム IRP を発行し、ノンブロッキング I/O を使用していないため、IRP は同期されますが、実際のファイル システムがファイル システム ドライバーの下から突然消えたように見えます。 IRP が完了することはありません。これは、あなたが詰め込まれていることを意味します-ファイルシステム IRP の発行につながるユーザーモード関数呼び出しは決して返されません。

ノンブロッキング I/O を使用してみてください。これにより、少なくともハングしないという観点からは、この問題を回避できます。IRP は引き続き継承され、ほぼ確実に元に戻ることはないため、リソースの損失などは引き続き発生しますが、少なくともそれをブロックすることはありません。

ところで、「迅速な削除のために最適化する」とは、進行中のキャッシュの量を減らし、おそらくファイルシステムへの書き込み順序に影響を与えて破損の可能性を減らすように設計されていると言えます。書き込み中にファイルシステムが離れた場合にファイルシステムを保持することを意図しているとは思えません!

これによりファイルシステムが強制終了されることに驚かないでください。

于 2009-03-25T17:48:03.580 に答える
1

これはドライバーの問題のようです。

すべてのハンドルをドライバーに解放して、それ自体をクリーンアップし、ウィンドウでアンロードできるようにする必要があります。そうしないと、ドライバーは、デバイスが変更されたにもかかわらず、デバイスに対してまだ責任があると考えます。

ユーザー モードでは、この問題を回避することはできません。

ハンドルを放棄すると、問題が後の段階に移行するだけです (たとえば、プログラムを終了すると、ウィンドウは放棄された開いているハンドルをすべて閉じようとします)。

于 2009-03-25T14:07:11.740 に答える
0

ハングの問題について:書き込み用に別のスレッドを生成し、メインスレッドから書き込みプロセスを監視し、疑わしい時間がかかる場合は書き込みスレッドを中止することができます。言い換えると、書き込みを非同期で実装し、タイムアウトを探します。

于 2009-03-25T11:48:39.123 に答える
0

ハードウェア ドライバーではなく、ファイル システム ドライバーに問題がある可能性はありますか? NTFS を使用すると、問題が解決する場合があります。

于 2009-03-26T10:02:48.807 に答える