Quellcode durchsuchen

1、基础串口类

scbc.sat2 vor 5 Jahren
Ursprung
Commit
32128b56c1

+ 186 - 1
短信猫/sms/sms/AsynSerial.cpp

@@ -1,10 +1,195 @@
 #include "StdAfx.h"
 #include "AsynSerial.h"
 
-CAsynSerial::CAsynSerial(void)
+CAsynSerial::CAsynSerial(void):m_hComm(INVALID_HANDLE_VALUE)
 {
 }
 
 CAsynSerial::~CAsynSerial(void)
 {
 }
+
+BOOL CAsynSerial::Open(LPCTSTR pszPort, BOOL bOverlapped /* = FALSE*/) throw()
+{
+	// ¹Ø±Õǰ¾ä±ú;
+	Close();
+
+	m_hComm = CreateFile(
+		pszPort, 
+		GENERIC_READ | GENERIC_WRITE, 
+		0,
+		NULL, 
+		OPEN_EXISTING,
+		bOverlapped ? FILE_FLAG_OVERLAPPED : 0,
+		NULL);
+
+	return (m_hComm != INVALID_HANDLE_VALUE);
+}
+
+BOOL CAsynSerial::Open(int nPort, DWORD dwBaud /* = 9600 */, int parity /* = NoParity */, BYTE DataBits /* = 8 */, int stopBits /* = OneStopBit */, int fc /* = NoFlowControl */, BOOL bOverlapped /* = FALSE */)
+{
+	CString sPort;
+	sPort.Format(_T("\\\\.\\COM%d"), nPort);
+	return Open(sPort, dwBaud, parity, DataBits, stopBits, fc, bOverlapped);
+}
+
+BOOL CAsynSerial::Open(LPCTSTR pszPort, DWORD dwBaud /* = 9600 */, int parity /* = NoParity */, BYTE DataBits /* = 8 */, int stopBits /* = OneStopBit */, int fc /* = NoFlowControl */, BOOL bOverlapped /* = FALSE */) throw()
+{
+	if (!Open(pszPort, bOverlapped))
+		return FALSE;
+
+	//Get the current state prior to changing it
+	DCB dcb = {0};
+	dcb.DCBlength = sizeof(DCB);
+	if (!GetState(dcb))
+	{
+		const DWORD dwLastError = GetLastError();
+		Close();
+		SetLastError(dwLastError);
+		return FALSE;
+	}
+
+	//Setup the baud rate
+	dcb.BaudRate = dwBaud;
+
+	//Setup the Parity
+	switch (parity)
+	{
+	case EvenParity:
+		{
+			dcb.Parity = EVENPARITY;
+			break;
+		}
+	case MarkParity:
+		{
+			dcb.Parity = MARKPARITY;
+			break;
+		}
+	case NoParity:
+		{
+			dcb.Parity = NOPARITY;
+			break;
+		}
+	case OddParity:
+		{
+			dcb.Parity = ODDPARITY;
+			break;
+		}
+	case SpaceParity:
+		{
+			dcb.Parity = SPACEPARITY;
+			break;
+		}
+	default:
+		{
+			ATLASSERT(FALSE);
+			break;
+		}
+	}
+
+	//Setup the data bits
+	dcb.ByteSize = DataBits;
+
+	//Setup the stop bits
+	switch (stopBits)
+	{
+	case OneStopBit:
+		{
+			dcb.StopBits = ONESTOPBIT;
+			break;
+		}
+	case OnePointFiveStopBits:
+		{
+			dcb.StopBits = ONE5STOPBITS;
+			break;
+		}
+	case TwoStopBits:
+		{
+			dcb.StopBits = TWOSTOPBITS;
+			break;
+		}
+	default:
+		{
+			ATLASSERT(FALSE);
+			break;
+		}
+	}
+
+	//Setup the flow control
+	dcb.fDsrSensitivity = FALSE;
+	switch (fc)
+	{
+	case NoFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case CtsRtsFlowControl:
+		{
+			dcb.fOutxCtsFlow = TRUE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case CtsDtrFlowControl:
+		{
+			dcb.fOutxCtsFlow = TRUE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case DsrRtsFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = TRUE;
+			dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case DsrDtrFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = TRUE;
+			dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case XonXoffFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fOutX = TRUE;
+			dcb.fInX = TRUE;
+			dcb.XonChar = 0x11;
+			dcb.XoffChar = 0x13;
+			dcb.XoffLim = 100;
+			dcb.XonLim = 100;
+			break;
+		}
+	default:
+		{
+			ATLASSERT(FALSE);
+			break;
+		}
+	}
+
+	//Now that we have all the settings in place, make the changes
+	if (!SetState(dcb))
+	{
+		const DWORD dwLastError = GetLastError();
+		Close();
+		SetLastError(dwLastError);
+		return FALSE;
+	}
+
+	return TRUE;
+}

+ 373 - 0
短信猫/sms/sms/AsynSerial.h

@@ -23,9 +23,382 @@
 
 class CAsynSerial
 {
+public:
+	//Enums
+	enum FlowControl
+	{
+		NoFlowControl,
+		CtsRtsFlowControl,
+		CtsDtrFlowControl,
+		DsrRtsFlowControl,
+		DsrDtrFlowControl,
+		XonXoffFlowControl
+	};
+
+	enum Parity
+	{
+		NoParity = 0,
+		OddParity = 1,
+		EvenParity = 2,
+		MarkParity = 3,
+		SpaceParity = 4
+	};
+
+	enum StopBits
+	{
+		OneStopBit,
+		OnePointFiveStopBits,
+		TwoStopBits
+	};
+protected:
+	HANDLE m_hComm;
 public:
 	CAsynSerial(void);
 	virtual ~CAsynSerial(void);
+
+	BOOL IsOpen() const throw() // noexcept 
+	{
+		return m_hComm != INVALID_HANDLE_VALUE;
+	}
+
+	void Close() throw()  // noexcept  
+	{
+		if (IsOpen())
+		{
+			CloseHandle(m_hComm);
+			m_hComm = INVALID_HANDLE_VALUE;
+		}
+	}
+
+	BOOL Open(LPCTSTR pszPort, BOOL bOverlapped = FALSE) throw(); // noexcept 
+	BOOL Open(int nPort, DWORD dwBaud = 9600, int parity = NoParity, BYTE DataBits = 8, int stopBits = OneStopBit, int fc = NoFlowControl, BOOL bOverlapped = FALSE);
+	BOOL Open(LPCTSTR pszPort, DWORD dwBaud = 9600, int parity = NoParity, BYTE DataBits = 8, int stopBits = OneStopBit, int fc = NoFlowControl, BOOL bOverlapped = FALSE) throw(); // noexcept 
+
+	//////////////////////////////////////////////////////////////////////////
+	//Reading / Writing Methods
+	BOOL Read(void* lpBuffer, DWORD dwNumberOfBytesToRead, DWORD& dwBytesRead) throw()
+	{
+		ATLASSERT(IsOpen());
+		dwBytesRead = 0;
+		return ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, &dwBytesRead, NULL);
+	}
+
+	BOOL Read(void* lpBuffer, DWORD dwNumberOfBytesToRead, OVERLAPPED& overlapped, DWORD* lpNumberOfBytesRead = NULL) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, lpNumberOfBytesRead, &overlapped);
+	}
+
+	BOOL ReadEx(LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ReadFileEx(m_hComm, lpBuffer, dwNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine);
+	}
+
+	BOOL Write(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, DWORD& dwBytesWritten) throw()
+	{
+		ATLASSERT(IsOpen());
+		dwBytesWritten = 0;
+		return WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, &dwBytesWritten, NULL);
+	}
+
+	BOOL Write(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, OVERLAPPED& overlapped, DWORD* lpNumberOfBytesWritten = NULL) throw()
+	{
+		ATLASSERT(IsOpen());
+		return WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, lpNumberOfBytesWritten, &overlapped);
+	}
+
+	BOOL WriteEx(LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) throw()
+	{
+		ATLASSERT(IsOpen());
+		return WriteFileEx(m_hComm, lpBuffer, dwNumberOfBytesToWrite, lpOverlapped, lpCompletionRoutine);
+	}
+
+	BOOL TransmitChar(char cChar) throw()
+	{
+		ATLASSERT(IsOpen());
+		return TransmitCommChar(m_hComm, cChar);
+	}
+
+	BOOL GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait);
+	}
+
+	__if_exists(::GetOverlappedResultEx)
+	{
+		BOOL GetOverlappedResultEx(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, DWORD dwMilliseconds, _In_ BOOL bAlertable) throw()
+		{
+			ATLASSERT(IsOpen());
+			return ::GetOverlappedResultEx(m_hComm, &overlapped, &dwBytesTransferred, dwMilliseconds, bAlertable);
+		}
+	}
+
+	BOOL CancelIo() throw()
+	{
+		ATLASSERT(IsOpen());
+		return ::CancelIo(m_hComm);
+	}
+
+	__if_exists(::CancelIoEx)
+	{
+		BOOL CancelIoEx(LPOVERLAPPED lpOverlapped = NULL) throw()
+		{
+			ATLASSERT(IsOpen());
+
+			return ::CancelIoEx(m_hComm, lpOverlapped);
+		}
+	}
+
+	BOOL BytesWaiting(DWORD& dwBytesWaiting) throw()
+	{
+		ATLASSERT(IsOpen());
+		//Check to see how many characters are unread
+		dwBytesWaiting = 0;
+		COMSTAT stat;
+		if (!GetStatus(stat))
+			return FALSE;
+		dwBytesWaiting = stat.cbInQue;
+		return TRUE;
+	}
+
+	//Configuration Methods
+	BOOL GetConfig(COMMCONFIG& config) throw()
+	{
+		ATLASSERT(IsOpen());
+
+		DWORD dwSize = sizeof(COMMCONFIG);
+		return GetCommConfig(m_hComm, &config, &dwSize);
+	}
+
+	static BOOL GetDefaultConfig(int nPort, COMMCONFIG& config)
+	{
+		CString sPort;
+		sPort.Format(_T("COM%d"), nPort);
+		//Delegate to the other version of the method
+		return GetDefaultConfig(sPort, config);
+	}
+
+	static BOOL GetDefaultConfig(LPCTSTR pszPort, COMMCONFIG& config) throw()
+	{
+		DWORD dwSize = sizeof(COMMCONFIG);
+		return GetDefaultCommConfig(pszPort, &config, &dwSize);
+	}
+
+	BOOL SetConfig(COMMCONFIG& config) throw()
+	{
+		ATLASSERT(IsOpen());
+		const DWORD dwSize = sizeof(COMMCONFIG);
+		return SetCommConfig(m_hComm, &config, dwSize);
+	}
+
+	static BOOL SetDefaultConfig(int nPort, COMMCONFIG& config)
+	{
+		CString sPort;
+		sPort.Format(_T("COM%d"), nPort);
+		//Delegate to the other version of the method
+		return SetDefaultConfig(sPort, config);
+	}
+
+	static BOOL SetDefaultConfig(LPCTSTR pszPort, COMMCONFIG& config) throw()
+	{
+		const DWORD dwSize = sizeof(COMMCONFIG);
+		return SetDefaultCommConfig(pszPort, &config, dwSize);
+	}
+
+	//Misc RS232 Methods
+	BOOL ClearBreak() throw()
+	{
+		ATLASSERT(IsOpen());
+		return ClearCommBreak(m_hComm);
+	}
+
+	BOOL SetBreak() throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommBreak(m_hComm);
+	}
+
+	BOOL ClearError(DWORD& dwErrors) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ClearCommError(m_hComm, &dwErrors, NULL);
+	}
+
+	BOOL GetStatus(COMSTAT& stat) throw()
+	{
+		ATLASSERT(IsOpen());
+		DWORD dwErrors = 0;
+		return ClearCommError(m_hComm, &dwErrors, &stat);
+	}
+
+	BOOL GetState(DCB& dcb) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommState(m_hComm, &dcb);
+	}
+
+	BOOL SetState(DCB& dcb) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommState(m_hComm, &dcb);
+	}
+
+	BOOL Escape(DWORD dwFunc) throw()
+	{
+		ATLASSERT(IsOpen());
+		return EscapeCommFunction(m_hComm, dwFunc);
+	}
+
+	BOOL ClearDTR() throw()
+	{
+		return Escape(CLRDTR);
+	}
+
+	BOOL ClearRTS() throw()
+	{
+		return Escape(CLRRTS);
+	}
+
+	BOOL SetDTR() throw()
+	{
+		return Escape(SETDTR);
+	}
+
+	BOOL SetRTS() throw()
+	{
+		return Escape(SETRTS);
+	}
+
+	BOOL SetXOFF() throw()
+	{
+		return Escape(SETXOFF);
+	}
+
+	BOOL SetXON() throw()
+	{
+		return Escape(SETXON);
+	}
+
+	BOOL GetProperties(COMMPROP& properties) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommProperties(m_hComm, &properties);
+	}
+
+	BOOL GetModemStatus(DWORD& dwModemStatus) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommModemStatus(m_hComm, &dwModemStatus);
+	}
+
+	//Timeouts
+	BOOL SetTimeouts(COMMTIMEOUTS& timeouts) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommTimeouts(m_hComm, &timeouts);
+	}
+
+	BOOL GetTimeouts(COMMTIMEOUTS& timeouts) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommTimeouts(m_hComm, &timeouts);
+	}
+
+	BOOL Set0Timeout() throw()
+	{
+		COMMTIMEOUTS Timeouts;
+		memset(&Timeouts, 0, sizeof(Timeouts));
+		Timeouts.ReadIntervalTimeout = MAXDWORD;
+		return SetTimeouts(Timeouts);
+	}
+
+	BOOL Set0WriteTimeout() throw()
+	{
+		COMMTIMEOUTS Timeouts;
+		GetTimeouts(Timeouts);
+		Timeouts.WriteTotalTimeoutMultiplier = 0;
+		Timeouts.WriteTotalTimeoutConstant = 0;
+		return SetTimeouts(Timeouts);
+	}
+
+	BOOL Set0ReadTimeout() throw()
+	{
+		COMMTIMEOUTS Timeouts;
+		GetTimeouts(Timeouts);
+		Timeouts.ReadIntervalTimeout = MAXDWORD;
+		Timeouts.ReadTotalTimeoutMultiplier = 0;
+		Timeouts.ReadTotalTimeoutConstant = 0;
+		return SetTimeouts(Timeouts);
+	}
+
+	//Event Methods
+	BOOL SetMask(DWORD dwMask) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommMask(m_hComm, dwMask);
+	}
+
+	BOOL GetMask(DWORD& dwMask) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommMask(m_hComm, &dwMask);
+	}
+
+	BOOL WaitEvent(DWORD& dwMask) throw()
+	{
+		ATLASSERT(IsOpen());
+		return WaitCommEvent(m_hComm, &dwMask, NULL);
+	}
+
+	BOOL WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped) throw()
+	{
+		ATLASSERT(IsOpen());
+		ATLASSERT(overlapped.hEvent != NULL);
+
+		return WaitCommEvent(m_hComm, &dwMask, &overlapped);
+	}
+
+	//Queue Methods
+	BOOL Flush() throw()
+	{
+		ATLASSERT(IsOpen());
+		return FlushFileBuffers(m_hComm);
+	}
+
+	BOOL Purge(DWORD dwFlags) throw()
+	{
+		ATLASSERT(IsOpen());
+		return PurgeComm(m_hComm, dwFlags);
+	}
+
+	BOOL TerminateOutstandingWrites() throw()
+	{
+		return Purge(PURGE_TXABORT);
+	}
+
+	BOOL TerminateOutstandingReads() throw()
+	{
+		return Purge(PURGE_RXABORT);
+	}
+
+	BOOL ClearWriteBuffer() throw()
+	{
+		return Purge(PURGE_TXCLEAR);
+	}
+
+	BOOL ClearReadBuffer() throw()
+	{
+		return Purge(PURGE_RXCLEAR);
+	}
+
+	BOOL Setup(DWORD dwInQueue, DWORD dwOutQueue) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetupComm(m_hComm, dwInQueue, dwOutQueue);
+	}
+
 };
 
 #endif // __ASYN_SERIAL__

