Hello,
I am doing embedded system programming. i want to read data from device through the COM1 port.

I have already a software that for access the device through the COM1 port and generate data for the device. I wrote a program in c++ that could open the port and waiting for data to read. But problem is that, when i run two programs, it will conflict to open port. i could able to solve the problem. But when i read data from the port, my program could not read because of "hPort" is INVALID. Another program opens the COM1 port so that it is INVALID. My program just skip to open the port. please help me, how can i read data from COM port. See my code bellow (for read data).

// Specify a set of events to be monitored for the port.
SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

while (hPort != INVALID_HANDLE_VALUE)
{
cout<<"Successfully open COM1 port!!!" <<endl <<"Waiting for Events...";
// Wait for an event to occur for the port.
WaitCommEvent (hPort, &dwCommModemStatus, 0);

// Re-specify the set of events to be monitored for the port.
SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);

if (dwCommModemStatus & EV_RXCHAR)
{
// Loop for waiting for the data.
do
{
// Read the data from the serial port.
ReadFile (hPort, &Byte, 1, &dwBytesTransferred, 0);

// Display the data read.
if (dwBytesTransferred == 1)
ProcessChar (Byte);

} while (dwBytesTransferred == 1);
}
}

Thanks in advance.

Dani AI

Generated

Root cause and quick checklist (for , building on ’s pointer)

  • When CreateFile returns INVALID_HANDLE_VALUE, inspect the error with GetLastError. The most common results are a sharing/permission error (port already opened exclusively) or “device not present.” The posted code prints “hPort INVALID” but never calls GetLastError, and later calls SetCommMask/WaitCommEvent even when the handle is invalid — that must be fixed.
  • Move all serial operations (SetCommMask, WaitCommEvent, ReadFile, CloseHandle) inside the block that runs only after a successful CreateFile. Do not call API functions with an invalid handle.

Safer open pattern (only an example — does not replicate the forum code)

HANDLE h = CreateFile("\\\\.\\COM1", GENERIC_READ,
    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED, NULL);
if (h == INVALID_HANDLE_VALUE) {
    DWORD e = GetLastError(); // inspect ERROR_ACCESS_DENIED / ERROR_SHARING_VIOLATION etc.
}
  • Using the \\\\.\\COM1 prefix and opening with appropriate share flags and/or FILE_FLAG_OVERLAPPED helps in many scenarios but does not force another process to allow sharing. If the other program opened COM1 exclusively, CreateFile will still fail.

Options when the port is already held by another app

  • If both programs are under control: make one process own the COM port and expose data via IPC (named pipe, local TCP, or a simple server). This is the most reliable approach.
  • If the other program cannot be changed: use a virtual serial splitter/monitor (com0com / commercial serial splitters or a serial port monitor) or a hardware-level splitter/buffer. Each approach has tradeoffs; hardware splitters require correct RS‑232 buffering to avoid contention.
  • For debugging: use Process Explorer / Sysinternals Handle to find which process holds COM1.

Other concrete fixes/improvements

  • Check all API return values (GetCommState, SetCommState, SetCommTimeouts, SetCommMask, ReadFile, WaitCommEvent) and call GetLastError on failure.
  • Fix DCB field inconsistencies (for example, don’t set fParity = TRUE while Parity = NOPARITY).
  • Call PurgeComm/ClearCommError on errors, and only CloseHandle when the handle is valid.
  • Consider overlapped I/O or proper timeouts to avoid blocking loops.

These changes address the immediate INVALID_HANDLE_VALUE behavior and make the reader’s code robust whether the port is free or currently owned by another application.

Recommended Answers

All 2 Replies

Look at this link -
Use code tags to post your source code.

Thanks. But the link does not help me lot. Please see my full code:

#include <windows.h>
#include <iostream>
#include <string>
//#include <fstream>

using namespace std;
DWORD dwError;
extern HWND hMainWnd;

