UltraVNC:C++源码分析远程文件传输界面显示远程端文件系统流程
UltraVNC:C++源码分析远程文件传输界面显示远程端文件系统流程
UltraVNC远程文件传输客户端主要在 FileTransfer.cpp 处理,服务端主要在 vncclient.cpp 处理。
另外这里顺便提一下windows下文件属性结构体 : WIN32_FIND_DATA
前面44个字节表示文件属性。
FILETIME结构持有的64位无符号的文件的日期和时间值。此值表示自1601年1月1日开始的100纳秒为单位的时间。
typedef struct _WIN32_FIND_DATA {DWORD dwFileAttributes; //文件类型,4个字节FILETIME ftCreationTime; // 文件创建时间,8个字节FILETIME ftLastAccessTime; // 文件最后一次访问时间,8个字节FILETIME ftLastWriteTime; // 文件最后一次修改时间,8个字节DWORD nFileSizeHigh; // 文件长度高32位,指向内存地址的指针,一般是0,4个字节DWORD nFileSizeLow; // 文件长度低32位,内存大小,4个字节DWORD dwReserved0; // 系统保留,4个字节DWORD dwReserved1; // 系统保留,4个字节TCHAR cFileName[ MAX_PATH ]; // 长文件名TCHAR cAlternateFileName[ 14 ]; // 8.3格式文件名
} WIN32_FIND_DATA, *PWIN32_FIND_DATA;
第一部分 客户端文件传输界面显示远程端磁盘信息
客户端请求远程端磁盘信息
//
// request the list of remote drives
//
void FileTransfer::RequestRemoteDrives()
{
// vnclog.Print(0, _T("RequestRemoteDrives\n"));if (!m_fFTAllowed) return;// TODO : hook error !rfbFileTransferMsg ft;ft.type = rfbFileTransfer;ft.contentType = rfbDirContentRequest;ft.contentParam = rfbRDrivesList; // List of Remote Drives pleaseft.length = 0;m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);return;
}
服务端接收请求,然后获取系统磁盘信息
获取磁盘信息的接口是 dwLen = GetLogicalDriveStrings(256, szDrivesList);
// The client requests the content of a directory or Drives List
case rfbDirContentRequest:switch (msg.ft.contentParam){// Client requests the List of Local Drivescase rfbRDrivesList:{...}break;// Client requests the content of a directorycase rfbRDirContent:{...}break;}break;
服务端发送系统磁盘信息给客户端
rfbFileTransferMsg ft;
ft.type = rfbFileTransfer;
ft.contentType = rfbDirPacket;
ft.contentParam = rfbADrivesList;
ft.length = Swap32IfLE((int)dwLen);
//adzm 2010-09 - minimize packets. SendExact flushes the queue.
m_socket->SendExactQueue((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
m_socket->SendExact((char *)szDrivesList, (int)dwLen);
客户端接收磁盘信息,并处理 ListRemoteDrives(hWnd, Swap32IfLE(ft.length));
case rfbADrivesList:ListRemoteDrives(hWnd, Swap32IfLE(ft.length));m_fFileCommandPending = false;break;
第二部分 客户端文件传输界面显示远程端某个磁盘内具体信息
客户端请求远程端发送某个磁盘下具体文件夹信息
//
// Request the contents of a remote directory
//
void FileTransfer::RequestRemoteDirectoryContent(HWND hWnd, LPSTR szPath)
{
// vnclog.Print(0, _T("RequestRemoteDirectoryContent\n"));if (!m_fFTAllowed){m_fFileCommandPending = false;return;}char ofDir[MAX_PATH];char ofDirT[MAX_PATH];int nSelected = -1;int nCount = 0;HWND hWndRemoteList = GetDlgItem(hWnd, IDC_REMOTE_FILELIST);ofDir[0] = '\0';ofDirT[0] = '\0';if (lstrlen(szPath) == 0){nCount = ListView_GetItemCount(hWndRemoteList);for (nSelected = 0; nSelected < nCount; nSelected++){if(ListView_GetItemState(hWndRemoteList, nSelected, LVIS_SELECTED) & LVIS_SELECTED){LVITEM Item;Item.mask = LVIF_TEXT;Item.iItem = nSelected;Item.iSubItem = 0;Item.pszText = ofDirT;Item.cchTextMax = MAX_PATH;ListView_GetItem(hWndRemoteList, &Item);break;}}}else{if (!IsShortcutFolder(szPath))szPath[6] = '\0';// szPath always contains a drive letter (X:) or (..)strcpy(ofDirT, szPath);// In the case of (..) we keep the current path intactchar szUpDirMask[16];sprintf(szUpDirMask, "%s..%s", rfbDirPrefix, rfbDirSuffix);if (strcmp(ofDirT, szUpDirMask))SetDlgItemText(hWnd, IDC_CURR_REMOTE, "");}if (nSelected == nCount || lstrlen(ofDirT) == 0){GetDlgItemText(hWnd, IDC_CURR_REMOTE, ofDirT, sizeof(ofDirT));if (strlen(ofDirT) == 0) {m_fFileCommandPending = false;return; }}else{if (ofDirT[0] == rfbDirPrefix[0] && ofDirT[1] == rfbDirPrefix[1]){strncpy(ofDir, ofDirT + 2, strlen(ofDirT) - 3); ofDir[strlen(ofDirT) - 4] = '\0';}else{m_fFileCommandPending = false;return;}GetDlgItemText(hWnd, IDC_CURR_REMOTE, ofDirT, sizeof(ofDirT));if (!_stricmp(ofDir, "..")){ char* p;ofDirT[strlen(ofDirT) - 1] = '\0';p = strrchr(ofDirT, '\\');if (p == NULL){m_fFileCommandPending = false;return;}*p = '\0';}elsestrcat(ofDirT, ofDir);strcat(ofDirT, "\\");SetDlgItemText(hWnd, IDC_CURR_REMOTE, ofDirT);}strcpy(ofDir, ofDirT);// Todo: In case of shortcuts dir, do a translation here !// Select the good drive in the drives combo box (the first time only)int nIndex = SendDlgItemMessage(hWnd, IDC_REMOTE_DRIVECB, CB_GETCURSEL, 0, 0L);if (nIndex == LB_ERR){char szDrive[5];strcpy(szDrive, rfbDirPrefix);strncat(szDrive, ofDir, 2);nIndex = SendDlgItemMessage(hWnd, IDC_REMOTE_DRIVECB, CB_FINDSTRING, -1, (LPARAM)(LPSTR)szDrive); SendDlgItemMessage(hWnd, IDC_REMOTE_DRIVECB, CB_SETCURSEL, nIndex, 0L);}ListView_DeleteAllItems(hWndRemoteList);rfbFileTransferMsg ft;ft.type = rfbFileTransfer;ft.contentType = rfbDirContentRequest;ft.contentParam = rfbRDirContent; // Directory content pleaseft.length = Swap32IfLE(strlen(ofDir));//adzm 2010-09m_pCC->WriteExactQueue((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);m_pCC->WriteExact((char *)ofDir, strlen(ofDir));return;
}
服务端接收请求,然后获取文件夹信息
// The client requests the content of a directory or Drives List
case rfbDirContentRequest:switch (msg.ft.contentParam){// Client requests the List of Local Drivescase rfbRDrivesList:{...}break;// Client requests the content of a directorycase rfbRDirContent:{...}break;}break;
获取文件夹内容主要方法
WIN32_FIND_DATA fd;
HANDLE ff;
BOOL fRet = TRUE;ff = FindFirstFile(szDir, &fd);
while ( fRet )
{.../*这里依次把文件夹下每个文件或者目录信息发送到客户端*/....fRet = FindNextFile(ff, &fd);
}
FindClose(ff);
最后服务端发送结束标志
// End of the transfer
ft.contentParam = 0;
ft.length = Swap32IfLE(0);
m_socket->SendExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
客户端接收服务端文件夹信息,这里有两个函数
PopulateRemoteListBox(hWnd, Swap32IfLE(ft.length)); 更新文件传输界面远程端显示的当前目录
ReceiveDirectoryItem(hWnd, Swap32IfLE(ft.length));更新文件传输界面远程端显示具体目录信息
case rfbDirPacket:switch (ft.contentParam){// Response to a rfbRDrivesList requestcase rfbADrivesList:ListRemoteDrives(hWnd, Swap32IfLE(ft.length));m_fFileCommandPending = false;break;// Response to a rfbRDirContent request case rfbADirectory:case rfbAFile:if (!m_fDirectoryReceptionRunning)PopulateRemoteListBox(hWnd, Swap32IfLE(ft.length));elseReceiveDirectoryItem(hWnd, Swap32IfLE(ft.length));break;default: // This is bad. Add rfbADirectoryEnd instead...if (m_fDirectoryReceptionRunning){FinishDirectoryReception();m_fFileCommandPending = false;}break;}break;
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
