⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zmodemcomm.cpp

📁 在Visual c++下可对串口和MODEM进行操作,并能用ZOMDEM协议进行收发文件的程序-C语言
💻 CPP
字号:
//-----------------------------------------------------------------------------
// project:		ZModem
// author:		Frank Weiler, Genshagen, Germany
// version:		0.91
// date:		October 10, 2000
// email:		frank@weilersplace.de
// copyright:	This Software is OpenSource.
// file:		ZModemComm.cpp
// description:	a class to handle all the communication stuff for ZModem
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "ZModemComm.h"
#include "ZModemCore.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//-----------------------------------------------------------------------------
CZModemComm::CZModemComm(HANDLE hcomm,HANDLE hCancelEvent)
//-----------------------------------------------------------------------------
{
	m_hcomm = hcomm;
	m_hCancelEvent = hCancelEvent;
}

//-----------------------------------------------------------------------------
CZModemComm::~CZModemComm()
//-----------------------------------------------------------------------------
{

}

//-----------------------------------------------------------------------------
DWORD CZModemComm::ReadBuffer(void *buffer, DWORD num)
//-----------------------------------------------------------------------------
{	//Variablen
	DWORD dwRead,numWaiting;
	COMSTAT cst;
	DWORD err;
	//Routine
	if(!ClearCommError(m_hcomm,&err,&cst))
	{
		TRACE("error ClearCommError() %lu\n",GetLastError());
		return(0);
	}
	numWaiting=cst.cbInQue;
	if(numWaiting==0)
		return(0);
	if(num > numWaiting)
		num = numWaiting;
	//start overlapped io
	OVERLAPPED ov={0,0,0,0,NULL};
	ov.hEvent=CreateEvent(NULL,true,true,NULL);
	HANDLE waitfor[2];
	waitfor[0]=m_hCancelEvent;
	waitfor[1]=ov.hEvent;
	DWORD dwHandleSignaled;
	if(!SetupReadEvent(&ov,buffer,num,&dwRead))
	{
		while(true)
		{
			dwHandleSignaled=WaitForMultipleObjects(2,waitfor,false,10000);
			// Which event occured?
			switch(dwHandleSignaled)
			{
				case WAIT_OBJECT_0:    //cancelled
				{   // Time to exit.
   					SetLastError(ZMODEM_ABORTFROMOUTSIDE);
      				goto EndZModem;
				}
   				case WAIT_OBJECT_0 + 1: // ReadEvent signaled.
      			{
         			if(HandleReadEvent(&ov,buffer,num,&dwRead))
						goto EndZModem;
					break;
				}
	   			default:
            		goto EndZModem;
			} 
		}
	}
EndZModem:
	CloseHandle(ov.hEvent);
	//all data received
	return(dwRead);
}

//-----------------------------------------------------------------------------
DWORD CZModemComm::WriteBuffer(void *buffer, DWORD num)
//-----------------------------------------------------------------------------
{

	HANDLE HandlesToWaitFor[2];
	DWORD start=0;
	DWORD dwLastError;
	OVERLAPPED ow={0,0,0,0,NULL};
	ow.hEvent=CreateEvent(NULL,true,true,NULL);
	DWORD dwNumberOfBytesWritten;
	DWORD dwHandleSignaled;

	HandlesToWaitFor[0]=m_hCancelEvent;
	HandlesToWaitFor[1]=ow.hEvent;
	// Keep looping until all characters have been written.
	do
	{	// Start the overlapped I/O.
		if(!WriteFile(m_hcomm,(char*)(buffer)+start,num,&dwNumberOfBytesWritten,&ow))
		{  // WriteFile failed.  Expected; lets handle it.
			dwLastError=GetLastError();
			if(dwLastError==ERROR_INVALID_HANDLE)
				return(0);
			if(dwLastError!=ERROR_IO_PENDING)
				return(0);
			dwHandleSignaled=WaitForMultipleObjects(2,HandlesToWaitFor,false,INFINITE);
			switch(dwHandleSignaled)
			{
				case WAIT_OBJECT_0:// CloseEvent signaled!
					return(0);
           	case WAIT_OBJECT_0 + 1: // Wait finished.
					break;
				default: // This case should never occur.
					return(0);
			}
			if(!GetOverlappedResult(m_hcomm,&ow,&dwNumberOfBytesWritten,true))
			{
				dwLastError=GetLastError();
				// Its possible for this error to occur if the
				// service provider has closed the port.
				if(dwLastError==ERROR_INVALID_HANDLE)
					return(0);
				return(0);
			}
         else
          	SetLastError(0);
		}
		num -= dwNumberOfBytesWritten;
		start += dwNumberOfBytesWritten;
	}
	while(num > 0);  // Write the whole thing!
	CloseHandle(ow.hEvent);
	return(start);
}

