filetransfer.cpp
来自「tightvnc源码」· C++ 代码 · 共 1,327 行 · 第 1/3 页
CPP
1,327 行
return TRUE;
} else {
_this->ShowTreeViewItems(hwnd, m_lParam);
}
}
return TRUE;
}
}
break;
}
break;
case WM_CLOSE:
case WM_DESTROY:
EndDialog(hwnd, FALSE);
_this->m_bServerBrowseRequest = FALSE;
return TRUE;
}
return 0;
}
void
FileTransfer::CreateFTBrowseDialog(BOOL status)
{
m_bServerBrowseRequest = status;
DialogBoxParam(m_pApp->m_instance, MAKEINTRESOURCE(IDD_FTBROWSE_DLG), m_hwndFileTransfer, (DLGPROC) FTBrowseDlgProc, (LONG) this);
}
void
FileTransfer::GetTVPath(HWND hwnd, HTREEITEM hTItem, char *path)
{
char szText[rfbMAX_PATH];
TVITEM _tvi;
path[0] = '\0';
do {
_tvi.mask = TVIF_TEXT | TVIF_HANDLE;
_tvi.hItem = hTItem;
_tvi.pszText = szText;
_tvi.cchTextMax = rfbMAX_PATH;
TreeView_GetItem(hwnd, &_tvi);
strcat(path, "\\");
strcat(path, _tvi.pszText);
hTItem = TreeView_GetParent(hwnd, hTItem);
}
while(hTItem != NULL);
char path_tmp[rfbMAX_PATH], path_out[rfbMAX_PATH];
path_tmp[0] = '\0';
path_out[0] = '\0';
int len = strlen(path);
int ii = 0;
for (int i = (len-1); i>=0; i--) {
if (path[i] == '\\') {
StrInvert(path_tmp);
strcat(path_out, path_tmp);
strcat(path_out, "\\");
path_tmp[0] = '\0';
ii = 0;
} else {
path_tmp[ii] = path[i];
path_tmp[ii+1] = '\0';
ii++;
}
}
if (path_out[strlen(path_out)-1] == '\\') path_out[strlen(path_out)-1] = '\0';
strcpy(path, path_out);
}
void
FileTransfer::StrInvert(char str[rfbMAX_PATH])
{
int len = strlen(str), i;
char str_out[rfbMAX_PATH];
str_out[0] = '\0';
for (i = (len-1); i>=0; i--) str_out[len-i-1] = str[i];
str_out[len] = '\0';
strcpy(str, str_out);
}
void
FileTransfer::ShowTreeViewItems(HWND hwnd, LPNMTREEVIEW m_lParam)
{
HANDLE m_handle;
WIN32_FIND_DATA m_FindFileData;
TVITEM tvi;
TVINSERTSTRUCT tvins;
char path[rfbMAX_PATH];
GetTVPath(GetDlgItem(hwnd, IDC_FTBROWSETREE), m_lParam->itemNew.hItem, path);
strcat(path, "\\*");
while (TreeView_GetChild(GetDlgItem(hwnd, IDC_FTBROWSETREE), m_lParam->itemNew.hItem) != NULL) {
TreeView_DeleteItem(GetDlgItem(hwnd, IDC_FTBROWSETREE), TreeView_GetChild(GetDlgItem(hwnd, IDC_FTBROWSETREE), m_lParam->itemNew.hItem));
}
SetErrorMode(SEM_FAILCRITICALERRORS);
m_handle = FindFirstFile(path, &m_FindFileData);
SetErrorMode(0);
if (m_handle == INVALID_HANDLE_VALUE) return;
while(1) {
if ((strcmp(m_FindFileData.cFileName, ".") != 0) &&
(strcmp(m_FindFileData.cFileName, "..") != 0)) {
if (m_FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
tvi.mask = TVIF_TEXT;
tvi.pszText = m_FindFileData.cFileName;
tvins.hParent = m_lParam->itemNew.hItem;
tvins.item = tvi;
tvins.hParent = TreeView_InsertItem(GetDlgItem(hwnd, IDC_FTBROWSETREE), &tvins);
TreeView_InsertItem(GetDlgItem(hwnd, IDC_FTBROWSETREE), &tvins);
}
}
if (!FindNextFile(m_handle, &m_FindFileData)) break;
}
FindClose(m_handle);
}
void
FileTransfer::ProcessDlgMessage(HWND hwnd)
{
MSG msg;
while(PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void
FileTransfer::BlockingFileTransferDialog(BOOL status)
{
EnableWindow(m_hwndFTClientList, status);
EnableWindow(m_hwndFTServerList, status);
EnableWindow(m_hwndFTClientPath, status);
EnableWindow(m_hwndFTServerPath, status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_UPLOAD), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_DOWNLOAD), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_CLIENTUP), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_SERVERUP), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_CLIENTRELOAD), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_SERVERRELOAD), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_CLIENTBROWSE_BUT), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_SERVERBROWSE_BUT), status);
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_EXIT), status);
}
void
FileTransfer::ShowServerItems()
{
rfbFileListDataMsg fld;
m_clientconn->ReadExact((char *) &fld, sz_rfbFileListDataMsg);
if ((fld.flags & 0x80) && !m_bServerBrowseRequest) {
BlockingFileTransferDialog(TRUE);
return;
}
fld.numFiles = Swap16IfLE(fld.numFiles);
fld.dataSize = Swap16IfLE(fld.dataSize);
fld.compressedSize = Swap16IfLE(fld.compressedSize);
FTSIZEDATA *pftSD = new FTSIZEDATA[fld.numFiles];
char *pFilenames = new char[fld.dataSize];
m_clientconn->ReadExact((char *)pftSD, fld.numFiles * 8);
m_clientconn->ReadExact(pFilenames, fld.dataSize);
if (!m_bServerBrowseRequest) {
if (fld.numFiles == 0) {
BlockingFileTransferDialog(TRUE);
strcpy(m_ServerPath, m_ServerPathTmp);
SetWindowText(m_hwndFTServerPath, m_ServerPath);
ListView_DeleteAllItems(m_hwndFTServerList);
delete [] pftSD;
delete [] pFilenames;
return;
} else {
m_FTServerItemInfo.Free();
ListView_DeleteAllItems(m_hwndFTServerList);
strcpy(m_ServerPath, m_ServerPathTmp);
SetWindowText(m_hwndFTServerPath, m_ServerPath);
CreateServerItemInfoList(&m_FTServerItemInfo, pftSD, fld.numFiles, pFilenames, fld.dataSize);
m_FTServerItemInfo.Sort();
ShowListViewItems(m_hwndFTServerList, &m_FTServerItemInfo);
}
} else {
while (TreeView_GetChild(GetDlgItem(m_hwndFTBrowse, IDC_FTBROWSETREE), m_hTreeItem) != NULL) {
TreeView_DeleteItem(GetDlgItem(m_hwndFTBrowse, IDC_FTBROWSETREE), TreeView_GetChild(GetDlgItem(m_hwndFTBrowse, IDC_FTBROWSETREE), m_hTreeItem));
}
TVITEM TVItem;
TVINSERTSTRUCT tvins;
TVItem.mask = TVIF_CHILDREN | TVIF_TEXT | TVIF_HANDLE;
TVItem.cChildren = 1;
int pos = 0;
for (int i = 0; i < fld.numFiles; i++) {
if (pftSD[i].size == -1) {
TVItem.pszText = pFilenames + pos;
TVItem.cChildren = 1;
tvins.item = TVItem;
tvins.hParent = m_hTreeItem;
tvins.hParent = TreeView_InsertItem(GetDlgItem(m_hwndFTBrowse, IDC_FTBROWSETREE), &tvins);
tvins.item = TVItem;
TreeView_InsertItem(GetDlgItem(m_hwndFTBrowse, IDC_FTBROWSETREE), &tvins);
tvins.hParent = m_hTreeItem;;
}
pos += strlen(pFilenames + pos) + 1;
}
}
delete [] pftSD;
delete [] pFilenames;
BlockingFileTransferDialog(TRUE);
}
void
FileTransfer::SendFileListRequestMessage(char *filename, unsigned char flags)
{
char _filename[rfbMAX_PATH];
strcpy(_filename, filename);
int len = strlen(_filename);
if (_filename[len-1] == '\\') _filename[len-1] = '\0';
ConvertPath(_filename);
len = strlen(_filename);
rfbFileListRequestMsg flr;
flr.type = rfbFileListRequest;
flr.dirNameSize = Swap16IfLE(len);
flr.flags = flags;
m_clientconn->WriteExact((char *)&flr, sz_rfbFileListRequestMsg);
m_clientconn->WriteExact(_filename, len);
}
void
FileTransfer::ProcessListViewDBLCLK(HWND hwnd, char *Path, char *PathTmp, int iItem)
{
SendMessage(m_hwndFTProgress, PBM_SETPOS, 0, 0);
SetWindowText(m_hwndFTStatus, "");
strcpy(PathTmp, Path);
char buffer[rfbMAX_PATH];
char buffer_tmp[16];
ListView_GetItemText(hwnd, iItem, 0, buffer, rfbMAX_PATH);
ListView_GetItemText(hwnd, iItem, 1, buffer_tmp, 16);
if (strcmp(buffer_tmp, m_FTClientItemInfo.folderText) == 0) {
BlockingFileTransferDialog(FALSE);
if (strlen(PathTmp) >= 2) strcat(PathTmp, "\\");
strcat(PathTmp, buffer);
if (hwnd == m_hwndFTClientList) ShowClientItems(PathTmp);
if (hwnd == m_hwndFTServerList) SendFileListRequestMessage(PathTmp, 0);
}
}
void
FileTransfer::ConvertPath(char *path)
{
int len = strlen(path);
if (len >= rfbMAX_PATH) return;
if (strcmp(path, "") == 0) {strcpy(path, "/"); return;}
for (int i = (len - 1); i >= 0; i--) {
if (path[i] == '\\') path[i] = '/';
path[i+1] = path[i];
}
path[len + 1] = '\0';
path[0] = '/';
return;
}
void
FileTransfer::ShowListViewItems(HWND hwnd, FileTransferItemInfo *ftii)
{
LVITEM LVItem;
LVItem.mask = LVIF_TEXT | LVIF_STATE;
LVItem.state = 0;
LVItem.stateMask = 0;
for (int i=0; i<ftii->GetNumEntries(); i++) {
LVItem.iItem = i;
LVItem.iSubItem = 0;
LVItem.pszText = LPSTR_TEXTCALLBACK;
ListView_InsertItem(hwnd, &LVItem);
}
}
void
FileTransfer::FTInsertColumn(HWND hwnd, char *iText, int iOrder, int xWidth)
{
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER;
lvc.fmt = LVCFMT_RIGHT;
lvc.iSubItem = iOrder;
lvc.pszText = iText;
lvc.cchTextMax = 10;
lvc.cx = xWidth;
lvc.iOrder = iOrder;
ListView_InsertColumn(hwnd, iOrder, &lvc);
}
void
FileTransfer::InitProgressBar(int nPosition, int nMinRange, int nMaxRange, int nStep)
{
SendMessage(m_hwndFTProgress, PBM_SETPOS, (WPARAM) nPosition, (LPARAM) 0);
SendMessage(m_hwndFTProgress, PBM_SETRANGE, (WPARAM) 0, MAKELPARAM(nMinRange, nMaxRange));
SendMessage(m_hwndFTProgress, PBM_SETSTEP, (WPARAM) nStep, 0);
}
void
FileTransfer::CreateServerItemInfoList(FileTransferItemInfo *pftii,
FTSIZEDATA *ftsd, int ftsdNum,
char *pfnames, int fnamesSize)
{
int pos = 0;
for (int i = 0; i < ftsdNum; i++) {
char buf[16];
ftsd[i].size = Swap32IfLE(ftsd[i].size);
ftsd[i].data = Swap32IfLE(ftsd[i].data);
if (ftsd[i].size == -1) {
strcpy(buf, FileTransferItemInfo::folderText);
} else {
sprintf(buf, "%d", ftsd[i].size);
}
pftii->Add(pfnames + pos, buf, ftsd[i].data);
pos += strlen(pfnames + pos) + 1;
}
}
void
FileTransfer::SendFileUploadDataMessage(unsigned int mTime)
{
rfbFileUploadDataMsg msg;
msg.type = rfbFileUploadData;
msg.compressedLevel = 0;
msg.realSize = Swap16IfLE(0);
msg.compressedSize = Swap16IfLE(0);
CARD32 time32 = Swap32IfLE((CARD32)mTime);
char data[sz_rfbFileUploadDataMsg + sizeof(CARD32)];
memcpy(data, &msg, sz_rfbFileUploadDataMsg);
memcpy(&data[sz_rfbFileUploadDataMsg], &time32, sizeof(CARD32));
m_clientconn->WriteExact(data, sz_rfbFileUploadDataMsg + sizeof(CARD32));
}
void
FileTransfer::SendFileUploadDataMessage(unsigned short size, char *pFile)
{
int msgLen = sz_rfbFileUploadDataMsg + size;
char *pAllFUDMessage = new char[msgLen];
rfbFileUploadDataMsg *pFUD = (rfbFileUploadDataMsg *) pAllFUDMessage;
char *pFollow = &pAllFUDMessage[sz_rfbFileUploadDataMsg];
pFUD->type = rfbFileUploadData;
pFUD->compressedLevel = 0;
pFUD->realSize = Swap16IfLE(size);
pFUD->compressedSize = Swap16IfLE(size);
memcpy(pFollow, pFile, size);
m_clientconn->WriteExact(pAllFUDMessage, msgLen);
delete [] pAllFUDMessage;
}
void
FileTransfer::SendFileDownloadCancelMessage(unsigned short reasonLen, char *reason)
{
int msgLen = sz_rfbFileDownloadCancelMsg + reasonLen;
char *pAllFDCMessage = new char[msgLen];
rfbFileDownloadCancelMsg *pFDC = (rfbFileDownloadCancelMsg *) pAllFDCMessage;
char *pFollow = &pAllFDCMessage[sz_rfbFileDownloadCancelMsg];
pFDC->type = rfbFileDownloadCancel;
pFDC->reasonLen = Swap16IfLE(reasonLen);
memcpy(pFollow, reason, reasonLen);
m_clientconn->WriteExact(pAllFDCMessage, msgLen);
delete [] pAllFDCMessage;
}
void
FileTransfer::ReadUploadCancel()
{
if (m_bUploadStarted) {
m_bUploadStarted = FALSE;
CloseHandle(m_hFiletoRead);
}
// Stop file transfer
CloseUndoneFileTransfers();
// Read the message
rfbFileUploadCancelMsg msg;
m_clientconn->ReadExact((char *)&msg, sz_rfbFileUploadCancelMsg);
int len = Swap16IfLE(msg.reasonLen);
char *reason = new char[len + 1];
m_clientconn->ReadExact(reason, len);
reason[len] = '\0';
// Report error (only once per upload)
if (m_bReportUploadCancel) {
char *errmsg = new char[128 + len];
sprintf(errmsg, "Upload failed: %s", reason);
MessageBox(m_hwndFileTransfer, errmsg, "Upload Failed", MB_ICONEXCLAMATION | MB_OK);
SetWindowText(m_hwndFTStatus, errmsg);
vnclog.Print(1, _T("Upload failed: %s\n"), reason);
m_bReportUploadCancel = FALSE;
delete[] errmsg;
}
delete[] reason;
// Enable dialog
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE);
BlockingFileTransferDialog(TRUE);
}
void
FileTransfer::ReadDownloadFailed()
{
// We'll report the error only if we're actually downloading
BOOL downloadActive = m_bDownloadStarted;
// Stop file transfer
CloseUndoneFileTransfers();
// Read the message
rfbFileDownloadFailedMsg msg;
m_clientconn->ReadExact((char *)&msg, sz_rfbFileDownloadFailedMsg);
int len = Swap16IfLE(msg.reasonLen);
char *reason = new char[len + 1];
m_clientconn->ReadExact(reason, len);
reason[len] = '\0';
// Report error
if (downloadActive) {
char *errmsg = new char[128 + len];
sprintf(errmsg, "Download failed: %s", reason);
MessageBox(m_hwndFileTransfer, errmsg, "Download Failed", MB_ICONEXCLAMATION | MB_OK);
SetWindowText(m_hwndFTStatus, errmsg);
vnclog.Print(1, _T("Download failed: %s\n"), reason);
delete[] errmsg;
}
delete[] reason;
// Enable dialog
EnableWindow(GetDlgItem(m_hwndFileTransfer, IDC_FTCANCEL), FALSE);
BlockingFileTransferDialog(TRUE);
}
unsigned int FileTransfer::FiletimeToTime70(FILETIME ftime)
{
LARGE_INTEGER uli;
uli.LowPart = ftime.dwLowDateTime;
uli.HighPart = ftime.dwHighDateTime;
uli.QuadPart = (uli.QuadPart - 116444736000000000) / 10000000;
return uli.LowPart;
}
void FileTransfer::Time70ToFiletime(unsigned int time70, FILETIME *pftime)
{
LONGLONG ll = Int32x32To64(time70, 10000000) + 116444736000000000;
pftime->dwLowDateTime = (DWORD) ll;
pftime->dwHighDateTime = (DWORD)(ll >> 32);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?