Обрабатывать утечки в WinAPI CreateFile? - PullRequest
2 голосов
/ 10 февраля 2009

CreateFile выделяет 2 (!!) дескриптора, а CloseHandle закрывает только один дескриптор при попытке получить низкоуровневый доступ к устройству cd-rom. ОС Windows XP SP3, 5 из 7 протестированных компьютеров работают одинаково.

При попытке получить доступ к букве жесткого диска CreateFiles работает нормально и выделяет только один дескриптор.

Вот пример кода:

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);

Какова возможная причина или это просто ошибка Microsoft?

Upd. Имя диска не вырезано и не вставлено. Правая строка - L "\\. \ E:". Ошибка все еще сохраняется.

UPD2. Задача решена! Смотрите ответ ниже от меня (омега).

Ответы [ 4 ]

3 голосов
/ 10 февраля 2009

Кажется, в вашем примере кода есть несколько ошибок. Если бы это было на самом деле скопировано и вставлено из вашей программы, тогда должно было бы быть что-то еще.

Сначала вы вызываете функцию Unicode со строкой MBCS: первый аргумент должен начинаться с 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 также увеличивается, как и ожидалось.

2 голосов
/ 10 февраля 2009

Проблема была в программном обеспечении Антивируса Касперского. KAV 6.0 был установлен на все проверенные машины. После удаления программного обеспечения необходимо очистить в реестре UpperFilters и LowerFilters для cd-драйвера:

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

Только после этого действия ручки перестают вытекать .. Новейшая версия программного обеспечения, Kaspersky Internet Security, также работает без утечек.

0 голосов
/ 10 февраля 2009

Вы пробовали инструмент "Ручка" SysInternals? Он может показать вам каждый дескриптор, открытый вашей программой, а не только счет. Следовательно, вы будете знать, какая ручка остается открытой.

0 голосов
/ 10 февраля 2009

Предложение:
Поставьте журнал начала при вызове CreateFileW, это подтвердит, сколько раз оно выполнено;

...