Thread: Using CreateFile() to get handle to COM port

  1. #1
    Registered User
    Join Date
    Jun 2012
    Posts
    4

    Post Using CreateFile() to get handle to COM port

    Hi,
    Using the C code outlined below (extract from a larger program) in Visual Studio 2110 express, I am having difficulty using CreateFile to return a valid pointer. It continues to return 0xfffff (the Invalid_Handle_Value).

    I have followed numerous guides on the internet to open COM ports in C in a Windows environment and have followed the syntax exactly, but with no success. Any suggestions why I can only get an invalid pointer would be appreciated.

    Thanks in advance,
    Mr. Whippy.
    (sorry about the formatting - first post - see attached file)
    temp1.c

    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    #include<windows.h>
    #include<conio.h>
    HANDLE hSerialIn = INVALID_HANDLE_VALUE;
    DCB dcbSerialParams = { 0 };
    
    DWORD WINAPI GetLastError(void);
    LPCWSTR lpFileName;
    long lLastError = ERROR_SUCCESS;
    char portIn[16];
    int main(void)
    {
      sprintf(portIn, "COM1");
      lpFileName = (LPCWSTR) portIn;
      printf("lpFileName: %s\n", lpFileName);
      hSerialIn =
          CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    
      if (hSerialIn == INVALID_HANDLE_VALUE) {
        if (GetLastError() == ERROR_FILE_NOT_FOUND) {
          printf("\nError: \nThe system cannot find the file specified (%s)\n", portIn);  //error code 0x02
        }
        else if(GetLastError() == ERROR_INVALID_NAME) {
          printf("\nError: \n%s 'filename, directory name, or volume label syntax is incorrect'\n", portIn);  //error code 0x7B
        }
        else
        {
          printf("\nHandle creation error code: %x\n", GetLastError());
        }
        puts("\t...CreateFile returned an invalid handle value");
      }
      if (!GetCommState(hSerialIn, &dcbSerialParams)) {
        printf("\nError: \ncould not get %s state!\n", portIn);
      }
      CloseHandle(hSerialIn);
      puts("\npress any key to exit...");
      getchar();
      return 1;
    
    }
    Last edited by Salem; 06-12-2012 at 11:02 PM. Reason: demungled the dog-food formatting

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Using the C code outlined below (extract from a larger program) in Visual Studio 2110 express
    Are you telling us that MS is still going 100 years from now, and that you're from the future?

    When pasting code, make sure you "paste as text".


    > lpFileName = (LPCWSTR) portIn;
    Do you know why you're doing this?
    casting does not magically transform your string into the correct format. In particular, newer versions of visual studio default to using UNICODE for strings, whereas you're using plain old ASCII.

    To turn UNICODE off, read this -> visual studio - How do I turn off Unicode in a VC++ project? - Stack Overflow
    That should at least make your program work (assuming nothing else is wrong).

    Longer term, read this -> Unicode and Multibyte Character Set (MBCS) Support
    And start to write things like
    TCHAR portIn = _T("COM1");
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2012
    Posts
    4
    Quote Originally Posted by Salem View Post
    > Using the C code outlined below (extract from a larger program) in Visual Studio 2110 express
    Are you telling us that MS is still going 100 years from now, and that you're from the future?
    Yes! In the future we;ve built time machines specifically for getting help with C code!

    Quote Originally Posted by Salem View Post
    >To turn UNICODE off, read this -> visual studio - How do I turn off Unicode in a VC++ project? - Stack Overflow
    That should at least make your program work (assuming nothing else is wrong).
    Thanks for your help and suggestions, unfortunatly trying to use the CString techniques you mentioned didn't work and neither did turining UNICODE off.

    Any other suggestions for why this might not be working, or just some general coding improvements would be appreciated. (Could this be a C vs. C++ issue? This is a *.c file and I am compiling it as such...)

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    What's your latest code?

    Personally, I would only call getLastError() once
    Code:
    if (hSerialIn == INVALID_HANDLE_VALUE) {
        DWORD err = GetLastError();
        if (err == ERROR_FILE_NOT_FOUND) {
          printf("\nError: \nThe system cannot find the file specified (%s)\n", portIn);  //error code 0x02
        }
        else if(err == ERROR_INVALID_NAME) {
          printf("\nError: \n%s 'filename, directory name, or volume label syntax is incorrect'\n", portIn);  //error code 0x7B
        }
        else
        {
          printf("\nHandle creation error code: %x\n", err);
        }
        puts("\t...CreateFile returned an invalid handle value");
      }
    Which error message are you seeing?


    > (Could this be a C vs. C++ issue? This is a *.c file and I am compiling it as such...)
    Unlikely, it's all down to usage of the Win32 API.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2012
    Posts
    4
    Thanks for all your help.

    I was consistantly getting the 0x02 error code.
    However, using the code below I am able to get a successful result on an older windows XP machine (running a release .exe) - even though it doesn't work on my 64bit windows 7 machine (that I'm developing on).

    Code:
    #include <stdio.h>
    #include <windows.h>
    HANDLE hSerialIn;
    char *pcCommPort = "COM5";
    int main (void)
    {
     hSerialIn = CreateFile(pcCommPort,
      GENERIC_READ | GENERIC_WRITE,
      0,
      0,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      0);
      
     if(hSerialIn==INVALID_HANDLE_VALUE)
     {
      DWORD err = GetLastError(); 
      printf("\nHandle creation error code: %x\n", err);
     }
     else
     {
      puts("SUCCESS!!!");
     }
    
      CloseHandle(hSerialIn);
      
      return 1;
    }

    Also, I completely agree about calling GetLastError() only once =)

    Any ideas why the success of this code varies depending on which PC I use?

    Thanks again!

  6. #6
    Registered User
    Join Date
    Jun 2012
    Posts
    4
    The last example I posted highlights the fact that it is only useful for a const char * that is defined somewhere in the program.

    I was more interested in the case where I could read in a string from an external source and pass that name to the CreateFile() function.

    The following code extract seems to work nicely for doing that (but only on my x32 WinXP machine...)

    Code:
    FILE *logFile, *serialInfo;
     
    char portIn[20];
    char *pPortIn = &portIn;
    int main ( void )
    {
     serialInfo = fopen("config","r") 
     fscanf(serialInfo,"%s",portIn); // read in port values from config file
     fclose(serialInfo);
     hSerialIn = CreateFile(pPortIn,
      GENERIC_READ | GENERIC_WRITE,
      0,
      0,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      0);
     
     if(hSerialIn==INVALID_HANDLE_VALUE)
     {
      DWORD err = GetLastError(); 
      printf("Handle creation error code: %x\n", err)
     }
     
     CloseHandle(hSerialIn);
     
     return 0;
    }
    Hope that might help a specific case for someone...

    Let me know if anyone knows why this won't work on a 64bit Win7 machine...

    Mr. Whippy.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Which is a better practice? (Global handle or finding handle)
    By C_Sparky in forum Windows Programming
    Replies: 4
    Last Post: 12-31-2010, 07:32 PM
  2. Replies: 1
    Last Post: 08-04-2009, 08:57 AM
  3. Using IRP_MJ_CREATE (handle/createFile/access rom drive)
    By Witchfinder in forum C Programming
    Replies: 1
    Last Post: 03-11-2009, 03:07 AM
  4. possible reasons for invalid handle from CreateFile
    By bling in forum Windows Programming
    Replies: 1
    Last Post: 10-01-2008, 08:06 AM
  5. createfile()
    By mr_empty in forum C++ Programming
    Replies: 4
    Last Post: 11-20-2007, 05:50 AM

Tags for this Thread