// SampleCPPDlg.cpp : implementation file
//
// Copyright © 1997-2008 - Rhino Software, Inc.
// FTP Voyager® is a registered trademark of Rhino Software, Inc.
// http://www.RhinoSoft.com/
//
// Author: Mark P. Peterson
// Date: August 19, 2005
//
// You are free to use/modify this code but leave this header intact.
// This code is public domain so you are free to use it any of your
// applications (Freeware, Trialware, Commercial, etc.). FTP Voyager,
// the FTP Voyager Software Development Kit, and FtpTree ActiveX Control
// are not public domain. Any registration IDs or non-public domain software
// from Rhino Software, Inc. remains copyrighted. For more information
// refer to the license agreement distributed with the FTP Voyager SDK.
//
// If you decide to use the FTP Voyager Software Development Kit, or FtpTree
// ActiveX control, you must first purchase a license. For more information
// visit http://www.RhinoSoft.com/
//------------------------------------------------------------------------------
//
// NOTE: This FTP Voyager SDK sample is more complex than the C Sample found in
// C:\Program Files\RhinoSoft.com\FVSDK\SampleC
// The intent of this sample is to cover all of the FTP Voyager SDK's functionality
//
//------------------------------------------------------------------------------
#include "stdafx.h"
#include "SampleCPP.h"
#include "SampleCPPDlg.h"
#include "GetFileNameDlg.h"
#include "GetCommandDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg dialog
CSampleCPPDlg::CSampleCPPDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSampleCPPDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSampleCPPDlg)
m_sServer = _T("ftp.simtel.net");
m_sUserID = _T("anonymous");
m_sPassword = _T("x@x.com");
m_nPort = 21;
m_bPASV = FALSE;
m_bShowRawListings = TRUE;
m_bXferDialogs = FALSE;
//}}AFX_DATA_INIT
// init vars
m_pSession = NULL;
m_sLocalFileName = "C:\\";
// load the application icon
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} // CSampleCPPDlg
CSampleCPPDlg::~CSampleCPPDlg()
{
// if this assertion fails, something is wrong because we didn't free the session
ASSERT(! m_pSession);
} // ~CSampleCPPDlg
void CSampleCPPDlg::DoDataExchange(CDataExchange* pDX)
{
// call the base class function
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSampleCPPDlg)
DDX_Text(pDX, IDC_BUILD_DATE, m_sBuildDate);
DDX_Text(pDX, IDC_VERSION, m_sVersion);
DDX_Text(pDX, IDC_SERVER, m_sServer);
DDX_Text(pDX, IDC_PORT, m_nPort);
DDX_Text(pDX, IDC_USER_ID, m_sUserID);
DDX_Text(pDX, IDC_PASSWORD, m_sPassword);
DDX_Text(pDX, IDC_STATUS, m_sStatus);
DDX_Check(pDX, IDC_PASV, m_bPASV);
DDX_Check(pDX, IDC_RAW, m_bShowRawListings);
DDX_Check(pDX, IDC_XFER_DIALOGS, m_bXferDialogs);
DDX_Control(pDX, IDC_LOG_LIST, m_LogList);
//}}AFX_DATA_MAP
} // DoDataExchange
BEGIN_MESSAGE_MAP(CSampleCPPDlg, CDialog)
//{{AFX_MSG_MAP(CSampleCPPDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CONNECT, OnBnClickedConnect)
ON_BN_CLICKED(IDC_STOP, OnBnClickedStop)
ON_BN_CLICKED(IDC_DISCONNECT, OnBnClickedDisconnect)
ON_BN_CLICKED(IDC_CWD, OnBnClickedCwd)
ON_BN_CLICKED(IDC_RMD, OnBnClickedRmd)
ON_BN_CLICKED(IDC_MKD, OnBnClickedMkd)
ON_BN_CLICKED(IDC_CDUP, OnBnClickedCdup)
ON_BN_CLICKED(IDC_LAST_RESPONSE, OnBnClickedLastResponse)
ON_BN_CLICKED(IDC_WELCOME_MESSAGE, OnBnClickedWelcomeMessage)
ON_BN_CLICKED(IDC_SEND_COMMAND, OnBnClickedSendCommand)
ON_BN_CLICKED(IDC_PASV, OnBnClickedPasv)
ON_BN_CLICKED(IDC_LIST_DIR, OnBnClickedListDir)
ON_BN_CLICKED(IDC_RAW, OnBnClickedRaw)
ON_BN_CLICKED(IDC_DOWNLOAD, OnBnClickedDownload)
ON_BN_CLICKED(IDC_MOVE_DOWN, OnBnClickedMoveDown)
ON_BN_CLICKED(IDC_UPLOAD, OnBnClickedUpload)
ON_BN_CLICKED(IDC_MOVE_UP, OnBnClickedMoveUp)
ON_BN_CLICKED(IDC_CLEAR_LOG, OnBnClickedClearLog)
ON_BN_CLICKED(IDC_DELETE_FILE, OnBnClickedDeleteFile)
ON_BN_CLICKED(IDC_RENAME, OnBnClickedRename)
ON_BN_CLICKED(IDC_SIZE_BUTTON, OnBnClickedSize)
ON_BN_CLICKED(IDC_FILE_UPLOAD, OnBnClickedFileUpload)
ON_BN_CLICKED(IDC_FILE_DOWNLOAD, OnBnClickedFileDownload)
ON_BN_CLICKED(IDC_EDIT_FILE, OnBnClickedEditFile)
ON_BN_CLICKED(IDC_VIEW_FILE, OnBnClickedViewFile)
ON_BN_CLICKED(IDC_XFER_DIALOGS, OnBnClickedXferDialogs)
ON_BN_CLICKED(IDC_FIND_FILES, OnBnClickedFindFiles)
ON_BN_CLICKED(IDC_SYNC_FOLDERS, OnBnClickedSyncFolders)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg operations
BOOL CSampleCPPDlg::LastOperationStopped()
{
// check if the last operation was stopped
return (FVSDK_LastOperationStopped(m_pSession) == FVSDK_YES);
} // LastOperationStopped
int CSampleCPPDlg::MsgBox(LPCTSTR pszMsg, UINT nType /*=MB_OK*/)
{
int nRet = MB_OK;
// check for registration ID errors, put up a message if it's a registration ID error
switch (m_pSession->fvecLastError) {
case FVSDK_INVALID_REGISTRATION_ID :
case FVSDK_EXPIRED_REGISTRATION_ID :
case FVSDK_EXPIRED_TEMP_REGISTRATION_ID :
case FVSDK_EXPIRED_TRIAL :
nRet = MsgBox(0);
break;
default :
nRet = AfxMessageBox(pszMsg, nType);
break;
} // switch
// return the return value from the message box
return (nRet);
} // MsgBox
int CSampleCPPDlg::MsgBox(int nID, UINT nType /*=MB_OK*/)
{
int nRet = MB_OK;
// check for registration ID errors, put up a message if it's a registration ID error
switch (m_pSession->fvecLastError) {
case FVSDK_INVALID_REGISTRATION_ID :
nRet = AfxMessageBox(IDS_INVALID_REGISTRATION_ID, (MB_ICONEXCLAMATION | MB_OK));
break;
case FVSDK_EXPIRED_REGISTRATION_ID :
nRet = AfxMessageBox(IDS_EXPIRED_REGISTRATION_ID, (MB_ICONEXCLAMATION | MB_OK));
break;
case FVSDK_EXPIRED_TEMP_REGISTRATION_ID :
nRet = AfxMessageBox(IDS_EXPIRED_TEMP_REGISTRATION_ID, (MB_ICONEXCLAMATION | MB_OK));
break;
case FVSDK_EXPIRED_TRIAL :
nRet = AfxMessageBox(IDS_EXPIRED_TRIAL, (MB_ICONEXCLAMATION | MB_OK));
break;
default :
if (! LastOperationStopped())
nRet = AfxMessageBox(nID, nType);
break;
} // switch
// return the return value from the message box
return (nRet);
} // MsgBox
BOOL CSampleCPPDlg::CheckBusy()
{
BOOL bRet = FALSE;
// check if the FTP Voyager SDK is busy or not
if (FVSDK_Working(m_pSession) == FVSDK_YES) {
// put up a "generic" sort of message that the SDK is busy
MsgBox(IDS_CURRENTLY_BUSY, MB_ICONEXCLAMATION);
// yes, it's busy
bRet = TRUE;
} // if
// return TRUE if the FVSDK is busy with another operation, or FALSE if it's not
return (bRet);
} // CheckBusy
BOOL CSampleCPPDlg::CheckNotConnected()
{
BOOL bRet = FALSE;
// check if the connected or not
if (FVSDK_Connected(m_pSession) == FVSDK_NO) {
// put up a "generic" sort of message that the session isn't connected
MsgBox(IDS_NOT_CONNECTED, MB_ICONEXCLAMATION);
// it's not connected
bRet = TRUE;
} // if
// return TRUE if the session is disconnected, or FALSE if it's connected
return (bRet);
} // CheckNotConnected
void CSampleCPPDlg::SetCurrentDirText()
{
CString sDir;
FVSDK_ERROR_CODE fvecLastError = m_pSession->fvecLastError;
// current directory
if (FVSDK_Connected(m_pSession) == FVSDK_YES) {
char pszBuffer[MAX_PATH * 2];
// show the current directory
if (FVSDK_GetCurrentDirectory(m_pSession, pszBuffer, sizeof(pszBuffer)) == FVSDK_OK)
sDir = pszBuffer;
else
sDir.LoadString(IDS_NA);
} // if
else
sDir.LoadString(IDS_NA);
// set the current directory string
m_sCurrentDir.Format(m_sCurrentDirFmt, sDir);
// instead of calling UpdateData(), just set the text of the string
GetDlgItem(IDC_CURRENT_DIR)->SetWindowText(m_sCurrentDir);
// reset the last error code
m_pSession->fvecLastError = fvecLastError;
} // SetCurrentDirText
void CSampleCPPDlg::SetStatus(int nSampleStatus /*=SAMPLE_CHECK_STATUS*/)
{
int nID = IDS_UNKNOWN;
CString sStatus;
FVSDK_ERROR_CODE fvecLastError = m_pSession->fvecLastError;
// get the status string ID
switch (nSampleStatus) {
case SAMPLE_CONNECTING :
nID = IDS_CONNECTING;
break;
case SAMPLE_DISCONNECTING :
nID = IDS_DISCONNECTING;
break;
case SAMPLE_CHECK_STATUS :
if (CheckBusy())
nID = IDS_BUSY;
else if (FVSDK_Connected(m_pSession) == FVSDK_YES)
nID = IDS_CONNECTED;
else if (FVSDK_Connected(m_pSession) == FVSDK_NO)
nID = IDS_DISCONNECTED;
break;
} // switch
// load the status string
sStatus.LoadString(nID);
// make it upper case so it's easier to see
sStatus.MakeUpper();
// build the status string for the dialog
m_sStatus.Format(m_sStatusFmt, sStatus);
// instead of calling UpdateData(), just set the text of the string
GetDlgItem(IDC_STATUS)->SetWindowText(m_sStatus);
// set the current directory text
SetCurrentDirText();
// reset the last error code
m_pSession->fvecLastError = fvecLastError;
} // SetStatus
BOOL CSampleCPPDlg::GetFileName(CString& rsFileName, LPCTSTR pszDefault /*=NULL*/)
{
char pszBuffer[MAX_PATH * 2];
BOOL bRet = FALSE;
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return (bRet);
// don't do anything if we're not connected
if (CheckNotConnected())
return (bRet);
// get the current directory so that we have somewhere to start in the dialog
if (FVSDK_GetCurrentDirectory(m_pSession, pszBuffer, sizeof(pszBuffer)) == FVSDK_YES) {
CGetFileNameDlg Dlg;
CString sDir = pszBuffer;
// create the default file name
if (pszDefault) {
// build the filename
if (sDir.Right(1) == '/')
sDir += pszDefault;
else if (! sDir.IsEmpty())
sDir += (CString("/") + pszDefault);
else
sDir = pszDefault;
} // if
// fill in the default
Dlg.SetFileName(sDir);
// ask the user for the directory name
if ((Dlg.DoModal() == IDOK) && (! Dlg.GetFileName().IsEmpty())) {
rsFileName = Dlg.GetFileName();
bRet = TRUE;
} // if
} // if
else
MsgBox(IDS_UNABLE_TO_GET_CURRENT_DIRECTORY);
// return TRUE if successful, FALSE if not
return (bRet);
} // GetFileName
BOOL CSampleCPPDlg::GetLocalFileName(CString& rsFileName)
{
BOOL bRet = FALSE;
CGetFileNameDlg Dlg;
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return (bRet);
// don't do anything if we're not connected
if (CheckNotConnected())
return (bRet);
// fill in the default
Dlg.SetFileName(m_sLocalFileName);
// ask the user for the directory name
if ((Dlg.DoModal() == IDOK) && (! Dlg.GetFileName().IsEmpty())) {
rsFileName = m_sLocalFileName = Dlg.GetFileName();
bRet = TRUE;
} // if
// return TRUE if successful, FALSE if not
return (bRet);
} // GetLocalFileName
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg message handlers
BOOL CSampleCPPDlg::OnInitDialog()
{
FVSDK_ERROR_CODE fvecRet;
char pszVersion[32];
CString sStr;
tm tmBuildDate;
// get the FTP Voyager SDK build date and time
FVSDK_BuildDate(&tmBuildDate);
// for simplicity's sake, convert the build date and time to a CTime object
CTime BuildTime((1900 + tmBuildDate.tm_year), (tmBuildDate.tm_mon + 1), tmBuildDate.tm_mday,
tmBuildDate.tm_hour, tmBuildDate.tm_min, tmBuildDate.tm_sec);
// subclass the log rich edit control
m_LogList.SubclassDlgItem(IDC_LOG_LIST, this);
// get the format string for the build date
GetDlgItem(IDC_BUILD_DATE)->GetWindowText(sStr);
// build the build date string
m_sBuildDate.Format(sStr, BuildTime.Format("%c"));
// get the format string for the version number
GetDlgItem(IDC_VERSION)->GetWindowText(sStr);
// get the FTP Voyager SDK version numbers
FVSDK_Version(pszVersion, sizeof(pszVersion));
// build version number string
m_sVersion.Format(sStr, pszVersion);
// get the format string for the version number
GetDlgItem(IDC_STATUS)->GetWindowText(m_sStatusFmt);
// build version number string
m_sVersion.Format(sStr, pszVersion);
// get the format string for the current directory
GetDlgItem(IDC_CURRENT_DIR)->GetWindowText(m_sCurrentDirFmt);
// call the base class function
CDialog::OnInitDialog();
// set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// make sure we have an allocated session, if not display an error message to the user
if ((fvecRet = FVSDK_NewSession(&m_pSession)) != FVSDK_OK) {
CString sMsg;
// let the user know what the error number is
sMsg.Format(IDS_SESSION_INITIALIZATION_FAILED_FMT, fvecRet);
// put the error up in a message box
MsgBox(sMsg, MB_ICONEXCLAMATION);
} // if
else {
CString sVer, sDate;
// set the main window handle
m_pSession->hwndMainWnd = m_hWnd;
// set the name of our application and version number
m_pSession->pszAppName = AfxGetAppName();
m_pSession->pszAppVersion = ((CSampleCPPApp *) AfxGetApp())->GetVersionInfo();
// get the format string for the FtpTree version number
GetDlgItem(IDC_FTPTREE_VERSION)->GetWindowText(sStr);
// get the version number
if (FVSDK_FtpTreeVersion(m_pSession, pszVersion, sizeof(pszVersion)) == FVSDK_OK)
sVer.Format(sStr, pszVersion);
else {
CString sNA;
sNA.LoadString(IDS_NA);
sVer.Format(sStr, sNA);
} // else
// set the FtpTree version number in the dialog
GetDlgItem(IDC_FTPTREE_VERSION)->SetWindowText(sVer);
// get the format string for the FtpTree build date
GetDlgItem(IDC_FTPTREE_BUILD_DATE)->GetWindowText(sStr);
// get the version number
if (FVSDK_FtpTreeBuildDate(m_pSession, &tmBuildDate) == FVSDK_OK) {
CTime BuildTime((1900 + tmBuildDate.tm_year), (tmBuildDate.tm_mon + 1), tmBuildDate.tm_mday,
tmBuildDate.tm_hour, tmBuildDate.tm_min, tmBuildDate.tm_sec);
// get the build date string
sDate.Format(sStr, BuildTime.Format("%c"));
} // if
else {
CString sNA;
sNA.LoadString(IDS_NA);
sDate.Format(sStr, sNA);
} // else
// set the FtpTree build date in the dialog
GetDlgItem(IDC_FTPTREE_BUILD_DATE)->SetWindowText(sDate);
// setup the log callback
m_LogList.SetupCallback(m_pSession);
// setup the dialog callbacks
m_pSession->pfnDownloadError = OnDownloadError;
m_pSession->pvDownloadErrorData = this;
m_pSession->pfnUploadError = OnUploadError;
m_pSession->pvUploadErrorData = this;
m_pSession->pfnNotifyTransferStatus = OnNotifyTransferStatus;
m_pSession->pvNotifyTransferStatusData = this;
} // else
// set the status
SetStatus();
return (TRUE); // return TRUE unless you set the focus to a control
} // OnInitDialog
void CSampleCPPDlg::OnOK()
{
// release the session if we have one allocated to us
if (m_pSession) {
FVSDK_ERROR_CODE fvecError;
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return ;
// release the session, if that fails, manually release it
if ((fvecError = FVSDK_FreeSession(m_pSession)) != FVSDK_OK) {
CString sMsg;
// let the user know what the error number is
sMsg.Format(IDS_SESSION_FREE_FAILED_FMT, fvecError);
// put the error up in a message box
MsgBox(sMsg, MB_ICONEXCLAMATION);
// release the allocated structure manually, since there was a failure the structure wasn't freed by the DLL
delete m_pSession;
} // if
// clear the pointer
m_pSession = NULL;
} // if
// call the base class function
CDialog::OnOK();
} // OnOK
void CSampleCPPDlg::OnCancel()
{
// ESC and X are still there, this function is called, call OnOK() instead
OnOK();
} // OnCancel
void CSampleCPPDlg::OnBnClickedClearLog()
{
// clear the log between sessions
m_LogList.ClearLog();
} // OnBnClickedClearLog
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg callback operations
void CALLBACK CSampleCPPDlg::OnDownloadError(FVSDK_CALLBACK_DATA pvData, long nErr, long nCause, LPCTSTR pszError, LPCTSTR pszRemotePath, LPCTSTR pszDestFileName, LPCTSTR pszExtraInfo)
{
CString sMsg;
// build the message
// for a definition of nErr, refer to FtpTreeErrors.h
sMsg.Format(IDS_DOWNLOAD_ERROR_FMT, nErr, nCause, pszError, pszRemotePath, pszDestFileName, pszExtraInfo);
// put up a simple error message
AfxMessageBox(sMsg, (MB_ICONEXCLAMATION | MB_OK));
} // OnDownloadError
void CALLBACK CSampleCPPDlg::OnUploadError(FVSDK_CALLBACK_DATA pvData, long nErr, long nCause, LPCTSTR pszError, LPCTSTR pszRemotePath, LPCTSTR pszLocalPath)
{
CString sMsg;
// build the message
// for a definition of nErr, refer to FtpTreeErrors.h
sMsg.Format(IDS_UPLOAD_ERROR_FMT, nErr, nCause, pszError, pszRemotePath, pszLocalPath);
// put up a simple error message
AfxMessageBox(sMsg, (MB_ICONEXCLAMATION | MB_OK));
} // OnUploadError
CString FormatDoubleStr(double dVal, int nPrec)
{
char buf[512];
CString sStr;
NUMBERFMT Num;
// convert to text
sStr.Format("%.*lf", nPrec, dVal);
// get locale information
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, buf, 10);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &buf[10], 10);
// the number of digits
Num.NumDigits = nPrec;
Num.LeadingZero = TRUE;
Num.Grouping = 3;
Num.lpDecimalSep = &buf[10];
Num.lpThousandSep = buf;
Num.NegativeOrder = 0;
// convert the string to a readable form
GetNumberFormat(LOCALE_USER_DEFAULT, 0, sStr, &Num, buf, sizeof(buf));
// return the formated string
return (buf);
} // FormatDoubleStr
void CALLBACK CSampleCPPDlg::OnNotifyTransferStatus(FVSDK_CALLBACK_DATA pvData, UINT nStatus, FVSDK_TransferStatus* pTransferStatus)
{
CSampleCPPDlg* pThis = (CSampleCPPDlg *) pvData;
CWnd* pStatus = pThis->GetDlgItem(IDC_TRANSFER_STATUS);
CString sStatus, sOldStatus;
// nothing to do if we can't get the status control
if (! pStatus)
return ;
// should not be negative
if (nStatus == FVSDK_TRANSFER_END) {
// the transfer is done
sStatus.LoadString(IDS_TRANSFER_DONE);
} // if
else {
CString sStr;
double dBytesPerSec = pTransferStatus->dBytesPerSecond;
// make it a bit easier to read
if (dBytesPerSec <= 1024.00)
sStr.LoadString(IDS_BYTES);
else if ((dBytesPerSec /= (double) 1024.00) < 1024.00)
sStr.LoadString(IDS_KB);
else {
sStr.LoadString(IDS_MB);
dBytesPerSec /= 1024.00;
} // else
// build a string with the transfer rate and time remaining
sStatus.Format(IDS_TIME_FMT, pTransferStatus->dwRemainingHours, pTransferStatus->dwRemainingMinutes,
pTransferStatus->dwRemainingSeconds, FormatDoubleStr(dBytesPerSec, 2), (LPCTSTR) sStr);
} // else
// get the current status
pStatus->GetWindowText(sOldStatus);
// update the display only if it's changed
if (sStatus != sOldStatus)
pStatus->SetWindowText(sStatus);
} // OnNotifyTransferStatus
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg connection operations
void CSampleCPPDlg::OnBnClickedConnect()
{
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return ;
// copy the fields from the dialog, then connect
if (UpdateData()) {
// set the status
SetStatus(SAMPLE_CONNECTING);
// clear the log between sessions
m_LogList.ClearLog();
// copy variables to the dialog
m_pSession->pszServer = (LPCTSTR) m_sServer;
m_pSession->nPort = m_nPort;
m_pSession->pszUserID = (LPCTSTR) m_sUserID;
m_pSession->pszPassword = (LPCTSTR) m_sPassword;
// extra parameters from the sample application
m_pSession->bPasv = m_bPASV;
m_pSession->bShowRawListings = m_bShowRawListings;
m_pSession->bShowTransferDialogs = m_bXferDialogs;
// try to connect to the server
FVSDK_ERROR_CODE fvecRet = FVSDK_Connect(m_pSession);
// set the current status
SetStatus();
// display an error message if we were unable to connect
if (fvecRet != FVSDK_OK) {
// display an error message if the operation was not stopped or canceled
MsgBox(IDS_UNABLE_TO_CONNECT, MB_ICONEXCLAMATION);
} // if
} // if
else
MsgBox(IDS_UNABLE_TO_COPY_FROM_DIALOG, MB_ICONEXCLAMATION);
} // OnBnClickedConnect
void CSampleCPPDlg::OnBnClickedDisconnect()
{
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return ;
// don't do anything if we're not connected
if (CheckNotConnected())
return ;
// set the status
SetStatus(SAMPLE_DISCONNECTING);
// disconnect
FVSDK_Disconnect(m_pSession);
// set the current status
SetStatus();
} // OnBnClickedDisconnect
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg directory operations
void CSampleCPPDlg::OnBnClickedCwd()
{
CString sDirName;
// get the directory name from the user
if (GetFileName(sDirName)) {
// try changing to the specified directory, put up an error if it fails
if (FVSDK_SetCurrentDirectory(m_pSession, sDirName) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_SET_CURRENT_DIRECTORY);
else
SetStatus();
} // if
} // OnBnClickedCwd
void CSampleCPPDlg::OnBnClickedRmd()
{
CString sDirName;
// get the directory name from the user
if (GetFileName(sDirName)) {
// try removing the specified directory, put up an error if it fails
if (FVSDK_RemoveDirectory(m_pSession, sDirName) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_REMOVE_DIRECTORY);
else
SetStatus();
} // if
} // OnBnClickedRmd
void CSampleCPPDlg::OnBnClickedMkd()
{
CString sDirName;
// get the directory name from the user
if (GetFileName(sDirName)) {
// try creating the specified directory, put up an error if it fails
if (FVSDK_CreateDirectory(m_pSession, sDirName) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_CREATE_DIRECTORY);
else
SetStatus();
} // if
} // OnBnClickedMkd
void CSampleCPPDlg::OnBnClickedCdup()
{
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return ;
// don't do anything if we're not connected
if (CheckNotConnected())
return ;
// try going up one directory, put up an error if it fails
if (FVSDK_UpOneDirectory(m_pSession) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_MOVE_UP_ONE_DIRECTORY);
else
SetStatus();
} // OnBnClickedCdup
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg misc. operations
void CSampleCPPDlg::OnBnClickedStop()
{
// stop any operation that may be going on
FVSDK_Stop(m_pSession);
} // OnBnClickedStop
void CSampleCPPDlg::OnBnClickedLastResponse()
{
char pszBuffer[128];
int nIndex = 0;
CString sResponse;
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return ;
// don't do anything if we're not connected
if (CheckNotConnected())
return ;
// get responses to the last command
while (FVSDK_GetLastResponse(m_pSession, nIndex++, pszBuffer, sizeof(pszBuffer)) == FVSDK_OK) {
// add the response to the message string
sResponse += pszBuffer;
// add a <CR><LF> for formatting
sResponse += "\r\n";
} // while
// show the last full response in a message box
MsgBox(sResponse, (MB_ICONINFORMATION | MB_OK));
} // OnBnClickedLastResponse
void CSampleCPPDlg::OnBnClickedWelcomeMessage()
{
char pszBuffer[128];
int nIndex = 0;
CString sWelcomeMessage;
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return ;
// don't do anything if we're not connected
if (CheckNotConnected())
return ;
// get the welcome message sent by the server when we connected
while (FVSDK_GetWelcomeMessage(m_pSession, nIndex++, pszBuffer, sizeof(pszBuffer)) == FVSDK_OK) {
// add the welcome message string to the message string
sWelcomeMessage += pszBuffer;
// add a <CR><LF> for formatting
sWelcomeMessage += "\r\n";
} // while
// show the last full welcome message in a message box
MsgBox(sWelcomeMessage, (MB_ICONINFORMATION | MB_OK));
} // OnBnClickedWelcomeMessage
void CSampleCPPDlg::OnBnClickedSendCommand()
{
CGetCommandDlg Dlg;
// don't do anything if the FTP Voyager SDK is working on another operation
if (CheckBusy())
return ;
// don't do anything if we're not connected
if (CheckNotConnected())
return ;
// fill in the default
Dlg.SetCommand("HELP");
// ask the user for the command
if ((Dlg.DoModal() == IDOK) && (! Dlg.GetCommand().IsEmpty())) {
int nResp;
CString sMsg;
// send a command to the server
if (FVSDK_SendCommand(m_pSession, Dlg.GetCommand(), &nResp) == FVSDK_OK) {
// format a message for the user
sMsg.Format(IDS_COMMAND_RESP_FMT, nResp, Dlg.GetCommand());
// put up a message box telling the user what happened
MsgBox(sMsg, (MB_ICONINFORMATION | MB_OK));
} // if
else {
// build the message
sMsg.Format(IDS_ERROR_SENDING_COMMAND_FMT, Dlg.GetCommand());
// put up an error message
MsgBox(sMsg, (MB_ICONEXCLAMATION | MB_OK));
} // else
} // if
} // OnBnClickedSendCommand
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg apply session settings
void CSampleCPPDlg::OnBnClickedPasv()
{
// copy from the dialog
if (UpdateData()) {
// change the PASV setting in the session
m_pSession->bPasv = m_bPASV;
// apply the session changes
// NOTE: in "normal" applications it is best to make many changes to the
// session structure, then call this function. For demonstration purposes
// only one setting is being changed here.
FVSDK_ApplySessionChange(m_pSession);
} // if
} // OnBnClickedPasv
void CSampleCPPDlg::OnBnClickedRaw()
{
// copy from the dialog
if (UpdateData()) {
// show raw listings in the log?
m_pSession->bShowRawListings = m_bShowRawListings;
// apply the session changes
// NOTE: in "normal" applications it is best to make many changes to the
// session structure, then call this function. For demonstration purposes
// only one setting is being changed here.
FVSDK_ApplySessionChange(m_pSession);
} // if
} // OnBnClickedRaw
void CSampleCPPDlg::OnBnClickedXferDialogs()
{
// copy from the dialog
if (UpdateData()) {
// show transfer dialogs
m_pSession->bShowTransferDialogs = m_bXferDialogs;
// apply the session changes
// NOTE: in "normal" applications it is best to make many changes to the
// session structure, then call this function. For demonstration purposes
// only one setting is being changed here.
FVSDK_ApplySessionChange(m_pSession);
} // if
} // OnBnClickedXferDialogs
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg directory listing
void CSampleCPPDlg::OnBnClickedListDir()
{
// make sure we're not busy and we're connected
if ((! CheckBusy()) && (! CheckNotConnected())) {
// find the file or files in the current directory
if (FVSDK_FindFile(m_pSession, "*") == FVSDK_YES) {
FVSDK_ERROR_CODE fvecRet;
FVSDK_FileInfo FileInfo;
// initialize the file info structure
FileInfo.nVersion = FVSDK_FILE_INFO_CURRENT_VERSION;
FileInfo.nSize = sizeof(FileInfo);
// find each of the files in the current directory all
do {
// get the current file information and move to the next file
fvecRet = FVSDK_FindNextFile(m_pSession, &FileInfo);
} while ((fvecRet == FVSDK_YES) && (! LastOperationStopped()));
} // if
// close the file find operation
FVSDK_FindFileClose(m_pSession);
} // if
} // OnBnClickedListDir
/////////////////////////////////////////////////////////////////////////////
// CSampleCPPDlg file transfer
void CSampleCPPDlg::OnBnClickedDownload()
{
CString sSourcePath, sDestPath;
// as the user for the file (or wild card) to download
if (GetFileName(sSourcePath)) {
// ask the user where it should be downloaded
if (GetLocalFileName(sDestPath)) {
// download the file
FVSDK_Download(m_pSession, sSourcePath, sDestPath);
} // if
} // if
} // OnBnClickedDownload
void CSampleCPPDlg::OnBnClickedMoveDown()
{
CString sSourcePath, sDestPath;
// as the user for the file (or wild card) to download
if (GetFileName(sSourcePath)) {
// ask the user where it should be downloaded
if (GetLocalFileName(sDestPath)) {
// move the file down
FVSDK_MoveDown(m_pSession, sSourcePath, sDestPath);
} // if
} // if
} // OnBnClickedMoveDown
void CSampleCPPDlg::OnBnClickedUpload()
{
CString sSourcePath, sDestPath;
// as the user for the file (or wild card) to upload
if (GetLocalFileName(sSourcePath)) {
// ask the user where it should be uploaded
if (GetFileName(sDestPath)) {
// upload the file
FVSDK_Upload(m_pSession, sSourcePath, sDestPath);
} // if
} // if
} // OnBnClickedUpload
void CSampleCPPDlg::OnBnClickedMoveUp()
{
CString sSourcePath, sDestPath;
// as the user for the file (or wild card) to upload
if (GetLocalFileName(sSourcePath)) {
// ask the user where it should be uploaded
if (GetFileName(sDestPath)) {
// move the file up
FVSDK_MoveUp(m_pSession, sSourcePath, sDestPath);
} // if
} // if
} // OnBnClickedMoveUp
void CSampleCPPDlg::OnBnClickedDeleteFile()
{
CString sPathName;
// get the file name from the user
if (GetFileName(sPathName)) {
// try removing the specified file, put up an error if it fails
if (FVSDK_RemoveFile(m_pSession, sPathName) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_REMOVE_FILE, MB_ICONEXCLAMATION);
} // if
} // OnBnClickedDeleteFile
void CSampleCPPDlg::OnBnClickedRename()
{
CString sOldPathName, sNewPathName;
// as the user for the old file path name
if (GetFileName(sOldPathName)) {
// ask the new file path name
if (GetFileName(sNewPathName)) {
// rename the file or directory
if (FVSDK_Rename(m_pSession, sOldPathName, sNewPathName) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_RENAME, MB_ICONEXCLAMATION);
} // if
} // if
} // OnBnClickedRename
CString FormatIntStr(FVSDK_FILE_SIZE fsNum)
{
char buf[512];
CString sStr;
NUMBERFMT Num;
// convert to text
sStr.Format("%I64d", fsNum);
// get locale information
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, buf, 10);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, &buf[10], 10);
// the number of digits
Num.NumDigits = 0;
Num.LeadingZero = 0;
Num.Grouping = 3;
Num.lpDecimalSep = &buf[10];
Num.lpThousandSep = buf;
Num.NegativeOrder = 0;
// convert the string to a readable form
GetNumberFormat(LOCALE_USER_DEFAULT, 0, sStr, &Num, buf, sizeof(buf));
// return the formated string
return (buf);
} // FormatIntStr
void CSampleCPPDlg::OnBnClickedSize()
{
CString sPathName;
// get the file name from the user
if (GetFileName(sPathName)) {
FVSDK_FILE_SIZE FileSize;
// get the file size from the server
if (FVSDK_Size(m_pSession, sPathName, &FileSize) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_GET_SIZE, MB_ICONEXCLAMATION);
else {
CString sMsg;
// build a message to display to the user
sMsg.Format("The file size is %s bytes.", FormatIntStr(FileSize));
// display a message to the user
MsgBox(sMsg, MB_ICONINFORMATION);
} // else
} // if
} // OnBnClickedSize
void CSampleCPPDlg::OnBnClickedFileUpload()
{
CString sPathName;
// get the file name from the user
if (GetLocalFileName(sPathName)) {
CStdioFile File;
// use try / catch to catch any local file errors
try {
// open the local file
if (File.Open(sPathName, (CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite))) {
CString sRemoteName = sPathName;
int nPos;
FVSDK_FILE_SIZE fsLocalFileSize = File.GetLength();
// get just the file name, removing any path information
if ((nPos = sRemoteName.ReverseFind('\\')) >= 0)
sRemoteName = sRemoteName.Mid(nPos + 1);
// get the file name from the user
if (GetFileName(sRemoteName, sRemoteName)) {
// attempt to open the file to be uploaded
if (FVSDK_CreateFile(m_pSession, sRemoteName, TRUE, 0) == FVSDK_YES) {
BYTE Buffer[1024];
int nBytes;
FVSDK_FILE_SIZE fsWritten = 0;
// read all of the data from the local file, and write it to the remote file
while ((nBytes = File.Read(Buffer, sizeof(Buffer))) > 0) {
// do the write
if (FVSDK_WriteFile(m_pSession, Buffer, &nBytes, ((nBytes + fsWritten) >= fsLocalFileSize)) != FVSDK_YES) {
// put up an error message
MsgBox(IDS_UNABLE_TO_WRITE_TO_FILE, MB_ICONEXCLAMATION);
// get out
break;
} // if
// increment the number of bytes written to the file
fsWritten += nBytes;
} // while
// close the remote file
if (FVSDK_CloseFile(m_pSession) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_CLOSE_FILE, MB_ICONEXCLAMATION);
else {
CFileStatus Status;
// get the status of the local file, then set the date and time of the remote file
if (File.GetStatus(Status)) {
tm tmLocalTime;
// get the last time the file was modified
Status.m_mtime.GetLocalTm(&tmLocalTime);
// set the date and time of the remote file, put up an error if it fails
if (FVSDK_SetFileDateAndTime(m_pSession, sRemoteName, &tmLocalTime) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_SET_REMOTE_FILE_DATE_TIME, MB_ICONEXCLAMATION);
} // if
} // else
} // if
else
MsgBox(IDS_UNABLE_TO_CREATE_FILE, MB_ICONEXCLAMATION);
} // if
// close the local file
File.Close();
} // if
else
MsgBox(IDS_UNABLE_TO_OPEN_LOCAL_FILE, MB_ICONEXCLAMATION);
} // try
catch (CFileException* pEx) {
char pszError[1024];
// get the error message
pEx->GetErrorMessage(pszError, sizeof(pszError));
// put up a message about the local file error
AfxMessageBox(pszError);
// close the remote file
FVSDK_CloseFile(m_pSession);
// release the exception
pEx->Delete();
} // catch
} // if
} // OnBnClickedFileUpload
void CSampleCPPDlg::OnBnClickedFileDownload()
{
CString sPathName;
// get the file name from the user
if (GetFileName(sPathName)) {
CString sLocalName = sPathName;
int nPos;
// get just the file name, removing any path information
if ((nPos = sLocalName.ReverseFind('/')) >= 0)
sLocalName = sLocalName.Mid(nPos + 1);
// create what is probably a good local file name
if ((nPos = m_sLocalFileName.ReverseFind('\\')) >= 0)
m_sLocalFileName = (m_sLocalFileName.Left(nPos + 1) + sLocalName);
// get the local file name
if (GetLocalFileName(sLocalName)) {
CStdioFile File;
// use try / catch to catch any local file errors
try {
// create the local file
if (File.Open(sLocalName, (CFile::modeCreate | CFile::modeWrite | CFile::typeBinary | CFile::shareDenyWrite))) {
// attempt to open the file to be downloaded
if (FVSDK_OpenFile(m_pSession, sPathName, TRUE, 0) == FVSDK_YES) {
BYTE Buffer[1024];
int nBytes = sizeof(Buffer);
// read all of the data from the remote file, and write it to the local file
while (FVSDK_ReadFile(m_pSession, Buffer, &nBytes) == FVSDK_YES) {
// write the data to the local file
File.Write(Buffer, nBytes);
// reset the buffer size
nBytes = sizeof(Buffer);
} // while
// close the remote file
if (FVSDK_CloseFile(m_pSession) != FVSDK_YES)
MsgBox(IDS_UNABLE_TO_CLOSE_FILE, MB_ICONEXCLAMATION);
} // if
else
MsgBox(IDS_UNABLE_TO_OPEN_FILE, MB_ICONEXCLAMATION);
// close the local file
File.Close();
} // if
else
MsgBox(IDS_UNABLE_TO_CREATE_LOCAL_FILE, MB_ICONEXCLAMATION);
} // try
catch (CFileException* pEx) {
char pszError[1024];
// get the error message
pEx->GetErrorMessage(pszError, sizeof(pszError));
// put up a message about the local file error
AfxMessageBox(pszError);
// close the remote file
FVSDK_CloseFile(m_pSession);
// release the exception
pEx->Delete();
} // catch
} // if
} // if
} // OnBnClickedFileDownload
void CSampleCPPDlg::OnBnClickedEditFile()
{
CString sPathName;
// get the file name from the user
if (GetFileName(sPathName)) {
// perform a remote file edit
FVSDK_RemoteEdit(m_pSession, sPathName);
} // if
} // OnBnClickedEditFile
void CSampleCPPDlg::OnBnClickedViewFile()
{
CString sPathName;
// get the file name from the user
if (GetFileName(sPathName)) {
// perform a remote file view
FVSDK_RemoteView(m_pSession, sPathName);
} // if
} // OnBnClickedViewFile
void CSampleCPPDlg::OnBnClickedFindFiles()
{
CString sPathName;
// get the file name from the user
if (GetFileName(sPathName)) {
// do the find files dialog
FVSDK_FindFilesDialog(m_pSession, sPathName);
} // if
} // OnBnClickedFindFiles
void CSampleCPPDlg::OnBnClickedSyncFolders()
{
CString sRemoteDir;
// get the file name from the user
if (GetFileName(sRemoteDir)) {
CString sLocalDir;
// get the local file name
if (GetLocalFileName(sLocalDir)) {
DWORD dwSyncOptions = 0;
// set the synchronize folders options
dwSyncOptions |= FVSDK_SYNCOPT_IGNORECASE;
dwSyncOptions |= FVSDK_SYNCOPT_COMPARESIZE;
dwSyncOptions |= FVSDK_SYNCOPT_COMPARETIME;
dwSyncOptions |= FVSDK_SYNCOPT_INCLUDEDIRS;
dwSyncOptions |= FVSDK_SYNCOPT_DONTDELETE;
dwSyncOptions |= FVSDK_SYNCOPT_OVERWRITECONFIRMATIONS;
dwSyncOptions |= FVSDK_SYNCOPT_DELETECONFIRMATIONS;
dwSyncOptions |= FVSDK_SYNCOPT_REMOTEIGNOREOLDER;
dwSyncOptions |= FVSDK_SYNCOPT_LOCALIGNORENEWER;
dwSyncOptions |= FVSDK_SYNCOPT_QUEUEERRORMESSAGES;
dwSyncOptions |= FVSDK_SYNCOPT_USEDIALOG;
// do the sync folders
FVSDK_SyncFolders(m_pSession, sRemoteDir, sLocalDir, dwSyncOptions, "", 1);
} // if
} // if
} // OnBnClickedSyncFolders