When I connect my embedded device to my system, I am running my program which will write to the port my embedded is connect and it prints the reply to console.
When I connect my device and run this program it is not giving any output.
But when I connect my device and use PUTTY to send some commands first and then run my program it is working.
Maybe there is a problem in the way I am starting communication?
My source code is:
#include "stdafx.h"
#include <iostream>
//#include <windows.h>
#include <afx.h>
int main()
{
using namespace std;
int i=0;
// cout << "Hello world!" << endl;
HANDLE hSerial;
hSerial = CreateFile("COM5",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hSerial==INVALID_HANDLE_VALUE)
{
if(GetLastError()==ERROR_FILE_NOT_FOUND)
{
// TRACE("serial port does not exist for reading\n");
//serial port does not exist. Inform user.
}
// TRACE("some other error,serial port does not exist for reading\n");
//some other error occurred. Inform user.
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams))
{
// TRACE("error getting state for reading\n");
//error getting state
}
dcbSerialParams.BaudRate=9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
if(!SetCommState(hSerial, &dcbSerialParams))
{
//TRACE("error setting state for reading\n");
//error setting serial port state
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;
if(!SetCommTimeouts(hSerial, &timeouts))
{
// TRACE("some error occured for reading\n");
//error occureed. Inform user
}
int n=100,n1=100;
char szBuff[100];
DWORD dwBytesRead = 0;
char szBuff1[100];
DWORD dwByteswrote = 0;
memset(szBuff1,0,100);
memcpy(szBuff1,"LIST\r",5);
if(!WriteFile(hSerial, szBuff1,5, &dwByteswrote, NULL))
{
cout << "error writing" ;
}
cout << szBuff1 << endl;
cout << dwByteswrote << endl;
while(1)
{
if(!ReadFile(hSerial, szBuff, n1, &dwBytesRead, NULL))
{
cout << "error reading";
break;
}
else
{
cout << dwBytesRead << endl;
szBuff[dwBytesRead]='\0';
if(dwBytesRead>0)
{
cout << (szBuff);
break;
}
}
}
cin >> i;
}
Try this... you will probably need to do the code for exceptions (ex: if the response is bigger than 2024)
bool SendModemATCommand(const string &strCommand, int iModemPort, string &strRetValue)
{
bool bRetValue = false;
strRetValue = "";
char cBuffer[2024];
HANDLE hCom = NULL;
char cComPort[64];
sprintf_s(cComPort,"\\\\.\\COM%d", iModemPort);
hCom = CreateFile( cComPort,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (hCom != INVALID_HANDLE_VALUE)
{
COMMTIMEOUTS comTimeOuts;
comTimeOuts.ReadIntervalTimeout = MAXDWORD;
comTimeOuts.ReadTotalTimeoutMultiplier = MAXDWORD;
comTimeOuts.ReadTotalTimeoutConstant = 0;//MAXDWORD;
comTimeOuts.WriteTotalTimeoutMultiplier = 0;
comTimeOuts.WriteTotalTimeoutConstant = 0;
if(SetCommTimeouts(hCom, &comTimeOuts))
{
DCB dcb;
dcb.DCBlength = sizeof(DCB);
if(GetCommState(hCom, &dcb))
{
DWORD dwBytesWritten = 0;
DWORD dwBytesRead = 0;
DWORD dwBytesTotal = 0;
if( WriteFile(hCom, strCommand.c_str(), (int)strCommand.size(), &dwBytesWritten, NULL) )
{
if(dwBytesWritten == strCommand.size())
{
dwBytesRead = 0;
DWORD tickStart = GetTickCount();
bool bTimeOut = false;
while(true)
{
while(ReadFile(hCom, cBuffer + dwBytesTotal, 1, &dwBytesRead, NULL))
{
if(dwBytesRead == 0 && dwBytesTotal != dwBytesWritten)
break;
dwBytesTotal += dwBytesRead;
}
if ( dwBytesTotal == 0 )
{
// timeout
if ( GetTickCount() - tickStart > 10000) // 10 Seconds
{
bTimeOut = true;
break;
}
}
else
break;
}
cBuffer[dwBytesTotal] = '\0';
strRetValue = cBuffer;
if(bTimeOut)
strRetValue = "Timed out:" + strCommand;
else
bRetValue = true;
}
}
}
}
CloseHandle(hCom);
}
return bRetValue;
}
Most likely the problem is with your initialization.
I recall having this type of trouble before and Com Timeouts structure was particularly troublesome.
I suggest you get a null modem cable from COM5 to another port on the machine (if you have one), or to another computer. Then use a terminal program to open up the other port and see you can see the "List" command coming through when you run the program. If not then it's very likely to be related to the way you are initializing & opening the com port.
This link may prove useful. Just strip out the Afx stuff and look particularly at the initialization.
http://www.codeproject.com/KB/system/chaiyasit_t.aspx
One other suggestion, you only send List once. If the device is not already plugged in and ready, nothing will happen. Maybe it should keep sending the list command until it gets a
Response.
Also, do you need "List\r\n" or just "List\r"? What is the other ends expecting?
Related
I'm working on a application that reads data on a serial port. Various messages can be sent over this serial port in a short period of time, and the thread that reads incoming data must identify what type of message it reads when the ReadFile operation completes. I'm using an overlapped structure and I want messages to be read one by one.
My problem is that the ReadFile operation often fills the buffer with multiple messages and I can't find values of com timeouts that prevent this from hapening. I suspect that reading operation doesn't complete when two messages are received back to back, which is seen from the reading thread as a single message as there is still data on the serial port when the first message is complete.
I'm observing the same phenomenon using a non-overlapped structure.
I'm using a serial com, configured as followed:
DCB configPort = { 0 };
COMMTIMEOUTS timeouts;
this->hDevice = CreateFileA(
this->portReady,
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (this->hDevice == INVALID_HANDLE_VALUE) {
std::cout << "INVALID HANDLE" << std::endl;
return 0;
}
OvReception.Offset = 0;
OvReception.OffsetHigh = 0;
OvReception.hEvent = ::CreateEvent(NULL, FALSE, FALSE, _T(""));
configPort.DCBlength = sizeof(DCB);
configPort.BaudRate = CBR_38400;
configPort.StopBits = ONESTOPBIT;
configPort.Parity = EVENPARITY;
configPort.ByteSize = 8;
configPort.fRtsControl = RTS_CONTROL_DISABLE;
configPort.fAbortOnError = 0;
configPort.XonLim = 800;
configPort.XoffLim = 2000;
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommState(this->hDevice, &configPort)) {
CloseHandle(this->hDevice);
return 0;
}
if (!SetCommTimeouts(this->hDevice, &timeouts)) {
CloseHandle(this->hDevice);
return 0;
}
And I read incoming data using :
bool readState = false;
char incomingMessage[512] = {0};
DWORD bytesRead = 0;
memset(incomingMessage, 0, sizeof(incomingMessage));
while (this->threadRunning) {
readState = ReadFile(
this->comSerie.hDevice,
incomingMessage,
sizeof(incomingMessage),
NULL,
&this->comSerie.OvReception);
if (::GetLastError() == ERROR_IO_PENDING)
{
::GetOverlappedResult(this->comSerie.hDevice, &this->comSerie.OvReception, &bytesRead, TRUE);
}
//NO ERRORS OBSERVED
std::cout << "ERROR" << std::endl;
std::cout << GetLastError() << std::endl;
std::cout << "Message received" << std::endl;
std::cout << incomingMessage<< std::endl;
switch(ReceivedMessageType(incomingMessage)){
//............ DO SOMETHING
}
//Clean buffer
memset(incomingMessage, 0, sizeof(incomingMessage));
}
I configured the bwait parameter to TRUE in the GetOverlappedResult so that it doesn't return before the write operation is completed.
I do not observe any error return by GetLastError().
I've also tried using WaitForSingleObject function, the issue was the same.
Am I missing something?
Thanks for the help
I have a measurment device and want to make a series of measurments and store them to a file.
For this I need to read out the com port properly. All I get back with this code is some weird signs.
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
int main() {
// opening the serial port
HANDLE hSerial;
fprintf(stderr, "Opening serial port...");
hSerial = CreateFile("\\\\.\\COM2",
GENERIC_READ | GENERIC_WRITE, 0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Error\n");
CloseHandle(hSerial);
return 1;
} else
fprintf(stderr, "OK\n");
// settings to communicate with device
DCB dcbSerialParams;
ZeroMemory(&dcbSerialParams, sizeof(dcbSerialParams));
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
//error getting state
fprintf(stderr,"error getting state ... ");
}
dcbSerialParams.BaudRate = 9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
//error setting state
fprintf(stderr,"error setting state ...");
}
char out_message[] = "fetch?"; // request for the device to send voltage and
current
char in_message[32];
DWORD BytesToWrite = sizeof(out_message);
DWORD BytesWritten;
DWORD BytesToRead = sizeof(in_message);
DWORD BytesRead;
WriteFile(hSerial, out_message, BytesToWrite, &BytesWritten, NULL);
ReadFile(hSerial, &in_message, BytesToRead, &BytesRead, NULL);
string buffer;
for (unsigned int i = 0; i < sizeof(in_message); i++) {
buffer += in_message[i];
}
buffer[sizeof(in_message) - 1] = '\0';
// try outs of different outputs
cout << buffer << "\n";
const char*c = buffer.c_str();
printf("%s\n",c);
CloseHandle(hSerial);
return 0;
}
I guess I cannot write to com an read out immediately?
Or is there a mistake in the conversion in_message to buffer?
I have a PLC connected to one of my laptop's COM Ports and I've trying to send it a default command that returns a default response. Currently WriteFile successfully sends the 20 bit command but ReadFile doesn't read anything though there's no error.
int main(){
HANDLE hCom = CreateFile("\\\\.\\COM4",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hCom == INVALID_HANDLE_VALUE)
{
DWORD err=GetLastError();
std::cout << "Failed\n";
return 0;
}
DCB dcbConfig;
if(GetCommState(hCom, &dcbConfig))
{
dcbConfig.BaudRate = CBR_115200;
dcbConfig.ByteSize = 8;
dcbConfig.Parity = NOPARITY;
dcbConfig.StopBits = ONESTOPBIT;
dcbConfig.fBinary = TRUE;
dcbConfig.fParity = FALSE;
}
if(!SetCommState(hCom, &dcbConfig))
{
CloseHandle(hCom);
return 0;
}
COMMTIMEOUTS commTimeout;
if(GetCommTimeouts(hCom, &commTimeout))
{
commTimeout.ReadIntervalTimeout = 1;
commTimeout.ReadTotalTimeoutConstant = 1;
commTimeout.ReadTotalTimeoutMultiplier = 1;
commTimeout.WriteTotalTimeoutConstant = 1;
commTimeout.WriteTotalTimeoutMultiplier = 1;
}
if(!SetCommTimeouts(hCom, &commTimeout))
//Handle Error Condition
CloseHandle(hCom);
// Write to the COM
static char data[22]="%01#RDD0010000107**\n";
int size = strlen(data);
DWORD dwWritten, dwReading;
int j;
WriteFile(hCom,data,(DWORD)size,&dwWritten,NULL);
DWORD err=GetLastError();
std::cout << err;
char datarecv[22];
ReadFile(hCom,&datarecv,1,&dwReading,NULL);
err = GetLastError();
std::cout << err;
std::cout << datarecv << "\n";
CloseHandle(hCom);
std::cin>>j;
return 0;
}
I have written a class to handle named pipe connections, and if I create an instance, close it, and then try to create another instance the call to CreateFile() returns INVALID_HANDLE_VALUE, and GetLastError() returns ERROR_PIPE_BUSY. What's going on here? What can I do to insure the call to Connect() succeeds?
PipeAsync A, B;
A.Connect("\\\\.\\pipe\\test",5000);
A.Close();
cout << GetLastError(); // some random value
B.Connect("\\\\.\\pipe\\test",5000);
cout << GetLastError(); // 231 (ERROR_PIPE_BUSY)
B.Close();
Here are my implementations of Connect() and Close()
BOOL PipeAsync::Connect(LPCSTR pszPipeName, DWORD dwTimeout)
{
this->pszPipeName = pszPipeName;
this->fExisting = TRUE;
DWORD dwMode = this->fMessageMode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE;
hPipe = CreateFile(
this->pszPipeName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if( INVALID_HANDLE_VALUE == hPipe )
return FALSE; /* set break point here ; breaks here on second call to Connect() */
if( GetLastError() == ERROR_PIPE_BUSY )
if(!WaitNamedPipe( this->pszPipeName, dwTimeout ))
return FALSE; /* set break point here */
if( !SetNamedPipeHandleState( hPipe, &dwMode, NULL, NULL ) )
return FALSE; /* set break point here */
return TRUE;
}
VOID PipeAsync::Close()
{
if( fExisting )
DisconnectNamedPipe( hPipe );
CloseHandle( hPipe );
}
EDIT: I forgot to tell you how I concluded this... I set break points indicated in the comments. When run, it stops on the first break point.
EDIT: This is my updated code
if( INVALID_HANDLE_VALUE == hPipe )
if( GetLastError() == ERROR_PIPE_BUSY )
{
if(!WaitNamedPipe( this->pszPipeName, dwTimeout ))
return FALSE; /* break-point: breaks here on second call */
}
else
return FALSE; /* break-point /*
Now, WaitNamedPipe() is returning false on the second call to Connect() and GetLastError() is returning 2, or ERROR_FILE_NOT_FOUND ?
From Named Pipe Client:
If the pipe exists but all of its instances are busy, CreateFile
returns INVALID_HANDLE_VALUE and the GetLastError function returns
ERROR_PIPE_BUSY. When this happens, the named pipe client uses the
WaitNamedPipe function to wait for an instance of the named pipe to
become available.
The link has example code on coping with ERROR_PIPE_BUSY.
EDIT:
Small compilable example that demonstrates accepting and connecting on a named pipe:
const char* const PIPE_NAME = "\\\\.\\pipe\\test";
const int MAX_CONNECTIONS = 10;
void client_main()
{
DWORD last_error;
unsigned int elapsed_seconds = 0;
const unsigned int timeout_seconds = 5;
HANDLE handle = CreateFile(PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
while (INVALID_HANDLE_VALUE == handle &&
elapsed_seconds < timeout_seconds)
{
last_error = GetLastError();
if (last_error != ERROR_PIPE_BUSY)
{
break;
}
Sleep(1 * 1000);
elapsed_seconds++;
handle = CreateFile(PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
}
if (INVALID_HANDLE_VALUE == handle)
{
std::cerr << "Failed to connect to pipe " << PIPE_NAME <<
": last_error=" << last_error << "\n";
}
else
{
std::cout << "Connected to pipe " << PIPE_NAME << "\n";
CloseHandle(handle);
}
}
HANDLE _get_server_handle()
{
// Error handling omitted for security descriptor creation.
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, static_cast<PACL>(0), FALSE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
// Create a bi-directional message pipe.
HANDLE handle = CreateNamedPipe(PIPE_NAME,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE |
PIPE_READMODE_MESSAGE |
PIPE_NOWAIT,
PIPE_UNLIMITED_INSTANCES,
4096,
4096,
0,
&sa);
if (INVALID_HANDLE_VALUE == handle)
{
std::cerr << "Failed to create named pipe handle: last_error=" <<
GetLastError() << "\n";
}
return handle;
}
void server_main()
{
HANDLE handle = _get_server_handle();
if (INVALID_HANDLE_VALUE != handle)
{
int count = 0;
while (count < MAX_CONNECTIONS)
{
BOOL result = ConnectNamedPipe(handle, 0);
const DWORD last_error = GetLastError();
if (ERROR_NO_DATA == last_error)
{
count++;
std::cout << "A client connected and disconnected: count=" <<
count << "\n";
CloseHandle(handle);
handle = _get_server_handle();
}
else if (ERROR_PIPE_CONNECTED == last_error)
{
count++;
std::cout << "A client connected before call to " <<
"ConnectNamedPipe(): count=" << count << "\n";
CloseHandle(handle);
handle = _get_server_handle();
}
else if (ERROR_PIPE_LISTENING != last_error)
{
std::cerr << "Failed to wait for connection: last_error=" <<
GetLastError() << "\n";
CloseHandle(handle);
break;
}
Sleep(100);
}
}
}
int main(int a_argc, char** a_argv)
{
if (2 == a_argc)
{
if (std::string("client") == *(a_argv + 1))
{
for (int i = 0; i < MAX_CONNECTIONS; i++)
{
client_main();
}
}
else if (std::string("server") == *(a_argv + 1))
{
server_main();
}
}
return 0;
}
Execute server-side first:
pipetest.exe server
Then execute client-side:
pipetest.exe client
I could not tell what the problem was from the posted code. Hopefully this small example will assist you in finding the issue.
I am working on an embeeded device.i connect to it using COM port.
It gives the list of all files when i send a command "LIST" to it.
so i wrote an "hello world" which will connect to the port device is connected and will send data.
When i connect my device and run my program it is writing to the port and not receiving any bytes from the port.
but when i open the COM port using PUTTY(which is used to open port and send some data) and send COMMAND it works and when i CLOSE PUTTY and NOW RUN MY PROGRAM now it is working fine,so i need to OPEN port with putty for the first time for my program to work.
may be i am not initialising some functions...:(
can anyone help me out in this,i am unable to find solution for the past day.thanks in advance...
my source code is:-
#include "stdafx.h"
#include <iostream>
#include <afx.h>
int main()
{
using namespace std;
int i=0;
// cout << "Hello world!" << endl;
HANDLE hSerial;
hSerial = CreateFile("COM5",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hSerial==INVALID_HANDLE_VALUE)
{
if(GetLastError()==ERROR_FILE_NOT_FOUND)
{
// TRACE("serial port does not exist for reading\n");
//serial port does not exist. Inform user.
}
// TRACE("some other error,serial port does not exist for reading\n");
//some other error occurred. Inform user.
}
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams))
{
// TRACE("error getting state for reading\n");
//error getting state
}
dcbSerialParams.BaudRate=9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
dcbSerialParams.fOutX=TRUE;
dcbSerialParams.fInX=TRUE;
if(!SetCommState(hSerial, &dcbSerialParams))
{
//TRACE("error setting state for reading\n");
//error setting serial port state
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;
if(!SetCommTimeouts(hSerial, &timeouts))
{
// TRACE("some error occured for reading\n");
//error occureed. Inform user
}
int n=100,n1=100;
char szBuff[100];
DWORD dwBytesRead = 0;
char szBuff1[100];
DWORD dwByteswrote = 0;
memset(szBuff1,0,100);
memcpy(szBuff1,"LIST\r",5);
FlushFileBuffers(hSerial);
LPDWORD uf=0;
GetCommModemStatus(hSerial,uf);
TRACE("%d\n",uf);
if(!WriteFile(hSerial, szBuff1,5, &dwByteswrote, NULL))
{
cout << "error writing" ;
}
cout << szBuff1 << endl;
cout << dwByteswrote << endl;
dwByteswrote=0;
while(1)
{
if(!ReadFile(hSerial, szBuff, n1, &dwBytesRead, NULL))
{
cout << "error reading";
break;
}
else
{
cout << dwBytesRead << endl;
szBuff[dwBytesRead]='\0';
if(dwBytesRead>0)
{
cout << (szBuff);
break;
}
else
{
}
}
}
cin >> i;
}
You might try setting all the DCB options and clearing port errors
// Common settings
dcbSerialParams.DCBlength = sizeof( dcbSerialParams );
dcbSerialParams.ByteSize = 8;
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.fParity = FALSE;
dcbSerialParams.Parity = NOPARITY;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.fDtrControl = 0;
dcbSerialParams.fRtsControl = 0;
// If you say so
dcbSerialParams.fOutX = TRUE;
dcbSerialParams.fInX = TRUE;
// Not so common settings
dcbSerialParams.fBinary = FALSE;
dcbSerialParams.fParity = FALSE;
dcbSerialParams.fOutxCtsFlow = FALSE;
dcbSerialParams.fOutxDsrFlow = FALSE;
dcbSerialParams.fDsrSensitivity = FALSE;
dcbSerialParams.fErrorChar = FALSE;
dcbSerialParams.fNull = FALSE;
dcbSerialParams.fAbortOnError = FALSE;
// Clear errors
unsigned long ulCommErr = 0;
ClearCommBreak( hSerial );
ClearCommError( hSerial, &ulCommErr, NULL );
Probably unrelated, but I noticed I at some point added a security descriptor to CreateFile() in my serial code, I believe some configuration of Windows Server required it.
// Allow access
SECURITY_ATTRIBUTES sa, *pSa = NULL;
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = (SECURITY_DESCRIPTOR*)LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH);
if ( sa.lpSecurityDescriptor
&& InitializeSecurityDescriptor( (SECURITY_DESCRIPTOR*)sa.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION )
&& SetSecurityDescriptorDacl( (SECURITY_DESCRIPTOR*)sa.lpSecurityDescriptor, TRUE, (PACL)NULL, FALSE ) )
pSa = &sa;
// Open the port
hSerial = CreateFile( x_pPort,
GENERIC_READ | GENERIC_WRITE,
0,
pSa,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( pSa )
LocalFree( pSa->lpSecurityDescriptor );
MSDN documentation of CreateFile demands using 0 as dwShareMode for Communications Resources like COM ports (you use FILE_SHARE_WRITE|FILE_SHARE_READ). Try this first. Even if it won't help it is better to follow the official documentation anyway.
If (1) doesn't work then try using CREATE_ALWAYS instead of OPEN_EXISTING. Actually OPEN_EXISTING is demanded by the documentation but one community message (on the same page after the official documentation) suggests using CREATE_ALWAYS for LPT ports (may be it is different though).