Click here to Skip to main content
15,880,392 members
Articles / Web Development / HTML

A Comprehensive CE Class Library to Replace ATL and MFC

Rate me:
Please Sign up or sign in to vote.
4.48/5 (14 votes)
4 Oct 2000CPOL 277.8K   998   70  
A collection of classes for CE that do not use ATL or MFC, plus an FTP client, database viewer, and sample application that solves beam deflection equations.
#ifndef __CeFtp_h__
#define __CeFtp_h__

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include <winsock.h>	// Winsock (RAW)

#include "CeSocket.h"	// Socket classes
#include "CeThread.h"	// Thread and Control classes
#include "CeArray.h"
#include "CeString.h"

#ifndef MTU_SIZE
#define MTU_SIZE    1460
#endif

#define RESP_BUFSIZ 2048

typedef WIN32_FIND_DATA FileData;
typedef CeArray<FileData> CeFileAttrArray;
typedef CeArray<CeString> CeStringArray;
typedef CeArray<BYTE> CeByteArray;

#define	WM_FTP_CALLBACK	(WM_USER + 200)

class CeFtpClient
{
public:
	enum FtpClientOptions
	{
		ftpOpt_ConnectTimeout,			// DWORD, milliseconds, default INFINITE
		ftpOpt_ConnectRetries,			// SHORT, default 1
		ftpOpt_CommandSendTimeout,		// DWORD, milliseconds, default INFINITE
		ftpOpt_CommandRecvTimeout,		// DWORD, milliseconds, default INFINITE
		ftpOpt_DataSendTimeout,			// DWORD, milliseconds, default INFINITE
		ftpOpt_DataRecvTimeout,			// DWORD, milliseconds, default INFINITE

		// Not implemented
		//ftpOpt_CALLBACK,					// BOOL, default FALSE
	};

	enum FtpTransferType
	{
		ftpTtype_ASCII,
		ftpTtype_BINARY,
		ftpTtype_EBCDIC,				// not supported yet
		ftpTtype_TENEX,					// not supported yet
	};

	enum FtpReplyCodes
	{
		ftpRcNoError = 0,

		// reply codes as defined in RFC 959

		ftpRc_RESTART_MARKER_REPLY = 110,
		ftpRc_SRV_START_PENDING = 120,
		ftpRc_DATA_OPEN = 125,
		ftpRc_FILE_OK_START_DATA = 150,
		ftpRc_CMD_OK = 200,
		ftpRc_CMD_NOT_REQUIRED = 202,
		ftpRc_SYSTEM_HELP_REPLY = 211,
		ftpRc_DIRECTORY_STATUS = 212,
		ftpRc_FILE_STAT = 213,
		ftpRc_HELP_REPLY = 214,
		ftpRc_SYSTEM_TYPE = 215,
		ftpRc_READY_FOR_USER = 220,
		ftpRc_CLOSING_CNTL_CONN = 221,
		ftpRc_DATA_OPEN_NO_TRANS = 225,
		ftpRc_CLOSING_DATA = 226,
		ftpRc_PASS_MODE = 227,
		ftpRc_USER_LOGGED_IN = 230,
		ftpRc_FILE_REQ_OK = 250,
		ftpRc_DIR_REQ_OK = 257,
		ftpRc_USER_OK_SEND_PASS = 331,
        ftpRc_ACCT_REQUIRED = 332,
		ftpRc_FILE_REQ_OK_PENDING = 350,
        ftpRc_SERVICE_UNAVAILABLE = 421,
		ftpRc_CANNOT_OPEN_DATA_CONNECT = 425,
		ftpRc_CONNECT_CLOSED = 426,
        ftpRc_FILE_UNAVAILABLE = 450,
        ftpRc_SERVER_ERROR = 451,
        ftpRc_NO_SPACE = 452,
		ftpRc_SYNTAX_ERROR_CMD = 500,
		ftpRc_SYNTAX_ERROR_ARG = 501,
		ftpRc_COMMAND_NOT_IMPL = 502,
		ftpRc_BAD_CMD_SEQ = 503,
		ftpRc_CMD_NOT_IMPL_ARG = 504,
		ftpRc_NOT_LOGGED_IN = 530,
        ftpRc_ACCT_REQUIRED_FOR_FILE_STORAGE = 532,
		ftpRc_FILE_REQUEST_DENIED = 550,
		ftpRc_PAGE_TYPE_UNKNOWN = 551,
        ftpRc_EXCEEDED_MAX = 552,
		ftpRc_NOT_ALLOWED = 553,

