www.pudn.com > zmodemclass.zip > ZModemFile.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:		ZModemFile 
// description:	a class to handle all the file-based stuff 
//  
//----------------------------------------------------------------------------- 
 
#include "stdafx.h" 
#include "ZModemFile.h" 
#include "ZModemCore.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
//----------------------------------------------------------------------------- 
CZModemFile::CZModemFile(HWND hOwner) 
//----------------------------------------------------------------------------- 
{ 
	m_hOwner = hOwner; 
	m_hFile = NULL; 
} 
 
//----------------------------------------------------------------------------- 
CZModemFile::~CZModemFile() 
//----------------------------------------------------------------------------- 
{ 
} 
 
//----------------------------------------------------------------------------- 
void CZModemFile::WriteData(void* buffer,DWORD bytes) 
//----------------------------------------------------------------------------- 
{	//Variablen 
	DWORD written; 
	//Routine 
	if(!WriteFile(m_hFile,buffer,bytes,&written,NULL)) 
		TRACE("error WriteFile %lu\n",GetLastError()); 
	else 
	{ 
		::PostMessage(m_hOwner,WM_USER_ZMODEMPROGRESS,(WPARAM)written,0L); 
   		if(bytes != written) 
			TRACE("should write %lu\n,written %lu\n",bytes,written); 
	} 
} 
 
//----------------------------------------------------------------------------- 
void CZModemFile::Finish() 
//----------------------------------------------------------------------------- 
{ 
	if(!CloseHandle(m_hFile)) 
		TRACE("error CloseHandle %lu\n",GetLastError()); 
} 
 
//----------------------------------------------------------------------------- 
void CZModemFile::SetPos(DWORD offset) 
//----------------------------------------------------------------------------- 
{ 
	if(0xFFFFFFFF==SetFilePointer(m_hFile,offset,NULL,FILE_BEGIN)) 
   		TRACE("error SetFilePointer %lu",GetLastError()); 
	else 
		TRACE("set filepointer to offset %lu",(DWORD)offset); 
} 
 
//----------------------------------------------------------------------------- 
int CZModemFile::GetData(void *buffer,DWORD max,LPDWORD bytes) 
//----------------------------------------------------------------------------- 
{ 
	int rw=ZMODEMFILE_OK; 
 
	if(::ReadFile(m_hFile,buffer,max,bytes,NULL)!=0) 
	{ 
		TRACE("error ReadFile %lu",GetLastError()); 
		rw = ZMODEMFILE_ERROR; 
	} 
	else 
	{ 
		if(*bytes == 0 ) //End of file reached 
		{ 
			TRACE("reached end of file\n"); 
			rw=ZMODEMFILE_NOMOREDATA; 
		} 
		else if(max != *bytes) 
		{ 
			TRACE("try to read %lu bytes ",max); 
			TRACE("only %lu bytes read",*bytes);     
		} 
		else 
		{ 
			TRACE("%lu bytes read",*bytes); 
		} 
		::PostMessage(m_hOwner,WM_USER_ZMODEMPROGRESS,(WPARAM)*bytes,0L); 
	} 
	return(rw); 
} 
 
//----------------------------------------------------------------------------- 
bool CZModemFile::Open(CString filename,DWORD mode) 
//----------------------------------------------------------------------------- 
{	//Variablen 
	bool ret=false; 
	//Routine 
	TRACE("opening file %s",filename); 
	m_hFile=CreateFile(filename,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ, 
								NULL,mode,FILE_ATTRIBUTE_NORMAL,NULL); 
	if(m_hFile==INVALID_HANDLE_VALUE) 
	{ 
		TRACE("error open file %s in CreateFile %lu",filename,GetLastError()); 
	} 
	else 
	{   //posting filename 
		m_Filename=filename; 
		::PostMessage(m_hOwner,WM_USER_ZMODEMNEXTFILE,0,(LPARAM)(LPCTSTR)m_Filename); 
		m_Filesize=::GetFileSize(m_hFile,NULL); 
		if(m_Filesize==0xFFFFFFFF) 
			TRACE("error GetFileSize %lu\n",GetLastError()); 
		else 
		{	//posting filesize 
			::PostMessage(m_hOwner,WM_USER_ZMODEMNEXTFILE,0,(LPARAM)(LPCTSTR)m_Filename); 
			::PostMessage(m_hOwner,WM_USER_ZMODEMNEXTFILESIZE,0,(LPARAM)m_Filesize); 
			ret=true; 
		} 
	} 
	return ret; 
} 
 
