/*------------------------------------------------------------------------- * clintlib\FTPSession.h * * Example usage of this code can be found at the bottom of this file. * * IFTPSession allows you to easily transfer files from an FTP * site while hiding the low level aspects of the Windows FTP API. * * IFTPSessionUpdateSink is used to receiving information about a transfer. * * Currently only downloading is supported. * * * Owner: * * Copyright 1986-2000 Microsoft Corporation, All Rights Reserved *-----------------------------------------------------------------------*/ // // IFTPSessionUpdateSink is used to receive events about the transfer. // You don't have to use it--not even for getting error messages. // GetLastErrorMessage() also can be used to get error messages. // class IInternetSessionSink { public: /*------------------------------------------------------------------------- * OnProgress() *------------------------------------------------------------------------- * Purpose: * Report the progress of a transfer. * * Paramters: * cTotalBytes: Total bytes of the all files in the transfer. * * szCurrentFile: Name of the current file being transfered. * * cCurrentFileBytes: Count of bytes currently transfered for the current file. * * Remarks: * * Updates occur at the start of the transfer, when a file finishes, and at 8k intervals * during large file transfers. The 8k interval is determined by Windows and subject to change. * */ virtual void OnProgress(unsigned long cTotalBytes, const char* szCurrentFile, unsigned long cCurrentFileBytes) {} /*------------------------------------------------------------------------- * OnProgress() *------------------------------------------------------------------------- * Purpose: * Report error occuring during transfer. * * Paramters: * szErrorMessage: Error message. Could be long and detailed. */ virtual void OnError(char *szErrorMessage) {} /*------------------------------------------------------------------------- * OnDataReceived() *------------------------------------------------------------------------- * Purpose: * Allow user to scan or change data as it comes in; and skip this * file if wanted. * * Paramters: * pData: pointer to file data chunk * cBytes: size of data chunk * * Returns: * true: if you want this file's transfer to continue, false to start * next file. */ virtual bool OnDataReceived(void * pData, unsigned long cBytes) { return true; } /*------------------------------------------------------------------------- * OnFileCompleted() *------------------------------------------------------------------------- * Purpose: * Signal that another file is transfered and written to disk with no errors. * * Paramters: * szFileName: filename of transfered file with complete local path. * * Returns: * true: if file downloaded okay * false: if file should be re-downloaded (sometimes http downloads fail, so you might want to retry) */ virtual bool OnFileCompleted(char *szFileName) { return true; } /*------------------------------------------------------------------------- * OnTransferComplete() *------------------------------------------------------------------------- * Purpose: * Singal that the entire transfer is over. This is also called in the event * of an error (or manual abort) stops the transfer. */ virtual void OnTransferFinished() {} }; class IHTTPSessionSink : public IInternetSessionSink { }; class IFTPSessionUpdateSink : public IInternetSessionSink { }; class IInternetSessionBase { public: virtual ~IInternetSessionBase() {} /*------------------------------------------------------------------------- * ContinueDownload() *------------------------------------------------------------------------- * Purpose: * Find out if any errors or events occured during the download. * Start downloading the next file if done with current one. * Fire events as needed. * * Returns: * false if aborted, or error, or successful download; true if download * is incomplete and needs to be continued. * * Remarks: * Errors (and other events) are reported to the Sink. */ virtual bool ContinueDownload() = 0; /*------------------------------------------------------------------------- * GetLastErrorMessage() *------------------------------------------------------------------------- * Returns: * Last error message or NULL if no errors have occured. * * Remarks: * Errors also are reported to the Sink. */ virtual const char* GetLastErrorMessage() = 0; // TODO: make this report the error code too /*------------------------------------------------------------------------- * GetDownloadPath() *------------------------------------------------------------------------- * * Returns a path of where the downloaded files are going. Guarenteed to * end with a backslash. */ virtual const char* GetDownloadPath() = 0; /*------------------------------------------------------------------------- * Abort() *------------------------------------------------------------------------- * Purpose: * Abort the download. * * Parameters: * bDisconnect: if true, the disconnect is automatic */ virtual void Abort(bool bAutoDisconnect = true) = 0; }; class IFTPSession : public IInternetSessionBase { public: virtual ~IFTPSession() {} /*------------------------------------------------------------------------- * ConnectToSite() *------------------------------------------------------------------------- * Paramters: * szFTPSite: FTP address of the server to connect to * szDirectory: The directory on the server where transfers will occur from * * Returns: * true if success; false if error * * Remarks: * Errors are reported to the Sink. */ virtual bool ConnectToSite(const char *szFTPSite, const char *szDirectory, const char *szUsername, const char *szPassword) = 0; /*------------------------------------------------------------------------- * InitiateDownload() *------------------------------------------------------------------------- * Purpose: * Begin downloading a batch of files. You must call ContinueDownload() * periodically to ensure file(s) get downloaded. * * Paramters: * pszFileList: A list of files to download. This is a pointer to a * NULL terminated array of NULL terminated char pointers. * * szDestFolder: The directory on the local machine of where the files go * * bDisconnectWhenDone: if true, session automatically disconnects when done * * nMaxBufferSize: maximum amount of memory allocated for download buffer * * Returns: * true if success; false if error * * Remarks: * Errors are reported to the Sink. */ virtual bool InitiateDownload(const char * const * pszFileList, const char * szDestFolder, bool bDisconnectWhenDone = true, int nMaxBufferSize = 1024*1024) = 0; /*------------------------------------------------------------------------- * Disconnect() *------------------------------------------------------------------------- * Purpose: * Disconnect from FTP server. * * Returns: * true if success; false if error * * Remarks: * Errors are reported to the Sink. */ virtual bool Disconnect() = 0; }; class IHTTPSession : public IInternetSessionBase { public: virtual ~IHTTPSession() {} /*------------------------------------------------------------------------- * InitiateDownload() *------------------------------------------------------------------------- * Purpose: * Begin downloading a batch of files. You must call ContinueDownload() * periodically to ensure file(s) get downloaded. * * Paramters: * pszFileList: A list of files to download. This is a pointer to a * NULL terminated array of NULL terminated char pointers. * Each entry is a pair: the first is the URL, the second * is the local filename * * szDestFolder: The directory on the local machine of where the files go * * nMaxBufferSize: maximum amount of memory allocated for download buffer * * Returns: * true if success; false if error * * Remarks: * Errors are reported to the Sink. */ virtual bool InitiateDownload(const char * const * pszFileList, const char * szDestFolder, int nMaxBufferSize = 1024*1024) = 0; }; IFTPSession * CreateFTPSession(IFTPSessionUpdateSink * pUpdateSink = NULL); // use this to make a new IFTPTransfer object IHTTPSession * CreateHTTPSession(IHTTPSessionSink * pUpdateSink = NULL); /* SAMPLE CODE: #include "stdafx.h" #include "FTPSession.h" class CFTPStatusClass : public IFTPSessionUpdateSink { public: void OnProgress(unsigned long cTotalBytes, const char* szCurrentFile, unsigned long cCurrentFileBytes) { char sz[80]; const int cEstimatedSize = 900; sprintf(sz, "%2.2f%% %i %s %i\n", 100.0f*float(cTotalBytes)/float(cEstimatedSize), cTotalBytes, szCurrentFile, cCurrentFileBytes); OutputDebugString(sz); } void OnError(char *szErrorMessage) { OutputDebugString("\nError:\n"); OutputDebugString(szErrorMessage); } }; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { CFTPStatusClass errorClass; IFTPSession *pFTP = CreateFTPSession(&errorClass); if (pFTP->ConnectToSite("a-markcu1", "Allegiance", "Anonymous", "Marco")) { char *pszFileList[] = {"test.vbs", "chat.vbs", "events.vbs", NULL}; if (pFTP->InitiateDownload(pszFileList, "C:\\temp")) { while (pFTP->ContinueDownload()) { } } } delete pFTP; return 0; } */