		// implied errors, for example, connection reset by server
		// when an error occurred mid connection
		// these codes are beyond those used in normal reply codes
		ftpErrorConnectionReset = 1000,
		ftpErrorBadServerResponse = 1001,
		ftpErrorSocket = 1002,
		ftpErrorInvalidArg = 1003,
		ftpErrorClientFile = 1004,
		ftpErrorNotConnected = 1005,
		ftpErrorThreadCreate = 1006,
		ftpErrorTimeout = 1007,
	};

private:
//	CeSockAddr m_saCtrlClient;		// used to create the ClientData socket address
	CeSockAddr m_saClientData;		// for PORT command
	CeSockAddr m_saServerCtrl;		// remote control socket
	CeSockAddr m_saServerData;		// used for accept validation
	
	CeSocket m_sockCtrl;			// control/command socket
	CeSocket m_sockListen;			// listening/accept socket
	CeSocket m_sockData;			// data transfer socket

	DWORD m_dwTimeoutConnect;		// various timeouts
	DWORD m_dwTimeoutCmdSend;
	DWORD m_dwTimeoutCmdRecv;
	DWORD m_dwTimeoutDataSend;
	DWORD m_dwTimeoutDataRecv;
	short m_sRetries;

	BOOL m_bPassive;
	BOOL m_bStaticPort;
	int m_nFtpDataPort;				// server ftp data port

	int m_nFtpCtrlPort;				// server ftp port
	CeString m_strSystem;			// system type connected to, as reported by SYST

	int m_nBufInUse;
	CeByteArray m_arCtrlRecv;		// control socket receive buffer
	CeByteArray m_arDataRecv;		// data socket receive buffer
	DWORD m_dwByteCount;			// bytes in the data buffer

	BOOL m_bConnected;				// TRUE when connected
	BOOL m_bDebug;					// TRUE when in debug mode
	FtpTransferType m_eTransferType;	// BINARY or ASCII transfer mode
	CeManualEvent m_eventAccept;		// event for syncronizing data socket listen/accept

	CeString m_strDir;				// the current directory

	CeString m_strRoot;
	BOOL m_chSep;

// error/message reporting
	void ClearFtpError();
	void SetFtpError(int nFtpError, LPCTSTR lpszErr);
	void SetSocketError(int nError);

	int m_nLastFtpReply;			// Last error code from FTP
	TCHAR m_szLastFtpReply[RESP_BUFSIZ];
	HWND m_hwnd;

// implementation methods

	BOOL SetTransferType(FtpTransferType eTransferType);

	BOOL SimpleCmd(int nFtpCmd, LPCTSTR szArg);
	void ResetConnection();

	BOOL InitDataConn();
	BOOL StartDataConn();

	BOOL AcceptDataConn();
	static DWORD WINAPI StartAccept(LPVOID pVoid);

	int SendFtpCmd(int nFtpCmd);
	int SendFtpCmd(int nFtpCmd, LPCTSTR szArg);
	int GetFtpReply();
	DWORD RecvBuffer(BOOL bTerminate=FALSE, DWORD dwSize=0);
	DWORD RecvFile(HANDLE hFile, DWORD dwSize);
	DWORD RecvFileList(CeFileAttrArray& arFiles);

	DWORD SendBuffer(BYTE* pBuf, DWORD dwLen);
	DWORD SendFile(HANDLE hFile, DWORD dwSize);

	int CleanupSocket();

