2

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

Svetlana
  • 1,103
  • 1
  • 14
  • 19
  • And how did you verify that it was a leak to begin with? – MSN Feb 09 '09 at 21:45
  • yes, we disable the possible wrapper software, including antivirus and nero (but not uninstalling it, hmmm...) – Svetlana Feb 09 '09 at 21:49
  • Leaks detected in the TaskManager, ProcessExplorer, etc. – Svetlana Feb 09 '09 at 21:50
  • Does it happen if you repeatedly open and close the file via CreateFile, CloseHandle? – MSN Feb 09 '09 at 21:52
  • 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 Feb 09 '09 at 22:44

4 Answers4

5

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.

Jason Owen
  • 7,200
  • 3
  • 21
  • 25
  • It was'nt Cut&Paste :) IT's all right with the drive name string, I will edit the text in the message now. – Svetlana Feb 10 '09 at 09:15
  • Does the sample program I wrote above leak handles when you compile it? Or is the number of handles open on the first line equal to the number of handles open on the last line? – Jason Owen Feb 10 '09 at 13:13
2

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.

Svetlana
  • 1,103
  • 1
  • 14
  • 19
0

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

lsalamon
  • 7,998
  • 6
  • 50
  • 63
0

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.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • I tried sysinternal's russinovich's tool ProcessExplorer. Here 2 handles also, it's show two handles as two kernel objects. – Svetlana Feb 10 '09 at 14:23