unsigned char buffer[255] = {0};
int nextin = 0; // next spot to add a new charcter

void ProcessChar(unsigned char c)
{
    if( nextin < sizeof(buffer)) // make sure there's room for the char
       buffer[nextin++] = c;
}


int main(){



// Open the serial port.
HANDLE hPort = CreateFile (TEXT("COM1"), // Pointer to the name of the port
                      GENERIC_READ | GENERIC_WRITE,
                                    // Access (read-write) mode
                      0,            // Share mode
                      NULL,         // Pointer to the security attribute
                      OPEN_EXISTING,// How to open the serial port
                      0,            // Port attributes
                      NULL);        // Handle to port with attribute to copy

if(hPort != INVALID_HANDLE_VALUE) {
    cout<<"hPort Not INVALID" <<endl;

DCB PortDCB;

// Initialize the DCBlength member. 
PortDCB.DCBlength = sizeof (DCB); 

// Get the default port setting information.
GetCommState (hPort, &PortDCB);

// Change the DCB structure settings.
PortDCB.BaudRate = 9600;              // Current baud 
PortDCB.fBinary = TRUE;               // Binary mode; no EOF check 
PortDCB.fParity = TRUE;               // Enable parity checking 
PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control 
PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control 
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; 
                                      // DTR flow control type 
PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity 
PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx 
PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control 
PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control 
PortDCB.fErrorChar = FALSE;           // Disable error replacement 
PortDCB.fNull = FALSE;                // Disable null stripping 
PortDCB.fRtsControl = RTS_CONTROL_ENABLE; 
                                      // RTS flow control 
PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on 
                                      // error
PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8 
PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space 
PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2 

// Configure the port according to the specifications of the DCB 
// structure.
if (!SetCommState (hPort, &PortDCB))
{
  // Could not configure the serial port.

/*
  dwError = GetLastError ();
  MessageBox (hMainWnd, TEXT("Unable to configure the serial port"), 
              TEXT("Error"), MB_OK);
*/
    cout<<"SetCommState failed" <<endl;
  return FALSE;
}



// Retrieve the timeout parameters for all read and write operations on the port. 
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (hPort, &CommTimeouts);

// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = 100;  
CommTimeouts.ReadTotalTimeoutMultiplier = 100;  
CommTimeouts.ReadTotalTimeoutConstant = 100;    
CommTimeouts.WriteTotalTimeoutMultiplier = 100;  
CommTimeouts.WriteTotalTimeoutConstant = 100;    

// Set the timeout parameters for all read and write operations on the port. 
if (!SetCommTimeouts (hPort, &CommTimeouts))
{
  // Could not set the timeout parameters.
/*  MessageBox (hMainWnd, TEXT("Unable to set the timeout parameters"), 
              TEXT("Error"), MB_OK);
  dwError = GetLastError ();
*/
    cout<<"SetCommTimeouts failed" <<endl;
  return FALSE;
}
}
else
cout<< "hPort INVALID" <<endl; // This is the Problem. 


BYTE Byte;
DWORD dwBytesTransferred;
DWORD dwCommModemStatus;

// Specify a set of events to be monitored for the port.
SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

while (hPort != INVALID_HANDLE_VALUE) // So that this condition does not satisfy.
{

  // Wait for an event to occur for the port.
  WaitCommEvent (hPort, &dwCommModemStatus, 0);

  // Re-specify the set of events to be monitored for the port.
  SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);

  if (dwCommModemStatus & EV_RXCHAR) 
  {
    // Loop for waiting for the data.
    do 
    {
      // Read the data from the serial port.
      ReadFile (hPort, &Byte, 1, &dwBytesTransferred, 0);

      // Display the data read.
      if (dwBytesTransferred == 1)
      ProcessChar (Byte);

    } while (dwBytesTransferred == 1);
  }
}

CloseHandle(hPort);


}

Please focus on the last part of my code.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.