	int ColumnStrings(const CeString& strRow, CeStringArray& arCol, int nMaxCol);
	static void SplitBuffer(LPCSTR szBuf, DWORD dwByteCount, CeStringArray& ar);

public:
// construction
	CeFtpClient();
	virtual ~CeFtpClient();

	void SetPortUse(BOOL bStatic)
		{	m_bStaticPort = bStatic; }
	void SetPassive(BOOL bPassive)
		{ m_bPassive = bPassive; }
	BOOL GetPassive() const
		{ return m_bPassive; }

// connect and operation settings commands
	void SetOption(DWORD dwOption, DWORD dwValue);
	DWORD GetOption(DWORD dwOption) const;

// connection 
	BOOL Connect(LPCTSTR szAddr, LPCTSTR pstrUserName = NULL, LPCTSTR pstrPassword = NULL);
	BOOL Connect(const ULONG ulAddr, LPCTSTR pstrUserName = NULL, LPCTSTR pstrPassword = NULL);
	BOOL Disconnect();

// status commands	
	BOOL IsConnected()
		{ return m_bConnected; }
	CeString& GetSystemType() const;

// file/buffer transfer commands
	BOOL PutFile(LPCTSTR szFileName, LPCTSTR szRemoteName, DWORD dwSize = 0, FtpTransferType eTransType=ftpTtype_BINARY);
	BOOL AppendFile(LPCTSTR szFileName, LPCTSTR szRemoteName, DWORD dwSize = 0, FtpTransferType eTransType=ftpTtype_BINARY);
	BOOL GetFile(LPCTSTR szRemoteName, LPCTSTR szFileName, DWORD dwSize = 0, BOOL bFailIfExists = TRUE, DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL, FtpTransferType eTransType=ftpTtype_BINARY);
	BOOL RenameFile(LPCTSTR szRemoteName, LPCTSTR szNewRemoteName);
	BOOL DeleteFile(LPCTSTR szRemoteName);

	BOOL GetFileAsBuffer(LPCTSTR szRemoteName, CeByteArray& arBuf, DWORD dwSize = 0, FtpTransferType eTransType=ftpTtype_BINARY);
	BOOL PutBufferAsFile(LPCTSTR szRemoteName, BYTE* pBuf, DWORD dwSize = 0, FtpTransferType eTransType=ftpTtype_BINARY);

	void CancelTransfer();

// directory commands
	LPCTSTR GetRoot() const
		{ return m_strRoot; }

	CeString GetCurDir();
	BOOL SetCurDir(LPCTSTR szPath);
	BOOL DeleteDir(LPCTSTR szPath);
	BOOL CreateDir(LPCTSTR szPath);

// directory listing
	BOOL GetFileList(CeStringArray& strFiles);
	BOOL GetFileList(CeFileAttrArray& arFiles, LPCTSTR lpszFileSpec=NULL);

// file info
	BOOL GetFileInfo(LPCTSTR lpszFileName, WIN32_FIND_DATA& finddata);

// NOOP command for maintaining connection without sending commands
	BOOL SendNoOp();

// Error and message handling
	CeString GetFtpErrorReplyString() const
		{ return CeString(m_szLastFtpReply); }
	int GetLastFtpError() const
		{ return m_nLastFtpReply; }

// user command support, returns the reply code if one was required
// the reply string can get retreived from get GetReplyString()
	int SendUserCommand(LPCTSTR szUserCmd);

// Overrideables
	virtual void OnStatusCallback();
	virtual void OnTransferCallback(DWORD dwSent, DWORD dwTotal, LPCTSTR szFile);
	virtual BOOL OnParseListFile(LPSTR szFile, PWIN32_FIND_DATA pFindData);
	virtual void OnFtpMessage(int nResp, LPCSTR szMsg);

	HWND SetCallbackHandle(HWND hWnd)
		{ HWND hWndSave = hWnd; m_hwnd = hWnd; return hWndSave; }
};

#endif // __CeFtp_h__

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions