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