|
|
/* 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 <windows.h>
#pragma hdrstop
// #define DEBUGSTR
#include <time.h>
#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 <comstd\comstd.hh> // Drivers are linked directly in in this vers.
#if defined(INCL_WINSOCK)
#include <comwsock\comwsock.hh>
#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; }
|