|
|
/*****************************************************************************
* * Hel.c * * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved. * * Abstract: * * Hardware emulation layer calls. Used to provide common functionality * for built-in device types we support ( WDM, serial and parallel) * While access to DCB could be built as internal COM object , it does not make * much sense to invest in it, because DCBs are exclusively owned and not shared * between application objects or different applications. We also want to minimize * any overhead when talking to raw device interface. * * Note1: We don't deal at this level with access control, lower level drivers are supposed * to take care of this. Queuing of requests for non-reentrant devices is also not done here. * This Hel is basically thin layer of imaging device primitives, used only to isolate * command translator from actual hardware. * * Note2: Hel is not made extensible . If command translator needs to talk to non-supported * device, it will need to establish direct link to it. There is no requirement to use * Hel , it is service we provide to conformant devices. * * Contents: * *****************************************************************************/
/*
#include "wia.h"
#include <stilog.h>
#include <stiregi.h>
#include <sti.h>
#include <stierr.h>
#include <stiusd.h>
#include "stipriv.h"
#include "debug.h"
#define DbgFl DbgFlDevice
*/ #include "sticomm.h"
#include "validate.h"
#define DbgFl DbgFlDevice
/*****************************************************************************
* * Declare the interfaces we will be providing. * *****************************************************************************/
Primary_Interface(CCommDeviceControl, IStiDeviceControl);
Interface_Template_Begin(CCommDeviceControl) Primary_Interface_Template(CCommDeviceControl, IStiDeviceControl) Interface_Template_End(CCommDeviceControl)
/*****************************************************************************
* * @doc INTERNAL * * @struct CCommDeviceControl | * * The <i CCommDeviceControl> device object * * * @field IStiDeviceControl | stidev * * @comm * * *****************************************************************************/
#define IOBUFFERSIZE 255
#define WRITETOTALTIMEOUT 20
typedef struct CCommDeviceControl {
/* Supported interfaces */ IStiDeviceControl devctl;
DWORD dwVersion;
DWORD dwDeviceType; WCHAR wszPortName[MAX_PATH]; DWORD dwFlags; DWORD dwMode;
DWORD dwContext; DWORD dwLastOperationError; HANDLE hDeviceHandle;
HANDLE hEvent; OVERLAPPED Overlapped;
} CCommDeviceControl, *PCCommDeviceControl;
#define ThisClass CCommDeviceControl
#define ThisInterface IStiDeviceControl
#ifdef DEBUG
Default_QueryInterface(CCommDeviceControl) Default_AddRef(CCommDeviceControl) Default_Release(CCommDeviceControl)
#else
#define CCommDeviceControl_QueryInterface Common_QueryInterface
#define CCommDeviceControl_AddRef Common_AddRef
#define CCommDeviceControl_Release Common_Release
#endif
#define CCommDeviceControl_QIHelper Common_QIHelper
#pragma BEGIN_CONST_DATA
#pragma END_CONST_DATA
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | RawReadData | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_RawReadData( PSTIDEVICECONTROL pDev, LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes, LPOVERLAPPED lpOverlapped ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0; BOOL fRet = TRUE; OVERLAPPED Overlapped; COMSTAT ComStat; BOOL fBlocking = FALSE; DWORD dwErrorFlags;
EnterProc(CCommDeviceControl_CommRawReadData, (_ "pppp",pDev,lpBuffer,lpdwNumberOfBytes,lpOverlapped));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwNumberOfBytes, 4, 3)) && SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,*lpdwNumberOfBytes, 2)) && (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4))) ){
// We always call asyncronous i/o operations in order to time-out lengthy ones
if (!lpOverlapped) {
ZeroX(Overlapped); lpOverlapped = &Overlapped; fBlocking = TRUE;
} //
ClearCommError(this->hDeviceHandle, &dwErrorFlags, &ComStat);
*lpdwNumberOfBytes = min(*lpdwNumberOfBytes, ComStat.cbInQue); if (*lpdwNumberOfBytes == 0) { return (STI_OK); }
//
if (fRet = ReadFile(this->hDeviceHandle, lpBuffer, *lpdwNumberOfBytes, lpdwNumberOfBytes, lpOverlapped)) { return (STI_OK); }
if (GetLastError() != ERROR_IO_PENDING) return (STI_OK);
this->dwLastOperationError = GetLastError(); hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError); } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | CommRawWriteData | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_RawWriteData( PSTIDEVICECONTROL pDev, LPVOID lpBuffer, DWORD dwNumberOfBytes, LPOVERLAPPED lpOverlapped ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0; BOOL fRet;
EnterProc(CCommDeviceControl_CommRawWriteData, (_ "ppup",pDev,lpBuffer,dwNumberOfBytes,lpOverlapped));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
hres = STIERR_INVALID_PARAM;
if (SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,dwNumberOfBytes, 2)) ) { if (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4)) ){ // Call appropriate entry point
fRet = WriteFile(this->hDeviceHandle, lpBuffer, dwNumberOfBytes, &dwBytesReturned, lpOverlapped ); this->dwLastOperationError = GetLastError(); hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError); } } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | RawReadControl | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_RawReadCommand( PSTIDEVICECONTROL pDev, LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes, LPOVERLAPPED lpOverlapped ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0; //BOOL fRet;
EnterProc(CCommDeviceControl_CommRawReadData, (_ "pppp",pDev,lpBuffer,lpdwNumberOfBytes,lpOverlapped));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwNumberOfBytes, 4, 3)) && SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,*lpdwNumberOfBytes, 2)) && (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4))) ){
hres = STIERR_UNSUPPORTED;
} }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | CommRawWriteData | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_RawWriteCommand( PSTIDEVICECONTROL pDev, LPVOID lpBuffer, DWORD dwNumberOfBytes, LPOVERLAPPED lpOverlapped ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0; //BOOL fRet;
EnterProc(CCommDeviceControl_CommRawWriteData, (_ "ppup",pDev,lpBuffer,dwNumberOfBytes,lpOverlapped));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
hres = STIERR_INVALID_PARAM;
if (SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,dwNumberOfBytes, 2)) ) { if (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4)) ){ hres = STIERR_UNSUPPORTED; } } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | RawReadControl | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_GetLastError( PSTIDEVICECONTROL pDev, LPDWORD lpdwLastError ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0;
EnterProc(CCommDeviceControl_GetLastError, (_ "pppp",pDev,lpdwLastError));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwLastError,4, 2))) { *lpdwLastError = this->dwLastOperationError ; hres = STI_OK; } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl_ | GetMyDevicePortName | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_GetMyDevicePortName( PSTIDEVICECONTROL pDev, LPWSTR lpszDevicePath, DWORD cwDevicePathSize ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0;
EnterProc(CCommDeviceControl_GetMyDevicePortName, (_ "pp",pDev,lpszDevicePath));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
if (SUCCEEDED(hres = hresFullValidReadPvCb(lpszDevicePath,4, 2)) && SUCCEEDED(hres = hresFullValidReadPvCb(lpszDevicePath,2*cwDevicePathSize, 2)) ) {
if (cwDevicePathSize > OSUtil_StrLenW(this->wszPortName)) { OSUtil_lstrcpyW(lpszDevicePath,this->wszPortName); hres = STI_OK; } else { hres = HRESULT_FROM_WIN32(ERROR_MORE_DATA); } } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | GetMyDeviceHandle | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_GetMyDeviceHandle( PSTIDEVICECONTROL pDev, LPHANDLE pHandle ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0;
EnterProc(CCommDeviceControl_GetMyDeviceHandle, (_ "pp",pDev,pHandle));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
if (SUCCEEDED(hres = hresFullValidReadPvCb(pHandle,4, 2)) ) {
if (INVALID_HANDLE_VALUE != this->hDeviceHandle) { *pHandle = this->hDeviceHandle; hres = STI_OK; } else { hres = HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE); } } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | GetMyDeviceOpenMode | pdwOpenMode | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_GetMyDeviceOpenMode( PSTIDEVICECONTROL pDev, LPDWORD pdwOpenMode ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0;
EnterProc(CCommDeviceControl_GetMyDeviceOpenMode, (_ "pp",pDev,pdwOpenMode));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
if (SUCCEEDED(hres = hresFullValidReadPvCb(pdwOpenMode,4, 2)) ) { *pdwOpenMode = this->dwMode; hres = STI_OK; } }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | RawReadControl | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_RawDeviceControl( PSTIDEVICECONTROL pDev, USD_CONTROL_CODE EscapeFunction, LPVOID lpInData, DWORD cbInDataSize, LPVOID pOutData, DWORD dwOutDataSize, LPDWORD pdwActualData ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0;
EnterProc(CCommDeviceControl_RawDeviceControl, (_ "p",pDev));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
// Validate parameters here
hres = STIERR_UNSUPPORTED; }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @method HRESULT | CCommDeviceControl | WriteToErrorLog | * * @parm | | * * @returns * * Returns a COM error code. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * *****************************************************************************/ STDMETHODIMP CCommDeviceControl_WriteToErrorLog( PSTIDEVICECONTROL pDev, DWORD dwMessageType, LPCWSTR pszMessage, DWORD dwErrorCode ) { HRESULT hres = STIERR_INVALID_PARAM; DWORD dwBytesReturned=0;
EnterProc(CCommDeviceControl_WriteToErrorLog, (_ "p",pDev));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
//
// Validate parameters here
//
if (SUCCEEDED(hres = hresFullValidReadPvCb(pszMessage,2, 3))) {
#ifdef UNICODE
ReportStiLogMessage(g_hStiFileLog, dwMessageType, pszMessage ); #else
LPTSTR lpszAnsi = NULL;
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszAnsi,pszMessage))) { ReportStiLogMessage(g_hStiFileLog, dwMessageType, lpszAnsi ); FreePpv(&lpszAnsi); } #endif
} }
ExitOleProc(); return hres; }
/*****************************************************************************
* * @doc EXTERNAL * * @mfunc HRESULT | CCommDeviceControl | Initialize | * * Initialize a DeviceControl object. * * @cwrap PSTIDEVICECONTROL | pDev * * @returns * Returns a COM error code. The following error codes are * intended to be illustrative and not necessarily comprehensive. * * <c STI_OK> = <c S_OK>: The operation completed successfully. * * <c S_FALSE>: The device had already been initialized with * the instance GUID passed in <p lpGUID>. * * *****************************************************************************/
STDMETHODIMP CCommDeviceControl_Initialize( PSTIDEVICECONTROL pDev, DWORD dwDeviceType, DWORD dwDeviceMode, LPCWSTR pwszPortName, DWORD dwFlags ) { HRESULT hres = STI_OK; BOOL fRet = TRUE;
WCHAR wszDeviceSymbolicName[MAX_PATH] = {L'\0'}; COMMTIMEOUTS timoutInfo; //DWORD dwError;
//LPSTR pszAnsiDeviceName;
EnterProcR(CCommDeviceControl::Initialize,(_ "pp", pDev, pwszPortName));
if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
PCCommDeviceControl this = _thisPv(pDev);
this->dwDeviceType = dwDeviceType; OSUtil_lstrcpyW(this->wszPortName,pwszPortName);
this->dwMode = dwDeviceMode;
if (dwFlags & STI_HEL_OPEN_DATA) {
this->hDeviceHandle = OSUtil_CreateFileW(wszDeviceSymbolicName, GENERIC_READ | GENERIC_WRITE, // Access mask
0, // Share mode
NULL, // SA
OPEN_EXISTING, // Create disposition
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL /* hTemplate must be NULL for comm devices */ ); this->dwLastOperationError = GetLastError();
hres = (this->hDeviceHandle != INVALID_HANDLE_VALUE) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,this->dwLastOperationError);
// wake up read thread will a byte arrives
SetCommMask(this->hDeviceHandle, EV_RXCHAR);
// setup read/write buffer for I/O
SetupComm(this->hDeviceHandle, IOBUFFERSIZE, IOBUFFERSIZE);
// set time outs
timoutInfo.ReadIntervalTimeout = MAXDWORD; timoutInfo.ReadTotalTimeoutMultiplier = 0; timoutInfo.ReadTotalTimeoutConstant = 0; timoutInfo.WriteTotalTimeoutMultiplier = 0; timoutInfo.WriteTotalTimeoutConstant = WRITETOTALTIMEOUT;
if (!SetCommTimeouts(this->hDeviceHandle, &timoutInfo)) { fRet = FALSE; } else {
// create I/O event used for overlapped i/o
ZeroX(this->Overlapped); this->hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ); // no name
if (this->hEvent == NULL) { fRet = FALSE; }
EscapeCommFunction(this->hDeviceHandle, SETDTR); }
// Error code
this->dwLastOperationError = GetLastError(); hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
} }
ExitOleProc(); return hres; }
#if 0
/*
* SetupConnection * * Configure serial port with specified settings. */
static BOOL SetupConnection(HANDLE hCom, LPDPCOMPORTADDRESS portSettings) { DCB dcb;
dcb.DCBlength = sizeof(DCB); if (!GetCommState(hCom, &dcb)) return (FALSE);
// setup various port settings
dcb.fBinary = TRUE; dcb.BaudRate = portSettings->dwBaudRate; dcb.ByteSize = 8; dcb.StopBits = (BYTE) portSettings->dwStopBits;
dcb.Parity = (BYTE) portSettings->dwParity; if (portSettings->dwParity == NOPARITY) dcb.fParity = FALSE; else dcb.fParity = TRUE;
// setup hardware flow control
if ((portSettings->dwFlowControl == DPCPA_DTRFLOW) || (portSettings->dwFlowControl == DPCPA_RTSDTRFLOW)) { dcb.fOutxDsrFlow = TRUE; dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; } else { dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_ENABLE; }
if ((portSettings->dwFlowControl == DPCPA_RTSFLOW) || (portSettings->dwFlowControl == DPCPA_RTSDTRFLOW)) { dcb.fOutxCtsFlow = TRUE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; } else { dcb.fOutxCtsFlow = FALSE; dcb.fRtsControl = RTS_CONTROL_ENABLE; }
// setup software flow control
if (portSettings->dwFlowControl == DPCPA_XONXOFFFLOW) { dcb.fInX = TRUE; dcb.fOutX = TRUE; } else { dcb.fInX = FALSE; dcb.fOutX = FALSE; }
dcb.XonChar = ASCII_XON; dcb.XoffChar = ASCII_XOFF; dcb.XonLim = 100; dcb.XoffLim = 100;
if (!SetCommState( hCom, &dcb )) return (FALSE);
return (TRUE); } #endif
/*****************************************************************************
* * @doc INTERNAL * * @mfunc void | CCommDeviceControl | Init | * * Initialize the internal parts of the StiDevice object. * *****************************************************************************/
void INLINE CCommDeviceControl_Init( PCCommDeviceControl this ) {
// Initialize instance variables
this->dwContext = 0L; this->dwLastOperationError = NO_ERROR; this->hDeviceHandle = INVALID_HANDLE_VALUE; }
/*****************************************************************************
* * @doc INTERNAL * * @func void | CCommDeviceControl_Finalize | * * Releases the resources of a communication port and closed the device * * @parm PV | pvObj | * * Object being released. Note that it may not have been * completely initialized, so everything should be done * carefully. * *****************************************************************************/
void INTERNAL CCommDeviceControl_Finalize(PV pvObj) { HRESULT hres = STI_OK;
PCCommDeviceControl this = pvObj;
//
SetCommMask(this->hDeviceHandle, 0 );
//
EscapeCommFunction(this->hDeviceHandle, CLRDTR );
// purge any outstanding reads/writes and close device handle
PurgeComm(this->hDeviceHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
// Close device handles
if (IsValidHANDLE(this->hDeviceHandle)) { CloseHandle(this->hDeviceHandle); }
this->dwContext = 0L; this->dwLastOperationError = NO_ERROR; this->hDeviceHandle = INVALID_HANDLE_VALUE; //this->hDeviceControlHandle = INVALID_HANDLE_VALUE;
}
/*****************************************************************************
* * @doc INTERNAL * * @mfunc HRESULT | CCommDeviceControl | New | * * Create a new IDeviceControl object, uninitialized. * * @parm IN PUNK | punkOuter | * * Controlling unknown for aggregation. * * @parm IN RIID | riid | * * Desired interface to new object. * * @parm OUT PPV | ppvObj | * * Output pointer for new object. * *****************************************************************************/
STDMETHODIMP CCommDeviceControl_New(PUNK punkOuter, RIID riid, PPV ppvObj) { HRESULT hres; EnterProcR(CCommDeviceControl::<constructor>, (_ "Gp", riid, punkOuter));
hres = Common_NewRiid(CCommDeviceControl, punkOuter, riid, ppvObj);
if (SUCCEEDED(hres)) { PCCommDeviceControl this = _thisPv(*ppvObj); CCommDeviceControl_Init(this); }
ExitOleProcPpvR(ppvObj); return hres; }
/*****************************************************************************
* * The long-awaited vtbls and templates * *****************************************************************************/
#pragma BEGIN_CONST_DATA
#define CCommDeviceControl_Signature (DWORD)'Comm'
Primary_Interface_Begin(CCommDeviceControl, IStiDeviceControl) CCommDeviceControl_Initialize, CCommDeviceControl_RawReadData, CCommDeviceControl_RawWriteData, CCommDeviceControl_RawReadCommand, CCommDeviceControl_RawWriteCommand, CCommDeviceControl_RawDeviceControl, CCommDeviceControl_GetLastError, CCommDeviceControl_GetMyDevicePortName, CCommDeviceControl_GetMyDeviceHandle, CCommDeviceControl_GetMyDeviceOpenMode, CCommDeviceControl_WriteToErrorLog, Primary_Interface_End(CCommDeviceControl, IStiDeviceControl)
|