+ 195 - 0
短信猫/sms/sms/BaseSerial.cpp

@@ -0,0 +1,195 @@
+#include "StdAfx.h"
+#include "BaseSerial.h"
+
+CBaseSerial::CBaseSerial(void):m_hComm(INVALID_HANDLE_VALUE)
+{
+}
+
+CBaseSerial::~CBaseSerial(void)
+{
+}
+
+BOOL CBaseSerial::Open(LPCTSTR pszPort, BOOL bOverlapped /* = FALSE*/) throw()
+{
+	// ¹Ø±Õǰ¾ä±ú;
+	Close();
+
+	m_hComm = CreateFile(
+		pszPort, 
+		GENERIC_READ | GENERIC_WRITE, 
+		0,
+		NULL, 
+		OPEN_EXISTING,
+		bOverlapped ? FILE_FLAG_OVERLAPPED : 0,
+		NULL);
+
+	return (m_hComm != INVALID_HANDLE_VALUE);
+}
+
+BOOL CBaseSerial::Open(int nPort, DWORD dwBaud /* = 9600 */, int parity /* = NoParity */, BYTE DataBits /* = 8 */, int stopBits /* = OneStopBit */, int fc /* = NoFlowControl */, BOOL bOverlapped /* = FALSE */)
+{
+	CString sPort;
+	sPort.Format(_T("\\\\.\\COM%d"), nPort);
+	return Open(sPort, dwBaud, parity, DataBits, stopBits, fc, bOverlapped);
+}
+
+BOOL CBaseSerial::Open(LPCTSTR pszPort, DWORD dwBaud /* = 9600 */, int parity /* = NoParity */, BYTE DataBits /* = 8 */, int stopBits /* = OneStopBit */, int fc /* = NoFlowControl */, BOOL bOverlapped /* = FALSE */) throw()
+{
+	if (!Open(pszPort, bOverlapped))
+		return FALSE;
+
+	//Get the current state prior to changing it
+	DCB dcb = {0};
+	dcb.DCBlength = sizeof(DCB);
+	if (!GetState(dcb))
+	{
+		const DWORD dwLastError = GetLastError();
+		Close();
+		SetLastError(dwLastError);
+		return FALSE;
+	}
+
+	//Setup the baud rate
+	dcb.BaudRate = dwBaud;
+
+	//Setup the Parity
+	switch (parity)
+	{
+	case EvenParity:
+		{
+			dcb.Parity = EVENPARITY;
+			break;
+		}
+	case MarkParity:
+		{
+			dcb.Parity = MARKPARITY;
+			break;
+		}
+	case NoParity:
+		{
+			dcb.Parity = NOPARITY;
+			break;
+		}
+	case OddParity:
+		{
+			dcb.Parity = ODDPARITY;
+			break;
+		}
+	case SpaceParity:
+		{
+			dcb.Parity = SPACEPARITY;
+			break;
+		}
+	default:
+		{
+			ATLASSERT(FALSE);
+			break;
+		}
+	}
+
+	//Setup the data bits
+	dcb.ByteSize = DataBits;
+
+	//Setup the stop bits
+	switch (stopBits)
+	{
+	case OneStopBit:
+		{
+			dcb.StopBits = ONESTOPBIT;
+			break;
+		}
+	case OnePointFiveStopBits:
+		{
+			dcb.StopBits = ONE5STOPBITS;
+			break;
+		}
+	case TwoStopBits:
+		{
+			dcb.StopBits = TWOSTOPBITS;
+			break;
+		}
+	default:
+		{
+			ATLASSERT(FALSE);
+			break;
+		}
+	}
+
+	//Setup the flow control
+	dcb.fDsrSensitivity = FALSE;
+	switch (fc)
+	{
+	case NoFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case CtsRtsFlowControl:
+		{
+			dcb.fOutxCtsFlow = TRUE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case CtsDtrFlowControl:
+		{
+			dcb.fOutxCtsFlow = TRUE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case DsrRtsFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = TRUE;
+			dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case DsrDtrFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = TRUE;
+			dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
+			dcb.fOutX = FALSE;
+			dcb.fInX = FALSE;
+			break;
+		}
+	case XonXoffFlowControl:
+		{
+			dcb.fOutxCtsFlow = FALSE;
+			dcb.fOutxDsrFlow = FALSE;
+			dcb.fOutX = TRUE;
+			dcb.fInX = TRUE;
+			dcb.XonChar = 0x11;
+			dcb.XoffChar = 0x13;
+			dcb.XoffLim = 100;
+			dcb.XonLim = 100;
+			break;
+		}
+	default:
+		{
+			ATLASSERT(FALSE);
+			break;
+		}
+	}
+
+	//Now that we have all the settings in place, make the changes
+	if (!SetState(dcb))
+	{
+		const DWORD dwLastError = GetLastError();
+		Close();
+		SetLastError(dwLastError);
+		return FALSE;
+	}
+
+	return TRUE;
+}

+ 404 - 0
短信猫/sms/sms/BaseSerial.h

@@ -0,0 +1,404 @@
+/************************************************************************/
+/*  Copyright (C), 2016-2020, [Home], 保留所有权利;
+/*  模 块 名:异步串口模块;
+/*  描    述:;
+/*
+/*  版    本:[V];	
+/*  作    者:[Home];
+/*  日    期:[12/20/2017];
+/*
+/*
+/*  注    意:;
+/*
+/*  修改记录:[Home];
+/*  修改日期:;
+/*  修改版本:;
+/*  修改内容:;
+/************************************************************************/
+
+#ifndef __BASE_SERIAL__
+#define __BASE_SERIAL__
+
+#pragma once
+
+class CBaseSerial
+{
+public:
+	//Enums
+	enum FlowControl
+	{
+		NoFlowControl,
+		CtsRtsFlowControl,
+		CtsDtrFlowControl,
+		DsrRtsFlowControl,
+		DsrDtrFlowControl,
+		XonXoffFlowControl
+	};
+
+	enum Parity
+	{
+		NoParity = 0,
+		OddParity = 1,
+		EvenParity = 2,
+		MarkParity = 3,
+		SpaceParity = 4
+	};
+
+	enum StopBits
+	{
+		OneStopBit,
+		OnePointFiveStopBits,
+		TwoStopBits
+	};
+protected:
+	HANDLE m_hComm;
+public:
+	CBaseSerial(void);
+	virtual ~CBaseSerial(void);
+
+	BOOL IsOpen() const throw() // noexcept 
+	{
+		return m_hComm != INVALID_HANDLE_VALUE;
+	}
+
+	void Close() throw()  // noexcept  
+	{
+		if (IsOpen())
+		{
+			CloseHandle(m_hComm);
+			m_hComm = INVALID_HANDLE_VALUE;
+		}
+	}
+
+	BOOL Open(LPCTSTR pszPort, BOOL bOverlapped = FALSE) throw(); // noexcept 
+	BOOL Open(int nPort, DWORD dwBaud = 9600, int parity = NoParity, BYTE DataBits = 8, int stopBits = OneStopBit, int fc = NoFlowControl, BOOL bOverlapped = FALSE);
+	BOOL Open(LPCTSTR pszPort, DWORD dwBaud = 9600, int parity = NoParity, BYTE DataBits = 8, int stopBits = OneStopBit, int fc = NoFlowControl, BOOL bOverlapped = FALSE) throw(); // noexcept 
+
+	//////////////////////////////////////////////////////////////////////////
+	//Reading / Writing Methods
+	BOOL Read(void* lpBuffer, DWORD dwNumberOfBytesToRead, DWORD& dwBytesRead) throw()
+	{
+		ATLASSERT(IsOpen());
+		dwBytesRead = 0;
+		return ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, &dwBytesRead, NULL);
+	}
+
+	BOOL Read(void* lpBuffer, DWORD dwNumberOfBytesToRead, OVERLAPPED& overlapped, DWORD* lpNumberOfBytesRead = NULL) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ReadFile(m_hComm, lpBuffer, dwNumberOfBytesToRead, lpNumberOfBytesRead, &overlapped);
+	}
+
+	BOOL ReadEx(LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ReadFileEx(m_hComm, lpBuffer, dwNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine);
+	}
+
+	BOOL Write(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, DWORD& dwBytesWritten) throw()
+	{
+		ATLASSERT(IsOpen());
+		dwBytesWritten = 0;
+		return WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, &dwBytesWritten, NULL);
+	}
+
+	BOOL Write(const void* lpBuffer, DWORD dwNumberOfBytesToWrite, OVERLAPPED& overlapped, DWORD* lpNumberOfBytesWritten = NULL) throw()
+	{
+		ATLASSERT(IsOpen());
+		return WriteFile(m_hComm, lpBuffer, dwNumberOfBytesToWrite, lpNumberOfBytesWritten, &overlapped);
+	}
+
+	BOOL WriteEx(LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) throw()
+	{
+		ATLASSERT(IsOpen());
+		return WriteFileEx(m_hComm, lpBuffer, dwNumberOfBytesToWrite, lpOverlapped, lpCompletionRoutine);
+	}
+
+	BOOL TransmitChar(char cChar) throw()
+	{
+		ATLASSERT(IsOpen());
+		return TransmitCommChar(m_hComm, cChar);
+	}
+
+	BOOL GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait);
+	}
+
+	__if_exists(::GetOverlappedResultEx)
+	{
+		BOOL GetOverlappedResultEx(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, DWORD dwMilliseconds, _In_ BOOL bAlertable) throw()
+		{
+			ATLASSERT(IsOpen());
+			return ::GetOverlappedResultEx(m_hComm, &overlapped, &dwBytesTransferred, dwMilliseconds, bAlertable);
+		}
+	}
+
+	BOOL CancelIo() throw()
+	{
+		ATLASSERT(IsOpen());
+		return ::CancelIo(m_hComm);
+	}
+
+	__if_exists(::CancelIoEx)
+	{
+		BOOL CancelIoEx(LPOVERLAPPED lpOverlapped = NULL) throw()
+		{
+			ATLASSERT(IsOpen());
+
+			return ::CancelIoEx(m_hComm, lpOverlapped);
+		}
+	}
+
+	BOOL BytesWaiting(DWORD& dwBytesWaiting) throw()
+	{
+		ATLASSERT(IsOpen());
+		//Check to see how many characters are unread
+		dwBytesWaiting = 0;
+		COMSTAT stat;
+		if (!GetStatus(stat))
+			return FALSE;
+		dwBytesWaiting = stat.cbInQue;
+		return TRUE;
+	}
+
+	//Configuration Methods
+	BOOL GetConfig(COMMCONFIG& config) throw()
+	{
+		ATLASSERT(IsOpen());
+
+		DWORD dwSize = sizeof(COMMCONFIG);
+		return GetCommConfig(m_hComm, &config, &dwSize);
+	}
+
+	static BOOL GetDefaultConfig(int nPort, COMMCONFIG& config)
+	{
+		CString sPort;
+		sPort.Format(_T("COM%d"), nPort);
+		//Delegate to the other version of the method
+		return GetDefaultConfig(sPort, config);
+	}
+
+	static BOOL GetDefaultConfig(LPCTSTR pszPort, COMMCONFIG& config) throw()
+	{
+		DWORD dwSize = sizeof(COMMCONFIG);
+		return GetDefaultCommConfig(pszPort, &config, &dwSize);
+	}
+
+	BOOL SetConfig(COMMCONFIG& config) throw()
+	{
+		ATLASSERT(IsOpen());
+		const DWORD dwSize = sizeof(COMMCONFIG);
+		return SetCommConfig(m_hComm, &config, dwSize);
+	}
+
+	static BOOL SetDefaultConfig(int nPort, COMMCONFIG& config)
+	{
+		CString sPort;
+		sPort.Format(_T("COM%d"), nPort);
+		//Delegate to the other version of the method
+		return SetDefaultConfig(sPort, config);
+	}
+
+	static BOOL SetDefaultConfig(LPCTSTR pszPort, COMMCONFIG& config) throw()
+	{
+		const DWORD dwSize = sizeof(COMMCONFIG);
+		return SetDefaultCommConfig(pszPort, &config, dwSize);
+	}
+
+	//Misc RS232 Methods
+	BOOL ClearBreak() throw()
+	{
+		ATLASSERT(IsOpen());
+		return ClearCommBreak(m_hComm);
+	}
+
+	BOOL SetBreak() throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommBreak(m_hComm);
+	}
+
+	BOOL ClearError(DWORD& dwErrors) throw()
+	{
+		ATLASSERT(IsOpen());
+		return ClearCommError(m_hComm, &dwErrors, NULL);
+	}
+
+	BOOL GetStatus(COMSTAT& stat) throw()
+	{
+		ATLASSERT(IsOpen());
+		DWORD dwErrors = 0;
+		return ClearCommError(m_hComm, &dwErrors, &stat);
+	}
+
+	BOOL GetState(DCB& dcb) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommState(m_hComm, &dcb);
+	}
+
+	BOOL SetState(DCB& dcb) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommState(m_hComm, &dcb);
+	}
+
+	BOOL Escape(DWORD dwFunc) throw()
+	{
+		ATLASSERT(IsOpen());
+		return EscapeCommFunction(m_hComm, dwFunc);
+	}
+
+	BOOL ClearDTR() throw()
+	{
+		return Escape(CLRDTR);
+	}
+
+	BOOL ClearRTS() throw()
+	{
+		return Escape(CLRRTS);
+	}
+
+	BOOL SetDTR() throw()
+	{
+		return Escape(SETDTR);
+	}
+
+	BOOL SetRTS() throw()
+	{
+		return Escape(SETRTS);
+	}
+
+	BOOL SetXOFF() throw()
+	{
+		return Escape(SETXOFF);
+	}
+
+	BOOL SetXON() throw()
+	{
+		return Escape(SETXON);
+	}
+
+	BOOL GetProperties(COMMPROP& properties) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommProperties(m_hComm, &properties);
+	}
+
+	BOOL GetModemStatus(DWORD& dwModemStatus) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommModemStatus(m_hComm, &dwModemStatus);
+	}
+
+	//Timeouts
+	BOOL SetTimeouts(COMMTIMEOUTS& timeouts) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommTimeouts(m_hComm, &timeouts);
+	}
+
+	BOOL GetTimeouts(COMMTIMEOUTS& timeouts) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommTimeouts(m_hComm, &timeouts);
+	}
+
+	BOOL Set0Timeout() throw()
+	{
+		COMMTIMEOUTS Timeouts;
+		memset(&Timeouts, 0, sizeof(Timeouts));
+		Timeouts.ReadIntervalTimeout = MAXDWORD;
+		return SetTimeouts(Timeouts);
+	}
+
+	BOOL Set0WriteTimeout() throw()
+	{
+		COMMTIMEOUTS Timeouts;
+		GetTimeouts(Timeouts);
+		Timeouts.WriteTotalTimeoutMultiplier = 0;
+		Timeouts.WriteTotalTimeoutConstant = 0;
+		return SetTimeouts(Timeouts);
+	}
+
+	BOOL Set0ReadTimeout() throw()
+	{
+		COMMTIMEOUTS Timeouts;
+		GetTimeouts(Timeouts);
+		Timeouts.ReadIntervalTimeout = MAXDWORD;
+		Timeouts.ReadTotalTimeoutMultiplier = 0;
+		Timeouts.ReadTotalTimeoutConstant = 0;
+		return SetTimeouts(Timeouts);
+	}
+
+	//Event Methods
+	BOOL SetMask(DWORD dwMask) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetCommMask(m_hComm, dwMask);
+	}
+
+	BOOL GetMask(DWORD& dwMask) throw()
+	{
+		ATLASSERT(IsOpen());
+		return GetCommMask(m_hComm, &dwMask);
+	}
+
+	BOOL WaitEvent(DWORD& dwMask) throw()
+	{
+		ATLASSERT(IsOpen());
+		return WaitCommEvent(m_hComm, &dwMask, NULL);
+	}
+
+	BOOL WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped) throw()
+	{
+		ATLASSERT(IsOpen());
+		ATLASSERT(overlapped.hEvent != NULL);
+
+		return WaitCommEvent(m_hComm, &dwMask, &overlapped);
+	}
+
+	//Queue Methods
+	BOOL Flush() throw()
+	{
+		ATLASSERT(IsOpen());
+		return FlushFileBuffers(m_hComm);
+	}
+
+	BOOL Purge(DWORD dwFlags) throw()
+	{
+		ATLASSERT(IsOpen());
+		return PurgeComm(m_hComm, dwFlags);
+	}
+
+	BOOL TerminateOutstandingWrites() throw()
+	{
+		return Purge(PURGE_TXABORT);
+	}
+
+	BOOL TerminateOutstandingReads() throw()
+	{
+		return Purge(PURGE_RXABORT);
+	}
+
+	BOOL ClearWriteBuffer() throw()
+	{
+		return Purge(PURGE_TXCLEAR);
+	}
+
+	BOOL ClearReadBuffer() throw()
+	{
+		return Purge(PURGE_RXCLEAR);
+	}
+
+	BOOL Setup(DWORD dwInQueue, DWORD dwOutQueue) throw()
+	{
+		ATLASSERT(IsOpen());
+		return SetupComm(m_hComm, dwInQueue, dwOutQueue);
+	}
+
+};
+
+#endif // __ASYN_SERIAL__

+ 8 - 0
短信猫/sms/sms/sms.vcproj

@@ -284,6 +284,14 @@
 				RelativePath=".\AsynSerial.h"
 				>
 			</File>
+			<File
+				RelativePath=".\BaseSerial.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\BaseSerial.h"
+				>
+			</File>
 			<File
 				RelativePath=".\CompletionSerial.cpp"
 				>