📄 filetransfer.cpp
字号:
// Copyright (C) 2003 Dennis Syrovatsky. All Rights Reserved.
//
// This file is part of the VNC system.
//
// The VNC system is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// TightVNC distribution homepage on the Web: http://www.tightvnc.com/
//
// If the source code for the VNC system is not available from the place
// whence you received this file, check http://www.uk.research.att.com/vnc or contact
// the authors on vnc@uk.research.att.com for information on obtaining it.
#include "vncviewer.h"
#include "VNCviewerApp32.h"
#include "FileTransfer.h"
#include "FileTransferItemInfo.h"
const char FileTransfer::uploadText[] = ">>>";
const char FileTransfer::downloadText[] = "<<<";
const char FileTransfer::noactionText[] = "<--->";
FileTransfer::FileTransfer(ClientConnection * pCC, VNCviewerApp * pApp)
{
m_clientconn = pCC;
m_pApp = pApp;
m_bUploadStarted = FALSE;
m_bDownloadStarted = FALSE;
m_bTransferEnable = FALSE;
m_bReportUploadCancel = FALSE;
m_bServerBrowseRequest = FALSE;
m_bFirstFileDownloadMsg = TRUE;
m_hTreeItem = NULL;
m_ClientPath[0] = '\0';
m_ClientPathTmp[0] = '\0';
m_ServerPath[0] = '\0';
m_ServerPathTmp[0] = '\0';
m_numOfFilesToDownload = -1;
m_currentDownloadIndex = -1;
}
FileTransfer::~FileTransfer()
{
m_FTClientItemInfo.Free();
m_FTServerItemInfo.Free();
}
void
FileTransfer::CreateFileTransferDialog()
{
m_hwndFileTransfer = CreateDialog(m_pApp->m_instance,
MAKEINTRESOURCE(IDD_FILETRANSFER_DLG),
NULL,
(DLGPROC) FileTransferDlgProc);
#ifndef _WIN32_WCE
VNCviewerApp32 *pApp = (VNCviewerApp32 *)(m_clientconn->m_pApp);
pApp->AddModelessDialog(m_hwndFileTransfer);
#endif
ShowWindow(m_hwndFileTransfer, SW_SHOW);
UpdateWindow(m_hwndFileTransfer);
SetWindowLong(m_hwndFileTransfer, GWL_USERDATA, (LONG) this);
m_hwndFTProgress = GetDlgItem(m_hwndFileTransfer, IDC_FTPROGRESS);
m_hwndFTClientList = GetDlgItem(m_hwndFileTransfer, IDC_FTCLIENTLIST);
m_hwndFTServerList = GetDlgItem(m_hwndFileTransfer, IDC_FTSERVERLIST);
m_hwndFTClientPath = GetDlgItem(m_hwndFileTransfer, IDC_CLIENTPATH);
m_hwndFTServerPath = GetDlgItem(m_hwndFileTransfer, IDC_SERVERPATH);
m_hwndFTStatus = GetDlgItem(m_hwndFileTransfer, IDC_FTSTATUS);
ListView_SetExtendedListViewStyleEx(m_hwndFTClientList, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
ListView_SetExtendedListViewStyleEx(m_hwndFTServerList, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
HANDLE hIcon = LoadImage(m_pApp->m_instance, MAKEINTRESOURCE(IDI_FILEUP), IMAGE_ICON, 16, 16, LR_SHARED);
SendMessage(GetDlgItem(m_hwndFileTransfer, IDC_CLIENTUP), BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) hIcon);
SendMessage(GetDlgItem(m_hwndFileTransfer, IDC_SERVERUP), BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) hIcon);
DestroyIcon((HICON) hIcon);
hIcon = LoadImage(m_pApp->m_instance, MAKEINTRESOURCE(IDI_FILERELOAD), IMAGE_ICON, 16, 16, LR_SHARED);
SendMessage(GetDlgItem(m_hwndFileTransfer, IDC_CLIENTRELOAD), BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) hIcon);
SendMessage(GetDlgItem(m_hwndFileTransfer, IDC_SERVERRELOAD), BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) hIcon);
DestroyIcon((HICON) hIcon);
RECT Rect;
GetClientRect(m_hwndFTClientList, &Rect);
int xwidth = (int) (0.7 * Rect.right);
int xwidth_ = (int) (0.25 * Rect.right);
FTInsertColumn(m_hwndFTClientList, "Name", 0, xwidth);
FTInsertColumn(m_hwndFTClientList, "Size", 1, xwidth_);
FTInsertColumn(m_hwndFTServerList, "Name", 0, xwidth);
FTInsertColumn(m_hwndFTServerList, "Size", 1, xwidth_);
ShowClientItems(m_ClientPathTmp);
SendFileListRequestMessage(m_ServerPathTmp, 0);
}
LRESULT CALLBACK
FileTransfer::FileTransferDlgProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
FileTransfer *_this = (FileTransfer *) GetWindowLong(hwnd, GWL_USERDATA);
int i;
switch (uMsg)
{
case WM_INITDIALOG:
{
SetForegroundWindow(hwnd);
CentreWindow(hwnd);
return TRUE;
}
break;
case WM_HELP:
help.Popup(lParam);
return 0;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_CLIENTPATH:
switch (HIWORD (wParam))
{
case EN_SETFOCUS:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
return TRUE;
}
break;
case IDC_SERVERPATH:
switch (HIWORD (wParam))
{
case EN_SETFOCUS:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
return TRUE;
}
break;
case IDC_EXIT:
case IDCANCEL:
PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
case IDC_CLIENTUP:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
SendMessage(_this->m_hwndFTProgress, PBM_SETPOS, 0, 0);
SetWindowText(_this->m_hwndFTStatus, "");
if (strcmp(_this->m_ClientPathTmp, "") == 0) return TRUE;
for (i=(strlen(_this->m_ClientPathTmp)-2); i>=0; i--) {
if (_this->m_ClientPathTmp[i] == '\\') {
_this->m_ClientPathTmp[i] = '\0';
break;
}
if (i == 0) _this->m_ClientPathTmp[0] = '\0';
}
_this->ShowClientItems(_this->m_ClientPathTmp);
return TRUE;
case IDC_SERVERUP:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
SendMessage(_this->m_hwndFTProgress, PBM_SETPOS, 0, 0);
SetWindowText(_this->m_hwndFTStatus, "");
if (strcmp(_this->m_ServerPathTmp, "") == 0) return TRUE;
for (i=(strlen(_this->m_ServerPathTmp)-2); i>=0; i--) {
if (_this->m_ServerPathTmp[i] == '\\') {
_this->m_ServerPathTmp[i] = '\0';
break;
}
if (i == 0) _this->m_ServerPathTmp[0] = '\0';
}
_this->SendFileListRequestMessage(_this->m_ServerPathTmp, 0);
return TRUE;
case IDC_CLIENTRELOAD:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
SendMessage(_this->m_hwndFTProgress, PBM_SETPOS, 0, 0);
SetWindowText(_this->m_hwndFTStatus, "");
_this->ShowClientItems(_this->m_ClientPath);
return TRUE;
case IDC_SERVERRELOAD:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
SendMessage(_this->m_hwndFTProgress, PBM_SETPOS, 0, 0);
SetWindowText(_this->m_hwndFTStatus, "");
_this->SendFileListRequestMessage(_this->m_ServerPathTmp, 0);
return TRUE;
case IDC_FTCOPY:
// First, check if the action is supported by the server.
if (_this->m_bFTCOPY == FALSE) {
// Upload was requested.
if ( !_this->m_clientconn->m_clientMsgCaps.IsEnabled(rfbFileUploadRequest) ||
!_this->m_clientconn->m_clientMsgCaps.IsEnabled(rfbFileUploadData) ) {
MessageBox(hwnd, "Sorry but the server does not support uploading files.",
"Error", MB_OK | MB_ICONEXCLAMATION);
char buf[MAX_PATH];
sprintf(buf, "File upload not supported by server");
SetWindowText(_this->m_hwndFTStatus, buf);
return TRUE;
}
} else {
// Download was requested.
if ( !_this->m_clientconn->m_clientMsgCaps.IsEnabled(rfbFileDownloadRequest) ||
!_this->m_clientconn->m_serverMsgCaps.IsEnabled(rfbFileDownloadData) ) {
MessageBox(hwnd, "Sorry but the server does not support downloading files.",
"Error", MB_OK | MB_ICONEXCLAMATION);
char buf[MAX_PATH];
sprintf(buf, "File download not supported by server");
SetWindowText(_this->m_hwndFTStatus, buf);
return TRUE;
}
}
// Now, try to upload/download.
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
if (_this->m_ClientPath[0] == '\0' || _this->m_ServerPath[0] == '\0') {
SetWindowText(_this->m_hwndFTStatus, "Cannot transfer files: illegal directory.");
return TRUE;
}
if (_this->m_bFTCOPY == FALSE) {
_this->m_bTransferEnable = TRUE;
_this->m_bReportUploadCancel = TRUE;
EnableWindow(GetDlgItem(hwnd, IDC_FTCANCEL), TRUE);
_this->FileTransferUpload();
} else {
return _this->SendMultipleFileDownloadRequests();
}
return TRUE;
case IDC_FTCANCEL:
// Check if we allowed to interrupt the transfer.
if ( _this->m_bUploadStarted &&
!_this->m_clientconn->m_clientMsgCaps.IsEnabled(rfbFileUploadFailed) ) {
char buf[MAX_PATH];
sprintf(buf, "Sorry, but interrupting upload is not supported by the server");
SetWindowText(_this->m_hwndFTStatus, buf);
return TRUE;
}
if ( _this->m_bDownloadStarted &&
!_this->m_clientconn->m_clientMsgCaps.IsEnabled(rfbFileDownloadCancel) ) {
char buf[MAX_PATH];
sprintf(buf, "Sorry, but interrupting download is not supported by the server");
SetWindowText(_this->m_hwndFTStatus, buf);
return TRUE;
}
// Now try to cancel the operation.
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
_this->m_bTransferEnable = FALSE;
EnableWindow(GetDlgItem(hwnd, IDC_FTCANCEL), FALSE);
return TRUE;
case IDC_CLIENTBROWSE_BUT:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
SendMessage(_this->m_hwndFTProgress, PBM_SETPOS, 0, 0);
SetWindowText(_this->m_hwndFTStatus, "");
_this->CreateFTBrowseDialog(FALSE);
return TRUE;
case IDC_SERVERBROWSE_BUT:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), noactionText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), FALSE);
SendMessage(_this->m_hwndFTProgress, PBM_SETPOS, 0, 0);
SetWindowText(_this->m_hwndFTStatus, "");
_this->CreateFTBrowseDialog(TRUE);
return TRUE;
}
}
break;
case WM_NOTIFY:
switch (LOWORD(wParam))
{
case IDC_FTCLIENTLIST:
switch (((LPNMHDR) lParam)->code)
{
case NM_SETFOCUS:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), uploadText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), TRUE);
_this->m_bFTCOPY = FALSE;
return TRUE;
case LVN_GETDISPINFO:
_this->OnGetDispClientInfo((NMLVDISPINFO *) lParam);
return TRUE;
case LVN_ITEMACTIVATE:
LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam;
_this->ProcessListViewDBLCLK(_this->m_hwndFTClientList, _this->m_ClientPath, _this->m_ClientPathTmp, lpnmia->iItem);
return TRUE;
}
break;
case IDC_FTSERVERLIST:
switch (((LPNMHDR) lParam)->code)
{
case NM_SETFOCUS:
SetWindowText(GetDlgItem(hwnd, IDC_FTCOPY), downloadText);
EnableWindow(GetDlgItem(hwnd, IDC_FTCOPY), TRUE);
_this->m_bFTCOPY = TRUE;
return TRUE;
case LVN_GETDISPINFO:
_this->OnGetDispServerInfo((NMLVDISPINFO *) lParam);
return TRUE;
case LVN_ITEMACTIVATE:
LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam;
_this->ProcessListViewDBLCLK(_this->m_hwndFTServerList, _this->m_ServerPath, _this->m_ServerPathTmp, lpnmia->iItem);
return TRUE;
}
break;
}
break;
case WM_CLOSE:
_this->m_clientconn->m_fileTransferDialogShown = false;
_this->m_FTClientItemInfo.Free();
_this->m_FTServerItemInfo.Free();
#ifndef _WIN32_WCE
{
VNCviewerApp32 *pApp = (VNCviewerApp32 *)(_this->m_clientconn->m_pApp);
pApp->RemoveModelessDialog(hwnd);
}
#endif
DestroyWindow(hwnd);
return TRUE;
}
return 0;
}
// This method will be called, each time window message 'IDC_FTCOPY' is sent for
// file download. In following cases IDC_FTCOPY will be sent for file download.
// 1. From UI, when download button is clicked
// 2. From 'FileTransferDownload' method after each file download is complete.
// This method will keep track of number of selected files for which download
// request is not sent. With each call it will send download request for one file
// and will return. After the completion of file download 'FileTransferDownload'
// method will do a PostMessage for 'IDC_FTCOPY', which will invoke this method
// again and it will send another request for file download if download request for
// some of the selected files is still pending.
BOOL
FileTransfer:: SendMultipleFileDownloadRequests()
{
// Download Request for all the selected files is sent.
if(m_numOfFilesToDownload == 0) {
m_numOfFilesToDownload = -1 ;
m_currentDownloadIndex = -1;
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE);
BlockingFileTransferDialog(TRUE);
return TRUE;
}
// This is the first call for currently select file list.
// Count of slected files is not calculated yet
if(m_numOfFilesToDownload == -1) {
m_numOfFilesToDownload = ListView_GetSelectedCount(m_hwndFTServerList);
if (m_numOfFilesToDownload <= 0) {
SetWindowText(m_hwndFTStatus, "No file is selected, nothing to download.");
m_numOfFilesToDownload = -1;
m_currentDownloadIndex = -1;
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE);
BlockingFileTransferDialog(TRUE);
return TRUE;
}
else {
// file transfer will start for all the selected files now. set m_bTransferEnable to true
// Enable cancel button and disable rest of the UI components.
m_bTransferEnable = TRUE;
BlockingFileTransferDialog(FALSE);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), TRUE);
}
}
// Calculate the next selected index for which file download request has to be sent.
int index = -1;
index = ListView_GetNextItem(m_hwndFTServerList, m_currentDownloadIndex, LVNI_SELECTED);
if (index < 0) {
SetWindowText(m_hwndFTStatus, "No file is selected, nothing to download.");
m_numOfFilesToDownload = -1;
m_currentDownloadIndex = -1;
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE);
BlockingFileTransferDialog(TRUE);
return TRUE;
}
// If Cancel button is clicked, dont send the file download request.
if(m_bTransferEnable == FALSE) {
m_numOfFilesToDownload = -1;
m_currentDownloadIndex = -1;
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE);
BlockingFileTransferDialog(TRUE);
return TRUE;
}
// Update member variables for next call.
m_currentDownloadIndex = index;
m_numOfFilesToDownload -= 1;
return SendFileDownloadRequest();
}
BOOL
FileTransfer:: SendFileDownloadRequest()
{
char path[rfbMAX_PATH + rfbMAX_PATH];
if (!m_FTServerItemInfo.IsFile(m_currentDownloadIndex)) {
SetWindowText(m_hwndFTStatus, "Cannot download: not a regular file.");
// Send message to start download for next selected file.
PostMessage(m_hwndFileTransfer, WM_COMMAND, IDC_FTCOPY, 0);
return TRUE;
}
ListView_GetItemText(m_hwndFTServerList, m_currentDownloadIndex, 0, m_ServerFilename, rfbMAX_PATH);
strcpy(m_ClientFilename, m_ServerFilename);
char buffer[rfbMAX_PATH + rfbMAX_PATH + rfbMAX_PATH];
sprintf(buffer, "Downloading: %s\\%s -> %s\\%s ...",
m_ServerPath, m_ServerFilename,
m_ClientPath, m_ClientFilename);
SetWindowText(m_hwndFTStatus, buffer);
m_sizeDownloadFile = m_FTServerItemInfo.GetIntSizeAt(m_currentDownloadIndex);
rfbFileDownloadRequestMsg fdr;
fdr.type = rfbFileDownloadRequest;
fdr.compressedLevel = 0;
fdr.position = Swap32IfLE(0);
sprintf(path, "%s\\%s", m_ServerPath, m_ServerFilename);
ConvertPath(path);
int len = strlen(path);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -