2
votes

CreateFile allocates 2(!!) handles and CloseHandle closes only one handle when trying to get the low-level access to cd-rom device. OS Windows XP SP3, 5 of 7 tested computers works the same.

When trying to access hdd drive letter CreateFiles works OK and allocate only one handle.

Here is the sample code:

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

What is the possible reason or it's just a microsoft bug?

Upd. The drive name was'nt cut&pasted.. The right string is L"\\.\E:". Bug still persists.

Upd2. Problem solved! See the answer below from me (omega).

4
And how did you verify that it was a leak to begin with?MSN
yes, we disable the possible wrapper software, including antivirus and nero (but not uninstalling it, hmmm...)Svetlana
Leaks detected in the TaskManager, ProcessExplorer, etc.Svetlana
Does it happen if you repeatedly open and close the file via CreateFile, CloseHandle?MSN
More likely a bug in your code than in Microsoft's code (although anything is possible). Please show more code so that we can look for problems on your side.jdigital

4 Answers

5
votes

There seem to be a few bugs in your sample code. If it was in fact copy & pasted from your program, then there would have to be something else going on.

First, you're calling a Unicode function with a MBCS string: the first argument should either be prepended with L or surrounded with _T().

Second, and perhaps more importantly, "\\\\.\\E" is not a valid name. You're missing a trailing colon: for opening a volume, it needs to be of the form \\.\X:, or in your case "\\\\.\\E:".

After fixing those two bugs (the first preventing compilation, the second required to get anything other than INVALID_HANDLE_VALUE back), everything seemed to be working as expected. I used GetProcessHandleCount to count the number of open handles, and it was the same before and after:

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

Commenting out the CloseHandle call causes handleCount to increment as expected, as well.

2
votes

The problem was in the Kaspersky Antivirus software. KAV 6.0 was installed on all tested machines. After removing the software it is needed to clear the UpperFilters and LowerFilters for the cd-driver in the registry:

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

Only after this steps handles stop leaking.. A newest version of the software, Kaspersky Internet Security, also works without leaking.

0
votes

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

0
votes

Have you tried SysInternals' "Handle" tool ? It can show you every handle opened by your program, not just a count. Hence, you'll know which handle remains open.