/* com.c -- High level com routines * * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI * All rights reserved * * $Revision: 15 $ * $Date: 7/08/02 6:40p $ */ #include #pragma hdrstop // #define DEBUGSTR #include #include "stdtyp.h" #include "session.h" #include "cnct.h" #include "assert.h" #include "mc.h" #include "cloop.h" #include "tdll.h" #include "sf.h" #include "htchar.h" #include "com.h" #include "comdev.h" #include "com.hh" #include // Drivers are linked directly in in this vers. #if defined(INCL_WINSOCK) #include #endif // defined(INCL_WINSOCK) #include "XFER_MSC.HH" // XD_TYPE int WINAPI WsckDeviceInitialize(HCOM hCom, unsigned nInterfaceVersion, void **ppvDriverData); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComCreateHandle * * DESCRIPTION: * Creates a communications handle to be used with subsequent Com calls. * The resulting com handle will not be associated with any actual device * or port initially. * * ARGUMENTS: * hSession -- Session handle of session creating com handle * hwndNotify -- Window to receive Com notifications * phcom -- pointer to a var. of type HCOM to receive new com handle * * RETURNS: * COM_OK * COM_NOT_ENOUGH_MEMORY if there is insufficient memory * COM_FAILED if resources could not be obtained * COM_INVALID_HANDLE if handle to Com is invalid */ int ComCreateHandle(const HSESSION hSession, HCOM *phcom) { int iRet = COM_OK; HCOM pstCom; DBGOUT_NORMAL("+ComCreateHandle for session %08lX\r\n", hSession,0,0,0,0); assert(phcom); if (phcom) { pstCom = *phcom; if(pstCom && ComValidHandle(pstCom)) { // Disconnect from driver ComFreeDevice(pstCom); if (pstCom->hRcvEvent) { ResetEvent(pstCom->hRcvEvent); CloseHandle(pstCom->hRcvEvent); pstCom->hRcvEvent = NULL; } if (pstCom->hSndReady) { ResetEvent(pstCom->hSndReady); CloseHandle(pstCom->hSndReady); pstCom->hSndReady = NULL; } *phcom = NULL; } } // See if we can get memory for a handle if ((pstCom = malloc(sizeof(*pstCom))) == NULL) { // This error can't be reported by ComReportError because no // Com Handle exists yet. //* utilReportError(hSession, RE_ERROR | RE_OK, NM_NEED_MEM, //* strldGet(mGetStrldHdl(hSession), NM_CREATE_SESSION)); DBGOUT_NORMAL("-ComCreateHandle returning COM_NOT_ENOUGH_MEMORY", 0,0,0,0,0); iRet = COM_NOT_ENOUGH_MEMORY; goto Checkout; } // Initialize to all zeros just to be on the safe side memset(pstCom, 0, sizeof(*pstCom)); // ComInitHdl will initialize most values. We must pre-initialize // enough so that ComInitHdl knows if it needs to shut anything down. pstCom->hSession = hSession; pstCom->hDriverModule = (HANDLE)0; pstCom->fPortActive = FALSE; pstCom->nGuard = COM_VERSION; pstCom->hRcvEvent = NULL; pstCom->hSndReady = NULL; pstCom->hRcvEvent = CreateEvent(NULL, TRUE, // must be manually reset FALSE, // create unsignalled NULL); // unnamed if (pstCom->hRcvEvent == NULL) { iRet = COM_FAILED; goto Checkout; } pstCom->hSndReady = CreateEvent(NULL, TRUE, // must be manually reset FALSE, // create unsignalled NULL); // unnamed if (pstCom->hSndReady == NULL) { CloseHandle(pstCom->hRcvEvent); pstCom->hRcvEvent = NULL; iRet = COM_FAILED; goto Checkout; } if ((iRet = ComInitHdl(pstCom)) != COM_OK) { goto Checkout; } Checkout: if (iRet == COM_OK) { *phcom = (HCOM)pstCom; } else { *phcom = NULL; if (pstCom) { if (pstCom->hRcvEvent) { ResetEvent(pstCom->hRcvEvent); CloseHandle(pstCom->hRcvEvent); pstCom->hRcvEvent = NULL; } if (pstCom->hSndReady) { ResetEvent(pstCom->hSndReady); CloseHandle(pstCom->hSndReady); pstCom->hSndReady = NULL; } free(pstCom); pstCom = NULL; } } DBGOUT_NORMAL("ComCreateHandle returning %d, pstCom == %08lX\r\n", iRet, pstCom, 0,0,0); return iRet; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComDestroyHandle * * DESCRIPTION: * Shuts down an existing com handle and frees all resources assigned to it. * * ARGUMENTS: * hCom -- A com handle returned from an earlier call to ComCreateHandle * (or ComCreateWudgeHandle) * * RETURNS: * COM_OK */ int ComDestroyHandle(HCOM *phCom) { int iRetVal = COM_OK; HCOM pstCom; DBGOUT_NORMAL("+ComDestroyHandle(%#08lx)\r\n", *phCom,0,0,0,0); assert(phCom); // OK to pass null handle to this function if (*phCom == NULL) { DBGOUT_NORMAL("-ComDestroyHandle returning COM_OK\r\n", 0,0,0,0,0); return COM_OK; } pstCom = *phCom; assert(ComValidHandle(pstCom)); // Disconnect from driver ComFreeDevice(pstCom); if (pstCom->hRcvEvent) { ResetEvent(pstCom->hRcvEvent);; CloseHandle(pstCom->hRcvEvent); pstCom->hRcvEvent = NULL; } if (pstCom->hSndReady) { ResetEvent(pstCom->hSndReady); CloseHandle(pstCom->hSndReady); pstCom->hSndReady = NULL; } free(pstCom); *phCom = NULL; DBGOUT_NORMAL("-ComDestroyHandle returned %d\r\n", usRetVal,0,0,0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * ComInitHdl * * DESCRIPTION: * Called to initialize the Com handle to its default state. Calling this * function will clear any existing settings or states and reset for a * new session. * * ARGUMENTS: * pstCom -- Pointer to our handle data. * * RETURNS: * COM_OK if all is well. */ int ComInitHdl(const HCOM pstCom) { int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); // Make sure we're disconnected from any driver loaded earlier ComFreeDevice(pstCom); // Fill in default values in exported com structure pstCom->stComCntrl.puchRBData = &pstCom->chDummy; pstCom->stComCntrl.puchRBDataLimit = &pstCom->chDummy; // Fill in default values for user-settable fields pstCom->stWorkSettings.szDeviceFile[0] = TEXT('\0'); pstCom->stWorkSettings.szPortName[0] = TEXT('\0'); pstCom->stFileSettings = pstCom->stWorkSettings; // Fill in default values in private com structure pstCom->fPortActive = FALSE; pstCom->fErrorReported = FALSE; pstCom->hDriverModule = (HANDLE)0; pstCom->szDeviceName[0]= (TCHAR)0; pstCom->chDummy = (TCHAR)0; pstCom->afOverride = 0; // // Free the send bufers prior to setting to NULL so we don't have // a memory leak when the buffers get malloc'd. REV: 02/27/2001. // if (pstCom->puchSendBufr1) { free(pstCom->puchSendBufr1); pstCom->puchSendBufr1 = NULL; } if (pstCom->puchSendBufr2) { free(pstCom->puchSendBufr2); pstCom->puchSendBufr2 = NULL; } pstCom->puchSendBufr = pstCom->puchSendBufr1; pstCom->puchSendPut = pstCom->puchSendBufr1; pstCom->nSBufrSize = 0; pstCom->nSendCount = 0; pstCom->fUserCalled = FALSE; pstCom->pfUserFunction = ComSendDefaultStatusFunction; // fill in defaults for driver functions pstCom->pfDeviceClose = ComDefDoNothing; pstCom->pfDeviceDialog = ComDefDeviceDialog; pstCom->pfDeviceGetCommon = ComDefDeviceGetCommon; pstCom->pfDeviceSetCommon = ComDefDeviceSetCommon; pstCom->pfDeviceSpecial = ComDefDeviceSpecial; pstCom->pfDeviceLoadHdl = ComDefDeviceLoadSaveHdl; pstCom->pfDeviceSaveHdl = ComDefDeviceLoadSaveHdl; pstCom->pfPortConfigure = ComDefDoNothing; pstCom->pfPortPreconnect = ComDefPortPreconnect; pstCom->pfPortActivate = ComDefPortActivate; pstCom->pfPortDeactivate = ComDefDoNothing; pstCom->pfPortConnected = ComDefDoNothing; pstCom->pfRcvRefill = ComDefBufrRefill; pstCom->pfRcvClear = ComDefDoNothing; pstCom->pfSndBufrSend = ComDefSndBufrSend; pstCom->pfSndBufrIsBusy = ComDefSndBufrBusy; pstCom->pfSndBufrClear = ComDefSndBufrClear; pstCom->pfSndBufrQuery = ComDefSndBufrQuery; pstCom->pfSendXon = ComDefDoNothing; pstCom->pvDriverData = NULL; if (pstCom->hRcvEvent) { ResetEvent(pstCom->hRcvEvent); } if (pstCom->hSndReady) { ResetEvent(pstCom->hSndReady); } // Normally, we would load the port type and port name values from the session file and set them, // but since we inherit such things from TAPI, just call ComSetDeviceFromFile with a dummy // name to get the proper initialization of the com driver. ComSetDeviceFromFile((HCOM)pstCom, "comstd.dll"); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * ComLoadHdl * * DESCRIPTION: * * ARGUMENTS: * * RETURNS: * */ int ComLoadHdl(const HCOM pstCom) { const SF_HANDLE sfHdl = sessQuerySysFileHdl(pstCom->hSession); int (WINAPI *pfDeviceLoadHdl)(void *pvDevData, SF_HANDLE sfHdl); int iRetVal; pfDeviceLoadHdl = DeviceLoadHdl; iRetVal = (*pfDeviceLoadHdl)(pstCom->pvDriverData, sfHdl); #if defined(INCL_WINSOCK) if (iRetVal == SF_OK) { pfDeviceLoadHdl = WsckDeviceLoadHdl; iRetVal = (*pfDeviceLoadHdl)(pstCom->pvDriverData, sfHdl); } #endif // defined(INCL_WINSOCK) return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * ComSaveHdl * * DESCRIPTION: * * ARGUMENTS: * * RETURNS: * */ int ComSaveHdl(const HCOM pstCom) { const SF_HANDLE sfHdl = sessQuerySysFileHdl(pstCom->hSession); int (WINAPI *pfDeviceSaveHdl)(void *pvDevData, SF_HANDLE sfHdl); int iRetVal; pfDeviceSaveHdl = DeviceSaveHdl; iRetVal = (*pfDeviceSaveHdl)(pstCom->pvDriverData, sfHdl); #if defined(INCL_WINSOCK) if (iRetVal == SF_OK) { pfDeviceSaveHdl = WsckDeviceSaveHdl; iRetVal = (*pfDeviceSaveHdl)(pstCom->pvDriverData, sfHdl); } #endif // defined(INCL_WINSOCK) return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * * DESCRIPTION: * * ARGUMENTS: * * RETURNS: * */ int ComSetDeviceFromFile(const HCOM pstCom, const TCHAR * const pszFileName) { int iRetVal = COM_OK; int (WINAPI *pfDeviceInit)(HCOM, unsigned, void **); if (pstCom->pvDriverData) return COM_OK; // If loadable com drivers were actually implemented, we wouldl load the proper .DLL module here // and initialize it. In this version, though, we have only one com driver and it is linked right // in. So rather than doing GetProcAddress calls to link to the driver, we can simply load function // addresses right into function pointers. // // Not true anymore! We now have two com drivers to support. But since // we still don't load from DLLs, we just let the two drivers share the // driver data structure, and each initializes its own specific members. // - jmh 02-22-96 pstCom->hDriverModule = (HANDLE)1; // Set this to fake value so we can close pfDeviceInit = DeviceInitialize; if ((iRetVal = (*pfDeviceInit)(pstCom, COM_VERSION, &pstCom->pvDriverData)) != COM_OK) { // The device driver cannot report errors itself until it has // been initialized. So we must report any errors it encountered. //* if (iRetVal == COM_DEVICE_VERSION_ERROR) //* ComReportError(pstCom, CM_ERR_WRONG_VERSION, pszFileName, TRUE); //* else //* ComReportError(pstCom, CM_ERR_CANT_INIT, pszFileName, TRUE); DBGOUT_NORMAL(" ComSetDevice: *pfDeviceInit failed\r\n",0,0,0,0,0); goto Checkout; } #if defined(INCL_WINSOCK) // Initialize the driver data structure members specific to WinSock. // pfDeviceInit = WsckDeviceInitialize; if ((iRetVal = (*pfDeviceInit)(pstCom, COM_VERSION, &pstCom->pvDriverData)) != COM_OK) { goto Checkout; } #endif // defined(INCL_WINSOCK) pstCom->pfDeviceClose = DeviceClose; pstCom->pfDeviceDialog = DeviceDialog; pstCom->pfDeviceGetCommon = DeviceGetCommon; pstCom->pfDeviceSetCommon = DeviceSetCommon; pstCom->pfDeviceSpecial = DeviceSpecial; pstCom->pfPortConfigure = PortConfigure; //pstCom->pfPortPreconnect = PortPreconnect; pstCom->pfPortPreconnect = ComDefPortPreconnect; pstCom->pfPortActivate = PortActivate; Checkout: // if something went wrong, set comm to invalid driver state and return err if (iRetVal != COM_OK) ComFreeDevice(pstCom); DBGOUT_NORMAL("-ComSetDevice returning %d\r\n", iRetVal,0,0,0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetDeviceName * * DESCRIPTION: * Returns name of device associated with a com handle * * ARGUMENTS: * pstCom -- com handle returned from earlier call to ComCreateHandle * pszName -- pointer to buffer to receive device name (may be NULL) * pusLen -- pointer length variable. If pszName is not NULL, this variable * should contain the size of the buffer pointed to by pszName. * In either case, *pusLen will be set to the size of the * device name to be returned. * * RETURNS: * COM_OK * COM_INVALID_HANDLE */ int ComGetDeviceName(const HCOM pstCom, TCHAR * const pszName, int * const pnLen) { int iRetVal = COM_OK; int nTheirLen; DBGOUT_NORMAL("+ComGetDevice(%#08lx)\r\n", pstCom,0,0,0,0); assert(ComValidHandle(pstCom)); assert(pnLen); nTheirLen = *pnLen; *pnLen = StrCharGetByteCount(pstCom->szDeviceName); if (pszName) { assert(nTheirLen >= (*pnLen + 1)); if (nTheirLen >= (*pnLen + 1)) StrCharCopyN(pszName, pstCom->szDeviceName, *pnLen); DBGOUT_NORMAL(" ComGetDevice: providing name (%s)\r\n", pszName,0,0,0,0); } DBGOUT_NORMAL("-ComGetDevice returning %d\r\n", iRetVal,0,0,0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * ComGetRcvEvent * * DESCRIPTION: * Returns a handle to an event object that can be used to wait for * received data to be available from the com routines. * * ARGUMENTS: * pstCom -- com handle returned from earlier call to ComCreateHandle * * RETURNS: * The Receive event object */ HANDLE ComGetRcvEvent(HCOM pstCom) { return pstCom->hRcvEvent; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetSession * * DESCRIPTION: * Returns Session Handle associated with a Com handle * * ARGUMENTS: * pstCom -- com handle returned from earlier call to ComCreateHandle * phSession -- pointer to session handle to receive result * * RETURNS: * always returns COM_OK */ int ComGetSession(const HCOM pstCom, HSESSION * const phSession) { assert(ComValidHandle(pstCom)); assert(phSession); *phSession = pstCom->hSession; return COM_OK; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComNotify * * DESCRIPTION: * Called by driver modules to notify com routines of significant events * * ARGUMENTS: * * * RETURNS: * */ void ComNotify(const HCOM pstCom, enum COM_EVENTS event) { assert(ComValidHandle(pstCom)); switch (event) { case CONNECT: cnctComEvent(sessQueryCnctHdl(pstCom->hSession), CONNECT); // // Set the send and recieve events so we'll wake the COM thread // and start sending and/or receiving data. REV: 08/27/2001 // SetEvent(pstCom->hSndReady); SetEvent(pstCom->hRcvEvent); break; case DATA_RECEIVED: SetEvent(pstCom->hRcvEvent); CLoopRcvControl(sessQueryCLoopHdl(pstCom->hSession), CLOOP_RESUME, CLOOP_RB_NODATA); break; case NODATA: ResetEvent(pstCom->hRcvEvent); break; case SEND_STARTED: // NotifyClient(pstCom->hSession, EVENT_LED_SD_ON, 0); //DbgOutStr("Send started\n",0,0,0,0,0); ResetEvent(pstCom->hSndReady); break; case SEND_DONE: // NotifyClient(pstCom->hSession, EVENT_LED_SD_OFF, 0); //DbgOutStr("Send done\n",0,0,0,0,0); SetEvent(pstCom->hSndReady); break; default: assert(FALSE); break; } } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComIsActive * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComIsActive(const HCOM pstCom) { int iRet = COM_OK; assert(ComValidHandle(pstCom)); if (pstCom == NULL || !pstCom->fPortActive) { iRet = COM_PORT_NOT_OPEN; } return iRet; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSetPortName * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSetPortName(const HCOM pstCom, const TCHAR * const pszPortName) { int iRetVal = COM_OK; DBGOUT_NORMAL("+ComSetPortName(%#08lx, %s)\r\n", pstCom, pszPortName,0,0,0); assert(ComValidHandle(pstCom)); if (!pszPortName) iRetVal = COM_PORT_INVALID_NAME; else if (ComIsActive(pstCom) == COM_OK) iRetVal = COM_PORT_IN_USE; if (StrCharCmp(pszPortName, pstCom->stWorkSettings.szPortName) != 0) { //* TODO: call driver to check validity of name StrCharCopyN(pstCom->stWorkSettings.szPortName, pszPortName, COM_MAX_PORT_NAME); } DBGOUT_NORMAL("-ComSetPortName returned %u\r\n", iRetVal, 0,0,0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetPortName * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComGetPortName(const HCOM pstCom, TCHAR * const pszName, int nLen) { int iRetVal = COM_INVALID_HANDLE; DBGOUT_NORMAL("+ComGetPortName(%#08lx)\r\n", pstCom, 0,0,0,0); if (pstCom && ComValidHandle(pstCom)) { if (pszName) { if (nLen > StrCharGetStrLength(pstCom->stWorkSettings.szPortName)) { iRetVal = COM_OK; StrCharCopyN(pszName, pstCom->stWorkSettings.szPortName, nLen); } else { iRetVal = COM_NOT_ENOUGH_MEMORY; pszName[0] = TEXT('\0'); } } else { iRetVal = COM_PORT_INVALID_NAME; pszName[0] = TEXT('\0'); } } DBGOUT_NORMAL("-ComGetPortName returning %u, size = %u, name = %s\r\n", iRetVal, nLen, pszName ? pszName : " ",0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetAutoDetect * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComGetAutoDetect(HCOM pstCom, int *pfAutoDetect) { int iRet = COM_OK; struct s_common stCommon; assert(ComValidHandle(pstCom)); assert(pfAutoDetect); if (pstCom->pfDeviceGetCommon == NULL) iRet = COM_NOT_SUPPORTED; else if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) iRet = COM_DEVICE_ERROR; else if (!bittest(stCommon.afItem, COM_AUTO)) iRet = COM_NOT_SUPPORTED; else if (pfAutoDetect) *pfAutoDetect = stCommon.fAutoDetect; return iRet; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSetAutoDetect * * DESCRIPTION: * * ARGUMENTS: * * RETURNS: * */ int ComSetAutoDetect(HCOM pstCom, int fAutoDetect) { struct s_common stCommon; int fDummy; int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); if (ComGetAutoDetect(pstCom, &fDummy) == COM_NOT_SUPPORTED) { iRetVal = COM_NOT_SUPPORTED; } else { stCommon.afItem = COM_AUTO; stCommon.fAutoDetect = fAutoDetect; if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) { iRetVal = COM_DEVICE_ERROR; } } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetBaud * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComGetBaud(const HCOM pstCom, long * const plBaud) { ST_COMMON stCommon; assert(ComValidHandle(pstCom)); assert(plBaud); if (pstCom->pfDeviceGetCommon == NULL) return COM_NOT_SUPPORTED; if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) return COM_DEVICE_ERROR; if (!bittest(stCommon.afItem, COM_BAUD)) return COM_NOT_SUPPORTED; *plBaud = stCommon.lBaud; return COM_OK; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSetBaud * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSetBaud(const HCOM pstCom, const long lBaud) { ST_COMMON stCommon; long lDummy; int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); if (ComGetBaud(pstCom, &lDummy) == COM_NOT_SUPPORTED) { iRetVal = COM_NOT_SUPPORTED; } else { stCommon.afItem = COM_BAUD; stCommon.lBaud = lBaud; if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) { iRetVal = COM_DEVICE_ERROR; } } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetDataBits * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComGetDataBits(const HCOM pstCom, int * const pnDataBits) { ST_COMMON stCommon; assert(ComValidHandle(pstCom)); assert(pnDataBits); if (pstCom->pfDeviceGetCommon == NULL) return COM_NOT_SUPPORTED; if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) return COM_DEVICE_ERROR; if (!bittest(stCommon.afItem, COM_DATABITS)) return COM_NOT_SUPPORTED; *pnDataBits = stCommon.nDataBits; return COM_OK; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSetDataBits * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSetDataBits(const HCOM pstCom, const int nDataBits) { ST_COMMON stCommon; int nDummy; int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); if (ComGetDataBits(pstCom, &nDummy) == COM_NOT_SUPPORTED) { iRetVal = COM_NOT_SUPPORTED; } else { stCommon.afItem = COM_DATABITS; stCommon.nDataBits = nDataBits; if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) { iRetVal = COM_DEVICE_ERROR; } } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetStopBits * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComGetStopBits(const HCOM pstCom, int * const pnStopBits) { ST_COMMON stCommon; assert(ComValidHandle(pstCom)); assert(pnStopBits); if (pstCom->pfDeviceGetCommon == NULL) return COM_NOT_SUPPORTED; if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) return COM_DEVICE_ERROR; if (!bittest(stCommon.afItem, COM_STOPBITS)) return COM_NOT_SUPPORTED; *pnStopBits = stCommon.nStopBits; return COM_OK; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSetStopBits * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSetStopBits(const HCOM pstCom, const int nStopBits) { ST_COMMON stCommon; int nDummy; int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); if (ComGetStopBits(pstCom, &nDummy) == COM_NOT_SUPPORTED) { iRetVal = COM_NOT_SUPPORTED; } else { stCommon.afItem = COM_STOPBITS; stCommon.nStopBits = nStopBits; if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) { iRetVal = COM_DEVICE_ERROR; } } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComGetParity * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComGetParity(const HCOM pstCom, int * const pnParity) { ST_COMMON stCommon; assert(ComValidHandle(pstCom)); assert(pnParity); if (pstCom->pfDeviceGetCommon == NULL) return COM_NOT_SUPPORTED; if ((*pstCom->pfDeviceGetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) return COM_DEVICE_ERROR; if (!bittest(stCommon.afItem, COM_PARITY)) return COM_NOT_SUPPORTED; *pnParity = stCommon.nParity; return COM_OK; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSetParity * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSetParity(const HCOM pstCom, const int nParity) { ST_COMMON stCommon; int nDummy; int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); if (ComGetParity(pstCom, &nDummy) == COM_NOT_SUPPORTED) { iRetVal = COM_NOT_SUPPORTED; } else { stCommon.afItem = COM_PARITY; stCommon.nParity = nParity; if ((*pstCom->pfDeviceSetCommon)(pstCom->pvDriverData, &stCommon) != COM_OK) { iRetVal = COM_DEVICE_ERROR; } } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComPreconnect * * DESCRIPTION: * This function is called just before a connection is attempted. It is * called at a point in the connection process when user interaction is * straight-forward. Certain devices may need to interact with the user * in order to work (having user insert a card, or select from a pool of * devices, etc.). User interaction may not be possible at the time that * ComActivatePort is called, so it should be done here. This routine * may lay claim to a resource and hold it pending the call to * ComActivatePort. Once this routine is called, ComActivatePort will * usually be called (but not necessarily always); ComDeactivatePort will * always be called. * * ARGUMENTS: * pstCom -- a com handle as returned by ComCreateHandle * * RETURNS: * COM_OK -- if the connection attempt should continue * COM_FAILED -- if the connection attempt should be abandoned. (in this * case, it is up to the driver to display the reason * before returning) */ int ComPreconnect(const HCOM pstCom) { int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); iRetVal = (*pstCom->pfPortPreconnect)(pstCom->pvDriverData, pstCom->stWorkSettings.szPortName, sessQueryHwnd(pstCom->hSession)); if (iRetVal != COM_OK) { iRetVal = COM_FAILED; } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComActivatePort * * DESCRIPTION: * Attempts to activate the port associated with a com handle. This call * will not necessarily attempt to complete a connection. * Note: this function will display an error messages for all errors except * COM_PORT_IN_USE. If a COM_PORT_IN_USE error is encountered and * is not rectified by borrowing or changing ports, the error message * should be displayed by the calling routine. * * ARGUMENTS: * pstCom -- a com handle as returned by ComCreateHandle * * RETURNS: * COM_OK * COM_PORT_IN_USE -- Port is in use by another process. * or error code as defined in COM.H */ int ComActivatePort(const HCOM pstCom, DWORD_PTR dwMediaHdl) { int iRetVal = COM_OK; // This function (or the functions it calls) should report all errors // except for COM_PORT_IN_USE. Higher level routines may want to // try some recovery techniques before reporting an unavailable port assert(ComValidHandle(pstCom)); DBGOUT_NORMAL("+ComActivatePort(%#08x)\r\n", pstCom, 0,0,0,0); if (ComIsActive(pstCom) != COM_OK) { //* TODO: this is temporary until we resolve how driver and program // decide on size of send buffers. pstCom->nSBufrSize = 128; // // Free the send bufers prior to setting to malloc so we don't // have a memory leak. REV: 02/27/2001. // if (pstCom->puchSendBufr1) { free(pstCom->puchSendBufr1); pstCom->puchSendBufr1 = NULL; } if (pstCom->puchSendBufr2) { free(pstCom->puchSendBufr2); pstCom->puchSendBufr2 = NULL; } // Allocate ComSend buffers if ((pstCom->puchSendBufr1 = malloc((size_t)pstCom->nSBufrSize)) == NULL || (pstCom->puchSendBufr2 = malloc((size_t)pstCom->nSBufrSize)) == NULL) { DBGOUT_NORMAL(" ComActivatePort -- no memory for send buffers\r\n", 0,0,0,0,0); //* ComReportError(pstCom, NM_NEED_MEMFOR, //* strldGet(mGetStrldHdl(pstCom->hSession), CM_NM_COMDRIVER), TRUE); iRetVal = COM_NOT_ENOUGH_MEMORY; goto checkout; } pstCom->puchSendBufr = pstCom->puchSendPut = pstCom->puchSendBufr1; pstCom->nSendCount = 0; pstCom->fUserCalled = FALSE; pstCom->pfUserFunction = ComSendDefaultStatusFunction; // Now call on driver code to activate the physical device if ((iRetVal = (*pstCom->pfPortActivate)(pstCom->pvDriverData, pstCom->stWorkSettings.szPortName, dwMediaHdl)) == COM_OK) { // // Reset the transfer's loss of carrier flag. REV: 08/23/2001 // XD_TYPE* pX = (XD_TYPE*)sessQueryXferHdl(pstCom->hSession); if (pX != NULL) { pX->nCarrierLost = FALSE; } pstCom->fPortActive = TRUE; } } checkout: if (iRetVal != COM_OK) { ComDeactivatePort(pstCom); } DBGOUT_NORMAL("-ComActivatePort returning %u\r\n", iRetVal, 0,0,0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComDeactivatePort * * DESCRIPTION: * Attempts to deactivate the port associated with a com handle. This call * * ARGUMENTS: * pstCom -- a com handle as returned by ComCreateHandle * * RETURNS: * COM_OK * or error code as defined in COM.H */ int ComDeactivatePort(const HCOM pstCom) { int iRetVal = COM_OK; int iPortConnected = COM_PORT_NOT_OPEN; DBGOUT_NORMAL("+ComDeactivatePort(%#08x)\r\n", pstCom,0,0,0,0); if (ComValidHandle(pstCom) == FALSE || pstCom == NULL) { assert(0); return COM_INVALID_HANDLE; } if (pstCom->pvDriverData != NULL) { iPortConnected = (*pstCom->pfPortConnected)(pstCom->pvDriverData); } if (pstCom->fPortActive || iPortConnected != COM_PORT_NOT_OPEN) { // Call on driver code to deactivate the physical device if ((iRetVal = (*pstCom->pfPortDeactivate)(pstCom->pvDriverData)) == COM_OK) { // // Reset the transfer's loss of carrier flag. REV: 08/23/2001 // XD_TYPE* pX = (XD_TYPE*)sessQueryXferHdl(pstCom->hSession); if (pX != NULL) { pX->nCarrierLost = TRUE; } pstCom->fPortActive = FALSE; } } if (pstCom->pfSndBufrClear) { // Call on driver code to clear the send buffer iRetVal = (*pstCom->pfSndBufrClear)(pstCom->pvDriverData); } if (pstCom->hSndReady) { ResetEvent(pstCom->hSndReady); } if (pstCom->pfRcvClear) { // Call on driver code to clear the receive buffer iRetVal = (*pstCom->pfRcvClear)(pstCom->pvDriverData); } if (pstCom->hRcvEvent) { ResetEvent(pstCom->hRcvEvent); } pstCom->pfPortDeactivate = ComDefDoNothing; pstCom->pfPortConnected = ComDefDoNothing; pstCom->pfRcvRefill = ComDefBufrRefill; pstCom->pfRcvClear = ComDefDoNothing; pstCom->pfSndBufrSend = ComDefSndBufrSend; pstCom->pfSndBufrIsBusy = ComDefSndBufrBusy; pstCom->pfSndBufrClear = ComDefSndBufrClear; pstCom->pfSndBufrQuery = ComDefSndBufrQuery; pstCom->pfSendXon = ComDefDoNothing; if (pstCom->puchSendBufr1) { free(pstCom->puchSendBufr1); pstCom->puchSendBufr1 = NULL; } if (pstCom->puchSendBufr2) { free(pstCom->puchSendBufr2); pstCom->puchSendBufr2 = NULL; } pstCom->puchSendBufr = pstCom->puchSendPut = pstCom->puchSendBufr1; pstCom->nSendCount = 0; pstCom->nSBufrSize = 0; pstCom->fUserCalled = FALSE; DBGOUT_NORMAL("-ComDeactivatePort returned %u\r\n", iRetVal, 0,0,0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComOverride * * DESCRIPTION: * Used to temporarily override the current com settings. Allows setting * the com channel to support specific data transfer needs without * specific knowledge of the current com device or its settings. * * ARGUMENTS: * pstCom Com handle returned by an call to CreateComHandle * uiOptions Options which specify transfer requirements. Currently: * COM_OVERRIDE_8BIT temporarily switchs port to * 8 bit, no parity mode * COM_OVERRIDE_RCVALL temporarily suspends any com * settings that would prevent some * characters from being received: * typically suspends recognition * of received XON/XOFF codes * COM_OVERRIDE_SNDALL temporarily suspends any com * settings that would prevent some * characters from being sent. * puiOldOptions Pointer to a unsigned variable to receive the options in * force prior to this call. The value returned in this * field should be used to restore the com driver when * the override is no longer needed. If this value is not * needed, puiOldOptions can be set to NULL. * * RETURNS: * COM_OK if requested override is possible with the current com device * COM_CANT_OVERRIDE if the current device cannot support the request * */ int ComOverride(const HCOM pstCom, const unsigned afOptions, unsigned * const pafOldOptions) { unsigned afOldOverride; int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); afOldOverride = pstCom->afOverride; if (pafOldOptions) *pafOldOptions = afOldOverride; pstCom->afOverride = afOptions; if ((iRetVal = ComConfigurePort(pstCom)) == COM_CANT_OVERRIDE) pstCom->afOverride = afOldOverride; return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComQueryOverride * * DESCRIPTION: * Returns the value of the override flags as described in ComOverride * * ARGUMENTS: * pstCom Com handle returned by an call to CreateComHandle * pafOptions Pointer to UINT to receive copy of override option flags * * RETURNS: * Always returns COM_OK */ int ComQueryOverride(HCOM pstCom, unsigned *pafOptions) { assert(ComValidHandle(pstCom)); assert(pafOptions); *pafOptions = pstCom->afOverride; return COM_OK; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComConfigurePort * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComConfigurePort(const HCOM pstCom) { int iRetVal = COM_OK; DBGOUT_NORMAL("+ComconfigurePort(%#08x)\r\n", pstCom, 0,0,0,0); assert(ComValidHandle(pstCom)); if (ComIsActive(pstCom) == COM_OK) iRetVal = (*pstCom->pfPortConfigure)(pstCom->pvDriverData); DBGOUT_NORMAL("-ComConfigurePort returning %u\r\n", iRetVal, 0,0,0,0); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComRcvBufrRefill * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComRcvBufrRefill(const HCOM pstCom, TCHAR * const tc, const int fRemoveChar) { int iRetVal; ST_COM_CONTROL *pstComCntrl = (ST_COM_CONTROL *)pstCom; iRetVal = (*pstCom->pfRcvRefill)(pstCom->pvDriverData); if (iRetVal) { if (tc) *tc = *pstComCntrl->puchRBData; if (fRemoveChar) ++pstComCntrl->puchRBData; } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComRcvBufrClear * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComRcvBufrClear(const HCOM pstCom) { return ((*pstCom->pfRcvClear)(pstCom->pvDriverData)); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSndBufrSend * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSndBufrSend( const HCOM pstCom, void * const pvBufr, const int nCount, const int nWait) { int iRetVal = COM_OK; assert(ComValidHandle(pstCom)); assert(pvBufr); if (nCount > 0) { if ((*pstCom->pfPortConnected)(pstCom->pvDriverData) == COM_PORT_NOT_OPEN) { iRetVal = COM_PORT_NOT_OPEN; } else if (ComSndBufrBusy(pstCom) == COM_BUSY && (!nWait || ComSndBufrWait(pstCom, nWait) != COM_OK)) iRetVal = COM_BUSY; else { iRetVal = (*pstCom->pfSndBufrSend)(pstCom->pvDriverData, pvBufr, nCount); } } return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSndBufrBusy * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSndBufrBusy(const HCOM pstCom) { int usResult; usResult = (*pstCom->pfSndBufrIsBusy)(pstCom->pvDriverData); return usResult; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSndBufrWait * * DESCRIPTION: * Waits until the Com driver can transmit more data. The amount of time to * wait can be specified. While waiting, a settable idle function is * repeatedly called. * * ARGUMENTS: * pstCom -- Com handle * nWait -- Time to wait in tenths of a second * * RETURNS: * COM_OK if driver can accept new data within the timeout interval * COM_BUSY if the transmitter is still not available after timeout interval */ int ComSndBufrWait(const HCOM pstCom, const int nWait) { int iRetVal = COM_OK; DWORD dwRet; // // See if the port is currently connected. If not, then return an // error stating the port is not connected. REV: 08/24/2001 // if ((*pstCom->pfPortConnected)(pstCom->pvDriverData) == COM_PORT_NOT_OPEN) { iRetVal = COM_PORT_NOT_OPEN; } else if ((iRetVal = ComSndBufrBusy(pstCom)) != COM_OK && nWait) { //DbgOutStr("DBG_WRITE: %d Wait started\n",GetTickCount(),0,0,0,0); dwRet = WaitForSingleObject(pstCom->hSndReady, nWait * 100); if (dwRet != WAIT_OBJECT_0) { iRetVal = COM_BUSY; } else { iRetVal = COM_OK; } } else { //DbgOutStr("DBG_WRITE: %d No wait\n",GetTickCount(),0,0,0,0); } return iRetVal; #if 0 // jmh 01-11-96 This was the previous method, which didn't block at all int iRetVal = COM_OK; DWORD dwTimer; if ((iRetVal = ComSndBufrBusy(pstCom)) != COM_OK && nWait) { dwTimer = startinterval(); while (interval(dwTimer) < (DWORD)nWait) { //* With thread model, not sure we still need ComIdle //* ComIdle(pstCom); // Keep from locking up the program if (ComSndBufrBusy(pstCom) == COM_OK) { iRetVal = COM_OK; break; } } } return iRetVal; #endif // 0 } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSndBufrClear * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSndBufrClear(const HCOM pstCom) { return (*pstCom->pfSndBufrClear)(pstCom->pvDriverData); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComSndBufrQuery * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComSndBufrQuery(const HCOM pstCom, unsigned * const pafStatus, long * const plHandshakeDelay) { return (*pstCom->pfSndBufrQuery)(pstCom->pvDriverData, pafStatus, plHandshakeDelay); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComDeviceDialog * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ int ComDeviceDialog(const HCOM pstCom, const HWND hwndParent) { int iRetVal; assert(ComValidHandle(pstCom)); iRetVal = (*pstCom->pfDeviceDialog)(pstCom->pvDriverData, hwndParent); return iRetVal; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComDriverSpecial * * DESCRIPTION: * Allows access to special features of specific Com Device Drivers using * a common API. * * ARGUMENTS: * pstCom -- A Com Handle * pszInstructions -- A driver specific string providing instructions * on what task a driver should carry out. * pszResults -- A buffer to receive a driver specific result string. * uiBufrSize -- The size (in bytes) of the pszResults buffer. * * RETURNS: * */ int ComDriverSpecial(const HCOM pstCom, const TCHAR * const pszInstructions, TCHAR * const pszResults, const int nBufrSize) { int iRetVal = COM_NOT_SUPPORTED; if (pstCom == NULL) return iRetVal; if (pstCom->pfDeviceSpecial) iRetVal = (*pstCom->pfDeviceSpecial)(pstCom->pvDriverData, pszInstructions, pszResults, nBufrSize); return iRetVal; } /* --- Internal functions --- */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComReportError * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ void ComReportError(const HCOM pstCom, int iErrStr, const TCHAR * const pszOptInfo, const int fFirstOnly) { if (!fFirstOnly || !pstCom->fErrorReported) { //* if (iErrStr == 0) //* iErrStr = GM_TEST_FORMAT; // just %s // Most error messages can be reported with a message error // string and (maybe) an optional string field. The optional // string is passed to utilReportError whether needed or not // since it does no harm if it is not referenced. //* utilReportError(pstCom->hSession, RE_ERROR | RE_OK, //* iErrStr, pszOptInfo); if (fFirstOnly) pstCom->fErrorReported = TRUE; } } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: ComFreeDevice * * DESCRIPTION: * * * ARGUMENTS: * * * RETURNS: * */ void ComFreeDevice(const HCOM pstCom) { if (pstCom == NULL) { assert(FALSE); return; } ComDeactivatePort(pstCom); if (pstCom->hDriverModule != (HANDLE)0) { if (pstCom->pfDeviceClose) { (void)(*pstCom->pfDeviceClose)(pstCom->pvDriverData); pstCom->pvDriverData = 0; // FreeLibrary(pstCom->hDriverModule); } pstCom->hDriverModule = (HANDLE)0; } pstCom->pfDeviceClose = ComDefDoNothing; pstCom->pfDeviceDialog = ComDefDeviceDialog; pstCom->pfDeviceGetCommon = ComDefDeviceGetCommon; pstCom->pfDeviceSetCommon = ComDefDeviceSetCommon; pstCom->pfDeviceSpecial = ComDefDeviceSpecial; pstCom->pfDeviceLoadHdl = ComDefDeviceLoadSaveHdl; pstCom->pfDeviceSaveHdl = ComDefDeviceLoadSaveHdl; pstCom->pfPortConfigure = ComDefDoNothing; pstCom->pfPortPreconnect = ComDefPortPreconnect; pstCom->pfPortActivate = ComDefPortActivate; pstCom->pfPortDeactivate = ComDefDoNothing; pstCom->fPortActive = FALSE; pstCom->szDeviceName[0] = TEXT('\0'); pstCom->stWorkSettings.szDeviceFile[0] = TEXT('\0'); pstCom->stWorkSettings.szPortName[0] = TEXT('\0'); return; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * ComValidHandle * * DESCRIPTION: * Tests whether a com handle points to a valid, initialize structure * * ARGUMENTS: * pstCom -- com handle to be tested * * RETURNS: * TRUE if com handle appears to be valid * FALSE if com handle if NULL or points to an invalid structure */ BOOL ComValidHandle(HCOM pstCom) { BOOL bReturnValue = TRUE; if (pstCom == NULL) { bReturnValue = FALSE; } #if !defined(NDEBUG) else if (pstCom->nGuard != COM_VERSION) { bReturnValue = FALSE; } #endif //!defined(NDEBUG) return bReturnValue; }