//-----------------------------------------------------------------------------
bool CZModemComm::SetupReadEvent(LPOVERLAPPED lpOverlappedRead,void* lpszInputBuffer,
					           DWORD dwSizeofBuffer,LPDWORD lpnNumberOfBytesRead)
//-----------------------------------------------------------------------------
{	
	DWORD dwLastError;
   
	if(ReadFile(m_hcomm,lpszInputBuffer,dwSizeofBuffer,lpnNumberOfBytesRead,
   				lpOverlappedRead))
	{
		TRACE("ReadFile successful in SetupReadEvent");
		return(true);
	}
	// ReadFile failed.  Expected because of overlapped I/O.
	dwLastError=GetLastError();
	// LastError was ERROR_IO_PENDING, as expected.
	if(dwLastError==ERROR_IO_PENDING)
		return(false);
	SetLastError(ZMODEM_TIMEOUT);
	return(true);//ok
}

//-----------------------------------------------------------------------------
bool CZModemComm::HandleReadEvent(LPOVERLAPPED lpOverlappedRead,void* lpszInputBuffer,
						         DWORD dwSizeofBuffer,LPDWORD lpnNumberOfBytesRead)
//-----------------------------------------------------------------------------
{
	if(GetOverlappedResult(m_hcomm,lpOverlappedRead,lpnNumberOfBytesRead,true))
	{
		TRACE("GetOverlapped succesfull in HandleReadEvent");
  		SetLastError(0);
	  	return(true);
	}
	return(false);
}

//-----------------------------------------------------------------------------
void CZModemComm::GetBlock(void *buffer,DWORD max,LPDWORD actual)
//-----------------------------------------------------------------------------
{	//Variablen
	int x;
	//Routine
	x= ReadBuffer(buffer,max);
	if(x==0)
	{
		for (int cnt=0;cnt<400;cnt++)
		{
			Sleep(10);
			x= ReadBuffer(buffer,max);
			if(x!=0)
				break;
		}
	}
	if(x==0)
	{
		TRACE("Setze Fehler %s\n","ZMODEM_TIMEOUT");
		SetLastError(ZMODEM_TIMEOUT);
	}
	*actual = x;
}

//-----------------------------------------------------------------------------
void CZModemComm::GetBlockImm(void *buffer,DWORD max,LPDWORD actual)
//-----------------------------------------------------------------------------
{	
	int x;
	
	x= ReadBuffer(buffer,max);
	if(x==0)
	{
		TRACE("set error %s\n","ZMODEM_TIMEOUT");
		SetLastError(ZMODEM_TIMEOUT);
	}
	*actual=x;
}

//-----------------------------------------------------------------------------
DWORD CZModemComm::WriteBlock(void* buf,DWORD max)
//-----------------------------------------------------------------------------
{
	return WriteBuffer(buf,max);
}

//-----------------------------------------------------------------------------
void CZModemComm::ClearInbound()
//-----------------------------------------------------------------------------
{
	if(!PurgeComm(m_hcomm,PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR))
	{
		TRACE("error PurgeComm %lu\n",GetLastError());
	}
}

//-----------------------------------------------------------------------------
void CZModemComm::ResetAll()
//-----------------------------------------------------------------------------
{
		
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -