views:

192

answers:

3

I'm trying to do 'pre-flight checks' by testing a COM port's 'openability' before launching a dialog window which allows the user to do com-porty things.

Here's the code sequence, in outline:

handle = CreateFile("\\\\.\\COM4:", GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);

if (handle != INVALID_HANDLE_VALUE)
{
  CloseHandle(handle);
  DoTheWork("\\\\.\\COM4:");
}
else
{ 
  ShowMessage("I'm sorry Dave, I can't do that"); 
} 

...

void DoTheWork(char * port)
{
  handle = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);
  /// do lots of stuff
  CloseHandle(port);
}

Here's the problem: "DoTheWork" is a tried and tested function, and performs correctly on it's own. It only fails when called immediately after the earlier CreateFile/CloseHandle calls, when the second CreateFile returns E_ACCESSDENIED.

Worse yet, if I step through the code slowly in the debugger, It works just fine.

It seems like I need a Sleep() after the first closeHandle, but that feels like a hack - and i have no way of knowing how long it must be.

+2  A: 

The system takes a bit of time to close the resource. There's probably some arcane way to test whether it's been freed, but I don't know what that is. What I do know is that if you check the registry key:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM

You'll see which serial ports are available without having to open them, which should solve your problem.

Ben M
That shows me which ports are *installed*, but it won't show me which ones are actually openable (ie, not already opened by some other code)
Roddy
A: 

Well, after more trawling, I found this, which relates to Windows CE rather than Win32.

There is a two-second delay after CloseHandle is called before the port is closed and resource are freed.

I guess the same applies to Win32, but I haven't found any documented proof.

Roddy
Its probably related - but part of the reason for the delay under ce was the lack of availability of FlushFileBuffers() on some platforms.
sylvanaar
+1  A: 

Try calling PurgeComm() or FlushFileBuffers() on the handle before closing it.

sylvanaar