|
|
/*===========================================================================*/ /* 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); }
|