Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

898 lines
25 KiB

  1. /*===========================================================================*/
  2. /* Copyright (c) 1987 - 1988, Future Soft Engineering, Inc. */
  3. /* Houston, Texas */
  4. /*===========================================================================*/
  5. #define NOGDICAPMASKS TRUE
  6. #define NOICONS TRUE
  7. #define NOKEYSTATES TRUE
  8. #define NOSYSCOMMANDS TRUE
  9. #define NOATOM TRUE
  10. #define NOCLIPBOARD TRUE
  11. #define NODRAWTEXT TRUE
  12. #define NOMINMAX TRUE
  13. #define NOOPENFILE TRUE
  14. #define NOSCROLL TRUE
  15. #define NOHELP TRUE
  16. #define NOPROFILER TRUE
  17. #define NODEFERWINDOWPOS TRUE
  18. #define NOPEN TRUE
  19. #define NO_TASK_DEFINES TRUE
  20. #define NOLSTRING TRUE
  21. #define USECOMM
  22. #include <stdarg.h>
  23. #include <windows.h>
  24. #include <port1632.h>
  25. #include "dcrc.h"
  26. #include "dynacomm.h"
  27. #include "task.h"
  28. #include "connect.h"
  29. /*---------------------------------------------------------------------------*/
  30. /* mdmConnect() - [mbb] */
  31. /*---------------------------------------------------------------------------*/
  32. /* NOTE: PATCH until WIN COMM DRV is fixed!!! */
  33. #define DEB_MSR_OFFSET 35 /* mbbx 1.10: carrier... */
  34. #define DEB_MSR_RLSD 0x80
  35. BOOL mdmConnect() /* mbbx 2.00: network... */
  36. {
  37. BOOL bRc,bCarrier = FALSE;
  38. // -sdj unreferenced local var: LPBYTE lpMSR;
  39. DWORD dwModemStatus;
  40. if(trmParams.fCarrier)
  41. {
  42. switch(trmParams.comDevRef)
  43. {
  44. case ITMWINCOM:
  45. DEBOUT("mdmConnect: %s\n","Calling getmodemstatus to see rlsd!");
  46. bRc = GetCommModemStatus(sPort,&dwModemStatus);
  47. DEBOUT("mdmConnect: rc of getmodemstatus = %lx\n",bRc);
  48. DEBOUT("mdmConnect: dw of getmodemstatus = %lx\n",dwModemStatus);
  49. if (!bRc)
  50. {
  51. DEBOUT("mdmconnect: %s\n","getmodemstatus failed, setting bCar=TRUE");
  52. bCarrier = TRUE;
  53. }
  54. else
  55. {
  56. bCarrier = (dwModemStatus & MS_RLSD_ON) ? TRUE : FALSE;
  57. DEBOUT("mdmconnect: bCarrier is set as: %lx\n",bCarrier);
  58. }
  59. break;
  60. default:
  61. bCarrier = TRUE;
  62. break;
  63. }
  64. if(mdmOnLine != bCarrier)
  65. {
  66. if(!(mdmOnLine = bCarrier))
  67. {
  68. }
  69. return(TRUE);
  70. }
  71. }
  72. return(FALSE);
  73. }
  74. /*---------------------------------------------------------------------------*/
  75. /* modemReset() - Send XON character to the serial port. [mbb] */
  76. /*---------------------------------------------------------------------------*/
  77. VOID modemReset() /* mbbx 2.00: network... */
  78. {
  79. switch(trmParams.comDevRef)
  80. {
  81. case ITMWINCOM:
  82. switch(trmParams.flowControl)
  83. {
  84. case ITMXONFLOW:
  85. DEBOUT("modemReset: Esccom(SETXON) on comport=%lx\n",sPort);
  86. EscapeCommFunction(sPort, SETXON);
  87. break;
  88. case ITMHARDFLOW:
  89. DEBOUT("modemReset: Esccom(SETRTS) on comport=%lx\n",sPort);
  90. EscapeCommFunction(sPort, SETRTS);
  91. break;
  92. }
  93. break;
  94. }
  95. sPortErr = FALSE;
  96. }
  97. /*---------------------------------------------------------------------------*/
  98. /* modemBreak() - Send BREAK signal to the serial port. [mbb] */
  99. /*---------------------------------------------------------------------------*/
  100. /* NOTE: units for modemSendBreak are approx. 1/9 secs ( = 7 ticks) */
  101. /*---------------------------------------------------------------------------*/
  102. /* VT100 standards for BREAK signals are as follows: */
  103. /* */
  104. /* short break: 0.233 sec = 2 units */
  105. /* long break: 3.500 sec = 30 units */
  106. /* */
  107. VOID modemSendBreak(INT nCount)
  108. {
  109. DCB dcb; /* slc nova 051 */
  110. switch(trmParams.comDevRef)
  111. {
  112. case ITMWINCOM:
  113. if(nCount > 2) /* slc nova 051 moved... */
  114. {
  115. if(GetCommState(sPort, (DCB FAR *)&dcb) == 0) /* slc nova 051 */
  116. {
  117. dcb.fRtsControl = RTS_CONTROL_DISABLE;
  118. dcb.fDtrControl = DTR_CONTROL_DISABLE;
  119. EscapeCommFunction(sPort,CLRRTS);
  120. EscapeCommFunction(sPort,CLRDTR);
  121. if(!SetCommState(sPort,(DCB FAR *)&dcb))
  122. {
  123. }
  124. }
  125. }
  126. DEBOUT("modemSendBrk:EscapeCommFunction(sPort, SETBREAK), DelayStart..for port=%lx\n",sPort);
  127. EscapeCommFunction(sPort, SETBREAK);
  128. delay(nCount*7, NULL);
  129. DEBOUT("modemSendBrk:DelayOver...EscapeCommFunction(sPort, CLRBREAK)for port=%lx\n",sPort);
  130. EscapeCommFunction(sPort, CLRBREAK);
  131. if(nCount > 2) /* slc nova 051 moved... */
  132. {
  133. if(GetCommState(sPort, (DCB FAR *)&dcb) == 0) /* slc nova 051 */
  134. {
  135. dcb.fRtsControl = RTS_CONTROL_ENABLE;
  136. dcb.fDtrControl = DTR_CONTROL_ENABLE;
  137. EscapeCommFunction(sPort,SETRTS);
  138. EscapeCommFunction(sPort,SETDTR);
  139. DEBOUT("modemSendBreak: set fRtsDtrdisable to false: for port=%lx\n",sPort);
  140. if(!SetCommState(sPort,(DCB FAR *)&dcb))
  141. {
  142. DEBOUT("FAIL: modemSendBreak: set fRtsDtrdisable to false: for port=%lx\n",sPort);
  143. }
  144. }
  145. }
  146. break;
  147. case ITMDLLCONNECT: /* rjs bug2 */
  148. DLL_modemSendBreak(ghCCB, nCount);
  149. break;
  150. }/* switch */
  151. resetSerial(&trmParams, FALSE, FALSE, 0);
  152. }
  153. /*---------------------------------------------------------------------------*/
  154. /* modemBytes() - [mbb] */
  155. /*---------------------------------------------------------------------------*/
  156. VOID NEAR WIN_modemBytes() /* mbbx 2.00: network... */
  157. {
  158. // -sdj unreferenced local var: INT i;
  159. LPBYTE ltmp;
  160. COMSTAT serInfo;
  161. DWORD dwErrors;
  162. DWORD dwBytesRead;
  163. OVERLAPPED overlap;
  164. BOOL bRc;
  165. overlap.hEvent = overlapEvent;
  166. overlap.Internal = 0;
  167. overlap.InternalHigh = 0;
  168. overlap.Offset = 0;
  169. overlap.OffsetHigh = 0;
  170. ResetEvent(overlapEvent);
  171. gotCommEvent = FALSE;
  172. bRc = ReadFile(sPort, serBytes+1, LOCALMODEMBUFSZ-1,
  173. (LPDWORD)&serCount, (LPOVERLAPPED)&overlap);
  174. if(!bRc && ((dwErrors = GetLastError()) != ERROR_IO_PENDING))
  175. {
  176. bRc = ClearCommError(sPort, &dwErrors, &serInfo); /* reset after error */
  177. if(trmParams.flowControl == ITMHARDFLOW)
  178. {
  179. if(serInfo.cbInQue < 100)
  180. {
  181. modemReset();
  182. }
  183. }
  184. if(serInfo.fXoffSent || serInfo.fCtsHold || serInfo.fDsrHold)
  185. {
  186. if(serInfo.cbInQue < 100)
  187. {
  188. modemReset();
  189. }
  190. }
  191. }
  192. else
  193. {
  194. if(!bRc && ((dwErrors = GetLastError()) == ERROR_IO_PENDING))
  195. {
  196. bRc = ClearCommError(sPort, &dwErrors, &serInfo);
  197. }
  198. if(!GetOverlappedResult(sPort, &overlap, &dwBytesRead, FALSE))
  199. return;
  200. if(serCount = dwBytesRead)
  201. {
  202. ltmp = serBytes+1;
  203. if(serCount != LOCALMODEMBUFSZ-1)
  204. {
  205. bRc = ClearCommError(sPort, &dwErrors, &serInfo); /* reset after error */
  206. if(trmParams.flowControl == ITMHARDFLOW) /* rjs bug2 003 */
  207. {
  208. if(serInfo.cbInQue < 100)
  209. {
  210. modemReset();
  211. }
  212. }
  213. if(serInfo.fXoffSent || serInfo.fCtsHold || serInfo.fDsrHold)
  214. {
  215. if(serInfo.cbInQue < 100)
  216. {
  217. modemReset();
  218. }
  219. }
  220. } /* if readfile cameout halfway through */
  221. else
  222. {
  223. gotCommEvent = TRUE; /* we read a full buffer, try again..*/
  224. }
  225. }
  226. } /* readfile succeded lets see the bytes read */
  227. }
  228. INT modemBytes() /* mbbx 2.00: network... */
  229. {
  230. LPCONNECTOR_CONTROL_BLOCK lpCCB; /* slc nova 031 */
  231. BYTE tmp1[TMPNSTR+1];
  232. BYTE tmp2[TMPNSTR+1];
  233. if(serNdx > 0)
  234. return(serCount - (serNdx-1));
  235. switch(trmParams.comDevRef)
  236. {
  237. case ITMWINCOM:
  238. //-sdj comments from checkcommevent():
  239. //-sdj for telnet-quit processing
  240. //-sdj if this is a telnet connection which was opened before and
  241. //-sdj the user hits cntl-c/bye/quit etc
  242. //-sdj the telnet service will stop talking
  243. //-sdj with us, but terminalapp still keeps
  244. //-sdj doing io without knowing that the handle
  245. //-sdj can only be closed now, The way we can
  246. //-sdj detect this is, to check if getlasterror
  247. //-sdj is ERROR_NETNAME_DELETED, if this is the
  248. //-sdj case then we should do exactly same thing
  249. //-sdj which we do when the user tries to go to
  250. //-sdj some other comm port, close this one, and
  251. //-sdj go to the next one.
  252. //-sdj by setting bPortDisconnected to TRUE,
  253. //-sdj further modemBytes()[reads] will stop on
  254. //-sdj this port, and modemBytes will prompt the
  255. //-sdj user to select some other port, and return.
  256. if (bPortDisconnected)
  257. {
  258. LoadString(hInst, STR_PORTDISCONNECT, (LPSTR) tmp1, TMPNSTR);
  259. LoadString(hInst, STR_ERRCAPTION, (LPSTR) tmp2, TMPNSTR);
  260. MessageBox(hItWnd, (LPSTR) tmp1, (LPSTR)tmp2, MB_OK | MB_APPLMODAL);
  261. serCount = 0; //so that return dword is 0, no chars to process
  262. // resetSerial(&trmParams, FALSE,TRUE,0);
  263. if(!trmParams.fResetDevice)
  264. trmParams.newDevRef = trmParams.comDevRef;
  265. exitSerial();
  266. doSettings(IDDBCOMM, dbComm);
  267. break;
  268. }
  269. if(gotCommEvent)
  270. {
  271. WIN_modemBytes();
  272. }
  273. else
  274. serCount = 0;
  275. break;
  276. case ITMDLLCONNECT: /* slc nova 012 bjw nova 002 */
  277. serCount = DLL_ConnectBytes(ghCCB); /* slc nova 031 */
  278. if((lpCCB = (LPCONNECTOR_CONTROL_BLOCK)GlobalLock(ghCCB)) != NULL) /* slc nova 031 */
  279. {
  280. if(serCount == CONNECT_READ_ERROR)
  281. serCount = lpCCB->wReadBufferRead;
  282. lmovmem((LPSTR)lpCCB->lpReadBuffer, (LPSTR)(serBytes + 1), (WORD)serCount);
  283. GlobalUnlock(ghCCB);
  284. }
  285. break;
  286. }
  287. if(serCount > 0)
  288. serNdx = 1; /* indicates chars to process */
  289. return(serCount);
  290. }
  291. /*---------------------------------------------------------------------------*/
  292. /* getMdmChar() - Get a modem character out of local buffer. [mbb] */
  293. /*---------------------------------------------------------------------------*/
  294. /* NOTE: modemBytes() must be called prior to this routine */
  295. BYTE getMdmChar(BOOL bText)
  296. {
  297. BYTE nextChar;
  298. nextChar = serBytes[serNdx++];
  299. if(serNdx > serCount)
  300. serNdx = 0;
  301. if(trmParams.parity != ITMNOPARITY)
  302. nextChar &= 0x7F;
  303. if(bText && (trmParams.language > ICS_NONE) && (termState == NULL)) /* mbbx 1.06A: ics new xlate... */
  304. {
  305. if(nextChar >= 0x80) /* slc swat */
  306. {
  307. if(trmParams.setIBMXANSI)
  308. nextChar = ansiXlateTable[nextChar]; /* IBM extended to ANSI */
  309. }
  310. else
  311. {
  312. if(trmParams.language > ICS_NONE)
  313. nextChar = icsXlateTable[nextChar]; /* ISO char to ANSI */
  314. }
  315. }
  316. return(nextChar);
  317. }
  318. /*---------------------------------------------------------------------------*/
  319. /* getRcvChar() - [mbb] */
  320. /*---------------------------------------------------------------------------*/
  321. BOOL getRcvChar(BYTE *theChar, BYTE charMask)
  322. {
  323. if(modemBytes())
  324. {
  325. *theChar = getMdmChar(FALSE);
  326. if(charMask != 0)
  327. *theChar &= charMask;
  328. return(TRUE);
  329. }
  330. *theChar = 0;
  331. return(FALSE);
  332. }
  333. /*---------------------------------------------------------------------------*/
  334. /* waitRcvChar() - [mbb] */
  335. /*---------------------------------------------------------------------------*/
  336. BOOL waitRcvChar(BYTE *theChar, WORD timeOut, BYTE charMask, BYTE charFirst, ...)
  337. {
  338. va_list ap;
  339. DWORD waitTicks; //-sdj was LONG, getcurrenttime,tickcount returns dword
  340. //-sdj this was causing a sign/unsign warning noise
  341. BYTE charList;
  342. waitTicks = tickCount() + (timeOut * 6);
  343. repeat
  344. {
  345. va_start(ap,charFirst);
  346. updateTimer();
  347. if(doneFlag)
  348. {
  349. xferStopped = TRUE;
  350. va_end(ap);
  351. return(FALSE);
  352. }
  353. if(xferStopped)
  354. break;
  355. gotCommEvent = TRUE;
  356. if(getRcvChar(theChar, charMask))
  357. {
  358. if(charFirst == 0)
  359. {
  360. va_end(ap);
  361. return(TRUE);
  362. }
  363. for(charList = charFirst; charList != 0; charList = va_arg(ap,BYTE))
  364. {
  365. if(charList == *theChar)
  366. {
  367. va_end(ap);
  368. return(TRUE);
  369. }
  370. }
  371. *theChar = 0;
  372. }
  373. //if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
  374. // mainEventLoop();
  375. //sdj: now that rcv and snd b file are threads the main
  376. //sdj: thread will deal with UI while the xfer is going on, so
  377. //sdj: no need of this hack to peek the msges.
  378. //sdj: but lets put sleep of 10ms so that we dont hog the CPU
  379. //sdj: and give chance for the buffer to fill and reduce number
  380. //sdj: of calls to ReadFile()
  381. Sleep(10);
  382. }
  383. until(tickCount() >= waitTicks);
  384. va_end(ap);
  385. return(FALSE);
  386. }
  387. /*---------------------------------------------------------------------------*/
  388. /* flushRBuf() - [mbb] */
  389. /*---------------------------------------------------------------------------*/
  390. VOID flushRBuff()
  391. {
  392. if(modemBytes())
  393. delay(6, NULL); /* mbbx: wtf??? */
  394. while(modemBytes())
  395. serNdx = 0; /* mbbx: dump serBytes data */
  396. }
  397. /*---------------------------------------------------------------------------*/
  398. /* checkUserAbort() - [mbb] */
  399. /*---------------------------------------------------------------------------*/
  400. BOOL checkUserAbort()
  401. {
  402. BOOL checkUserAbort = FALSE;
  403. return(FALSE);
  404. if(PeekMessage(&msg, hdbXferCtrls, 0, 0, PM_REMOVE))
  405. {
  406. if((msg.hwnd != xferCtlStop) ||
  407. (msg.message < WM_MOUSEFIRST) ||
  408. (msg.message > WM_MOUSELAST))
  409. {
  410. IsDialogMessage(hdbXferCtrls, &msg);
  411. }
  412. }
  413. while(PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
  414. {
  415. if((msg.message == WM_KEYDOWN) && (msg.wParam == VK_CANCEL))
  416. checkUserAbort = TRUE;
  417. }
  418. return(checkUserAbort);
  419. }
  420. /*---------------------------------------------------------------------------*/
  421. /* modemWrite() - Send data to comm port (no special processing here) [mbb] */
  422. /*---------------------------------------------------------------------------*/
  423. BOOL NEAR WIN_modemWrite(LPSTR lpData, INT nSize)
  424. {
  425. BOOL modemWrite = TRUE;
  426. BOOL bWriteFile;
  427. INT nRemain;
  428. INT nBytes;
  429. INT nSent;
  430. COMSTAT serInfo;
  431. // -sdj unreferenced local var: BYTE str[80];
  432. DWORD dwErrors;
  433. OVERLAPPED overlap;
  434. BOOL bRc;
  435. overlap.hEvent = overlapEvent;
  436. overlap.Internal = 0;
  437. overlap.InternalHigh = 0;
  438. overlap.Offset = 0;
  439. overlap.OffsetHigh = 0;
  440. for(nRemain = nSize; nRemain > 0; nRemain -= nSent)
  441. {
  442. nBytes = nRemain;
  443. bWriteFile = WriteFile(sPort, (LPVOID) (lpData+(nSize-nRemain)),
  444. nBytes, (LPDWORD) &nSent,
  445. (LPOVERLAPPED)&overlap);
  446. dwErrors = GetLastError();
  447. if ((!bWriteFile) && (dwErrors != ERROR_IO_PENDING))
  448. {
  449. bRc = ClearCommError(sPort, &dwErrors, &serInfo);
  450. if(serInfo.fXoffSent || serInfo.fCtsHold)
  451. {
  452. if(serInfo.fCtsHold)
  453. {
  454. sPortErr = TRUE;
  455. return(FALSE);
  456. }
  457. rxEventLoop(); /* jtf 3.20 */
  458. if ( (xferStopped == TRUE) && (xferFlag != XFRNONE) ) /* jtf 3.33 3.30 */
  459. {
  460. modemWrite = TRUE;
  461. return(modemWrite); /* jtf 3.30 */
  462. }
  463. if(checkUserAbort()) /* mbbx: see if CTRL BREAK hit */
  464. {
  465. switch(trmParams.flowControl) /* mbbx 1.10: CUA... */
  466. {
  467. case ITMXONFLOW:
  468. modemReset();
  469. break;
  470. case ITMHARDFLOW: /* drastic ... */
  471. trmParams.flowControl = ITMNOFLOW;
  472. resetSerial(&trmParams, FALSE, FALSE, 0);
  473. break;
  474. }
  475. modemWrite = FALSE;
  476. break;
  477. }/* if checkUserAbort */
  478. }/* if serInfo.hold */
  479. }/* if writeComm */
  480. else
  481. {
  482. if(!bWriteFile)
  483. if(dwErrors != ERROR_IO_PENDING)
  484. {
  485. bRc = ClearCommError(sPort, &dwErrors, &serInfo);
  486. modemWrite = FALSE;
  487. nSent = 0;
  488. }
  489. else
  490. {
  491. if(WaitForSingleObject(overlapEvent, dwWriteFileTimeout) == 0)
  492. {
  493. GetOverlappedResult(sPort, &overlap, (LPDWORD)&nSent, TRUE);
  494. }
  495. else
  496. {
  497. ResetEvent(overlapEvent);
  498. bRc = ClearCommError(sPort, &dwErrors, &serInfo);
  499. nSent = 0;
  500. }
  501. }
  502. #ifdef SLEEP_FOR_CONTEXT_SWITCH
  503. Sleep((DWORD)5);
  504. #endif
  505. // if(!nSent)
  506. // {
  507. // modemWrite = FALSE;
  508. // break;
  509. // }
  510. }
  511. }/* for */
  512. if(xferBreak) /* mbbx 2.00: xfer ctrls... */
  513. {
  514. setXferCtrlButton(IDSTOP, STR_STOP);
  515. xferBreak = FALSE;
  516. }
  517. return(modemWrite);
  518. }/* WIN_modemWrite */
  519. /* ----------------------------------------------------------------------- */
  520. BOOL modemWrite(LPSTR lpData, INT nSize)
  521. {
  522. LPCONNECTOR_CONTROL_BLOCK lpCCB; /* slc nova 031 */
  523. BOOL bResult = FALSE; /* slc swat */
  524. if (nSize == 0) /* mbbx 2.00.04: check outgoing buffer... */
  525. {
  526. switch(trmParams.comDevRef)
  527. {
  528. case ITMDLLCONNECT: /* slc nova 028 */
  529. if((lpCCB = (LPCONNECTOR_CONTROL_BLOCK)GlobalLock(ghCCB)) != NULL)
  530. {
  531. lpCCB->wWriteBufferUsed = (WORD)nSize; /* slc nova 031 */
  532. GlobalUnlock(ghCCB);
  533. DLL_WriteConnector(ghCCB);
  534. }
  535. break;
  536. case ITMWINCOM:
  537. default:
  538. break;
  539. }
  540. return(TRUE);
  541. }
  542. /* We cannot allow recursive calls to the modemWrite() sub,
  543. cuz we stack overflow! Design issue: caller should check
  544. this return value and re-call with same data!
  545. */
  546. if(bgOutStandingWrite) /* slc swat */
  547. {
  548. sysBeep();
  549. return(FALSE);
  550. }
  551. else
  552. bgOutStandingWrite = TRUE;
  553. switch(trmParams.comDevRef)
  554. {
  555. case ITMWINCOM:
  556. bResult = WIN_modemWrite(lpData, nSize);
  557. break;
  558. case ITMDLLCONNECT: /* slc nova 012 bjw nova 002 */
  559. if((lpCCB = (LPCONNECTOR_CONTROL_BLOCK)GlobalLock(ghCCB)) != NULL) /* slc nova 031 */
  560. {
  561. if(lpCCB->lpWriteBuffer) /* seh nova 005 */
  562. {
  563. lmovmem((LPSTR)lpData, (LPSTR)lpCCB->lpWriteBuffer, (WORD)nSize); /* seh nova 005 */
  564. lpCCB->wWriteBufferUsed = (WORD)nSize; /* seh nova 005 */
  565. GlobalUnlock(ghCCB); /* slc nova 031 */
  566. bResult = DLL_WriteConnector(ghCCB);
  567. }
  568. }
  569. break;
  570. }/* switch */
  571. bgOutStandingWrite = FALSE; /* slc swat */
  572. return(bResult);
  573. }
  574. /*---------------------------------------------------------------------------*/
  575. /* modemWr() - Send character to the windows serial port driver. [mbb] */
  576. /*---------------------------------------------------------------------------*/
  577. VOID modemWr(BYTE theByte)
  578. {
  579. BYTE saveByte = theByte;
  580. BYTE ISOByte;
  581. if((theByte >= 0x80) && (xferFlag < XFRBSND)) /* mbbx 1.10: VT220 8BIT... */
  582. {
  583. if(trmParams.language > ICS_NONE)
  584. ISOByte = icsXlateTable[theByte];
  585. else
  586. ISOByte = theByte;
  587. if(trmParams.setIBMXANSI)
  588. {
  589. if(ISOByte >= 0x80) /* was not ISO */
  590. theByte = ansiXlateTable[theByte & 0x7F]; /* ANSI to IBM extended */
  591. }
  592. else
  593. theByte = ISOByte;
  594. }
  595. else if((theByte == CR) && (trmParams.emulate == ITMDELTA))
  596. theByte = XOFF;
  597. if(!modemWrite((LPSTR) &theByte, 1))
  598. return;
  599. if(trmParams.localEcho && (xferFlag < XFRTYP))
  600. {
  601. modemInp(saveByte, FALSE);
  602. if((theByte == CR) && (xferFlag == XFRSND))
  603. modemInp(LF, FALSE);
  604. }
  605. if(trmParams.outCRLF && (theByte == CR) && (xferFlag == XFRNONE)) /* mbbx 2.00: heed outCRLF... */
  606. modemWr(LF); /* yikes! it's recursive!!! */
  607. }
  608. /*---------------------------------------------------------------------------*/
  609. /* termStr() - Send PASCAL character string to the modem. [mbb] */
  610. /*---------------------------------------------------------------------------*/
  611. VOID termStr(STRING *tStr, INT nDelay, BOOL crFlag)
  612. {
  613. WORD ndx;
  614. for(ndx = 1; ndx <= *tStr; ndx++)
  615. {
  616. modemWr(tStr[ndx]);
  617. if(nDelay > 0)
  618. delay(nDelay, NULL);
  619. if(!dialing)
  620. idleProcess();
  621. }
  622. if(crFlag)
  623. modemWr(CR);
  624. }
  625. DWORD checkCommEvent(LPVOID lpThreadParameter)
  626. {
  627. DWORD eventMask;
  628. HANDLE hEvent;
  629. OVERLAPPED OverLapped;
  630. DWORD dwGetLastError;
  631. // eventMask = EV_RXCHAR | EV_ERR | EV_BREAK | EV_CTS | EV_DSR;
  632. eventMask = EV_RXCHAR;
  633. SetCommMask(sPort, eventMask);
  634. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  635. OverLapped.hEvent = hEvent;
  636. while(TRUE)
  637. {
  638. if(bPortIsGood && (sPort != NULL) && (sPort != (HANDLE)-1) && (!CommThreadExit) )
  639. {
  640. if(WaitForSingleObject(hMutex, 50) == 0)
  641. {
  642. eventMask = EV_RXCHAR;
  643. // SetCommMask(sPort, eventMask);
  644. if(WaitCommEvent(sPort, (LPDWORD)&eventMask, &OverLapped))
  645. {
  646. gotCommEvent = TRUE;
  647. }
  648. else
  649. {
  650. dwGetLastError = GetLastError();
  651. if (dwGetLastError == ERROR_IO_PENDING)
  652. {
  653. DWORD Trash;
  654. GetOverlappedResult(
  655. sPort,
  656. &OverLapped,
  657. &Trash,
  658. TRUE
  659. );
  660. gotCommEvent = TRUE;
  661. }
  662. else {
  663. //-sdj for telnet-quit processing
  664. //-sdj if this is a telnet connection and
  665. //-sdj the user hits cntl-c/bye/quit etc
  666. //-sdj the telnet service will stop talking
  667. //-sdj with us, but terminalapp still keeps
  668. //-sdj doing io without knowing that the handle
  669. //-sdj can only be close now, The way we can
  670. //-sdj detect this is, to check if getlasterror
  671. //-sdj is ERROR_NETNAME_DELETED, if this is the
  672. //-sdj case then we should do exactly same thing
  673. //-sdj which we do when the user tries to go to
  674. //-sdj some other comm port, close this one, and
  675. //-sdj go to the next one.
  676. //-sdj by setting bPortDisconnected to TRUE,
  677. //-sdj further modemBytes()[reads] will stop on
  678. //-sdj this port, and modemBytes will prompt the
  679. //-sdj user to select some other port, and return.
  680. CloseHandle(sPort); // only valid operation in this state
  681. sPort = NULL; // this will prevent checkcommevent to
  682. // attempt unnecessary waits untill sPort
  683. // becomes valid, and bPortDisconnected
  684. // is set back to FALSE by modembytes/resetserial
  685. bPortDisconnected = TRUE;
  686. }
  687. }
  688. if(CommThreadExit) // was ,doneFlag but doneFlag
  689. // does not get set for sometime
  690. // even after the comm port closes
  691. // so exit the thread when you know
  692. // that the port is going to get closed
  693. // This flag is init to false and set
  694. // to true just before calling exitserial
  695. // in termfile.c
  696. {
  697. gbThreadDoneFlag = TRUE;
  698. ReleaseMutex(hMutex);
  699. ResetEvent(hEvent);
  700. ExitThread((DWORD)0);
  701. }
  702. ReleaseMutex(hMutex);
  703. eventMask = EV_RXCHAR;
  704. } // wait on mutex
  705. #ifdef SLEEP_FOR_CONTEXT_SWITCH
  706. Sleep((DWORD)3);
  707. #endif
  708. ResetEvent(hEvent);
  709. } // good sPort
  710. else
  711. {
  712. if(CommThreadExit) // was doneFlag : see above for comments
  713. {
  714. gbThreadDoneFlag = TRUE;
  715. ReleaseMutex(hMutex);
  716. ResetEvent(hEvent);
  717. ExitThread((DWORD)0);
  718. }
  719. Sleep((DWORD)3); // -sdj either the comm port handle is changing
  720. // or it is invalid, so instead of doing
  721. // a tight while-true, sleep each time you
  722. // come here, so that others get a chance
  723. }
  724. }
  725. return 0;
  726. }