📄 filetransfer.cpp
字号:
{
// vnclog.Print(0, VNCLOG(_T("ListRemoteDrives")));
TCHAR szDrivesList[256]; // Format when filled : "C:t<NULL>D:t<NULL>....Z:t<NULL><NULL>"
TCHAR szDrive[4];
TCHAR szTheDrive[128];
TCHAR szType[32];
int nIndex = 0;
if (nLen > sizeof(szDrivesList)) return;
m_pCC->ReadString((char *)szDrivesList, nLen);
HWND hWndRemoteList = GetDlgItem(hWnd, IDC_REMOTE_FILELIST);
SendDlgItemMessage(hWnd, IDC_REMOTE_DRIVECB, LB_RESETCONTENT, 0, 0L);
ListView_DeleteAllItems(hWndRemoteList);
SetDlgItemText(hWnd, IDC_CURR_REMOTE, "");
// Fill the tree with the remote drives
while (nIndex < nLen - 3)
{
strcpy(szDrive, szDrivesList + nIndex);
nIndex += 4;
// Get the type of drive
switch (szDrive[2])
{
case 'l':
sprintf(szType, "%s", "Local Disk");
break;
case 'f':
sprintf(szType, "%s", "Removable");
break;
case 'c':
sprintf(szType, "%s", "CD-ROM");
break;
case 'n':
sprintf(szType, "%s", "Network");
break;
default:
sprintf(szType, "%s", "Unknown");
break;
}
szDrive[2] = '\0'; // remove the type char
sprintf(szTheDrive, "%s%s%s", rfbDirPrefix, szDrive, rfbDirSuffix);
LVITEM Item;
Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.iImage = 2;
Item.pszText = szTheDrive;
Item.lParam = FILE_ATTRIBUTE_DEVICE;;
int nItem = ListView_InsertItem(hWndRemoteList, &Item);
Item.mask = LVIF_TEXT | LVIF_PARAM;
Item.iItem = nItem;
Item.iSubItem = 1;
Item.pszText = szType;
Item.lParam = FILE_ATTRIBUTE_DEVICE;
ListView_SetItem(hWndRemoteList, &Item);
// Prepare it for Combo Box and add it
strcat(szTheDrive, " - ");
strcat(szTheDrive, szType);
SendMessage(GetDlgItem(hWnd, IDC_REMOTE_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szTheDrive);
}
// List the usual shorcuts
if (!m_fOldFTProtocole)
{
char szGUIDir[64];
// MyDocuments
LVITEM Item;
Item.mask = LVIF_TEXT | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.lParam = FILE_ATTRIBUTE_DIRECTORY;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "My Documents", rfbDirSuffix);
Item.pszText = szGUIDir; // Todo: Fr/De
ListView_InsertItem(hWndRemoteList, &Item);
SendMessage(GetDlgItem(hWnd, IDC_REMOTE_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szGUIDir);
// Desktop
Item.mask = LVIF_TEXT | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.lParam = FILE_ATTRIBUTE_DIRECTORY;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Desktop", rfbDirSuffix);
Item.pszText = szGUIDir; // Todo: Fr/De
ListView_InsertItem(hWndRemoteList, &Item);
SendMessage(GetDlgItem(hWnd, IDC_REMOTE_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szGUIDir);
Item.mask = LVIF_TEXT | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.lParam = FILE_ATTRIBUTE_DIRECTORY;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Network Favorites", rfbDirSuffix);
Item.pszText = szGUIDir; // Todo: Fr/De
ListView_InsertItem(hWndRemoteList, &Item);
SendMessage(GetDlgItem(hWnd, IDC_REMOTE_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szGUIDir);
}
SendMessage(GetDlgItem(hWnd, IDC_REMOTE_DRIVECB), CB_SETCURSEL, -1, 0);
static LISTVIEWSORTPARAMS sort;
sort.hWndLV = hWndRemoteList;
sort.nColumn = 0;
sort.bAscending = true;
ListView_SortItemsEx(hWndRemoteList, ListViewFileCompareFunc, (LPARAM)&sort);
}
//
// List local drives
//
void FileTransfer::ListDrives(HWND hWnd)
{
// vnclog.Print(0, VNCLOG(_T("ListDrives")));
TCHAR szDrivesList[256]; // Format when filled : "C:\<NULL>D:\<NULL>....Z:\<NULL><NULL>"
TCHAR szDrive[4];
TCHAR szTheDrive[32];
TCHAR szType[32];
UINT nType = 0;
DWORD dwLen;
int nIndex = 0;
dwLen = GetLogicalDriveStrings(256, szDrivesList);
HWND hWndLocalList = GetDlgItem(hWnd, IDC_LOCAL_FILELIST);
SendDlgItemMessage(hWnd, IDC_LOCAL_DRIVECB, LB_RESETCONTENT, 0, 0L);
ListView_DeleteAllItems(hWndLocalList);
SetDlgItemText(hWnd, IDC_CURR_LOCAL, "");
// Parse the list of drives
while (nIndex < dwLen - 3)
{
strcpy(szDrive, szDrivesList + nIndex);
nIndex += 4;
szDrive[2] = '\0'; // remove the '\'
sprintf(szTheDrive, "%s%s%s", rfbDirPrefix, szDrive, rfbDirSuffix);
// szName[0] = '\0';
szType[0] = '\0';
strcat(szDrive, "\\");
// GetVolumeInformation(szDrive, szName, sizeof(szName), NULL, NULL, NULL, NULL, NULL);
// Get infos on the Drive (type and Name)
nType = GetDriveType(szDrive);
switch (nType)
{
case DRIVE_FIXED:
sprintf(szType, "%s", "Local Disk");
break;
case DRIVE_REMOVABLE:
sprintf(szType, "%s", "Removable");
break;
case DRIVE_CDROM:
sprintf(szType, "%s", "CD-ROM");
break;
case DRIVE_REMOTE:
sprintf(szType, "%s", "Network");
break;
default:
sprintf(szType, "%s", "Unknown");
break;
}
// Add it to the ListView
LVITEM Item;
Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.iImage = 2;
Item.lParam = FILE_ATTRIBUTE_DEVICE;
Item.pszText = szTheDrive;
int nItem = ListView_InsertItem(hWndLocalList, &Item);
Item.mask = LVIF_TEXT;
Item.iItem = nItem;
Item.iSubItem = 1;
Item.pszText = szType;
ListView_SetItem(hWndLocalList, &Item);
// Prepare it for Combo Box and add it
strcat(szTheDrive, " - ");
strcat(szTheDrive, szType);
SendMessage(GetDlgItem(hWnd, IDC_LOCAL_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szTheDrive);
}
BOOL personateState = vncService::BeginImpersonation();
// List the usual shorcuts
char szGUIDir[64];
// MyDocuments
LVITEM Item;
Item.mask = LVIF_TEXT | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.lParam = FILE_ATTRIBUTE_DIRECTORY;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "My Documents", rfbDirSuffix);
Item.pszText = szGUIDir; // Todo: Fr/De
ListView_InsertItem(hWndLocalList, &Item);
SendMessage(GetDlgItem(hWnd, IDC_LOCAL_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szGUIDir);
// Desktop
Item.mask = LVIF_TEXT | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.lParam = FILE_ATTRIBUTE_DIRECTORY;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Desktop", rfbDirSuffix);
Item.pszText = szGUIDir; // Todo: Fr/De
ListView_InsertItem(hWndLocalList, &Item);
SendMessage(GetDlgItem(hWnd, IDC_LOCAL_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szGUIDir);
// MyDocuments
Item.mask = LVIF_TEXT | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.lParam = FILE_ATTRIBUTE_DIRECTORY;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Network Favorites", rfbDirSuffix);
Item.pszText = szGUIDir; // Todo: Fr/De
ListView_InsertItem(hWndLocalList, &Item);
SendMessage(GetDlgItem(hWnd, IDC_LOCAL_DRIVECB), CB_ADDSTRING, 0, (LPARAM)szGUIDir);
SendMessage(GetDlgItem(hWnd, IDC_LOCAL_DRIVECB), CB_SETCURSEL, -1, 0);
if (personateState)
vncService::EndImpersonation();
static LISTVIEWSORTPARAMS sort;
sort.hWndLV = hWndLocalList;
sort.nColumn = 0;
sort.bAscending = true;
ListView_SortItemsEx(hWndLocalList, ListViewFileCompareFunc, (LPARAM)&sort);
}
//
// Set gauge max value
//
void FileTransfer::SetTotalSize(HWND hWnd, DWORD dwTotalSize)
{
// vnclog.Print(0, VNCLOG(_T("SetTotalSize")));
SendDlgItemMessage(hWnd, IDC_PROGRESS, PBM_SETPOS, (WPARAM)0, (LPARAM)0L);
SendDlgItemMessage(hWnd, IDC_PROGRESS, PBM_SETRANGE, (WPARAM)0, MAKELPARAM(0, m_nBlockSize));
}
//
// Set gauge value
//
void FileTransfer::SetGauge(HWND hWnd, __int64 dwCount)
{
// vnclog.Print(0, VNCLOG(_T("SetGauge")));
DWORD dwSmallerCount = (DWORD)(dwCount / m_nBlockSize);
DWORD dwSmallerFileSize = (DWORD)(m_nnFileSize / m_nBlockSize);
if (dwSmallerFileSize == 0) dwSmallerFileSize = 1;
DWORD dwValue = (DWORD)( (((__int64)(dwSmallerCount) * m_nBlockSize / dwSmallerFileSize)));
if (dwValue != m_dwCurrentValue)
{
SendDlgItemMessage(hWnd, IDC_PROGRESS, PBM_SETPOS, dwValue, 0);
m_dwCurrentValue = dwValue;
}
DWORD dwPercent = (DWORD)(((__int64)(dwSmallerCount) * 100 / dwSmallerFileSize));
if (dwPercent != m_dwCurrentPercent)
{
char szPercent[5];
sprintf(szPercent, "%d%%", dwPercent);
SetDlgItemText(hWnd, IDC_PERCENT, szPercent);
m_dwCurrentPercent = dwPercent;
}
}
//
// Display global progress (ratio files transfered/Total Files To transfer)
//
void FileTransfer::SetGlobalCount()
{
// vnclog.Print(0, VNCLOG(_T("SetGlobalCount")));
char szGlobal[64];
wsprintf(szGlobal,
"File %d/%d",
m_nFilesTransfered,
m_nFilesToTransfer
);
SetDlgItemText(hWnd, IDC_GLOBAL_STATUS, szGlobal);
}
//
// Display current status and add it to the history combo box
//
void FileTransfer::SetStatus(LPSTR szStatus)
{
// vnclog.Print(0, VNCLOG(_T("SetStatus")));
// time_t lTime;
char dbuffer [9];
char tbuffer [9];
char szHist[255 + 64];
SetDlgItemText(hWnd, IDC_STATUS, szStatus);
_tzset();
// time(&lTime);
_strdate(dbuffer);
_strtime(tbuffer);
sprintf(szHist, " > %s %s - %s", dbuffer, tbuffer/*ctime(&lTime)*/, szStatus);
LRESULT Index = SendMessage(GetDlgItem(hWnd, IDC_HISTORY), LB_ADDSTRING, 0, (LPARAM)szHist);
SendMessage(GetDlgItem(hWnd, IDC_HISTORY), LB_SETCURSEL, (WPARAM)Index, (LPARAM)0);
}
//
// Request a file
//
void FileTransfer::RequestRemoteFile()
{
// vnclog.Print(0, VNCLOG(_T("RequestRemoteFile")));
if (!m_fFTAllowed) return;
//// Ensure Backward FT compatibility (Directory reception)....
//if (m_fOldFTProtocole)
//{
// char* p1 = strrchr(szRemoteFileName, '\\') + 1;
// char* p2 = strrchr(szRemoteFileName, rfbDirSuffix[0]);
// if (
// p1[0] == rfbDirPrefix[0] && p1[1] == rfbDirPrefix[1] // Check dir prefix
// && p2[0] == rfbDirSuffix[0] && p2[1] == rfbDirSuffix[1] && p2 != NULL && p1 < p2 // Check dir suffix
// ) //
// {
// // p1 = strrchr(szRemoteFileName, '\\') + 1;
// char szDirectoryName[MAX_PATH];
// strcpy(szDirectoryName, p1 + 2); // Skip dir prefix (2 chars)
// szDirectoryName[strlen(szDirectoryName) - 2] = '\0'; // Remove dir suffix (2 chars)
// *p1 = '\0';
// strcat(szRemoteFileName, "("),
// strcat(szRemoteFileName, szDirectoryName);
// strcat(szRemoteFileName, ")");
// }
//}
// TODO : hook error !
rfbFileTransferMsg ft;
ft.type = rfbFileTransfer;
ft.contentType = rfbFileTransferRequest;
ft.contentParam = 0;
ft.length = Swap32IfLE(m_iFile->sourceFile.length());
ft.size = (m_pCC->kbitsPerSecond > 2048) ? Swap32IfLE(0) : Swap32IfLE(1); // 1 means "Enable compression"
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
m_pCC->WriteExact((char *)m_iFile->sourceFile.c_str(), m_iFile->sourceFile.length());
return;
}
//
// Receive a file
//
bool FileTransfer::ReceiveFile(unsigned long lSize, int nLen)
{
// vnclog.Print(0, VNCLOG(_T("ReceiveFile")));
if (!m_fFTAllowed) return false;
int fError = false;
rfbFileTransferMsg ft;
ft.type = rfbFileTransfer;
ft.contentType = rfbFileHeader;
ft.size = Swap32IfLE(0);
ft.length = Swap32IfLE(0);
char *szRemoteFileName = new char [nLen+1];
if (szRemoteFileName == NULL) return false;
memset(szRemoteFileName, 0, nLen+1);
// Read in the Name of the file to copy (remote full name !)
m_pCC->ReadExact(szRemoteFileName, nLen);
char szStatus[512];
// If lSize = -1 (0xFFFFFFFF) that means that the Src file on the remote machine
// could not be opened for some reason (locked, doesn't exits any more...)
if (lSize == -1)
{
sprintf(szStatus, " %s < %s > %s", sz_H12, szRemoteFileName, sz_H13);
// SetDlgItemText(pFileTransfer->hWnd, IDC_STATUS, szStatus);
SetStatus(szStatus);
delete [] szRemoteFileName;
return false;
}
// sf@2004 - The file size can be wrong for huge files (>4Gb)
// idealy we should pass another param (sizeH) in the rfbFileTransfer msg (same thing
// for the Date/Time) but we want to maintain backward compatibility between all Ultra V1 RC version..
// So instead we pass the additionnal High size param after the received string...of the current msg
// Parse the FileTime and isolate filename
CARD32 sizeH = 0;
if (!m_fOldFTProtocole)
{
CARD32 sizeHtmp;
m_pCC->ReadExact((char*)&sizeHtmp, sizeof(CARD32));
sizeH = Swap32IfLE(sizeHtmp);
}
char *p = strrchr(szRemoteFileName, ',');
if (p == NULL)
m_szIncomingFileTime[0] = '\0';
else
{
strcpy(m_szIncomingFileTime, p+1);
*p = '\0';
}
// Check the free space on local destination drive
bool fErr = false;
ULARGE_INTEGER lpFreeBytesAvailable;
ULARGE_INTEGER lpTotalBytes;
ULARGE_INTEGER lpTotalFreeBytes;
unsigned long dwFreeKBytes;
char *szDestPath = new char [m_iFile->destFile.length() + 1];
memset(szDestPath, 0, m_iFile->destFile.length());
strcpy(szDestPath, (char*)m_iFile->destFile.c_str());
char *pos = strrchr(szDestPath, '\\'); // We don't handle UNCs for now
if(!pos)
{
fErr = true;
}
else
{
*pos = '\0';
PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX)GetProcAddress( GetModuleHandle("kernel32.dll"),"GetDiskFreeSpaceExA");
if (pGetDiskFreeSpaceEx)
{
if (!pGetDiskFreeSpaceEx((LPCTSTR)szDestPath,
&lpFreeBytesAvailable,
&lpTotalBytes,
&lpTotalFreeBytes)) fErr = true;
}
dwFreeKBytes = (unsigned long) (Int64ShraMod32(lpFreeBytesAvailable.QuadPart, 10));
if (dwFreeKBytes < (unsigned long)(lSize / 1000)) fErr = true;
}
delete [] szDestPath;
if (fErr)
{
sprintf(szStatus, " %s < %s >",sz_H14, strrchr(szRemoteFileName, '\\') + 1);
SetStatus(szStatus);
delete [] szRemoteFileName;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -