Leaked source code of windows server 2003
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.

1835 lines
44 KiB

  1. /* com.c -- High level com routines
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 15 $
  7. * $Date: 7/08/02 6:40p $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. // #define DEBUGSTR
  12. #include <time.h>
  13. #include "stdtyp.h"
  14. #include "session.h"
  15. #include "cnct.h"
  16. #include "assert.h"
  17. #include "mc.h"
  18. #include "cloop.h"
  19. #include "tdll.h"
  20. #include "sf.h"
  21. #include "htchar.h"
  22. #include "com.h"
  23. #include "comdev.h"
  24. #include "com.hh"
  25. #include <comstd\comstd.hh> // Drivers are linked directly in in this vers.
  26. #if defined(INCL_WINSOCK)
  27. #include <comwsock\comwsock.hh>
  28. #endif // defined(INCL_WINSOCK)
  29. #include "XFER_MSC.HH" // XD_TYPE
  30. int WINAPI WsckDeviceInitialize(HCOM hCom,
  31. unsigned nInterfaceVersion,
  32. void **ppvDriverData);
  33. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  34. * FUNCTION: ComCreateHandle
  35. *
  36. * DESCRIPTION:
  37. * Creates a communications handle to be used with subsequent Com calls.
  38. * The resulting com handle will not be associated with any actual device
  39. * or port initially.
  40. *
  41. * ARGUMENTS:
  42. * hSession -- Session handle of session creating com handle
  43. * hwndNotify -- Window to receive Com notifications
  44. * phcom -- pointer to a var. of type HCOM to receive new com handle
  45. *
  46. * RETURNS:
  47. * COM_OK
  48. * COM_NOT_ENOUGH_MEMORY if there is insufficient memory
  49. * COM_FAILED if resources could not be obtained
  50. * COM_INVALID_HANDLE if handle to Com is invalid
  51. */
  52. int ComCreateHandle(const HSESSION hSession, HCOM *phcom)
  53. {
  54. int iRet = COM_OK;
  55. HCOM pstCom;
  56. DBGOUT_NORMAL("+ComCreateHandle for session %08lX\r\n", hSession,0,0,0,0);
  57. assert(phcom);
  58. if (phcom)
  59. {
  60. pstCom = *phcom;
  61. if(pstCom && ComValidHandle(pstCom))
  62. {
  63. // Disconnect from driver
  64. ComFreeDevice(pstCom);
  65. if (pstCom->hRcvEvent)
  66. {
  67. ResetEvent(pstCom->hRcvEvent);
  68. CloseHandle(pstCom->hRcvEvent);
  69. pstCom->hRcvEvent = NULL;
  70. }
  71. if (pstCom->hSndReady)
  72. {
  73. ResetEvent(pstCom->hSndReady);
  74. CloseHandle(pstCom->hSndReady);
  75. pstCom->hSndReady = NULL;
  76. }
  77. *phcom = NULL;
  78. }
  79. }
  80. // See if we can get memory for a handle
  81. if ((pstCom = malloc(sizeof(*pstCom))) == NULL)
  82. {
  83. // This error can't be reported by ComReportError because no
  84. // Com Handle exists yet.
  85. //* utilReportError(hSession, RE_ERROR | RE_OK, NM_NEED_MEM,
  86. //* strldGet(mGetStrldHdl(hSession), NM_CREATE_SESSION));
  87. DBGOUT_NORMAL("-ComCreateHandle returning COM_NOT_ENOUGH_MEMORY",
  88. 0,0,0,0,0);
  89. iRet = COM_NOT_ENOUGH_MEMORY;
  90. goto Checkout;
  91. }
  92. // Initialize to all zeros just to be on the safe side
  93. memset(pstCom, 0, sizeof(*pstCom));
  94. // ComInitHdl will initialize most values. We must pre-initialize
  95. // enough so that ComInitHdl knows if it needs to shut anything down.
  96. pstCom->hSession = hSession;
  97. pstCom->hDriverModule = (HANDLE)0;
  98. pstCom->fPortActive = FALSE;
  99. pstCom->nGuard = COM_VERSION;
  100. pstCom->hRcvEvent = NULL;
  101. pstCom->hSndReady = NULL;
  102. pstCom->hRcvEvent = CreateEvent(NULL,
  103. TRUE, // must be manually reset
  104. FALSE, // create unsignalled
  105. NULL); // unnamed
  106. if (pstCom->hRcvEvent == NULL)
  107. {
  108. iRet = COM_FAILED;
  109. goto Checkout;
  110. }
  111. pstCom->hSndReady = CreateEvent(NULL,
  112. TRUE, // must be manually reset
  113. FALSE, // create unsignalled
  114. NULL); // unnamed
  115. if (pstCom->hSndReady == NULL)
  116. {
  117. CloseHandle(pstCom->hRcvEvent);
  118. pstCom->hRcvEvent = NULL;
  119. iRet = COM_FAILED;
  120. goto Checkout;
  121. }
  122. if ((iRet = ComInitHdl(pstCom)) != COM_OK)
  123. {
  124. goto Checkout;
  125. }
  126. Checkout:
  127. if (iRet == COM_OK)
  128. {
  129. *phcom = (HCOM)pstCom;
  130. }
  131. else
  132. {
  133. *phcom = NULL;
  134. if (pstCom)
  135. {
  136. if (pstCom->hRcvEvent)
  137. {
  138. ResetEvent(pstCom->hRcvEvent);
  139. CloseHandle(pstCom->hRcvEvent);
  140. pstCom->hRcvEvent = NULL;
  141. }
  142. if (pstCom->hSndReady)
  143. {
  144. ResetEvent(pstCom->hSndReady);
  145. CloseHandle(pstCom->hSndReady);
  146. pstCom->hSndReady = NULL;
  147. }
  148. free(pstCom);
  149. pstCom = NULL;
  150. }
  151. }
  152. DBGOUT_NORMAL("ComCreateHandle returning %d, pstCom == %08lX\r\n",
  153. iRet, pstCom, 0,0,0);
  154. return iRet;
  155. }
  156. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  157. * FUNCTION: ComDestroyHandle
  158. *
  159. * DESCRIPTION:
  160. * Shuts down an existing com handle and frees all resources assigned to it.
  161. *
  162. * ARGUMENTS:
  163. * hCom -- A com handle returned from an earlier call to ComCreateHandle
  164. * (or ComCreateWudgeHandle)
  165. *
  166. * RETURNS:
  167. * COM_OK
  168. */
  169. int ComDestroyHandle(HCOM *phCom)
  170. {
  171. int iRetVal = COM_OK;
  172. HCOM pstCom;
  173. DBGOUT_NORMAL("+ComDestroyHandle(%#08lx)\r\n", *phCom,0,0,0,0);
  174. assert(phCom);
  175. // OK to pass null handle to this function
  176. if (*phCom == NULL)
  177. {
  178. DBGOUT_NORMAL("-ComDestroyHandle returning COM_OK\r\n", 0,0,0,0,0);
  179. return COM_OK;
  180. }
  181. pstCom = *phCom;
  182. assert(ComValidHandle(pstCom));
  183. // Disconnect from driver
  184. ComFreeDevice(pstCom);
  185. if (pstCom->hRcvEvent)
  186. {
  187. ResetEvent(pstCom->hRcvEvent);;
  188. CloseHandle(pstCom->hRcvEvent);
  189. pstCom->hRcvEvent = NULL;
  190. }
  191. if (pstCom->hSndReady)
  192. {
  193. ResetEvent(pstCom->hSndReady);
  194. CloseHandle(pstCom->hSndReady);
  195. pstCom->hSndReady = NULL;
  196. }
  197. free(pstCom);
  198. *phCom = NULL;
  199. DBGOUT_NORMAL("-ComDestroyHandle returned %d\r\n",
  200. usRetVal,0,0,0,0);
  201. return iRetVal;
  202. }
  203. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  204. * FUNCTION:
  205. * ComInitHdl
  206. *
  207. * DESCRIPTION:
  208. * Called to initialize the Com handle to its default state. Calling this
  209. * function will clear any existing settings or states and reset for a
  210. * new session.
  211. *
  212. * ARGUMENTS:
  213. * pstCom -- Pointer to our handle data.
  214. *
  215. * RETURNS:
  216. * COM_OK if all is well.
  217. */
  218. int ComInitHdl(const HCOM pstCom)
  219. {
  220. int iRetVal = COM_OK;
  221. assert(ComValidHandle(pstCom));
  222. // Make sure we're disconnected from any driver loaded earlier
  223. ComFreeDevice(pstCom);
  224. // Fill in default values in exported com structure
  225. pstCom->stComCntrl.puchRBData = &pstCom->chDummy;
  226. pstCom->stComCntrl.puchRBDataLimit = &pstCom->chDummy;
  227. // Fill in default values for user-settable fields
  228. pstCom->stWorkSettings.szDeviceFile[0] = TEXT('\0');
  229. pstCom->stWorkSettings.szPortName[0] = TEXT('\0');
  230. pstCom->stFileSettings = pstCom->stWorkSettings;
  231. // Fill in default values in private com structure
  232. pstCom->fPortActive = FALSE;
  233. pstCom->fErrorReported = FALSE;
  234. pstCom->hDriverModule = (HANDLE)0;
  235. pstCom->szDeviceName[0]= (TCHAR)0;
  236. pstCom->chDummy = (TCHAR)0;
  237. pstCom->afOverride = 0;
  238. //
  239. // Free the send bufers prior to setting to NULL so we don't have
  240. // a memory leak when the buffers get malloc'd. REV: 02/27/2001.
  241. //
  242. if (pstCom->puchSendBufr1)
  243. {
  244. free(pstCom->puchSendBufr1);
  245. pstCom->puchSendBufr1 = NULL;
  246. }
  247. if (pstCom->puchSendBufr2)
  248. {
  249. free(pstCom->puchSendBufr2);
  250. pstCom->puchSendBufr2 = NULL;
  251. }
  252. pstCom->puchSendBufr = pstCom->puchSendBufr1;
  253. pstCom->puchSendPut = pstCom->puchSendBufr1;
  254. pstCom->nSBufrSize = 0;
  255. pstCom->nSendCount = 0;
  256. pstCom->fUserCalled = FALSE;
  257. pstCom->pfUserFunction = ComSendDefaultStatusFunction;
  258. // fill in defaults for driver functions
  259. pstCom->pfDeviceClose = ComDefDoNothing;
  260. pstCom->pfDeviceDialog = ComDefDeviceDialog;
  261. pstCom->pfDeviceGetCommon = ComDefDeviceGetCommon;
  262. pstCom->pfDeviceSetCommon = ComDefDeviceSetCommon;
  263. pstCom->pfDeviceSpecial = ComDefDeviceSpecial;
  264. pstCom->pfDeviceLoadHdl = ComDefDeviceLoadSaveHdl;
  265. pstCom->pfDeviceSaveHdl = ComDefDeviceLoadSaveHdl;
  266. pstCom->pfPortConfigure = ComDefDoNothing;
  267. pstCom->pfPortPreconnect = ComDefPortPreconnect;
  268. pstCom->pfPortActivate = ComDefPortActivate;
  269. pstCom->pfPortDeactivate = ComDefDoNothing;
  270. pstCom->pfPortConnected = ComDefDoNothing;
  271. pstCom->pfRcvRefill = ComDefBufrRefill;
  272. pstCom->pfRcvClear = ComDefDoNothing;
  273. pstCom->pfSndBufrSend = ComDefSndBufrSend;
  274. pstCom->pfSndBufrIsBusy = ComDefSndBufrBusy;
  275. pstCom->pfSndBufrClear = ComDefSndBufrClear;
  276. pstCom->pfSndBufrQuery = ComDefSndBufrQuery;
  277. pstCom->pfSendXon = ComDefDoNothing;
  278. pstCom->pvDriverData = NULL;
  279. if (pstCom->hRcvEvent)
  280. {
  281. ResetEvent(pstCom->hRcvEvent);
  282. }
  283. if (pstCom->hSndReady)
  284. {
  285. ResetEvent(pstCom->hSndReady);
  286. }
  287. // Normally, we would load the port type and port name values from the session file and set them,
  288. // but since we inherit such things from TAPI, just call ComSetDeviceFromFile with a dummy
  289. // name to get the proper initialization of the com driver.
  290. ComSetDeviceFromFile((HCOM)pstCom, "comstd.dll");
  291. return iRetVal;
  292. }
  293. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  294. * FUNCTION:
  295. * ComLoadHdl
  296. *
  297. * DESCRIPTION:
  298. *
  299. * ARGUMENTS:
  300. *
  301. * RETURNS:
  302. *
  303. */
  304. int ComLoadHdl(const HCOM pstCom)
  305. {
  306. const SF_HANDLE sfHdl = sessQuerySysFileHdl(pstCom->hSession);
  307. int (WINAPI *pfDeviceLoadHdl)(void *pvDevData, SF_HANDLE sfHdl);
  308. int iRetVal;
  309. pfDeviceLoadHdl = DeviceLoadHdl;
  310. iRetVal = (*pfDeviceLoadHdl)(pstCom->pvDriverData, sfHdl);
  311. #if defined(INCL_WINSOCK)
  312. if (iRetVal == SF_OK)
  313. {
  314. pfDeviceLoadHdl = WsckDeviceLoadHdl;
  315. iRetVal = (*pfDeviceLoadHdl)(pstCom->pvDriverData, sfHdl);
  316. }
  317. #endif // defined(INCL_WINSOCK)
  318. return iRetVal;
  319. }
  320. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  321. * FUNCTION:
  322. * ComSaveHdl
  323. *
  324. * DESCRIPTION:
  325. *
  326. * ARGUMENTS:
  327. *
  328. * RETURNS:
  329. *
  330. */
  331. int ComSaveHdl(const HCOM pstCom)
  332. {
  333. const SF_HANDLE sfHdl = sessQuerySysFileHdl(pstCom->hSession);
  334. int (WINAPI *pfDeviceSaveHdl)(void *pvDevData, SF_HANDLE sfHdl);
  335. int iRetVal;
  336. pfDeviceSaveHdl = DeviceSaveHdl;
  337. iRetVal = (*pfDeviceSaveHdl)(pstCom->pvDriverData, sfHdl);
  338. #if defined(INCL_WINSOCK)
  339. if (iRetVal == SF_OK)
  340. {
  341. pfDeviceSaveHdl = WsckDeviceSaveHdl;
  342. iRetVal = (*pfDeviceSaveHdl)(pstCom->pvDriverData, sfHdl);
  343. }
  344. #endif // defined(INCL_WINSOCK)
  345. return iRetVal;
  346. }
  347. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  348. * FUNCTION:
  349. *
  350. * DESCRIPTION:
  351. *
  352. * ARGUMENTS:
  353. *
  354. * RETURNS:
  355. *
  356. */
  357. int ComSetDeviceFromFile(const HCOM pstCom, const TCHAR * const pszFileName)
  358. {
  359. int iRetVal = COM_OK;
  360. int (WINAPI *pfDeviceInit)(HCOM, unsigned, void **);
  361. if (pstCom->pvDriverData)
  362. return COM_OK;
  363. // If loadable com drivers were actually implemented, we wouldl load the proper .DLL module here
  364. // and initialize it. In this version, though, we have only one com driver and it is linked right
  365. // in. So rather than doing GetProcAddress calls to link to the driver, we can simply load function
  366. // addresses right into function pointers.
  367. //
  368. // Not true anymore! We now have two com drivers to support. But since
  369. // we still don't load from DLLs, we just let the two drivers share the
  370. // driver data structure, and each initializes its own specific members.
  371. // - jmh 02-22-96
  372. pstCom->hDriverModule = (HANDLE)1; // Set this to fake value so we can close
  373. pfDeviceInit = DeviceInitialize;
  374. if ((iRetVal = (*pfDeviceInit)(pstCom, COM_VERSION,
  375. &pstCom->pvDriverData)) != COM_OK)
  376. {
  377. // The device driver cannot report errors itself until it has
  378. // been initialized. So we must report any errors it encountered.
  379. //* if (iRetVal == COM_DEVICE_VERSION_ERROR)
  380. //* ComReportError(pstCom, CM_ERR_WRONG_VERSION, pszFileName, TRUE);
  381. //* else
  382. //* ComReportError(pstCom, CM_ERR_CANT_INIT, pszFileName, TRUE);
  383. DBGOUT_NORMAL(" ComSetDevice: *pfDeviceInit failed\r\n",0,0,0,0,0);
  384. goto Checkout;
  385. }
  386. #if defined(INCL_WINSOCK)
  387. // Initialize the driver data structure members specific to WinSock.
  388. //
  389. pfDeviceInit = WsckDeviceInitialize;
  390. if ((iRetVal = (*pfDeviceInit)(pstCom, COM_VERSION,
  391. &pstCom->pvDriverData)) != COM_OK)
  392. {
  393. goto Checkout;
  394. }
  395. #endif // defined(INCL_WINSOCK)
  396. pstCom->pfDeviceClose = DeviceClose;
  397. pstCom->pfDeviceDialog = DeviceDialog;
  398. pstCom->pfDeviceGetCommon = DeviceGetCommon;
  399. pstCom->pfDeviceSetCommon = DeviceSetCommon;
  400. pstCom->pfDeviceSpecial = DeviceSpecial;
  401. pstCom->pfPortConfigure = PortConfigure;
  402. //pstCom->pfPortPreconnect = PortPreconnect;
  403. pstCom->pfPortPreconnect = ComDefPortPreconnect;
  404. pstCom->pfPortActivate = PortActivate;
  405. Checkout:
  406. // if something went wrong, set comm to invalid driver state and return err
  407. if (iRetVal != COM_OK)
  408. ComFreeDevice(pstCom);
  409. DBGOUT_NORMAL("-ComSetDevice returning %d\r\n", iRetVal,0,0,0,0);
  410. return iRetVal;
  411. }
  412. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  413. * FUNCTION: ComGetDeviceName
  414. *
  415. * DESCRIPTION:
  416. * Returns name of device associated with a com handle
  417. *
  418. * ARGUMENTS:
  419. * pstCom -- com handle returned from earlier call to ComCreateHandle
  420. * pszName -- pointer to buffer to receive device name (may be NULL)
  421. * pusLen -- pointer length variable. If pszName is not NULL, this variable
  422. * should contain the size of the buffer pointed to by pszName.
  423. * In either case, *pusLen will be set to the size of the
  424. * device name to be returned.
  425. *
  426. * RETURNS:
  427. * COM_OK
  428. * COM_INVALID_HANDLE
  429. */
  430. int ComGetDeviceName(const HCOM pstCom,
  431. TCHAR * const pszName,
  432. int * const pnLen)
  433. {
  434. int iRetVal = COM_OK;
  435. int nTheirLen;
  436. DBGOUT_NORMAL("+ComGetDevice(%#08lx)\r\n", pstCom,0,0,0,0);
  437. assert(ComValidHandle(pstCom));
  438. assert(pnLen);
  439. nTheirLen = *pnLen;
  440. *pnLen = StrCharGetByteCount(pstCom->szDeviceName);
  441. if (pszName)
  442. {
  443. assert(nTheirLen >= (*pnLen + 1));
  444. if (nTheirLen >= (*pnLen + 1))
  445. StrCharCopyN(pszName, pstCom->szDeviceName, *pnLen);
  446. DBGOUT_NORMAL(" ComGetDevice: providing name (%s)\r\n", pszName,0,0,0,0);
  447. }
  448. DBGOUT_NORMAL("-ComGetDevice returning %d\r\n", iRetVal,0,0,0,0);
  449. return iRetVal;
  450. }
  451. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  452. * FUNCTION:
  453. * ComGetRcvEvent
  454. *
  455. * DESCRIPTION:
  456. * Returns a handle to an event object that can be used to wait for
  457. * received data to be available from the com routines.
  458. *
  459. * ARGUMENTS:
  460. * pstCom -- com handle returned from earlier call to ComCreateHandle
  461. *
  462. * RETURNS:
  463. * The Receive event object
  464. */
  465. HANDLE ComGetRcvEvent(HCOM pstCom)
  466. {
  467. return pstCom->hRcvEvent;
  468. }
  469. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  470. * FUNCTION: ComGetSession
  471. *
  472. * DESCRIPTION:
  473. * Returns Session Handle associated with a Com handle
  474. *
  475. * ARGUMENTS:
  476. * pstCom -- com handle returned from earlier call to ComCreateHandle
  477. * phSession -- pointer to session handle to receive result
  478. *
  479. * RETURNS:
  480. * always returns COM_OK
  481. */
  482. int ComGetSession(const HCOM pstCom, HSESSION * const phSession)
  483. {
  484. assert(ComValidHandle(pstCom));
  485. assert(phSession);
  486. *phSession = pstCom->hSession;
  487. return COM_OK;
  488. }
  489. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  490. * FUNCTION: ComNotify
  491. *
  492. * DESCRIPTION:
  493. * Called by driver modules to notify com routines of significant events
  494. *
  495. * ARGUMENTS:
  496. *
  497. *
  498. * RETURNS:
  499. *
  500. */
  501. void ComNotify(const HCOM pstCom, enum COM_EVENTS event)
  502. {
  503. assert(ComValidHandle(pstCom));
  504. switch (event)
  505. {
  506. case CONNECT:
  507. cnctComEvent(sessQueryCnctHdl(pstCom->hSession), CONNECT);
  508. //
  509. // Set the send and recieve events so we'll wake the COM thread
  510. // and start sending and/or receiving data. REV: 08/27/2001
  511. //
  512. SetEvent(pstCom->hSndReady);
  513. SetEvent(pstCom->hRcvEvent);
  514. break;
  515. case DATA_RECEIVED:
  516. SetEvent(pstCom->hRcvEvent);
  517. CLoopRcvControl(sessQueryCLoopHdl(pstCom->hSession), CLOOP_RESUME,
  518. CLOOP_RB_NODATA);
  519. break;
  520. case NODATA:
  521. ResetEvent(pstCom->hRcvEvent);
  522. break;
  523. case SEND_STARTED:
  524. // NotifyClient(pstCom->hSession, EVENT_LED_SD_ON, 0);
  525. //DbgOutStr("Send started\n",0,0,0,0,0);
  526. ResetEvent(pstCom->hSndReady);
  527. break;
  528. case SEND_DONE:
  529. // NotifyClient(pstCom->hSession, EVENT_LED_SD_OFF, 0);
  530. //DbgOutStr("Send done\n",0,0,0,0,0);
  531. SetEvent(pstCom->hSndReady);
  532. break;
  533. default:
  534. assert(FALSE);
  535. break;
  536. }
  537. }
  538. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  539. * FUNCTION: ComIsActive
  540. *
  541. * DESCRIPTION:
  542. *
  543. *
  544. * ARGUMENTS:
  545. *
  546. *
  547. * RETURNS:
  548. *
  549. */
  550. int ComIsActive(const HCOM pstCom)
  551. {
  552. int iRet = COM_OK;
  553. assert(ComValidHandle(pstCom));
  554. if (pstCom == NULL || !pstCom->fPortActive)
  555. {
  556. iRet = COM_PORT_NOT_OPEN;
  557. }
  558. return iRet;
  559. }
  560. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  561. * FUNCTION: ComSetPortName
  562. *
  563. * DESCRIPTION:
  564. *
  565. *
  566. * ARGUMENTS:
  567. *
  568. *
  569. * RETURNS:
  570. *
  571. */
  572. int ComSetPortName(const HCOM pstCom, const TCHAR * const pszPortName)
  573. {
  574. int iRetVal = COM_OK;
  575. DBGOUT_NORMAL("+ComSetPortName(%#08lx, %s)\r\n", pstCom, pszPortName,0,0,0);
  576. assert(ComValidHandle(pstCom));
  577. if (!pszPortName)
  578. iRetVal = COM_PORT_INVALID_NAME;
  579. else if (ComIsActive(pstCom) == COM_OK)
  580. iRetVal = COM_PORT_IN_USE;
  581. if (StrCharCmp(pszPortName, pstCom->stWorkSettings.szPortName) != 0)
  582. {
  583. //* TODO: call driver to check validity of name
  584. StrCharCopyN(pstCom->stWorkSettings.szPortName, pszPortName, COM_MAX_PORT_NAME);
  585. }
  586. DBGOUT_NORMAL("-ComSetPortName returned %u\r\n", iRetVal, 0,0,0,0);
  587. return iRetVal;
  588. }
  589. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  590. * FUNCTION: ComGetPortName
  591. *
  592. * DESCRIPTION:
  593. *
  594. *
  595. * ARGUMENTS:
  596. *
  597. *
  598. * RETURNS:
  599. *
  600. */
  601. int ComGetPortName(const HCOM pstCom, TCHAR * const pszName, int nLen)
  602. {
  603. int iRetVal = COM_INVALID_HANDLE;
  604. DBGOUT_NORMAL("+ComGetPortName(%#08lx)\r\n", pstCom, 0,0,0,0);
  605. if (pstCom && ComValidHandle(pstCom))
  606. {
  607. if (pszName)
  608. {
  609. if (nLen > StrCharGetStrLength(pstCom->stWorkSettings.szPortName))
  610. {
  611. iRetVal = COM_OK;
  612. StrCharCopyN(pszName, pstCom->stWorkSettings.szPortName, nLen);
  613. }
  614. else
  615. {
  616. iRetVal = COM_NOT_ENOUGH_MEMORY;
  617. pszName[0] = TEXT('\0');
  618. }
  619. }
  620. else
  621. {
  622. iRetVal = COM_PORT_INVALID_NAME;
  623. pszName[0] = TEXT('\0');
  624. }
  625. }
  626. DBGOUT_NORMAL("-ComGetPortName returning %u, size = %u, name = %s\r\n",
  627. iRetVal, nLen, pszName ? pszName : " ",0,0);
  628. return iRetVal;
  629. }
  630. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  631. * FUNCTION: ComGetAutoDetect
  632. *
  633. * DESCRIPTION:
  634. *
  635. *
  636. * ARGUMENTS:
  637. *
  638. *
  639. * RETURNS:
  640. *
  641. */
  642. int ComGetAutoDetect(HCOM pstCom, int *pfAutoDetect)
  643. {
  644. int iRet = COM_OK;
  645. struct s_common stCommon;
  646. assert(ComValidHandle(pstCom));
  647. assert(pfAutoDetect);
  648. if (pstCom->pfDeviceGetCommon == NULL)
  649. iRet = COM_NOT_SUPPORTED;
  650. else if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  651. iRet = COM_DEVICE_ERROR;
  652. else if (!bittest(stCommon.afItem, COM_AUTO))
  653. iRet = COM_NOT_SUPPORTED;
  654. else if (pfAutoDetect)
  655. *pfAutoDetect = stCommon.fAutoDetect;
  656. return iRet;
  657. }
  658. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  659. * FUNCTION: ComSetAutoDetect
  660. *
  661. * DESCRIPTION:
  662. *
  663. * ARGUMENTS:
  664. *
  665. * RETURNS:
  666. *
  667. */
  668. int ComSetAutoDetect(HCOM pstCom, int fAutoDetect)
  669. {
  670. struct s_common stCommon;
  671. int fDummy;
  672. int iRetVal = COM_OK;
  673. assert(ComValidHandle(pstCom));
  674. if (ComGetAutoDetect(pstCom, &fDummy) == COM_NOT_SUPPORTED)
  675. {
  676. iRetVal = COM_NOT_SUPPORTED;
  677. }
  678. else
  679. {
  680. stCommon.afItem = COM_AUTO;
  681. stCommon.fAutoDetect = fAutoDetect;
  682. if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  683. {
  684. iRetVal = COM_DEVICE_ERROR;
  685. }
  686. }
  687. return iRetVal;
  688. }
  689. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  690. * FUNCTION: ComGetBaud
  691. *
  692. * DESCRIPTION:
  693. *
  694. *
  695. * ARGUMENTS:
  696. *
  697. *
  698. * RETURNS:
  699. *
  700. */
  701. int ComGetBaud(const HCOM pstCom, long * const plBaud)
  702. {
  703. ST_COMMON stCommon;
  704. assert(ComValidHandle(pstCom));
  705. assert(plBaud);
  706. if (pstCom->pfDeviceGetCommon == NULL)
  707. return COM_NOT_SUPPORTED;
  708. if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  709. return COM_DEVICE_ERROR;
  710. if (!bittest(stCommon.afItem, COM_BAUD))
  711. return COM_NOT_SUPPORTED;
  712. *plBaud = stCommon.lBaud;
  713. return COM_OK;
  714. }
  715. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  716. * FUNCTION: ComSetBaud
  717. *
  718. * DESCRIPTION:
  719. *
  720. *
  721. * ARGUMENTS:
  722. *
  723. *
  724. * RETURNS:
  725. *
  726. */
  727. int ComSetBaud(const HCOM pstCom, const long lBaud)
  728. {
  729. ST_COMMON stCommon;
  730. long lDummy;
  731. int iRetVal = COM_OK;
  732. assert(ComValidHandle(pstCom));
  733. if (ComGetBaud(pstCom, &lDummy) == COM_NOT_SUPPORTED)
  734. {
  735. iRetVal = COM_NOT_SUPPORTED;
  736. }
  737. else
  738. {
  739. stCommon.afItem = COM_BAUD;
  740. stCommon.lBaud = lBaud;
  741. if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  742. {
  743. iRetVal = COM_DEVICE_ERROR;
  744. }
  745. }
  746. return iRetVal;
  747. }
  748. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  749. * FUNCTION: ComGetDataBits
  750. *
  751. * DESCRIPTION:
  752. *
  753. *
  754. * ARGUMENTS:
  755. *
  756. *
  757. * RETURNS:
  758. *
  759. */
  760. int ComGetDataBits(const HCOM pstCom, int * const pnDataBits)
  761. {
  762. ST_COMMON stCommon;
  763. assert(ComValidHandle(pstCom));
  764. assert(pnDataBits);
  765. if (pstCom->pfDeviceGetCommon == NULL)
  766. return COM_NOT_SUPPORTED;
  767. if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  768. return COM_DEVICE_ERROR;
  769. if (!bittest(stCommon.afItem, COM_DATABITS))
  770. return COM_NOT_SUPPORTED;
  771. *pnDataBits = stCommon.nDataBits;
  772. return COM_OK;
  773. }
  774. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  775. * FUNCTION: ComSetDataBits
  776. *
  777. * DESCRIPTION:
  778. *
  779. *
  780. * ARGUMENTS:
  781. *
  782. *
  783. * RETURNS:
  784. *
  785. */
  786. int ComSetDataBits(const HCOM pstCom, const int nDataBits)
  787. {
  788. ST_COMMON stCommon;
  789. int nDummy;
  790. int iRetVal = COM_OK;
  791. assert(ComValidHandle(pstCom));
  792. if (ComGetDataBits(pstCom, &nDummy) == COM_NOT_SUPPORTED)
  793. {
  794. iRetVal = COM_NOT_SUPPORTED;
  795. }
  796. else
  797. {
  798. stCommon.afItem = COM_DATABITS;
  799. stCommon.nDataBits = nDataBits;
  800. if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  801. {
  802. iRetVal = COM_DEVICE_ERROR;
  803. }
  804. }
  805. return iRetVal;
  806. }
  807. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  808. * FUNCTION: ComGetStopBits
  809. *
  810. * DESCRIPTION:
  811. *
  812. *
  813. * ARGUMENTS:
  814. *
  815. *
  816. * RETURNS:
  817. *
  818. */
  819. int ComGetStopBits(const HCOM pstCom, int * const pnStopBits)
  820. {
  821. ST_COMMON stCommon;
  822. assert(ComValidHandle(pstCom));
  823. assert(pnStopBits);
  824. if (pstCom->pfDeviceGetCommon == NULL)
  825. return COM_NOT_SUPPORTED;
  826. if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  827. return COM_DEVICE_ERROR;
  828. if (!bittest(stCommon.afItem, COM_STOPBITS))
  829. return COM_NOT_SUPPORTED;
  830. *pnStopBits = stCommon.nStopBits;
  831. return COM_OK;
  832. }
  833. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  834. * FUNCTION: ComSetStopBits
  835. *
  836. * DESCRIPTION:
  837. *
  838. *
  839. * ARGUMENTS:
  840. *
  841. *
  842. * RETURNS:
  843. *
  844. */
  845. int ComSetStopBits(const HCOM pstCom, const int nStopBits)
  846. {
  847. ST_COMMON stCommon;
  848. int nDummy;
  849. int iRetVal = COM_OK;
  850. assert(ComValidHandle(pstCom));
  851. if (ComGetStopBits(pstCom, &nDummy) == COM_NOT_SUPPORTED)
  852. {
  853. iRetVal = COM_NOT_SUPPORTED;
  854. }
  855. else
  856. {
  857. stCommon.afItem = COM_STOPBITS;
  858. stCommon.nStopBits = nStopBits;
  859. if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  860. {
  861. iRetVal = COM_DEVICE_ERROR;
  862. }
  863. }
  864. return iRetVal;
  865. }
  866. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  867. * FUNCTION: ComGetParity
  868. *
  869. * DESCRIPTION:
  870. *
  871. *
  872. * ARGUMENTS:
  873. *
  874. *
  875. * RETURNS:
  876. *
  877. */
  878. int ComGetParity(const HCOM pstCom, int * const pnParity)
  879. {
  880. ST_COMMON stCommon;
  881. assert(ComValidHandle(pstCom));
  882. assert(pnParity);
  883. if (pstCom->pfDeviceGetCommon == NULL)
  884. return COM_NOT_SUPPORTED;
  885. if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  886. return COM_DEVICE_ERROR;
  887. if (!bittest(stCommon.afItem, COM_PARITY))
  888. return COM_NOT_SUPPORTED;
  889. *pnParity = stCommon.nParity;
  890. return COM_OK;
  891. }
  892. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  893. * FUNCTION: ComSetParity
  894. *
  895. * DESCRIPTION:
  896. *
  897. *
  898. * ARGUMENTS:
  899. *
  900. *
  901. * RETURNS:
  902. *
  903. */
  904. int ComSetParity(const HCOM pstCom, const int nParity)
  905. {
  906. ST_COMMON stCommon;
  907. int nDummy;
  908. int iRetVal = COM_OK;
  909. assert(ComValidHandle(pstCom));
  910. if (ComGetParity(pstCom, &nDummy) == COM_NOT_SUPPORTED)
  911. {
  912. iRetVal = COM_NOT_SUPPORTED;
  913. }
  914. else
  915. {
  916. stCommon.afItem = COM_PARITY;
  917. stCommon.nParity = nParity;
  918. if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK)
  919. {
  920. iRetVal = COM_DEVICE_ERROR;
  921. }
  922. }
  923. return iRetVal;
  924. }
  925. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  926. * FUNCTION: ComPreconnect
  927. *
  928. * DESCRIPTION:
  929. * This function is called just before a connection is attempted. It is
  930. * called at a point in the connection process when user interaction is
  931. * straight-forward. Certain devices may need to interact with the user
  932. * in order to work (having user insert a card, or select from a pool of
  933. * devices, etc.). User interaction may not be possible at the time that
  934. * ComActivatePort is called, so it should be done here. This routine
  935. * may lay claim to a resource and hold it pending the call to
  936. * ComActivatePort. Once this routine is called, ComActivatePort will
  937. * usually be called (but not necessarily always); ComDeactivatePort will
  938. * always be called.
  939. *
  940. * ARGUMENTS:
  941. * pstCom -- a com handle as returned by ComCreateHandle
  942. *
  943. * RETURNS:
  944. * COM_OK -- if the connection attempt should continue
  945. * COM_FAILED -- if the connection attempt should be abandoned. (in this
  946. * case, it is up to the driver to display the reason
  947. * before returning)
  948. */
  949. int ComPreconnect(const HCOM pstCom)
  950. {
  951. int iRetVal = COM_OK;
  952. assert(ComValidHandle(pstCom));
  953. iRetVal = (*pstCom->pfPortPreconnect)(pstCom->pvDriverData,
  954. pstCom->stWorkSettings.szPortName, sessQueryHwnd(pstCom->hSession));
  955. if (iRetVal != COM_OK)
  956. {
  957. iRetVal = COM_FAILED;
  958. }
  959. return iRetVal;
  960. }
  961. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  962. * FUNCTION: ComActivatePort
  963. *
  964. * DESCRIPTION:
  965. * Attempts to activate the port associated with a com handle. This call
  966. * will not necessarily attempt to complete a connection.
  967. * Note: this function will display an error messages for all errors except
  968. * COM_PORT_IN_USE. If a COM_PORT_IN_USE error is encountered and
  969. * is not rectified by borrowing or changing ports, the error message
  970. * should be displayed by the calling routine.
  971. *
  972. * ARGUMENTS:
  973. * pstCom -- a com handle as returned by ComCreateHandle
  974. *
  975. * RETURNS:
  976. * COM_OK
  977. * COM_PORT_IN_USE -- Port is in use by another process.
  978. * or error code as defined in COM.H
  979. */
  980. int ComActivatePort(const HCOM pstCom, DWORD_PTR dwMediaHdl)
  981. {
  982. int iRetVal = COM_OK;
  983. // This function (or the functions it calls) should report all errors
  984. // except for COM_PORT_IN_USE. Higher level routines may want to
  985. // try some recovery techniques before reporting an unavailable port
  986. assert(ComValidHandle(pstCom));
  987. DBGOUT_NORMAL("+ComActivatePort(%#08x)\r\n", pstCom, 0,0,0,0);
  988. if (ComIsActive(pstCom) != COM_OK)
  989. {
  990. //* TODO: this is temporary until we resolve how driver and program
  991. // decide on size of send buffers.
  992. pstCom->nSBufrSize = 128;
  993. //
  994. // Free the send bufers prior to setting to malloc so we don't
  995. // have a memory leak. REV: 02/27/2001.
  996. //
  997. if (pstCom->puchSendBufr1)
  998. {
  999. free(pstCom->puchSendBufr1);
  1000. pstCom->puchSendBufr1 = NULL;
  1001. }
  1002. if (pstCom->puchSendBufr2)
  1003. {
  1004. free(pstCom->puchSendBufr2);
  1005. pstCom->puchSendBufr2 = NULL;
  1006. }
  1007. // Allocate ComSend buffers
  1008. if ((pstCom->puchSendBufr1 =
  1009. malloc((size_t)pstCom->nSBufrSize)) == NULL ||
  1010. (pstCom->puchSendBufr2 =
  1011. malloc((size_t)pstCom->nSBufrSize)) == NULL)
  1012. {
  1013. DBGOUT_NORMAL(" ComActivatePort -- no memory for send buffers\r\n",
  1014. 0,0,0,0,0);
  1015. //* ComReportError(pstCom, NM_NEED_MEMFOR,
  1016. //* strldGet(mGetStrldHdl(pstCom->hSession), CM_NM_COMDRIVER), TRUE);
  1017. iRetVal = COM_NOT_ENOUGH_MEMORY;
  1018. goto checkout;
  1019. }
  1020. pstCom->puchSendBufr = pstCom->puchSendPut = pstCom->puchSendBufr1;
  1021. pstCom->nSendCount = 0;
  1022. pstCom->fUserCalled = FALSE;
  1023. pstCom->pfUserFunction = ComSendDefaultStatusFunction;
  1024. // Now call on driver code to activate the physical device
  1025. if ((iRetVal = (*pstCom->pfPortActivate)(pstCom->pvDriverData,
  1026. pstCom->stWorkSettings.szPortName, dwMediaHdl)) == COM_OK)
  1027. {
  1028. //
  1029. // Reset the transfer's loss of carrier flag. REV: 08/23/2001
  1030. //
  1031. XD_TYPE* pX = (XD_TYPE*)sessQueryXferHdl(pstCom->hSession);
  1032. if (pX != NULL)
  1033. {
  1034. pX->nCarrierLost = FALSE;
  1035. }
  1036. pstCom->fPortActive = TRUE;
  1037. }
  1038. }
  1039. checkout:
  1040. if (iRetVal != COM_OK)
  1041. {
  1042. ComDeactivatePort(pstCom);
  1043. }
  1044. DBGOUT_NORMAL("-ComActivatePort returning %u\r\n", iRetVal, 0,0,0,0);
  1045. return iRetVal;
  1046. }
  1047. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1048. * FUNCTION: ComDeactivatePort
  1049. *
  1050. * DESCRIPTION:
  1051. * Attempts to deactivate the port associated with a com handle. This call
  1052. *
  1053. * ARGUMENTS:
  1054. * pstCom -- a com handle as returned by ComCreateHandle
  1055. *
  1056. * RETURNS:
  1057. * COM_OK
  1058. * or error code as defined in COM.H
  1059. */
  1060. int ComDeactivatePort(const HCOM pstCom)
  1061. {
  1062. int iRetVal = COM_OK;
  1063. int iPortConnected = COM_PORT_NOT_OPEN;
  1064. DBGOUT_NORMAL("+ComDeactivatePort(%#08x)\r\n", pstCom,0,0,0,0);
  1065. if (ComValidHandle(pstCom) == FALSE || pstCom == NULL)
  1066. {
  1067. assert(0);
  1068. return COM_INVALID_HANDLE;
  1069. }
  1070. if (pstCom->pvDriverData != NULL)
  1071. {
  1072. iPortConnected = (*pstCom->pfPortConnected)(pstCom->pvDriverData);
  1073. }
  1074. if (pstCom->fPortActive || iPortConnected != COM_PORT_NOT_OPEN)
  1075. {
  1076. // Call on driver code to deactivate the physical device
  1077. if ((iRetVal =
  1078. (*pstCom->pfPortDeactivate)(pstCom->pvDriverData)) == COM_OK)
  1079. {
  1080. //
  1081. // Reset the transfer's loss of carrier flag. REV: 08/23/2001
  1082. //
  1083. XD_TYPE* pX = (XD_TYPE*)sessQueryXferHdl(pstCom->hSession);
  1084. if (pX != NULL)
  1085. {
  1086. pX->nCarrierLost = TRUE;
  1087. }
  1088. pstCom->fPortActive = FALSE;
  1089. }
  1090. }
  1091. if (pstCom->pfSndBufrClear)
  1092. {
  1093. // Call on driver code to clear the send buffer
  1094. iRetVal = (*pstCom->pfSndBufrClear)(pstCom->pvDriverData);
  1095. }
  1096. if (pstCom->hSndReady)
  1097. {
  1098. ResetEvent(pstCom->hSndReady);
  1099. }
  1100. if (pstCom->pfRcvClear)
  1101. {
  1102. // Call on driver code to clear the receive buffer
  1103. iRetVal = (*pstCom->pfRcvClear)(pstCom->pvDriverData);
  1104. }
  1105. if (pstCom->hRcvEvent)
  1106. {
  1107. ResetEvent(pstCom->hRcvEvent);
  1108. }
  1109. pstCom->pfPortDeactivate = ComDefDoNothing;
  1110. pstCom->pfPortConnected = ComDefDoNothing;
  1111. pstCom->pfRcvRefill = ComDefBufrRefill;
  1112. pstCom->pfRcvClear = ComDefDoNothing;
  1113. pstCom->pfSndBufrSend = ComDefSndBufrSend;
  1114. pstCom->pfSndBufrIsBusy = ComDefSndBufrBusy;
  1115. pstCom->pfSndBufrClear = ComDefSndBufrClear;
  1116. pstCom->pfSndBufrQuery = ComDefSndBufrQuery;
  1117. pstCom->pfSendXon = ComDefDoNothing;
  1118. if (pstCom->puchSendBufr1)
  1119. {
  1120. free(pstCom->puchSendBufr1);
  1121. pstCom->puchSendBufr1 = NULL;
  1122. }
  1123. if (pstCom->puchSendBufr2)
  1124. {
  1125. free(pstCom->puchSendBufr2);
  1126. pstCom->puchSendBufr2 = NULL;
  1127. }
  1128. pstCom->puchSendBufr = pstCom->puchSendPut = pstCom->puchSendBufr1;
  1129. pstCom->nSendCount = 0;
  1130. pstCom->nSBufrSize = 0;
  1131. pstCom->fUserCalled = FALSE;
  1132. DBGOUT_NORMAL("-ComDeactivatePort returned %u\r\n", iRetVal, 0,0,0,0);
  1133. return iRetVal;
  1134. }
  1135. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1136. * FUNCTION: ComOverride
  1137. *
  1138. * DESCRIPTION:
  1139. * Used to temporarily override the current com settings. Allows setting
  1140. * the com channel to support specific data transfer needs without
  1141. * specific knowledge of the current com device or its settings.
  1142. *
  1143. * ARGUMENTS:
  1144. * pstCom Com handle returned by an call to CreateComHandle
  1145. * uiOptions Options which specify transfer requirements. Currently:
  1146. * COM_OVERRIDE_8BIT temporarily switchs port to
  1147. * 8 bit, no parity mode
  1148. * COM_OVERRIDE_RCVALL temporarily suspends any com
  1149. * settings that would prevent some
  1150. * characters from being received:
  1151. * typically suspends recognition
  1152. * of received XON/XOFF codes
  1153. * COM_OVERRIDE_SNDALL temporarily suspends any com
  1154. * settings that would prevent some
  1155. * characters from being sent.
  1156. * puiOldOptions Pointer to a unsigned variable to receive the options in
  1157. * force prior to this call. The value returned in this
  1158. * field should be used to restore the com driver when
  1159. * the override is no longer needed. If this value is not
  1160. * needed, puiOldOptions can be set to NULL.
  1161. *
  1162. * RETURNS:
  1163. * COM_OK if requested override is possible with the current com device
  1164. * COM_CANT_OVERRIDE if the current device cannot support the request
  1165. *
  1166. */
  1167. int ComOverride(const HCOM pstCom,
  1168. const unsigned afOptions,
  1169. unsigned * const pafOldOptions)
  1170. {
  1171. unsigned afOldOverride;
  1172. int iRetVal = COM_OK;
  1173. assert(ComValidHandle(pstCom));
  1174. afOldOverride = pstCom->afOverride;
  1175. if (pafOldOptions)
  1176. *pafOldOptions = afOldOverride;
  1177. pstCom->afOverride = afOptions;
  1178. if ((iRetVal = ComConfigurePort(pstCom)) == COM_CANT_OVERRIDE)
  1179. pstCom->afOverride = afOldOverride;
  1180. return iRetVal;
  1181. }
  1182. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1183. * FUNCTION: ComQueryOverride
  1184. *
  1185. * DESCRIPTION:
  1186. * Returns the value of the override flags as described in ComOverride
  1187. *
  1188. * ARGUMENTS:
  1189. * pstCom Com handle returned by an call to CreateComHandle
  1190. * pafOptions Pointer to UINT to receive copy of override option flags
  1191. *
  1192. * RETURNS:
  1193. * Always returns COM_OK
  1194. */
  1195. int ComQueryOverride(HCOM pstCom, unsigned *pafOptions)
  1196. {
  1197. assert(ComValidHandle(pstCom));
  1198. assert(pafOptions);
  1199. *pafOptions = pstCom->afOverride;
  1200. return COM_OK;
  1201. }
  1202. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1203. * FUNCTION: ComConfigurePort
  1204. *
  1205. * DESCRIPTION:
  1206. *
  1207. *
  1208. * ARGUMENTS:
  1209. *
  1210. *
  1211. * RETURNS:
  1212. *
  1213. */
  1214. int ComConfigurePort(const HCOM pstCom)
  1215. {
  1216. int iRetVal = COM_OK;
  1217. DBGOUT_NORMAL("+ComconfigurePort(%#08x)\r\n", pstCom, 0,0,0,0);
  1218. assert(ComValidHandle(pstCom));
  1219. if (ComIsActive(pstCom) == COM_OK)
  1220. iRetVal = (*pstCom->pfPortConfigure)(pstCom->pvDriverData);
  1221. DBGOUT_NORMAL("-ComConfigurePort returning %u\r\n", iRetVal, 0,0,0,0);
  1222. return iRetVal;
  1223. }
  1224. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1225. * FUNCTION: ComRcvBufrRefill
  1226. *
  1227. * DESCRIPTION:
  1228. *
  1229. *
  1230. * ARGUMENTS:
  1231. *
  1232. *
  1233. * RETURNS:
  1234. *
  1235. */
  1236. int ComRcvBufrRefill(const HCOM pstCom, TCHAR * const tc, const int fRemoveChar)
  1237. {
  1238. int iRetVal;
  1239. ST_COM_CONTROL *pstComCntrl = (ST_COM_CONTROL *)pstCom;
  1240. iRetVal = (*pstCom->pfRcvRefill)(pstCom->pvDriverData);
  1241. if (iRetVal)
  1242. {
  1243. if (tc)
  1244. *tc = *pstComCntrl->puchRBData;
  1245. if (fRemoveChar)
  1246. ++pstComCntrl->puchRBData;
  1247. }
  1248. return iRetVal;
  1249. }
  1250. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1251. * FUNCTION: ComRcvBufrClear
  1252. *
  1253. * DESCRIPTION:
  1254. *
  1255. *
  1256. * ARGUMENTS:
  1257. *
  1258. *
  1259. * RETURNS:
  1260. *
  1261. */
  1262. int ComRcvBufrClear(const HCOM pstCom)
  1263. {
  1264. return ((*pstCom->pfRcvClear)(pstCom->pvDriverData));
  1265. }
  1266. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1267. * FUNCTION: ComSndBufrSend
  1268. *
  1269. * DESCRIPTION:
  1270. *
  1271. *
  1272. * ARGUMENTS:
  1273. *
  1274. *
  1275. * RETURNS:
  1276. *
  1277. */
  1278. int ComSndBufrSend(
  1279. const HCOM pstCom,
  1280. void * const pvBufr,
  1281. const int nCount,
  1282. const int nWait)
  1283. {
  1284. int iRetVal = COM_OK;
  1285. assert(ComValidHandle(pstCom));
  1286. assert(pvBufr);
  1287. if (nCount > 0)
  1288. {
  1289. if ((*pstCom->pfPortConnected)(pstCom->pvDriverData) == COM_PORT_NOT_OPEN)
  1290. {
  1291. iRetVal = COM_PORT_NOT_OPEN;
  1292. }
  1293. else if (ComSndBufrBusy(pstCom) == COM_BUSY &&
  1294. (!nWait || ComSndBufrWait(pstCom, nWait) != COM_OK))
  1295. iRetVal = COM_BUSY;
  1296. else
  1297. {
  1298. iRetVal = (*pstCom->pfSndBufrSend)(pstCom->pvDriverData,
  1299. pvBufr, nCount);
  1300. }
  1301. }
  1302. return iRetVal;
  1303. }
  1304. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1305. * FUNCTION: ComSndBufrBusy
  1306. *
  1307. * DESCRIPTION:
  1308. *
  1309. *
  1310. * ARGUMENTS:
  1311. *
  1312. *
  1313. * RETURNS:
  1314. *
  1315. */
  1316. int ComSndBufrBusy(const HCOM pstCom)
  1317. {
  1318. int usResult;
  1319. usResult = (*pstCom->pfSndBufrIsBusy)(pstCom->pvDriverData);
  1320. return usResult;
  1321. }
  1322. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1323. * FUNCTION: ComSndBufrWait
  1324. *
  1325. * DESCRIPTION:
  1326. * Waits until the Com driver can transmit more data. The amount of time to
  1327. * wait can be specified. While waiting, a settable idle function is
  1328. * repeatedly called.
  1329. *
  1330. * ARGUMENTS:
  1331. * pstCom -- Com handle
  1332. * nWait -- Time to wait in tenths of a second
  1333. *
  1334. * RETURNS:
  1335. * COM_OK if driver can accept new data within the timeout interval
  1336. * COM_BUSY if the transmitter is still not available after timeout interval
  1337. */
  1338. int ComSndBufrWait(const HCOM pstCom, const int nWait)
  1339. {
  1340. int iRetVal = COM_OK;
  1341. DWORD dwRet;
  1342. //
  1343. // See if the port is currently connected. If not, then return an
  1344. // error stating the port is not connected. REV: 08/24/2001
  1345. //
  1346. if ((*pstCom->pfPortConnected)(pstCom->pvDriverData) == COM_PORT_NOT_OPEN)
  1347. {
  1348. iRetVal = COM_PORT_NOT_OPEN;
  1349. }
  1350. else if ((iRetVal = ComSndBufrBusy(pstCom)) != COM_OK && nWait)
  1351. {
  1352. //DbgOutStr("DBG_WRITE: %d Wait started\n",GetTickCount(),0,0,0,0);
  1353. dwRet = WaitForSingleObject(pstCom->hSndReady, nWait * 100);
  1354. if (dwRet != WAIT_OBJECT_0)
  1355. {
  1356. iRetVal = COM_BUSY;
  1357. }
  1358. else
  1359. {
  1360. iRetVal = COM_OK;
  1361. }
  1362. }
  1363. else
  1364. {
  1365. //DbgOutStr("DBG_WRITE: %d No wait\n",GetTickCount(),0,0,0,0);
  1366. }
  1367. return iRetVal;
  1368. #if 0 // jmh 01-11-96 This was the previous method, which didn't block at all
  1369. int iRetVal = COM_OK;
  1370. DWORD dwTimer;
  1371. if ((iRetVal = ComSndBufrBusy(pstCom)) != COM_OK && nWait)
  1372. {
  1373. dwTimer = startinterval();
  1374. while (interval(dwTimer) < (DWORD)nWait)
  1375. {
  1376. //* With thread model, not sure we still need ComIdle
  1377. //* ComIdle(pstCom); // Keep from locking up the program
  1378. if (ComSndBufrBusy(pstCom) == COM_OK)
  1379. {
  1380. iRetVal = COM_OK;
  1381. break;
  1382. }
  1383. }
  1384. }
  1385. return iRetVal;
  1386. #endif // 0
  1387. }
  1388. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1389. * FUNCTION: ComSndBufrClear
  1390. *
  1391. * DESCRIPTION:
  1392. *
  1393. *
  1394. * ARGUMENTS:
  1395. *
  1396. *
  1397. * RETURNS:
  1398. *
  1399. */
  1400. int ComSndBufrClear(const HCOM pstCom)
  1401. {
  1402. return (*pstCom->pfSndBufrClear)(pstCom->pvDriverData);
  1403. }
  1404. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1405. * FUNCTION: ComSndBufrQuery
  1406. *
  1407. * DESCRIPTION:
  1408. *
  1409. *
  1410. * ARGUMENTS:
  1411. *
  1412. *
  1413. * RETURNS:
  1414. *
  1415. */
  1416. int ComSndBufrQuery(const HCOM pstCom, unsigned * const pafStatus,
  1417. long * const plHandshakeDelay)
  1418. {
  1419. return (*pstCom->pfSndBufrQuery)(pstCom->pvDriverData, pafStatus,
  1420. plHandshakeDelay);
  1421. }
  1422. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1423. * FUNCTION: ComDeviceDialog
  1424. *
  1425. * DESCRIPTION:
  1426. *
  1427. *
  1428. * ARGUMENTS:
  1429. *
  1430. *
  1431. * RETURNS:
  1432. *
  1433. */
  1434. int ComDeviceDialog(const HCOM pstCom, const HWND hwndParent)
  1435. {
  1436. int iRetVal;
  1437. assert(ComValidHandle(pstCom));
  1438. iRetVal = (*pstCom->pfDeviceDialog)(pstCom->pvDriverData, hwndParent);
  1439. return iRetVal;
  1440. }
  1441. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1442. * FUNCTION: ComDriverSpecial
  1443. *
  1444. * DESCRIPTION:
  1445. * Allows access to special features of specific Com Device Drivers using
  1446. * a common API.
  1447. *
  1448. * ARGUMENTS:
  1449. * pstCom -- A Com Handle
  1450. * pszInstructions -- A driver specific string providing instructions
  1451. * on what task a driver should carry out.
  1452. * pszResults -- A buffer to receive a driver specific result string.
  1453. * uiBufrSize -- The size (in bytes) of the pszResults buffer.
  1454. *
  1455. * RETURNS:
  1456. *
  1457. */
  1458. int ComDriverSpecial(const HCOM pstCom, const TCHAR * const pszInstructions,
  1459. TCHAR * const pszResults, const int nBufrSize)
  1460. {
  1461. int iRetVal = COM_NOT_SUPPORTED;
  1462. if (pstCom == NULL)
  1463. return iRetVal;
  1464. if (pstCom->pfDeviceSpecial)
  1465. iRetVal = (*pstCom->pfDeviceSpecial)(pstCom->pvDriverData,
  1466. pszInstructions, pszResults, nBufrSize);
  1467. return iRetVal;
  1468. }
  1469. /* --- Internal functions --- */
  1470. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1471. * FUNCTION: ComReportError
  1472. *
  1473. * DESCRIPTION:
  1474. *
  1475. *
  1476. * ARGUMENTS:
  1477. *
  1478. *
  1479. * RETURNS:
  1480. *
  1481. */
  1482. void ComReportError(const HCOM pstCom, int iErrStr,
  1483. const TCHAR * const pszOptInfo, const int fFirstOnly)
  1484. {
  1485. if (!fFirstOnly || !pstCom->fErrorReported)
  1486. {
  1487. //* if (iErrStr == 0)
  1488. //* iErrStr = GM_TEST_FORMAT; // just %s
  1489. // Most error messages can be reported with a message error
  1490. // string and (maybe) an optional string field. The optional
  1491. // string is passed to utilReportError whether needed or not
  1492. // since it does no harm if it is not referenced.
  1493. //* utilReportError(pstCom->hSession, RE_ERROR | RE_OK,
  1494. //* iErrStr, pszOptInfo);
  1495. if (fFirstOnly)
  1496. pstCom->fErrorReported = TRUE;
  1497. }
  1498. }
  1499. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1500. * FUNCTION: ComFreeDevice
  1501. *
  1502. * DESCRIPTION:
  1503. *
  1504. *
  1505. * ARGUMENTS:
  1506. *
  1507. *
  1508. * RETURNS:
  1509. *
  1510. */
  1511. void ComFreeDevice(const HCOM pstCom)
  1512. {
  1513. if (pstCom == NULL)
  1514. {
  1515. assert(FALSE);
  1516. return;
  1517. }
  1518. ComDeactivatePort(pstCom);
  1519. if (pstCom->hDriverModule != (HANDLE)0)
  1520. {
  1521. if (pstCom->pfDeviceClose)
  1522. {
  1523. (void)(*pstCom->pfDeviceClose)(pstCom->pvDriverData);
  1524. pstCom->pvDriverData = 0;
  1525. // FreeLibrary(pstCom->hDriverModule);
  1526. }
  1527. pstCom->hDriverModule = (HANDLE)0;
  1528. }
  1529. pstCom->pfDeviceClose = ComDefDoNothing;
  1530. pstCom->pfDeviceDialog = ComDefDeviceDialog;
  1531. pstCom->pfDeviceGetCommon = ComDefDeviceGetCommon;
  1532. pstCom->pfDeviceSetCommon = ComDefDeviceSetCommon;
  1533. pstCom->pfDeviceSpecial = ComDefDeviceSpecial;
  1534. pstCom->pfDeviceLoadHdl = ComDefDeviceLoadSaveHdl;
  1535. pstCom->pfDeviceSaveHdl = ComDefDeviceLoadSaveHdl;
  1536. pstCom->pfPortConfigure = ComDefDoNothing;
  1537. pstCom->pfPortPreconnect = ComDefPortPreconnect;
  1538. pstCom->pfPortActivate = ComDefPortActivate;
  1539. pstCom->pfPortDeactivate = ComDefDoNothing;
  1540. pstCom->fPortActive = FALSE;
  1541. pstCom->szDeviceName[0] = TEXT('\0');
  1542. pstCom->stWorkSettings.szDeviceFile[0] = TEXT('\0');
  1543. pstCom->stWorkSettings.szPortName[0] = TEXT('\0');
  1544. return;
  1545. }
  1546. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1547. * FUNCTION:
  1548. * ComValidHandle
  1549. *
  1550. * DESCRIPTION:
  1551. * Tests whether a com handle points to a valid, initialize structure
  1552. *
  1553. * ARGUMENTS:
  1554. * pstCom -- com handle to be tested
  1555. *
  1556. * RETURNS:
  1557. * TRUE if com handle appears to be valid
  1558. * FALSE if com handle if NULL or points to an invalid structure
  1559. */
  1560. BOOL ComValidHandle(HCOM pstCom)
  1561. {
  1562. BOOL bReturnValue = TRUE;
  1563. if (pstCom == NULL)
  1564. {
  1565. bReturnValue = FALSE;
  1566. }
  1567. #if !defined(NDEBUG)
  1568. else if (pstCom->nGuard != COM_VERSION)
  1569. {
  1570. bReturnValue = FALSE;
  1571. }
  1572. #endif //!defined(NDEBUG)
  1573. return bReturnValue;
  1574. }