2

CreateFileは2(!!)ハンドルを割り当て、CloseHandleはcd-romデバイスへの低レベルアクセスを取得しようとしたときに1つのハンドルのみを閉じます。OS Windows XP SP3、7台のテスト済みコンピューターのうち5台は同じように動作します。

hddドライブ文字にアクセスしようとすると、CreateFilesは正常に機能し、ハンドルを1つだけ割り当てます。

サンプルコードは次のとおりです。

HANDLE m_driveHandle = CreateFileW("\\\\。\\E"、GENERIC_READ | GENERIC_WRITE、FILE_SHARE_READ | FILE_SHARE_WRITE、NULL、OPEN_EXISTING、FILE_ATTRIBUTE_NORMAL、NULL);
CloseHandle(m_driveHandle);

考えられる理由は何ですか、それとも単なるマイクロソフトのバグですか?

更新 ドライブ名が「切り取られて貼り付けられていません。正しい文字列はL"\\。\E:"です。バグはまだ残っています。

Upd2。問題が解決しました!私(オメガ)からの以下の答えを参照してください。

4

4 に答える 4

5

サンプルコードにはいくつかのバグがあるようです。それが実際にあなたのプログラムからコピー&ペーストされた場合、何か他のことが起こっている必要があります。

まず、MBCS文字列を使用してUnicode関数を呼び出します。最初の引数は、先頭に。を付けるか、でL囲む必要があり_T()ます。

第二に、そしておそらくもっと重要なことに"\\\\.\\E"、有効な名前ではありません。末尾のコロンがありません。ボリュームを開くには、の形式\\.\X:である必要があります。あなたの場合は"\\\\.\\E:"

これらの2つのバグ(最初のバグはコンパイルを妨げ、2番目のバグは元に戻す以外のものを取得する必要がありINVALID_HANDLE_VALUEます)を修正した後、すべてが期待どおりに機能しているように見えました。GetProcessHandleCountを使用して開いているハンドルの数をカウントしましたが、前後で同じでした。

HANDLE m_driveHandle = NULL;
HANDLE m_process = GetCurrentProcess();
DWORD handleCount;
GetProcessHandleCount(m_process, &handleCount);
cout << "Currently held handles: " << handleCount << endl;

for (int i = 0; i < 10; ++i)    {
    m_driveHandle = CreateFileW(L"\\\\.\\E:",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );
    if (INVALID_HANDLE_VALUE == m_driveHandle)  {
        cout << "Invalid handle" << endl;
    }   else    {
        CloseHandle(m_driveHandle);
    }

    GetProcessHandleCount(m_process, &handleCount);
    cout << "Currently held handles: " << handleCount << endl;
}

CloseHandle呼び出しをコメントアウトすると、handleCountも期待どおりにインクリメントされます。

于 2009-02-10T06:40:27.467 に答える
0

SysInternals の「Handle」ツールを試しましたか? カウントだけでなく、プログラムによって開かれたすべてのハンドルを表示できます。したがって、どのハンドルが開いたままかがわかります。

于 2009-02-10T14:02:43.120 に答える
0

提案:
CreateFileW の呼び出しでログを開始します。これにより、実行回数が確認されます。

于 2009-02-10T01:08:54.563 に答える