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.

496 lines
15 KiB

  1. /*===========================================================================*/
  2. /* Copyright (c) 1987 - 1988, Future Soft Engineering, Inc. */
  3. /* Houston, Texas */
  4. /*===========================================================================*/
  5. #define NOGDICAPMASKS TRUE
  6. #define NOVIRTUALKEYCODES TRUE
  7. #define NOICONS TRUE
  8. #define NOKEYSTATES TRUE
  9. #define NOSYSCOMMANDS TRUE
  10. #define NOATOM TRUE
  11. #define NOCLIPBOARD TRUE
  12. #define NODRAWTEXT TRUE
  13. #define NOMINMAX TRUE
  14. #define NOOPENFILE TRUE
  15. #define NOSCROLL TRUE
  16. #define NOHELP TRUE
  17. #define NOPROFILER TRUE
  18. #define NODEFERWINDOWPOS TRUE
  19. #define NOPEN TRUE
  20. #define NO_TASK_DEFINES TRUE
  21. #define NOLSTRING TRUE
  22. #define WIN31
  23. #define USECOMM
  24. #include <windows.h>
  25. #include <port1632.h>
  26. #include "dcrc.h"
  27. #include "dynacomm.h"
  28. #include "connect.h"
  29. /*---------------------------------------------------------------------------*/
  30. /* exitSerial() - [mbb/rkh] */
  31. /*---------------------------------------------------------------------------*/
  32. VOID NEAR WIN_exitSerial() /* mbbx 2.00: network... */
  33. {
  34. DCB dcb;
  35. if(GetCommState(sPort, (DCB FAR *) &dcb) == 0) /* mbbx 1.04: RTS/DTR disable... */
  36. {
  37. dcb.fRtsControl = RTS_CONTROL_DISABLE;
  38. dcb.fDtrControl = DTR_CONTROL_DISABLE;
  39. EscapeCommFunction(sPort,CLRRTS);
  40. EscapeCommFunction(sPort,CLRDTR);
  41. DEBOUT("SetCommState from Win_exitSerial for comport=%lx\n",sPort);
  42. if(!SetCommState(sPort,(DCB FAR *) &dcb))
  43. {
  44. DEBOUT("FAIL: SetCommState from Win_exitSerial for comport=%lx\n",sPort);
  45. }
  46. }
  47. #ifdef ORGCODE
  48. FlushComm(sPort, 1);
  49. FlushComm(sPort, 0);
  50. #else
  51. DEBOUT("FlushFileBuffers from Win_exitSerial: comport %lx\n",sPort);
  52. #ifndef BUGBYPASS
  53. DEBOUT("FlushFileBuffers from Win_exitSerial: BYPASSING FLUSH DUE TO BUG %lx\n",sPort);
  54. #else
  55. if (!FlushFileBuffers(sPort))
  56. {
  57. DEBOUT("FAIL: FlushFileBuffers comport %lx\n",sPort);
  58. }
  59. #endif
  60. DEBOUT("PurgeComm from Win_exitSerial:comport %lx\n",sPort);
  61. if (!PurgeComm(sPort,0))
  62. {
  63. DEBOUT("FAIL: PurgeComm comport %lx\n",sPort);
  64. }
  65. #endif
  66. SetCommMask(sPort, EV_RXCHAR);
  67. //WaitForSingleObject(hMutex, 500);
  68. bPortIsGood = FALSE;
  69. /**********
  70. {
  71. // Make suer sPort gets closed, bug#9671
  72. // Actually a bug in serial driver, The fix is a
  73. // quick hack, should be removed once the driver
  74. // is fixed.
  75. int cnt=20;
  76. while (cnt-- && CloseHandle(sPort)) Sleep (200);
  77. }
  78. **********/
  79. //
  80. // We can't close the handle twice now.
  81. // So, just close it and wait a little.
  82. //
  83. Sleep (200);
  84. CloseHandle (sPort);
  85. Sleep (200);
  86. sPort = NULL;
  87. //ReleaseMutex(hMutex);
  88. }
  89. VOID exitSerial() /* mbbx 2.00: network... */
  90. {
  91. switch(trmParams.comDevRef)
  92. {
  93. case ITMWINCOM:
  94. WIN_exitSerial();
  95. break;
  96. case ITMDLLCONNECT: /* slc nova 012 bjw nova 02 */
  97. DLL_ExitConnector(ghCCB, &trmParams); /* slc nova 031 */
  98. break;
  99. }
  100. trmParams.comDevRef = ITMNOCOM;
  101. }
  102. /*---------------------------------------------------------------------------*/
  103. /* resetSerial() - [mbb/rkh] */
  104. /*---------------------------------------------------------------------------*/
  105. VOID NEAR WIN_resetSerial(recTrmParams *trmParams, BOOL bLoad, NEARPROC errProc)
  106. {
  107. INT attempts;
  108. // sdj: this is replaced by global szCurrentPortName ;BYTE tmp1[TMPNSTR+1];
  109. BYTE tmp1[TMPNSTR+1],tmp2[TMPNSTR+1];
  110. DCB dcb;
  111. DCB PrevDcb;
  112. COMMTIMEOUTS CommTimeOuts;
  113. BOOL bRc;
  114. DWORD dwError;
  115. COMMPROP CommProp; // -sdj sep92 on low mem rx buffer can be < 1024
  116. modemReset(); /* mbbx 0.72: avoid hang if XOFF-ed */
  117. if(bLoad)
  118. {
  119. for(attempts = 0; trmParams->comDevRef == ITMNOCOM; attempts += 1)
  120. {
  121. if(trmParams->comPortRef > MaxComPortNumberInMenu)
  122. strcpy(szCurrentPortName, "\\\\.\\TELNET");
  123. else
  124. {
  125. // LoadString(hInst, STR_COM, (LPSTR) tmp2, MINRESSTR);
  126. // sprintf(szCurrentPortName, tmp2, trmParams->comPortRef);
  127. strcpy(szCurrentPortName,arComNumAndName[trmParams->comPortRef].PortName);
  128. }
  129. if( (sPort != NULL) && (sPort != (HANDLE)-1) )
  130. {
  131. SetCommMask(sPort, 0); // so that waitcommevent comes out; -sdj
  132. sPort = NULL;
  133. }
  134. sPort = CreateFile(szCurrentPortName, GENERIC_READ|GENERIC_WRITE, 0, NULL,
  135. OPEN_EXISTING,
  136. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
  137. if (sPort == (HANDLE)-1)
  138. {
  139. dwError = GetLastError();
  140. bPortIsGood = FALSE;
  141. if(!(*errProc)(trmParams, attempts))
  142. return;
  143. }
  144. else
  145. {
  146. SetCommMask(sPort, EV_RXCHAR); // -sdj 27apr92 telnet deadlock
  147. dwWriteFileTimeout = 5000; // -sdj 28apr92 telnet debug
  148. trmParams->comDevRef = ITMWINCOM;
  149. CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
  150. CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
  151. CommTimeOuts.ReadTotalTimeoutConstant = 0;
  152. CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
  153. if (trmParams->flowControl == ITMHARDFLOW)
  154. {
  155. CommTimeOuts.WriteTotalTimeoutConstant = 5000; // 5msecs
  156. }
  157. else
  158. {
  159. CommTimeOuts.WriteTotalTimeoutConstant = 10000; //10secs
  160. }
  161. if (!(bRc = SetCommTimeouts(sPort,&CommTimeOuts) ) )
  162. {
  163. if(!(*errProc)(trmParams, attempts))
  164. return;
  165. }
  166. // There may be data already waiting to be read - i.e. data
  167. // that arrived before we set comm mask. This data will not
  168. // be uncovered by wait mask, so we must try to read it.
  169. gotCommEvent = TRUE;
  170. }
  171. } // endof for
  172. } // endof if bload
  173. /* This would work on both win30 and win32 -sdj*/
  174. /* if(GetCommState(sPort, (DCB FAR *) &dcb) == 0) -sdj*/
  175. DEBOUT("HACK : %s\n","rc of GetCommState: not checked for now");
  176. {
  177. GetCommState(sPort, (DCB FAR *) &dcb);
  178. GetCommState(sPort, (DCB FAR *) &PrevDcb);
  179. // -sdj sep92 on low mem rx buffer can be < 1024
  180. // -sdj set rx buffer to nice 4096 bytes size
  181. // -sdj driver will do its best and set the Rx buffer to this size
  182. // -sdj if it fails then dwCurrentRxQueue will be the one we have
  183. // -sdj so do getcommprop again to fetch this value, which can
  184. // -sdj be used to set xoff and xon lims
  185. GetCommProperties(sPort,&CommProp);
  186. SetupComm(sPort,4096,4096);
  187. CommProp.dwCurrentRxQueue = 0; // -sdj dirty it so that we
  188. // -sdj can use this only if !=0
  189. GetCommProperties(sPort,&CommProp);
  190. // sdj: added this code to take care of extra baud rates support
  191. if (trmParams->speed <= 57600)
  192. {
  193. dcb.BaudRate = trmParams->speed; /* mbbx 2.00: allow any baud... */
  194. }
  195. else
  196. {
  197. if (trmParams->speed == 57601)
  198. {
  199. // sdj: this means 115.2K baud rate which cannot fit into BYTE!
  200. dcb.BaudRate = 115200;
  201. }
  202. else{
  203. if (trmParams->speed == 57602)
  204. {
  205. dcb.BaudRate = 128000;
  206. }
  207. else
  208. {
  209. // sdj: something wrong! default to 1200
  210. dcb.BaudRate = 1200;
  211. }
  212. }
  213. }
  214. dcb.ByteSize = 8 + (trmParams->dataBits - ITMDATA8);
  215. dcb.Parity = NOPARITY + (trmParams->parity - ITMNOPARITY);
  216. dcb.StopBits = ONESTOPBIT + (trmParams->stopBits - ITMSTOP1);
  217. // dcb.RlsTimeout = 0;
  218. // dcb.CtsTimeout = (trmParams->flowControl == ITMHARDFLOW) ? 5 : 0; /* mbbx 1.10: CUA */
  219. // dcb.DsrTimeout = 0;
  220. dcb.fBinary = TRUE;
  221. dcb.fRtsControl = RTS_CONTROL_ENABLE;
  222. dcb.fParity = trmParams->fParity; /* mbbx 1.10: CUA */
  223. dcb.fOutxCtsFlow = (trmParams->flowControl == ITMHARDFLOW); /* mbbx 1.10: CUA... */
  224. dcb.fOutxDsrFlow = FALSE;
  225. dcb.fDtrControl = DTR_CONTROL_ENABLE;
  226. dcb.fOutX =
  227. dcb.fInX = (trmParams->flowControl == ITMXONFLOW);
  228. dcb.fErrorChar = trmParams->fParity; /* mbbx 1.10: CUA */
  229. dcb.fNull = FALSE;
  230. // dcb.fChEvt = FALSE;
  231. // dcb.fDtrFlow = FALSE;
  232. if (trmParams->flowControl == ITMHARDFLOW)
  233. {
  234. dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; /* mbbx 1.10: CUA... */
  235. }
  236. dcb.XonChar = XON;
  237. dcb.XoffChar = XOFF;
  238. /* -sdj sep92, this is 1k/4=256, 9M system can have RXQ=256
  239. -sdj in that case SetCommState can fail due to invalid
  240. -sdj parameters of xoff xon limits
  241. dcb.XonLim = NINQUEUE / 4;
  242. dcb.XoffLim = NINQUEUE / 4;
  243. */
  244. // -sdj if for some wierd reason dwCurrentRxQueue is not
  245. // -sdj filled in by the driver, then let xon xoff lims
  246. // -sdj be the default which the driver has.
  247. // -sdj (dwCurrentRxQueue was set to 0 before calling Get again)
  248. if (CommProp.dwCurrentRxQueue != 0)
  249. {
  250. dcb.XonLim = (WORD)(CommProp.dwCurrentRxQueue / 4);
  251. dcb.XoffLim = (WORD)(CommProp.dwCurrentRxQueue / 4);
  252. }
  253. dcb.ErrorChar = '?';
  254. dcb.EofChar = CNTRLZ;
  255. dcb.EvtChar = 0;
  256. dcb.wReserved = 0;
  257. #ifdef ORGCODE
  258. if(SetCommState((DCB FAR *) &dcb) == 0)
  259. {
  260. #else
  261. if(SetCommState(sPort, (DCB FAR *) &dcb) == 0)
  262. {
  263. DEBOUT("FAIL: SetCommState for comport=%lx\n",sPort);
  264. #endif
  265. mdmOnLine = FALSE; /* mbbx 1.10: carrier... */
  266. mdmConnect();
  267. LoadString(hInst, STR_SETCOMFAIL, (LPSTR) tmp1, TMPNSTR);
  268. LoadString(hInst, STR_ERRCAPTION, (LPSTR) tmp2, TMPNSTR);
  269. MessageBox(hItWnd, (LPSTR) tmp1, (LPSTR)tmp2, MB_OK | MB_APPLMODAL);
  270. SetCommState(sPort,&PrevDcb);
  271. return;
  272. }
  273. #ifdef ORGCODE
  274. #else
  275. /*DWORD ReadIntervalTimeout; Maximum time between read chars. */
  276. /*DWORD ReadTotalTimeoutMultiplier; Multiplier of characters. */
  277. /*DWORD ReadTotalTimeoutConstant; Constant in milliseconds. */
  278. /*DWORD WriteTotalTimeoutMultiplier; Multiplier of characters. */
  279. /*DWORD WriteTotalTimeoutConstant; Constant in milliseconds. */
  280. DEBOUT("Win_resetSerial: %s\n","Setting Comm timeouts");
  281. CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
  282. CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
  283. CommTimeOuts.ReadTotalTimeoutConstant = 0;
  284. CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
  285. if (trmParams->flowControl == ITMHARDFLOW)
  286. {
  287. CommTimeOuts.WriteTotalTimeoutConstant = 5000; //5 msecs
  288. }
  289. else
  290. {
  291. CommTimeOuts.WriteTotalTimeoutConstant = 10000; //10secs
  292. }
  293. if (!(bRc = SetCommTimeouts(sPort,&CommTimeOuts) ) )
  294. {
  295. DEBOUT("FAIL: SetCommTimeouts failed rc: %lx\n",bRc);
  296. mdmOnLine = FALSE; /* mbbx 1.10: carrier... */
  297. mdmConnect();
  298. return;
  299. }
  300. #endif
  301. }
  302. bPortIsGood = TRUE; /* now the port is properly initialized -sdj 05/21/92*/
  303. //-sdj for telnet-quit processing
  304. bPortDisconnected = FALSE; /* there is no problem of port_was_opened_but_not_working */
  305. }
  306. VOID resetSerial(recTrmParams *trmParams, BOOL bLoad,BOOL bInit,BYTE byFlowFlag) /* slc swat */
  307. {
  308. /* LPCONNECTOR_CONTROL_BLOCK lpCCB; -sdj no unref variables please ; slc nova 031 */
  309. if(bLoad)
  310. {
  311. if(!trmParams->fResetDevice)
  312. trmParams->newDevRef = trmParams->comDevRef;
  313. exitSerial();
  314. }
  315. switch(bLoad ? trmParams->newDevRef : trmParams->comDevRef)
  316. {
  317. case ITMNOCOM:
  318. break;
  319. default: // case ITMWINCOM:
  320. WIN_resetSerial(trmParams, bLoad, bInit ? (NEARPROC)resetSerialError0 : (NEARPROC)resetSerialError1 /*, byFlowFlag*/); /* slc swat */
  321. break;
  322. #ifdef OLDCODE
  323. case ITMWINCOM:
  324. WIN_resetSerial(trmParams, bLoad, bInit ? (NEARPROC)resetSerialError0 : (NEARPROC)resetSerialError1 /*, byFlowFlag*/); /* slc swat */
  325. break;
  326. case ITMDLLCONNECT: /* slc nova 012 bjw nova 002 */
  327. if((lpCCB = (LPCONNECTOR_CONTROL_BLOCK)GlobalLock(ghCCB)) != NULL) /* slc nova 031 */
  328. {
  329. if(lpCCB->hConnectorInst == NULL) /* first time? */
  330. if(!loadConnector(NULL, ghCCB, (LPSTR)trmParams->szConnectorName, FALSE))
  331. return;
  332. GlobalUnlock(ghCCB);
  333. trmParams->comDevRef = ITMDLLCONNECT;
  334. DLL_SetupConnector(ghCCB, FALSE); /* slc nova 031 */
  335. }
  336. break;
  337. #endif
  338. }
  339. trmParams->fResetDevice = FALSE;
  340. }
  341. /*---------------------------------------------------------------------------*/
  342. /* resetSerialError0 - called during initialization; [mbb] */
  343. /* auto attempt other COM port, then fail */
  344. /*---------------------------------------------------------------------------*/
  345. BOOL PASCAL NEAR resetSerialError0(recTrmParams *trmParams, WORD count)
  346. {
  347. BYTE tmp1[TMPNSTR+1];
  348. BYTE tmp2[TMPNSTR+1];
  349. //sdj: if this is a telnet port then advice the user to go to
  350. //sdj: the control panel and see if telnet service is started
  351. //sdj: else stick with the original msg of selected com port not
  352. //sdj: available, select other port.
  353. if (!strcmp(szCurrentPortName,"\\\\.\\TELNET"))
  354. {
  355. LoadString(hInst, STR_TELNETFAIL, (LPSTR) tmp1, TMPNSTR);
  356. }
  357. else
  358. {
  359. LoadString(hInst, STR_OTHERCOM, (LPSTR) tmp1, TMPNSTR);
  360. }
  361. LoadString(hInst, STR_ERRCAPTION, (LPSTR) tmp2, TMPNSTR);
  362. MessageBox(hItWnd, (LPSTR) tmp1, (LPSTR)tmp2, MB_OK | MB_APPLMODAL);
  363. doSettings(IDDBCOMM, dbComm);
  364. return(FALSE);
  365. }
  366. /*---------------------------------------------------------------------------*/
  367. /* resetSerialError1 - default case (e.g., after loading settings) [mbb] */
  368. /* prompt to attempt other COM port, then fail */
  369. /*---------------------------------------------------------------------------*/
  370. BOOL PASCAL NEAR resetSerialError1(recTrmParams *trmParams, WORD count)
  371. {
  372. BYTE tmp1[TMPNSTR+1];
  373. BYTE tmp2[TMPNSTR+1];
  374. if(count > 0)
  375. {
  376. LoadString(hInst, STR_NOCOMMPORTS, (LPSTR) tmp1, TMPNSTR); /* mbbx 1.00 */
  377. testMsg(tmp1,NULL,NULL);
  378. }
  379. else
  380. {
  381. //sdj: if this is a telnet port then advice the user to go to
  382. //sdj: the control panel and see if telnet service is started
  383. //sdj: else stick with the original msg of selected com port not
  384. //sdj: available, select other port.
  385. if (!strcmp(szCurrentPortName,"\\\\.\\TELNET"))
  386. {
  387. LoadString(hInst, STR_TELNETFAIL, (LPSTR) tmp1, TMPNSTR);
  388. }
  389. else
  390. {
  391. LoadString(hInst, STR_OTHERCOM, (LPSTR) tmp1, TMPNSTR);
  392. }
  393. LoadString(hInst, STR_ERRCAPTION, (LPSTR) tmp2, TMPNSTR);
  394. MessageBox(hItWnd, (LPSTR) tmp1, (LPSTR)tmp2, MB_OK | MB_APPLMODAL);
  395. trmParams->comPortRef = ITMNOCOM; /* mbbx 1.10: CUA */
  396. }
  397. return(FALSE);
  398. }
  399.