📄 filetransfer.cpp
字号:
SetDlgItemText(hWnd, IDC_REMOTE_STATUS, sz_H2);
SetStatus(sz_H3);
DisableButtons(hWnd);
//forces the abort button to be shown, so a user can redisplay the remote directory content.
//see IDC_ABORT_B for this button click event
ShowWindow(GetDlgItem(hWnd, IDCANCEL), SW_SHOW);
}
else
{
m_fFTAllowed = true;
RequestRemoteDrives();
SetStatus(sz_H4);
}
return true;
}
//
// Receive all the files that are referenced in m_FilesList
//
bool FileTransfer::ReceiveFiles(unsigned long lSize, int nLen)
{
// vnclog.Print(0, VNCLOG(_T("ReceiveFiles")));
// Receive the incoming file
m_nFilesTransfered++;
SetGlobalCount();
if (!ReceiveFile(lSize, nLen))
RequestNextFile();
return true;
}
//
// A file has just been received
// Request the following one if any
//
bool FileTransfer::RequestNextFile()
{
// vnclog.Print(0, VNCLOG(_T("RequestNextFile")));
SetGlobalCount();
m_iFile++; // go to next file in the list of files to receive
// If one more file has to be received, ask for it !
if (m_iFile != m_FilesList.end() && !m_fAbort)
{
RequestRemoteFile();
}
else // All the files have been processed and hopefully received
{
FinishRequestFiles();
}
return true;
}
void FileTransfer::FinishRequestFiles()
{
// Refresh the local list so new files are displayed and highlighted
HWND hWndLocalList = GetDlgItem(hWnd, IDC_LOCAL_FILELIST);
ListView_DeleteAllItems(hWndLocalList);
PopulateLocalListBox(hWnd, "");
if (m_fAbort)
SetStatus(sz_H5);
else
SetStatus(sz_H6);
EnableButtons(hWnd);
ShowFileTransferWindow(true);
Sleep(500);
// Unlock
m_fFileCommandPending = false;
}
//
// Send all the files that are referenced in m_FilesList
//
bool FileTransfer::SendFiles(long lSize, int nLen)
{
InitFTTimer(); // sf@2005
// vnclog.Print(0, VNCLOG(_T("SendFiles")));
// Receive the incoming file
m_nFilesTransfered++;
SetGlobalCount();
if (!SendFile(lSize, nLen))
OfferNextFile();
return true;
}
bool FileTransfer::OfferNextFile()
{
// vnclog.Print(0, VNCLOG(_T("OfferNextFile")));
SetGlobalCount();
m_iFile++; // go to next file in the list of files to send
HWND hWndRemoteList = GetDlgItem(hWnd, IDC_REMOTE_FILELIST);
// If one more file has to be sent, offer it !
if (m_iFile != m_FilesList.end() && !m_fAbort)
{
if (!OfferLocalFile())
SendFiles(-1, 0);
}
else // All the files have been processed and hopefully received
{
// Refresh the remote list so new files are displayed and highlighted
ListView_DeleteAllItems(hWndRemoteList);
RequestRemoteDirectoryContent(hWnd, "");
if (m_fAbort)
SetStatus(sz_H7);
else
SetStatus(sz_H6);
EnableButtons(hWnd);
ShowFileTransferWindow(true);
Sleep(1000);
//MessageBeep(-1);
// Unlock
m_fFileCommandPending = false;
KillFTTimer(); // sf@2005
}
return true;
}
//
// Format file size so it is user friendly to read
//
void FileTransfer::GetFriendlyFileSizeString(__int64 Size, char* szText)
{
szText[0] = '\0';
if( Size > (1024*1024*1024) )
{
__int64 lRest = (Size % (1024*1024*1024));
Size /= (1024*1024*1024);
wsprintf(szText,"%u.%2.2lu Gb", (unsigned long)Size, (unsigned long)(lRest * 100 / 1024 / 1024 / 1024));
}
else if( Size > (1024*1024) )
{
unsigned long lRest = (unsigned long)(Size % (1024*1024));
Size /= (1024*1024);
wsprintf(szText,"%u.%2.2lu Mb", (unsigned long)Size, lRest * 100 / 1024 / 1024);
}
else if ( Size > 1024 )
{
unsigned long lRest = (unsigned long)(Size % (1024));
Size /= 1024;
wsprintf(szText,"%u.%2.2lu Kb", (unsigned long)Size, lRest * 100 / 1024);
}
else
{
wsprintf(szText,"%u bytes", (unsigned long)Size);
}
}
//
// GetFileSize() doesn't handle files > 4GBytes...
// GetFileSizeEx() doesn't exist under Win9x...
// So let's write our own function.
//
bool FileTransfer::MyGetFileSize(char* szFilePath, ULARGE_INTEGER *n2FileSize)
{
WIN32_FIND_DATA fd;
HANDLE ff;
SetErrorMode(SEM_FAILCRITICALERRORS); // No popup please !
ff = FindFirstFile(szFilePath, &fd);
SetErrorMode( 0 );
if (ff == INVALID_HANDLE_VALUE)
{
return false;
}
FindClose(ff);
(*n2FileSize).LowPart = fd.nFileSizeLow;
(*n2FileSize).HighPart = fd.nFileSizeHigh;
(*n2FileSize).QuadPart = (((__int64)fd.nFileSizeHigh) << 32 ) + fd.nFileSizeLow;
return true;
}
//
// Add a file line to a ListView
//
void FileTransfer::AddFileToFileList(HWND hWnd, int nListId, WIN32_FIND_DATA& fd, bool fLocalSide)
{
// vnclog.Print(0, VNCLOG(_T("AddFileToFileList")));
char szFileName[MAX_PATH + 2];
HWND hWndList = GetDlgItem(hWnd, nListId);
// If we need to keep more info on the file, we can use LVITEM lParam
// (it will be usefull if we want to make comparison between local and remote files
// for a resume function for instance, or for sorting purposes)
//
// We could also display Files attributes and other Files times...
if (((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY && strcmp(fd.cFileName, "."))
||
(!strcmp(fd.cFileName, ".."))
)
{
sprintf(szFileName, "%s%s%s", rfbDirPrefix, fd.cFileName, rfbDirSuffix);
char szUpDirMask[16];
sprintf(szUpDirMask, "%s..%s", rfbDirPrefix, rfbDirSuffix);
if (!strcmp(szFileName, szUpDirMask) && nListId == IDC_LOCAL_FILELIST)
{
nListId = nListId;
}
// Name
LVITEM Item;
Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.iImage = 0;
Item.pszText = szFileName;
Item.lParam = fd.dwFileAttributes;
int nItem = ListView_InsertItem(hWndList, &Item);
// Type
Item.mask = LVIF_TEXT;
Item.iItem = nItem;
Item.iSubItem = 1;
Item.pszText = "Folder";
ListView_SetItem(hWndList, &Item);
}
else if (strcmp(fd.cFileName, ".")) // Test actually Not necessary for remote list
{
// Name
LVITEM Item;
Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
Item.iItem = 0;
Item.iSubItem = 0;
Item.iImage = 1;
Item.pszText = fd.cFileName;
Item.lParam = fd.dwFileAttributes;
int nItem = ListView_InsertItem(hWndList,&Item);
// Size
__int64 Size = ( ((__int64)fd.nFileSizeHigh) << 32 ) + fd.nFileSizeLow;
char szText[256];
GetFriendlyFileSizeString(Size, szText);
Item.mask = LVIF_TEXT;
Item.iItem = nItem;
Item.iSubItem = 1;
Item.pszText = szText;
ListView_SetItem(hWndList, &Item);
// Last Modif Time
// sf@2003
// For now, we've made the choice off displaying all the files
// off client AND server sides converted in clients local
// time only. So we ALSO convert server's files times in client local time
FILETIME LocalFileTime;
FileTimeToLocalFileTime(&fd.ftLastWriteTime, &LocalFileTime);
SYSTEMTIME FileTime;
FileTimeToSystemTime(fLocalSide ? &LocalFileTime : &LocalFileTime /*&fd.ftLastWriteTime*/, &FileTime);
wsprintf(szText,"%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
FileTime.wMonth,
FileTime.wDay,
FileTime.wYear,
FileTime.wHour,
FileTime.wMinute
);
Item.mask = LVIF_TEXT;
Item.iItem = nItem;
Item.iSubItem = 2;
Item.pszText = szText;
ListView_SetItem(hWndList,&Item);
}
}
//
// Select the new transfered files in the dest FileList so the user find them easely
//
void FileTransfer::HighlightTransferedFiles(HWND hSrcList, HWND hDstList)
{
// vnclog.Print(0, VNCLOG(_T("HighlightTransferedFiles")));
if (m_FilesList.size() > 0)
{
TCHAR szSelectedFile[128];
LVITEM Item;
Item.mask = LVIF_TEXT;
Item.iSubItem = 0;
Item.pszText = szSelectedFile;
Item.cchTextMax = 128;
LVFINDINFO Info;
Info.flags = LVFI_STRING;
Info.psz = (LPSTR)szSelectedFile;
for (m_iFile = m_FilesList.begin();
m_iFile != m_FilesList.end();
m_iFile++)
{
// Get the name of the file sent
Item.iItem = m_iFile->id;
ListView_GetItem(hSrcList, &Item);
// Find this file in the list and highlight it
int nTheIndex = ListView_FindItem(hDstList, -1, &Info);
if (nTheIndex > -1)
{
ListView_SetItemState(hDstList, nTheIndex, LVIS_SELECTED, LVIS_SELECTED);
ListView_EnsureVisible(hDstList, nTheIndex, FALSE);
}
}
//m_FilesList.clear();
/*do not call because
in case of error we use it in FinishFileReception()
otherwise an exception occured
*/
}
}
//
//
//
bool FileTransfer::IsShortcutFolder(LPSTR szPath)
{
// vnclog.Print(0, VNCLOG(_T("IsShortcutFolder")));
// Todo: Cultures Translation
char szGUIDir[64];
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "My Documents", rfbDirSuffix);
if (!strnicmp(szPath, szGUIDir, strlen(szGUIDir)))
return true;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Desktop", rfbDirSuffix);
if (!strnicmp(szPath, szGUIDir, strlen(szGUIDir)))
return true;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Network Favorites", rfbDirSuffix);
if (!strnicmp(szPath, szGUIDir, strlen(szGUIDir)))
return true;
return false;
}
//
//
//
bool FileTransfer::ResolvePossibleShortcutFolder(HWND hWnd, LPSTR szFolder)
{
// vnclog.Print(0, VNCLOG(_T("ResolvePossibleShortcutFolder")));
// TCHAR szP[MAX_PATH];
int nFolder = -1;
char szGUIDir[64];
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "My Documents", rfbDirSuffix);
if (!strnicmp(szFolder, szGUIDir, strlen(szGUIDir)))
nFolder = CSIDL_PERSONAL;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Desktop", rfbDirSuffix);
if (!strnicmp(szFolder, szGUIDir, strlen(szGUIDir)))
nFolder = CSIDL_DESKTOP;
sprintf(szGUIDir, "%s%s%s", rfbDirPrefix, "Network Favorites", rfbDirSuffix);
if (!strnicmp(szFolder, szGUIDir, strlen(szGUIDir)))
nFolder = CSIDL_NETHOOD;
/*
if (!strnicmp(szFolder, "(Net. Shares)", 9))
nFolder = CSIDL_NETWORK;
*/
if (nFolder != -1)
{
// if (SHGetSpecialFolderPath(NULL, szP, nFolder, FALSE))
string sPath;
if (GetSpecialFolderPath(nFolder, sPath,true)) //we do want an user impersonated folder path
{
//strcat(szP,"\\");
sPath += '\\';
SetDlgItemText(hWnd, IDC_CURR_LOCAL, sPath.c_str());
}
return true;
}
return false;
}
/*
struct used by ListViewFileCompareFunc
*/
typedef struct
{
HWND hWndLV; //handle of listview
int nColumn; //column to be sorted
BOOL bAscending; //
} LISTVIEWSORTPARAMS;
/**
* ListViewFileCompareFunc compares two file names of a listview.
* It is called by ListView_SortItemsEx.
* Warning: This callback function only works with the Ex-Version of ListView_SortItemsEx.
* [@author CW]
* [@param lParam1 Contains the value of the first listview item index to be compared]
* [@param lParam2 Contains the value of the second listview item index to be compared]
* [@param lParamSort lParamSort expects LISTVIEWSORTPARAMS struct that is set by ListView_SortItemsEx lParam parameter
If nColumn in LISTVIEWSORTPARAMS is not zero the extended comparing function is not used.]
* [@see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/structures/lvitem.asp]
* [@return See link for return value.]
* precondition : This function must be called by ListView_SortItemsEx. Do not call it by ListView_SortItems.
* postcondition : none
*/
int CALLBACK ListViewFileCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
LISTVIEWSORTPARAMS* pSort;
int nRet = 0;
pSort = (LISTVIEWSORTPARAMS*)lParamSort;
//does not support unicode!
TCHAR sz1[MAX_PATH], sz2[MAX_PATH];
ListView_GetItemText(pSort->hWndLV, lParam1, pSort->nColumn, sz1, MAX_PATH-1);
ListView_GetItemText(pSort->hWndLV, lParam2, pSort->nColumn, sz2, MAX_PATH-1);
LVITEM pItem1;
ZeroMemory(&pItem1,sizeof(LVITEM));
pItem1.mask = LVIF_PARAM; //get lParam value
pItem1.iItem = lParam1;
pItem1.iSubItem = 0;
pItem1.lParam = 0;
ListView_GetItem(pSort->hWndLV,&pItem1);
LVITEM pItem2;
ZeroMemory(&pItem2,sizeof(LVITEM));
pItem2.mask = LVIF_PARAM; //get lParam value
pItem2.iItem = lParam2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -