497 lines
15 KiB
C
497 lines
15 KiB
C
/*===========================================================================*/
|
||
/* Copyright (c) 1987 - 1988, Future Soft Engineering, Inc. */
|
||
/* Houston, Texas */
|
||
/*===========================================================================*/
|
||
|
||
#define NOGDICAPMASKS TRUE
|
||
#define NOVIRTUALKEYCODES TRUE
|
||
#define NOICONS TRUE
|
||
#define NOKEYSTATES TRUE
|
||
#define NOSYSCOMMANDS TRUE
|
||
#define NOATOM TRUE
|
||
#define NOCLIPBOARD TRUE
|
||
#define NODRAWTEXT TRUE
|
||
#define NOMINMAX TRUE
|
||
#define NOOPENFILE TRUE
|
||
#define NOSCROLL TRUE
|
||
#define NOHELP TRUE
|
||
#define NOPROFILER TRUE
|
||
#define NODEFERWINDOWPOS TRUE
|
||
#define NOPEN TRUE
|
||
#define NO_TASK_DEFINES TRUE
|
||
#define NOLSTRING TRUE
|
||
#define WIN31
|
||
#define USECOMM
|
||
|
||
#include <windows.h>
|
||
#include <port1632.h>
|
||
#include "dcrc.h"
|
||
#include "dynacomm.h"
|
||
#include "connect.h"
|
||
|
||
/*---------------------------------------------------------------------------*/
|
||
/* exitSerial() - [mbb/rkh] */
|
||
/*---------------------------------------------------------------------------*/
|
||
|
||
VOID NEAR WIN_exitSerial() /* mbbx 2.00: network... */
|
||
{
|
||
DCB dcb;
|
||
|
||
if(GetCommState(sPort, (DCB FAR *) &dcb) == 0) /* mbbx 1.04: RTS/DTR disable... */
|
||
{
|
||
dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||
dcb.fDtrControl = DTR_CONTROL_DISABLE;
|
||
EscapeCommFunction(sPort,CLRRTS);
|
||
EscapeCommFunction(sPort,CLRDTR);
|
||
|
||
DEBOUT("SetCommState from Win_exitSerial for comport=%lx\n",sPort);
|
||
if(!SetCommState(sPort,(DCB FAR *) &dcb))
|
||
{
|
||
DEBOUT("FAIL: SetCommState from Win_exitSerial for comport=%lx\n",sPort);
|
||
}
|
||
}
|
||
|
||
|
||
#ifdef ORGCODE
|
||
FlushComm(sPort, 1);
|
||
FlushComm(sPort, 0);
|
||
#else
|
||
DEBOUT("FlushFileBuffers from Win_exitSerial: comport %lx\n",sPort);
|
||
#ifndef BUGBYPASS
|
||
DEBOUT("FlushFileBuffers from Win_exitSerial: BYPASSING FLUSH DUE TO BUG %lx\n",sPort);
|
||
#else
|
||
if (!FlushFileBuffers(sPort))
|
||
{
|
||
DEBOUT("FAIL: FlushFileBuffers comport %lx\n",sPort);
|
||
}
|
||
#endif
|
||
|
||
DEBOUT("PurgeComm from Win_exitSerial:comport %lx\n",sPort);
|
||
if (!PurgeComm(sPort,0))
|
||
{
|
||
DEBOUT("FAIL: PurgeComm comport %lx\n",sPort);
|
||
}
|
||
#endif
|
||
|
||
SetCommMask(sPort, EV_RXCHAR);
|
||
//WaitForSingleObject(hMutex, 500);
|
||
bPortIsGood = FALSE;
|
||
|
||
|
||
|
||
/**********
|
||
{
|
||
// Make suer sPort gets closed, bug#9671
|
||
// Actually a bug in serial driver, The fix is a
|
||
// quick hack, should be removed once the driver
|
||
// is fixed.
|
||
|
||
int cnt=20;
|
||
|
||
while (cnt-- && CloseHandle(sPort)) Sleep (200);
|
||
}
|
||
**********/
|
||
|
||
//
|
||
// We can't close the handle twice now.
|
||
// So, just close it and wait a little.
|
||
//
|
||
|
||
Sleep (200);
|
||
CloseHandle (sPort);
|
||
Sleep (200);
|
||
|
||
|
||
|
||
sPort = NULL;
|
||
//ReleaseMutex(hMutex);
|
||
}
|
||
|
||
|
||
VOID exitSerial() /* mbbx 2.00: network... */
|
||
{
|
||
switch(trmParams.comDevRef)
|
||
{
|
||
case ITMWINCOM:
|
||
WIN_exitSerial();
|
||
break;
|
||
|
||
case ITMDLLCONNECT: /* slc nova 012 bjw nova 02 */
|
||
DLL_ExitConnector(ghCCB, &trmParams); /* slc nova 031 */
|
||
break;
|
||
}
|
||
|
||
trmParams.comDevRef = ITMNOCOM;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*/
|
||
/* resetSerial() - [mbb/rkh] */
|
||
/*---------------------------------------------------------------------------*/
|
||
|
||
VOID NEAR WIN_resetSerial(recTrmParams *trmParams, BOOL bLoad, NEARPROC errProc)
|
||
{
|
||
INT attempts;
|
||
// sdj: this is replaced by global szCurrentPortName ;BYTE tmp1[TMPNSTR+1];
|
||
BYTE tmp1[TMPNSTR+1],tmp2[TMPNSTR+1];
|
||
DCB dcb;
|
||
DCB PrevDcb;
|
||
COMMTIMEOUTS CommTimeOuts;
|
||
BOOL bRc;
|
||
DWORD dwError;
|
||
COMMPROP CommProp; // -sdj sep92 on low mem rx buffer can be < 1024
|
||
|
||
modemReset(); /* mbbx 0.72: avoid hang if XOFF-ed */
|
||
|
||
if(bLoad)
|
||
{
|
||
for(attempts = 0; trmParams->comDevRef == ITMNOCOM; attempts += 1)
|
||
{
|
||
if(trmParams->comPortRef > MaxComPortNumberInMenu)
|
||
|
||
strcpy(szCurrentPortName, "\\\\.\\TELNET");
|
||
|
||
else
|
||
|
||
{
|
||
// LoadString(hInst, STR_COM, (LPSTR) tmp2, MINRESSTR);
|
||
// sprintf(szCurrentPortName, tmp2, trmParams->comPortRef);
|
||
strcpy(szCurrentPortName,arComNumAndName[trmParams->comPortRef].PortName);
|
||
}
|
||
|
||
|
||
if( (sPort != NULL) && (sPort != (HANDLE)-1) )
|
||
{
|
||
SetCommMask(sPort, 0); // so that waitcommevent comes out; -sdj
|
||
sPort = NULL;
|
||
}
|
||
|
||
sPort = CreateFile(szCurrentPortName, GENERIC_READ|GENERIC_WRITE, 0, NULL,
|
||
OPEN_EXISTING,
|
||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
||
|
||
if (sPort == (HANDLE)-1)
|
||
{
|
||
dwError = GetLastError();
|
||
bPortIsGood = FALSE;
|
||
if(!(*errProc)(trmParams, attempts))
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
SetCommMask(sPort, EV_RXCHAR); // -sdj 27apr92 telnet deadlock
|
||
dwWriteFileTimeout = 5000; // -sdj 28apr92 telnet debug
|
||
|
||
trmParams->comDevRef = ITMWINCOM;
|
||
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
|
||
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
|
||
CommTimeOuts.ReadTotalTimeoutConstant = 0;
|
||
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
|
||
|
||
if (trmParams->flowControl == ITMHARDFLOW)
|
||
{
|
||
CommTimeOuts.WriteTotalTimeoutConstant = 5000; // 5msecs
|
||
}
|
||
else
|
||
{
|
||
CommTimeOuts.WriteTotalTimeoutConstant = 10000; //10secs
|
||
}
|
||
|
||
if (!(bRc = SetCommTimeouts(sPort,&CommTimeOuts) ) )
|
||
{
|
||
if(!(*errProc)(trmParams, attempts))
|
||
return;
|
||
}
|
||
|
||
// There may be data already waiting to be read - i.e. data
|
||
// that arrived before we set comm mask. This data will not
|
||
// be uncovered by wait mask, so we must try to read it.
|
||
|
||
gotCommEvent = TRUE;
|
||
|
||
}
|
||
} // endof for
|
||
} // endof if bload
|
||
|
||
/* This would work on both win30 and win32 -sdj*/
|
||
/* if(GetCommState(sPort, (DCB FAR *) &dcb) == 0) -sdj*/
|
||
|
||
DEBOUT("HACK : %s\n","rc of GetCommState: not checked for now");
|
||
{
|
||
GetCommState(sPort, (DCB FAR *) &dcb);
|
||
GetCommState(sPort, (DCB FAR *) &PrevDcb);
|
||
|
||
// -sdj sep92 on low mem rx buffer can be < 1024
|
||
// -sdj set rx buffer to nice 4096 bytes size
|
||
// -sdj driver will do its best and set the Rx buffer to this size
|
||
// -sdj if it fails then dwCurrentRxQueue will be the one we have
|
||
// -sdj so do getcommprop again to fetch this value, which can
|
||
// -sdj be used to set xoff and xon lims
|
||
|
||
GetCommProperties(sPort,&CommProp);
|
||
|
||
SetupComm(sPort,4096,4096);
|
||
|
||
CommProp.dwCurrentRxQueue = 0; // -sdj dirty it so that we
|
||
// -sdj can use this only if !=0
|
||
GetCommProperties(sPort,&CommProp);
|
||
|
||
// sdj: added this code to take care of extra baud rates support
|
||
|
||
if (trmParams->speed <= 57600)
|
||
{
|
||
dcb.BaudRate = trmParams->speed; /* mbbx 2.00: allow any baud... */
|
||
}
|
||
else
|
||
{
|
||
if (trmParams->speed == 57601)
|
||
{
|
||
// sdj: this means 115.2K baud rate which cannot fit into BYTE!
|
||
dcb.BaudRate = 115200;
|
||
}
|
||
else{
|
||
if (trmParams->speed == 57602)
|
||
{
|
||
dcb.BaudRate = 128000;
|
||
}
|
||
else
|
||
{
|
||
// sdj: something wrong! default to 1200
|
||
dcb.BaudRate = 1200;
|
||
}
|
||
}
|
||
}
|
||
|
||
dcb.ByteSize = 8 + (trmParams->dataBits - ITMDATA8);
|
||
dcb.Parity = NOPARITY + (trmParams->parity - ITMNOPARITY);
|
||
dcb.StopBits = ONESTOPBIT + (trmParams->stopBits - ITMSTOP1);
|
||
|
||
// dcb.RlsTimeout = 0;
|
||
// dcb.CtsTimeout = (trmParams->flowControl == ITMHARDFLOW) ? 5 : 0; /* mbbx 1.10: CUA */
|
||
// dcb.DsrTimeout = 0;
|
||
|
||
dcb.fBinary = TRUE;
|
||
dcb.fRtsControl = RTS_CONTROL_ENABLE;
|
||
dcb.fParity = trmParams->fParity; /* mbbx 1.10: CUA */
|
||
dcb.fOutxCtsFlow = (trmParams->flowControl == ITMHARDFLOW); /* mbbx 1.10: CUA... */
|
||
dcb.fOutxDsrFlow = FALSE;
|
||
dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
||
|
||
dcb.fOutX =
|
||
dcb.fInX = (trmParams->flowControl == ITMXONFLOW);
|
||
dcb.fErrorChar = trmParams->fParity; /* mbbx 1.10: CUA */
|
||
dcb.fNull = FALSE;
|
||
// dcb.fChEvt = FALSE;
|
||
// dcb.fDtrFlow = FALSE;
|
||
|
||
if (trmParams->flowControl == ITMHARDFLOW)
|
||
{
|
||
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; /* mbbx 1.10: CUA... */
|
||
}
|
||
|
||
dcb.XonChar = XON;
|
||
dcb.XoffChar = XOFF;
|
||
|
||
/* -sdj sep92, this is 1k/4=256, 9M system can have RXQ=256
|
||
-sdj in that case SetCommState can fail due to invalid
|
||
-sdj parameters of xoff xon limits
|
||
dcb.XonLim = NINQUEUE / 4;
|
||
dcb.XoffLim = NINQUEUE / 4;
|
||
*/
|
||
|
||
// -sdj if for some wierd reason dwCurrentRxQueue is not
|
||
// -sdj filled in by the driver, then let xon xoff lims
|
||
// -sdj be the default which the driver has.
|
||
// -sdj (dwCurrentRxQueue was set to 0 before calling Get again)
|
||
|
||
if (CommProp.dwCurrentRxQueue != 0)
|
||
{
|
||
dcb.XonLim = (WORD)(CommProp.dwCurrentRxQueue / 4);
|
||
dcb.XoffLim = (WORD)(CommProp.dwCurrentRxQueue / 4);
|
||
}
|
||
|
||
dcb.ErrorChar = '?';
|
||
dcb.EofChar = CNTRLZ;
|
||
dcb.EvtChar = 0;
|
||
dcb.wReserved = 0;
|
||
|
||
#ifdef ORGCODE
|
||
if(SetCommState((DCB FAR *) &dcb) == 0)
|
||
{
|
||
#else
|
||
if(SetCommState(sPort, (DCB FAR *) &dcb) == 0)
|
||
{
|
||
|
||
DEBOUT("FAIL: SetCommState for comport=%lx\n",sPort);
|
||
#endif
|
||
mdmOnLine = FALSE; /* mbbx 1.10: carrier... */
|
||
mdmConnect();
|
||
LoadString(hInst, STR_SETCOMFAIL, (LPSTR) tmp1, TMPNSTR);
|
||
LoadString(hInst, STR_ERRCAPTION, (LPSTR) tmp2, TMPNSTR);
|
||
MessageBox(hItWnd, (LPSTR) tmp1, (LPSTR)tmp2, MB_OK | MB_APPLMODAL);
|
||
SetCommState(sPort,&PrevDcb);
|
||
return;
|
||
}
|
||
|
||
#ifdef ORGCODE
|
||
#else
|
||
/*DWORD ReadIntervalTimeout; Maximum time between read chars. */
|
||
/*DWORD ReadTotalTimeoutMultiplier; Multiplier of characters. */
|
||
/*DWORD ReadTotalTimeoutConstant; Constant in milliseconds. */
|
||
/*DWORD WriteTotalTimeoutMultiplier; Multiplier of characters. */
|
||
/*DWORD WriteTotalTimeoutConstant; Constant in milliseconds. */
|
||
|
||
DEBOUT("Win_resetSerial: %s\n","Setting Comm timeouts");
|
||
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
|
||
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
|
||
CommTimeOuts.ReadTotalTimeoutConstant = 0;
|
||
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
|
||
|
||
if (trmParams->flowControl == ITMHARDFLOW)
|
||
{
|
||
CommTimeOuts.WriteTotalTimeoutConstant = 5000; //5 msecs
|
||
}
|
||
else
|
||
{
|
||
CommTimeOuts.WriteTotalTimeoutConstant = 10000; //10secs
|
||
}
|
||
|
||
if (!(bRc = SetCommTimeouts(sPort,&CommTimeOuts) ) )
|
||
{
|
||
DEBOUT("FAIL: SetCommTimeouts failed rc: %lx\n",bRc);
|
||
mdmOnLine = FALSE; /* mbbx 1.10: carrier... */
|
||
mdmConnect();
|
||
return;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
bPortIsGood = TRUE; /* now the port is properly initialized -sdj 05/21/92*/
|
||
//-sdj for telnet-quit processing
|
||
bPortDisconnected = FALSE; /* there is no problem of port_was_opened_but_not_working */
|
||
|
||
}
|
||
|
||
|
||
VOID resetSerial(recTrmParams *trmParams, BOOL bLoad,BOOL bInit,BYTE byFlowFlag) /* slc swat */
|
||
{
|
||
/* LPCONNECTOR_CONTROL_BLOCK lpCCB; -sdj no unref variables please ; slc nova 031 */
|
||
|
||
if(bLoad)
|
||
{
|
||
if(!trmParams->fResetDevice)
|
||
trmParams->newDevRef = trmParams->comDevRef;
|
||
|
||
exitSerial();
|
||
}
|
||
|
||
switch(bLoad ? trmParams->newDevRef : trmParams->comDevRef)
|
||
{
|
||
|
||
case ITMNOCOM:
|
||
|
||
break;
|
||
|
||
|
||
default: // case ITMWINCOM:
|
||
WIN_resetSerial(trmParams, bLoad, bInit ? (NEARPROC)resetSerialError0 : (NEARPROC)resetSerialError1 /*, byFlowFlag*/); /* slc swat */
|
||
break;
|
||
|
||
#ifdef OLDCODE
|
||
|
||
case ITMWINCOM:
|
||
WIN_resetSerial(trmParams, bLoad, bInit ? (NEARPROC)resetSerialError0 : (NEARPROC)resetSerialError1 /*, byFlowFlag*/); /* slc swat */
|
||
break;
|
||
|
||
case ITMDLLCONNECT: /* slc nova 012 bjw nova 002 */
|
||
if((lpCCB = (LPCONNECTOR_CONTROL_BLOCK)GlobalLock(ghCCB)) != NULL) /* slc nova 031 */
|
||
{
|
||
if(lpCCB->hConnectorInst == NULL) /* first time? */
|
||
if(!loadConnector(NULL, ghCCB, (LPSTR)trmParams->szConnectorName, FALSE))
|
||
return;
|
||
GlobalUnlock(ghCCB);
|
||
|
||
trmParams->comDevRef = ITMDLLCONNECT;
|
||
DLL_SetupConnector(ghCCB, FALSE); /* slc nova 031 */
|
||
}
|
||
break;
|
||
|
||
#endif
|
||
|
||
}
|
||
|
||
trmParams->fResetDevice = FALSE;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*/
|
||
/* resetSerialError0 - called during initialization; [mbb] */
|
||
/* auto attempt other COM port, then fail */
|
||
/*---------------------------------------------------------------------------*/
|
||
|
||
BOOL PASCAL NEAR resetSerialError0(recTrmParams *trmParams, WORD count)
|
||
{
|
||
BYTE tmp1[TMPNSTR+1];
|
||
BYTE tmp2[TMPNSTR+1];
|
||
|
||
//sdj: if this is a telnet port then advice the user to go to
|
||
//sdj: the control panel and see if telnet service is started
|
||
//sdj: else stick with the original msg of selected com port not
|
||
//sdj: available, select other port.
|
||
|
||
if (!strcmp(szCurrentPortName,"\\\\.\\TELNET"))
|
||
{
|
||
LoadString(hInst, STR_TELNETFAIL, (LPSTR) tmp1, TMPNSTR);
|
||
}
|
||
else
|
||
{
|
||
LoadString(hInst, STR_OTHERCOM, (LPSTR) tmp1, TMPNSTR);
|
||
}
|
||
LoadString(hInst, STR_ERRCAPTION, (LPSTR) tmp2, TMPNSTR);
|
||
|
||
MessageBox(hItWnd, (LPSTR) tmp1, (LPSTR)tmp2, MB_OK | MB_APPLMODAL);
|
||
doSettings(IDDBCOMM, dbComm);
|
||
|
||
return(FALSE);
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*/
|
||
/* resetSerialError1 - default case (e.g., after loading settings) [mbb] */
|
||
/* prompt to attempt other COM port, then fail */
|
||
/*---------------------------------------------------------------------------*/
|
||
|
||
BOOL PASCAL NEAR resetSerialError1(recTrmParams *trmParams, WORD count)
|
||
{
|
||
BYTE tmp1[TMPNSTR+1];
|
||
BYTE tmp2[TMPNSTR+1];
|
||
|
||
if(count > 0)
|
||
{
|
||
LoadString(hInst, STR_NOCOMMPORTS, (LPSTR) tmp1, TMPNSTR); /* mbbx 1.00 */
|
||
testMsg(tmp1,NULL,NULL);
|
||
}
|
||
else
|
||
{
|
||
//sdj: if this is a telnet port then advice the user to go to
|
||
//sdj: the control panel and see if telnet service is started
|
||
//sdj: else stick with the original msg of selected com port not
|
||
//sdj: available, select other port.
|
||
|
||
if (!strcmp(szCurrentPortName,"\\\\.\\TELNET"))
|
||
{
|
||
LoadString(hInst, STR_TELNETFAIL, (LPSTR) tmp1, TMPNSTR);
|
||
}
|
||
else
|
||
{
|
||
LoadString(hInst, STR_OTHERCOM, (LPSTR) tmp1, TMPNSTR);
|
||
}
|
||
LoadString(hInst, STR_ERRCAPTION, (LPSTR) tmp2, TMPNSTR);
|
||
MessageBox(hItWnd, (LPSTR) tmp1, (LPSTR)tmp2, MB_OK | MB_APPLMODAL);
|
||
|
||
trmParams->comPortRef = ITMNOCOM; /* mbbx 1.10: CUA */
|
||
}
|
||
return(FALSE);
|
||
}
|
||
|