//----------------------------------------------------------------------------- 
void CZModemFile::OpenReceivingFile(LPDWORD offset,bool* skip) 
//----------------------------------------------------------------------------- 
{ 
	::DeleteFile(m_Filename); 
	m_Filename = m_ReceiveDir + m_Filename; 
	m_hFile=CreateFile(m_Filename,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_ALWAYS, 
					   FILE_ATTRIBUTE_NORMAL,NULL); 
	if(m_hFile==INVALID_HANDLE_VALUE) 
	{ 
		TRACE("error open file %s\n",m_Filename); 
		TRACE("error CreateFile %lu\n",GetLastError()); 
	} 
	else 
	{ 
		::PostMessage(m_hOwner,WM_USER_ZMODEMNEXTFILE,0,(LPARAM)(LPCTSTR)m_Filename); 
		TRACE("file opened: %s",m_Filename); 
	} 
	*offset = 0; 
	*skip = 0; 
	// 
	if(m_fileinfo[0]!='\0')//FILEINFO was sent 
	{ 
		char* fi= new char[strlen(m_fileinfo)+1]; 
		memset(fi,0,strlen(m_fileinfo)+1); 
		strcpy(fi,m_fileinfo); 
		char* item=strtok(fi," "); 
		int itemcount=0; 
		while(item!=NULL) 
		{ 
			switch(itemcount) 
			{ 
         		case 0://size 
					m_Filesize = atol(item); 
					TRACE("filesize %lu Bytes",m_Filesize); 
					TRACE("filename: %s ",m_Filename); 
					 
					::PostMessage(m_hOwner,WM_USER_ZMODEMNEXTFILE,0,(LPARAM)(LPCTSTR)m_Filename); 
					::PostMessage(m_hOwner,WM_USER_ZMODEMNEXTFILESIZE,0,(LPARAM)m_Filesize); 
               break; 
            case 1://	Modification date (ocatl number) 
            	break; 
            case 2://	file mode (only for UNIX, should be 0) 
            	break; 
            case 3://	serial number 
            	break; 
            case 4://	number of files remaining (incl. current) 
            { 
            	int fnum=atoi(item); 
				if(fnum>0) 
					::PostMessage(m_hOwner,WM_USER_ZMODEMTOTALFILES,0,(LPARAM)fnum); 
				break; 
            } 
            case 5://bytes remaining (incl. current) 
            { 
            	long ftotal=atol(item); 
				if(ftotal>0) 
					::PostMessage(m_hOwner,WM_USER_ZMODEMTOTALSIZE,0,(LPARAM)ftotal); 
               break; 
            } 
         } 
         itemcount++; 
         item=strtok(NULL," "); 
		}//while() 
		delete[] fi; 
	} 
} 
 
//----------------------------------------------------------------------------- 
int CZModemFile::MakeFileInfo(unsigned char* buf) 
//----------------------------------------------------------------------------- 
{ 
	CString fname; 
	CString fext; 
	CString ffname; 
	int cnt=0; 
 
	fext = m_Filename.Mid(m_Filename.ReverseFind('.')+1); 
	if(m_Filename.Find("\\") >= 0) 
		fname = m_Filename.Mid(m_Filename.ReverseFind('\\')); 
	else 
		fname= m_Filename; 
	ffname = fname.Mid(0,fname.Find('.')); 
 
	strcpy((char*)buf,fname.GetBuffer(fname.GetLength())); 
	strcat((char*)buf,"."); 
	strcat((char*)buf,fext.GetBuffer(fname.GetLength())); 
	cnt = strlen((char*)buf) + 1; 
	wsprintf((char*)buf + cnt, "%ld", m_Filesize); 
	cnt = cnt + strlen((char*)buf + cnt) + 1; 
 
	return cnt; 
} 
 
//----------------------------------------------------------------------------- 
bool CZModemFile::InitFromFILEINFO(char *buffer) 
//----------------------------------------------------------------------------- 
{ 
	char filename[MAX_PATH]; 
	memset(filename,0,MAX_PATH); 
	strcpy(filename,buffer);//copy upto first \0 
	//get next block 
	char* pos=(char*)memchr(buffer,'\0',(sizeof buffer)-1); 
	if(pos!=NULL) 
	{ 
    	pos++; 
		//pos points to start of FILEINFO 
		memset(m_fileinfo,0,1024); 
		strncpy(m_fileinfo,pos,1023); 
	} 
	return true; 
} 
 
//----------------------------------------------------------------------------- 
void CZModemFile::SetReceivingDir(CString szDir) 
//----------------------------------------------------------------------------- 
{ 
	m_ReceiveDir = szDir; 
	if(m_ReceiveDir.Right(1).Compare("\\")!=0) 
		m_ReceiveDir += "\\"; 
} 
 
//----------------------------------------------------------------------------- 
void CZModemFile::ResetAll() 
//----------------------------------------------------------------------------- 
{ 
	memset(m_fileinfo,0,1024); 
	m_Filename = ""; 
	m_Filesize=0; 
	if(m_hFile != NULL) 
		Finish(); 
	m_hFile = NULL; 
	m_ReceiveDir = ""; 
} 
 
//----------------------------------------------------------------------------- 
CString CZModemFile::GetReceivedFileName() 
//----------------------------------------------------------------------------- 
{ 
	return m_Filename; 
}