Createfile can hang opening a serial port. Looking for alternative
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Thread: Createfile can hang opening a serial port. Looking for alternative

  1. #1
    Join Date
    Feb 2014
    Posts
    6

    Createfile can hang opening a serial port. Looking for alternative

    this really has nothing to do with a C++ problem, but I see it as a bug in the API, and I'm looking for an alliterative. I need to deal with serial ports a LOT, and of course the first step in working with a serial port is to open it, with Createfile(). Well I have a laptop her, an old DELL Latitude running Win-XP SR3, which at one time apparently was used with a PCI card driver that mimicked a few serial ports, which has since been uninstalled. However, if my application attempts a CreateFile(), such as...

    Code:
    HANDLE hTmp = CreateFile("\\\\.\\COM2", GENERIC_READ | GENERIC WRITE, 0,0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE ATTRIBUTE_OVERLAPPED, 0);
    I would normally expect the returned handle to be either a valid handle, or == INVALID_HANDLE#_VALUE. But on this machine, opening some ports just cau7ses a HANG, and then there is no shutting the application down, without resorting to the power button!

    Now its not just my app... even HYPERTERM will hang on this machine if I try to open certain serial ports. So what I'm looking for is an alternate way to TEST the ports that are actually available, perhaps by reading the device list (in the hardware manager)?

    I'm reasonably sure the problem is some trace of the uninstalled PCI card device driver that is opening the serial port, because opening already open files can cause a hang too. But like I said, I'm looking for an alternate method. The device manager in this laptop correctly reports all teh good serial ports, so Windows must have some way of "knowing" without freezing itself during startup.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,270

  3. #3
    Join Date
    Feb 2014
    Posts
    6

    Re: Createfile can hang opening a serial port. Looking for alternative

    Thanks Victor! I'll try some of these, and I'll be sure to post whether it solves the problem. One of these methods should suffice to reading whether serial ports are there. And if they report ports that will likely fail, perhaps some of the enumeration data I pull will offer a clue why, and allow for defensive action!

  4. #4
    Join Date
    Feb 2014
    Posts
    6

    Re: Createfile can hang opening a serial port. Looking for alternative

    OK, so a lot of these links speak of this same code block, except the one that references using CreateFile() as a test, which I already know is problematic. First of all, as a point of interest,
    The code to get the com port data in most of these examples fails as written, at least under the XP-SR3 machine I'm working with. It fails, and a subsequent GetLastError() returns a 122, which indicates the buffer size passed (1 byte in these examples) is not sufficient. In fact after the call to GetDefaultCommConfig(), dwSize contains 52, which is actually 2 bytes more than sizeof(COMMCONFIG) returns! So this is another case of Microsoft breaking calls, by increasing the size of structures. Happens all the time though, and I usually find it makes sense to allocate more space than is 'supposedly" needed for a WINDOWS struct. Here's the original...

    Code:
    void DetectComPorts(CStringList& list)
    {
    	for(int i=1; i<=8; i++)	
    	{
    		CString strPort;
    		strPort.Format("COM%d",i);
    	
    		DWORD dwSize = 1;
    		LPCOMMCONFIG lpCC = (LPCOMMCONFIG) new BYTE[1];
    		BOOL ret = GetDefaultCommConfig(strPort, lpCC, &dwSize);
    		delete [] lpCC;	
    
    		lpCC = (LPCOMMCONFIG) new BYTE[dwSize];
    		ret = GetDefaultCommConfig(strPort, lpCC, &dwSize);
    		
    		if(ret)
    			list.AddTail(strPort);
    		
    		delete [] lpCC;
    	}
    }
    Now here's my version. I was pretty sure I was going to need the COMCONFIG info anyway, hence the extra pointer for debugging. Sorry for my "old school "C" style of doing things...
    Code:
    #define MAXPORTS 8
    
    BOOL * tmpsertest(void)
     {
       CString strPort;
       BYTE cc[sizeof(COMMCONFIG] + 50);        // ought to be good for any future size increases
       LPCOMMCONFIG lpCC = (COMMCONFIG)cc; // -> so i can easily examine the contents.
       DWORD dwSize;   
       BOOL ret;
       static BOOL bMap[MAXPORTS + 1] = {0}; // a map of available ports, after call completes
    
       for(int i=1; i <=MAXPORTS ; i++)	
    	{
    	strPort.Format("COM%d", i );
            dwSize = sizeof(cc);   
            ret = GetDefaultCommConfig(strPort, (LPCOMMCONFIG )cc, &dwSize);
            bMap[i] = ret;
            if (!ret) 
               {
    	     DWORD err = GetLastError();
                 // ... see what happened?
    	   }
      	}
      return bMap;
    }
    So anyway, the above works, and returns a pointer to the BOOL static array. The caller can then plug in the COM port number as an index into the map and get a TRUE/FALSE indicator of whether the port exists in the registry. No clue why GetDefaultCommConfig() reports needing a buffer 2 bytes more than the actual structure. probably my V studio 2008 needs an update.

    But the bigger issue is that this still does not solve the original problem, and there may not be a way! Because the above code says that the very serial ports that will cause CreateFile to forever block do in fact exist in the registry! I suppose i can manually delete them. After all, even Hyperterm will choke on these ports! And remeber, it was caused by a product with a bad "uninstall" service, so there may be no way to guard against it. I wish I could see something suspicious in the returned structure, or its included DCB structure, that offers a clue that it is a ghost port that will hang the system if touched. But so far I don't see a single suspicious thing!

  5. #5
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,760

    Re: Createfile can hang opening a serial port. Looking for alternative

    ideally you want to fix the problem so the opening doesn't hang. This could be part of a badly written driver that's still installed, if so, there's probably very little you can do other than not using those com ports.

    You can try to delete/uninstall the offending ports and the old IO card in the Device manager of the control panel then allow windows to autodetect the actual com ports. I have seen some hard-persisting driver issues that needed a reformat and reinstall of windows to fix though.

  6. #6
    Join Date
    Feb 2014
    Posts
    6

    Re: Createfile can hang opening a serial port. Looking for alternative

    Thanks OReuben.

    It is certainly a driver issue, and the only reason I'm bothering with it is because the PCI card that causes the issue was needed by a lot of my work colleagues, who also need my applications. Note that even before I had uninstalled the card product, trying to open its "simulated" ports by any application other than the one that came with the card would be fatal. It just disturbs me that after all this time the API for serial ports is still broken, and that there is no way for the application to really test for these wayward ports.

    Well one thing I have done, I've implemented a command line flag to allow the user to block offending ports from ever being touched by the application. This way, by setting up a shortcut to the app, I can pass on my "TARGET" line, so that known problem ports won't hang the app in the future.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center