2

CreateFile 分配 2(!!) 个句柄,而 CloseHandle 在尝试获得对 cd-rom 设备的低级访问时仅关闭一个句柄。操作系统 Windows XP SP3,7 台测试计算机中有 5 台运行相同。

当尝试访问硬盘驱动器号时,CreateFiles 工作正常并且只分配一个句柄。

这是示例代码:

HANDLE m_driveHandle = CreateFileW("\\\\.\\E", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
关闭句柄(m_driveHandle);

可能的原因是什么,或者它只是一个微软的错误?

更新。驱动器名称没有剪切和粘贴。正确的字符串是 L"\\.\E:"。错误仍然存​​在。

更新2。问题解决了!请参阅下面的我(欧米茄)的答案。

4

4 回答 4

5

您的示例代码中似乎存在一些错误。如果它实际上是从您的程序中复制和粘贴的,那么肯定会有其他事情发生。

首先,您使用 MBCS 字符串调用 Unicode 函数:第一个参数应该L_T().

其次,也许更重要的是,"\\\\.\\E"它不是一个有效的名称。您缺少一个尾随冒号:要打开一个卷,它需要是 形式\\.\X:,或者在您的情况下是"\\\\.\\E:"

在修复了这两个错误之后(第一个阻止编译,第二个需要获取除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 回答
2

问题出在卡巴斯基反病毒软件中。KAV 6.0 安装在所有测试机器上。删除软件后,需要清除注册表中 cd-driver 的 UpperFilters 和 LowerFilters:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class{4D36E965-E325-11CE-BFC1-08002BE10318}

只有在此步骤处理停止泄漏之后。最新版本的软件卡巴斯基安全软件也可以在不泄漏的情况下工作。

于 2009-02-10T16:46:14.210 回答
0

您是否尝试过 SysInternals 的“Handle”工具?它可以显示程序打开的每个句柄,而不仅仅是计数。因此,您将知道哪个句柄保持打开状态。

于 2009-02-10T14:02:43.120 回答
0

Suggestion:
Put log begin at call CreateFileW, this confirm how many times it is executed;

于 2009-02-10T01:08:54.563 回答