COM PORT PROBLEM
-
Hello!! I am trying to send and receive some data using COMM(communications ). I using C/SDK for prgramming and the OS is Win98 and Win 2000. I have got the handle to COM port(COM port1) by the use of lineGetID() ( using VARSTRING datastructure). I have only modified the timeout value (commtimeouts.ReadIntervalTimeout = 3000; and set the others to zero).. When I transmit the data from the client using WriteFile(), it gives error in the client saying ERROR_ALREADY_EXISTS (0x000000b7).. When I try to open the COM port by using CreateFile() it gives error "Access Denied". Could you please advise what could be the problem... Sandeep
-
Hello!! I am trying to send and receive some data using COMM(communications ). I using C/SDK for prgramming and the OS is Win98 and Win 2000. I have got the handle to COM port(COM port1) by the use of lineGetID() ( using VARSTRING datastructure). I have only modified the timeout value (commtimeouts.ReadIntervalTimeout = 3000; and set the others to zero).. When I transmit the data from the client using WriteFile(), it gives error in the client saying ERROR_ALREADY_EXISTS (0x000000b7).. When I try to open the COM port by using CreateFile() it gives error "Access Denied". Could you please advise what could be the problem... Sandeep
My hunch is that you're not calling
lineGetID()
appropriately. To determine this, why not try to write to COM1 without using TAPI at all? A handle to the port can be gotten with
CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
My hunch is that you're not calling
lineGetID()
appropriately. To determine this, why not try to write to COM1 without using TAPI at all? A handle to the port can be gotten with
CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
Joaquín M López Muñoz Telefónica, Investigación y DesarrolloThanks for your mail.. I have managed to print the device name (modem name) connected to COM1. So I think I am getting a valid handle to the COM Port. Do I have to use "Overlapped" structure at the sending end as well as the receiving end.. i.e. for WriteFile() as well as ReadFile().. and would there be a problem if the code with the use of "OverLapped" stucture give any problem if the code is run on WIn 98 or WinNT.. I want to make the code OS independent it should run on atleast WIn 98.Win NT,Win ME,Win 2000 and Win XP. Please help
-
Thanks for your mail.. I have managed to print the device name (modem name) connected to COM1. So I think I am getting a valid handle to the COM Port. Do I have to use "Overlapped" structure at the sending end as well as the receiving end.. i.e. for WriteFile() as well as ReadFile().. and would there be a problem if the code with the use of "OverLapped" stucture give any problem if the code is run on WIn 98 or WinNT.. I want to make the code OS independent it should run on atleast WIn 98.Win NT,Win ME,Win 2000 and Win XP. Please help
Well this little piece of code shows how to use
lineGetID()
. Assume you've got aHCALL
handle obtained withlineMakeCall
in passthrough mode:LONG res;
LPVARSTRING p_varString=NULL;
size_t size=sizeof(VARSTRING)+1024;
HANDLE hCOM;for( ; ; ){
if((p_varString=(LPVARSTRING)malloc(size))==NULL)return FALSE;
p_varString->dwTotalSize=size;if(lineGetID(0,0,hCall,LINECALLSELECT_CALL,p_varString,"comm/datamodem")!=0){
free(p_varString);
return FALSE;
}
else if(p_varString->dwNeededSize>size){
size=p_varString->dwNeededSize;
free(p_varString);
}
else break;
}
hCOM=*((LPHANDLE)((LPBYTE)p_varString+p_varString->dwStringOffset));
free(p_varString);Try with this to see if you're any luckier. As for overlapped mode, I'm afraid that if you're obtaining you're COM handle via
lineGetID()
instead that withCreateFile()
then you must assume that the port may be in overlapped mode. This mode is supported on all Windows OSs starting from Win95. The Microsoft sample TAPICOMM shows how to deal withWriteFile()
andReadFile()
handling both modes (overlapped and nonoverlapped) in a unified way. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
Well this little piece of code shows how to use
lineGetID()
. Assume you've got aHCALL
handle obtained withlineMakeCall
in passthrough mode:LONG res;
LPVARSTRING p_varString=NULL;
size_t size=sizeof(VARSTRING)+1024;
HANDLE hCOM;for( ; ; ){
if((p_varString=(LPVARSTRING)malloc(size))==NULL)return FALSE;
p_varString->dwTotalSize=size;if(lineGetID(0,0,hCall,LINECALLSELECT_CALL,p_varString,"comm/datamodem")!=0){
free(p_varString);
return FALSE;
}
else if(p_varString->dwNeededSize>size){
size=p_varString->dwNeededSize;
free(p_varString);
}
else break;
}
hCOM=*((LPHANDLE)((LPBYTE)p_varString+p_varString->dwStringOffset));
free(p_varString);Try with this to see if you're any luckier. As for overlapped mode, I'm afraid that if you're obtaining you're COM handle via
lineGetID()
instead that withCreateFile()
then you must assume that the port may be in overlapped mode. This mode is supported on all Windows OSs starting from Win95. The Microsoft sample TAPICOMM shows how to deal withWriteFile()
andReadFile()
handling both modes (overlapped and nonoverlapped) in a unified way. Joaquín M López Muñoz Telefónica, Investigación y DesarrolloHello!! Thank you very much for your help , but the problem persists.. I have double checked and the error I am getting is because of the WriteFile() iteself.. I cannot open the COM port by CreatFile() because the connection is established and hence if tried to open the COM port it gives error "Access denied".... Please help..
-
Hello!! Thank you very much for your help , but the problem persists.. I have double checked and the error I am getting is because of the WriteFile() iteself.. I cannot open the COM port by CreatFile() because the connection is established and hence if tried to open the COM port it gives error "Access denied".... Please help..
Well it's hard to think of what more to do... I suggest you try the following suit of tests:
- check
WriteFile
works with a handle obtained withCreateFile
--just get the handle without establishing any connection before. - Make sure the modem is behaving properly --by using some TAPI program like HyperTerminal.
- Try to determine if the handle is valid by calling other functions different from WriteFile() and checking the result (with
GetFileType
, for instance). - Make sure the modem port settings are compatible with the requirements of the modem (port speed, parity, stop bits, control flow).
- See what happens with different modems/drivers.
- See what happens with different OSs/machines.
If nothing of this sheds any light, you could try to write a little self contained program reproducing the error that we can grasp and play with. Do not abandone all hope (yet) :) Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
- check
-
Well it's hard to think of what more to do... I suggest you try the following suit of tests:
- check
WriteFile
works with a handle obtained withCreateFile
--just get the handle without establishing any connection before. - Make sure the modem is behaving properly --by using some TAPI program like HyperTerminal.
- Try to determine if the handle is valid by calling other functions different from WriteFile() and checking the result (with
GetFileType
, for instance). - Make sure the modem port settings are compatible with the requirements of the modem (port speed, parity, stop bits, control flow).
- See what happens with different modems/drivers.
- See what happens with different OSs/machines.
If nothing of this sheds any light, you could try to write a little self contained program reproducing the error that we can grasp and play with. Do not abandone all hope (yet) :) Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
Thanks for your reply.... I tried opening the COM port by CreateFile() and validated it by using GetFileType(). It was successfull and it seems that the handle we are getting is valid one. Following is the code we tried with setting COMM properties but WriteFile() gives an error. hHandleForWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); overlapped.Offset = 0; overlapped.OffsetHigh = 0; overlapped.hEvent = hHandleForWaitEvent; hHandleForCOMPort = CreateFile("COM2", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, //CREATE_ALWAYS, //NULL, FILE_FLAG_OVERLAPPED, NULL); if(GetFileType(hHandleForCOMPort) != FILE_TYPE_CHAR) { MessageBox(NULL, "INVALID_HANDLE", NULL, 0); } sprintf(str1, "HANDLE of com port = %d", hHandleForCOMPort); MessageBox(NULL, str1, NULL, 0); //Get comm properties GetCommState(hHandleForCOMPort, &SerialDCB); GetCommProperties(hHandleForCOMPort, &commprop); GetCommMask(hHandleForCOMPort, &fdwEvtMask); GetCommTimeouts(hHandleForCOMPort, &commtimeouts); //Set COM TimeOuts commtimeouts.ReadIntervalTimeout = 3000; commtimeouts.ReadTotalTimeoutMultiplier = 0; commtimeouts.ReadTotalTimeoutConstant = 0; commtimeouts.WriteTotalTimeoutMultiplier = 0; commtimeouts.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hHandleForCOMPort, &commtimeouts); //fAbortOnError is the only DCB dependancy in TapiComm. //Can't guarentee that the SP will set this to what we expect. SerialDCB.fAbortOnError = FALSE; //SerialDCB.BaudRate = 115200; //SerialDCB.ByteSize = 8; SetCommState(hHandleForCOMPort, &SerialDCB); strcpy(str1, ""); //write it to COM port bResult = WriteFile(hHandleForCOMPort, 'A', 1, &dwBytesWritten, &overlapped); if(bResult == 0) { MessageBox(NULL, "WriteFile() failed", NULL, 0); //dwLastError = GetLastError(); sprintf(str1, "Return value of GetLastError() = %d", GetLastError()); MessageBox(NULL, str1, NULL, 0); if(dwLastError != ERROR_IO_PENDING) MessageBox(NULL, "dwLastError != ERROR_IO_PENDING", NULL, 0); else MessageBox(NULL, "dwLastError == ERROR_IO_PENDING", NULL, 0); } MessageBox(NULL, "SUCCESS", "SUCCESS", 0); /*************************************************************/ :( :(
- check
-
Thanks for your reply.... I tried opening the COM port by CreateFile() and validated it by using GetFileType(). It was successfull and it seems that the handle we are getting is valid one. Following is the code we tried with setting COMM properties but WriteFile() gives an error. hHandleForWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); overlapped.Offset = 0; overlapped.OffsetHigh = 0; overlapped.hEvent = hHandleForWaitEvent; hHandleForCOMPort = CreateFile("COM2", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, //CREATE_ALWAYS, //NULL, FILE_FLAG_OVERLAPPED, NULL); if(GetFileType(hHandleForCOMPort) != FILE_TYPE_CHAR) { MessageBox(NULL, "INVALID_HANDLE", NULL, 0); } sprintf(str1, "HANDLE of com port = %d", hHandleForCOMPort); MessageBox(NULL, str1, NULL, 0); //Get comm properties GetCommState(hHandleForCOMPort, &SerialDCB); GetCommProperties(hHandleForCOMPort, &commprop); GetCommMask(hHandleForCOMPort, &fdwEvtMask); GetCommTimeouts(hHandleForCOMPort, &commtimeouts); //Set COM TimeOuts commtimeouts.ReadIntervalTimeout = 3000; commtimeouts.ReadTotalTimeoutMultiplier = 0; commtimeouts.ReadTotalTimeoutConstant = 0; commtimeouts.WriteTotalTimeoutMultiplier = 0; commtimeouts.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hHandleForCOMPort, &commtimeouts); //fAbortOnError is the only DCB dependancy in TapiComm. //Can't guarentee that the SP will set this to what we expect. SerialDCB.fAbortOnError = FALSE; //SerialDCB.BaudRate = 115200; //SerialDCB.ByteSize = 8; SetCommState(hHandleForCOMPort, &SerialDCB); strcpy(str1, ""); //write it to COM port bResult = WriteFile(hHandleForCOMPort, 'A', 1, &dwBytesWritten, &overlapped); if(bResult == 0) { MessageBox(NULL, "WriteFile() failed", NULL, 0); //dwLastError = GetLastError(); sprintf(str1, "Return value of GetLastError() = %d", GetLastError()); MessageBox(NULL, str1, NULL, 0); if(dwLastError != ERROR_IO_PENDING) MessageBox(NULL, "dwLastError != ERROR_IO_PENDING", NULL, 0); else MessageBox(NULL, "dwLastError == ERROR_IO_PENDING", NULL, 0); } MessageBox(NULL, "SUCCESS", "SUCCESS", 0); /*************************************************************/ :( :(
Well, I'm running out of ideas :) but two things in your code caught my eye. Not that I think these will account for the problem, but it may be worth checking:
-
You've opened the port with
FILE_SHARE_READ|FILE_SHARE_WRITE
: Microsoft docs saydwShareMode
must be zero for communications resources. -
The piece of code
if(bResult == 0)
{
MessageBox(NULL, "WriteFile() failed", NULL, 0);
//dwLastError = GetLastError();
sprintf(str1, "Return value of GetLastError() = %d", GetLastError());
...should be written
if(bResult == 0)
{
DWORD dwLastError = GetLastError();
MessageBox(NULL, "WriteFile() failed", NULL, 0);
//dwLastError = GetLastError();
sprintf(str1, "Return value of GetLastError() = %d", (int)GetLastError());
...to avoid the possibility of
MessageBox
altering the error code.
Tell us what this leads to... Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
-