title: Passive Monitoring Serial Port in Windows using C
body: <p>I am a noob at serial programming. I am trying to code a passive monitor in C that displays to screen whatever is written to or read from a COM port. Most of the code, that I have seen actually reads from or writes to the COM Port.</p>
  
  <p>I have tried to read from a COM port that is transmitting and receive Modbus traffic but I get no readings. I am using a com0com serial port emulator. Only time the code works is if I actually read from the other port that the COM port is paired with.</p>
  
  <p>I am trying to mimic the Serial Port Monitor application. So far it is not working. Kindly assist.</p>
  
  <p>Thanks.</p>
  
  <p>Below is the code for the COM read:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;windows.h&gt;
  void setupPort(HANDLE * handle, char * portName);
  void readFromPort(HANDLE * handle);
  
  int main()
  {
      HANDLE first_port;
      char * first_port_name = "COM3";
      setupPort(&amp;first_port, first_port_name);
      readFromPort(&amp;first_port);
  
  
  
  
      return 0;
  }
  
  void setupPort(HANDLE * handle, char * portName)
  {
      BOOL status;
      *handle = CreateFile(portName,            //port name
                           GENERIC_READ | GENERIC_WRITE, //Read/Write
                           0,            // No Sharing
                           NULL,         // No Security
                           OPEN_EXISTING,// Open existing port only
                           0,            // Non Overlapped I/O
                           NULL);        // Null for Comm Devices
  
  
      if (handle == INVALID_HANDLE_VALUE)
      {
          printf("\n%s could not be opened\n", portName);
      }
      else
      {
          printf("\n%s successfully opened.\n", portName);
      }
  
      DCB dcbSerialParams = { 0 };                         // Initializing DCB structure
      dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
  
      status = GetCommState(*handle, &amp;dcbSerialParams);      //retreives  the current settings
  
      if (status == FALSE)
          printf("\n    Error! in GetCommState()");
  
      dcbSerialParams.BaudRate = CBR_9600;      // Setting BaudRate = 9600
      dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
      dcbSerialParams.StopBits = ONESTOPBIT;    // Setting StopBits = 1
      dcbSerialParams.Parity = NOPARITY;        // Setting Parity = None
  
      status = SetCommState(*handle, &amp;dcbSerialParams);  //Configuring the port according to settings in DCB
  
      if (status == FALSE)
      {
          printf("\n    Error! in Setting DCB Structure");
      }
      else //If Successful display the contents of the DCB Structure
      {
          printf("\n\n    Setting DCB Structure Successful\n");
          printf("\n       Baudrate = %d", dcbSerialParams.BaudRate);
          printf("\n       ByteSize = %d", dcbSerialParams.ByteSize);
          printf("\n       StopBits = %d", dcbSerialParams.StopBits);
          printf("\n       Parity   = %d", dcbSerialParams.Parity);
      }
  
      /*------------------------------------ Setting Timeouts --------------------------------------------------*/
  
      COMMTIMEOUTS timeouts = { 0 };
      timeouts.ReadIntervalTimeout         = 50;
      timeouts.ReadTotalTimeoutConstant    = 50;
      timeouts.ReadTotalTimeoutMultiplier  = 10;
      timeouts.WriteTotalTimeoutConstant   = 50;
      timeouts.WriteTotalTimeoutMultiplier = 10;
  
      if (SetCommTimeouts(*handle, &amp;timeouts) == FALSE)
          printf("\n\n    Error! in Setting Time Outs");
      else
          printf("\n\n    Setting Serial Port Timeouts Successful");
  
      /*------------------------------------ Setting Receive Mask ----------------------------------------------*/
  
      status = SetCommMask(*handle, EV_RXCHAR); //Configure Windows to Monitor the serial device for Character Reception
  
      if (status == FALSE)
          printf("\n\n    Error! in Setting CommMask");
      else
          printf("\n\n    Setting CommMask successful");
  }
  
  void readFromPort(HANDLE * handle)
  {
      BOOL status;
      DWORD dwEventMask;                     // Event mask to trigger
      char  TempChar;                        // Temporary Character
      char  SerialBuffer[256];               // Buffer Containing Rxed Data
      DWORD NoBytesRead;                     // Bytes read by ReadFile()
      int i = 0;
  
      /*------------------------------------ Setting WaitComm() Event   ----------------------------------------*/
  
      while(TRUE)
      {
          printf("\n\n    Waiting for Data Reception");
  
          status = TRUE; //Wait for the character to be received
  
          /*-------------------------- Program will Wait here till a Character is received ------------------------*/
  
          if (status == FALSE)
          {
              printf("\n    Error! in Setting WaitCommEvent()");
          }
          else //If  WaitCommEvent()==True Read the RXed data using ReadFile();
          {
              printf("\n\n    Characters Received\n");
              do
              {
                  status = ReadFile(*handle, &amp;TempChar, sizeof(TempChar), &amp;NoBytesRead, NULL);
                  SerialBuffer[i] = TempChar;
                  i++;
              }
              while (NoBytesRead &gt; 0);
  
              /*------------Printing the RXed String to Console----------------------*/
  
              printf("\n\n    ");
              int j =0;
              for (j = 0; j &lt; i-1; j++)       // j &lt; i-1 to remove the dupliated last character
              {
                  printf("%02X", (unsigned int)(unsigned char)SerialBuffer[j]);
              }
              i=0;
  
          }
  
          //CloseHandle(*handle);//Closing the Serial Port
          printf("\n +==========================================+\n");
      }
  
  }
  </code></pre>