📄 filetransfer.cpp
字号:
// Tell the server to cancel the transfer
ft.size = Swap32IfLE(-1);
if (m_fOldFTProtocole)
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg);
else
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
return false;
}
m_nnFileSize = (((__int64)(sizeH)) << 32) + lSize;
char szFFS[96];
GetFriendlyFileSizeString(m_nnFileSize, szFFS);
sprintf(szStatus, " %s < %s > (%s) <<<",
sz_H15, m_iFile->destFile.c_str(), szFFS/*, szRemoteFileName*/);
SetStatus(szStatus);
SetTotalSize(hWnd, lSize); // In bytes
SetGauge(hWnd, 0); // In bytes
UpdateWindow(hWnd);
// Create the local Destination file
m_hDestFile = CreateFile(m_iFile->destFile.c_str(),
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
// sf@2004 - Delta Transfer
// DWORD dwErr = GetLastError();
bool fAlreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);
if (m_hDestFile == INVALID_HANDLE_VALUE)
{
sprintf(szStatus, " %s < %s > %s", sz_H12, m_iFile->destFile.c_str(), sz_H16);
SetStatus(szStatus);
if (m_hDestFile != INVALID_HANDLE_VALUE)
CloseHandle(m_hDestFile);
m_hDestFile = INVALID_HANDLE_VALUE;
delete [] szRemoteFileName;
// Tell the server to cancel the transfer
ft.size = Swap32IfLE(-1);
if (m_fOldFTProtocole)
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg);
else
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
return false;
}
delete [] szRemoteFileName;
m_pCC->CheckFileChunkBufferSize(m_nBlockSize + 1024);
// sf@2004 - Delta Transfer
if (fAlreadyExists && !m_fOldFTProtocole)
{
// DWORD dwFileSize = GetFileSize(m_hDestFile, NULL);
ULARGE_INTEGER n2FileSize;
bool bSizeOk = MyGetFileSize((char*)m_iFile->destFile.c_str(), &n2FileSize);
// if (dwFileSize != 0xFFFFFFFF)
if (bSizeOk)
{
unsigned long nCSBufferSize = (4 * (unsigned long)(n2FileSize.QuadPart / m_nBlockSize)) + 1024;
char* lpCSBuff = new char [nCSBufferSize];
if (lpCSBuff != NULL)
{
int nCSBufferLen = GenerateFileChecksums( m_hDestFile,
lpCSBuff,
nCSBufferSize
);
if (nCSBufferLen != -1)
{
//sprintf(szStatus, " Sending %d bytes of file checksums to remote machine. Please Wait...", nCSBufferSize);
//SetStatus(szStatus);
rfbFileTransferMsg ftm;
ftm.type = rfbFileTransfer;
ftm.contentType = rfbFileChecksums;
ftm.size = Swap32IfLE(nCSBufferSize);
ftm.length = Swap32IfLE(nCSBufferLen);
m_pCC->WriteExact((char *)&ftm, sz_rfbFileTransferMsg, rfbFileTransfer);
m_pCC->WriteExact((char *)lpCSBuff, nCSBufferLen);
}
delete []lpCSBuff;
}
}
}
// Tell the server that the transfer can start
ft.size = Swap32IfLE(lSize);
if (m_fOldFTProtocole)
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg);
else
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
// DWORD dwNbPackets = (DWORD)(lSize / m_nBlockSize);
m_dwNbReceivedPackets = 0;
m_dwNbBytesWritten = 0;
m_dwTotalNbBytesWritten = 0;
m_dwTotalNbBytesNotReallyWritten = 0;
m_nPacketCount = 0;
m_fPacketCompressed = true;
m_fFileDownloadError = false;
m_fFileDownloadRunning = true;
// FT Backward compatibility DIRTY hack for DSMPlugin mode...
if (m_fOldFTProtocole && m_pCC->m_fUsePlugin)
{
m_pCC->m_nTO = 0;
ProcessFileTransferMsg();
}
return true;
}
//
// Receive incoming file chunk
//
bool FileTransfer::ReceiveFileChunk(int nLen, int nSize)
{
// vnclog.Print(0, VNCLOG(_T("ReceiveFileChunk")));
if (!m_fFileDownloadRunning) return false;
if (m_fFileDownloadError)
FinishFileReception();
BOOL fRes = true;
bool fAlreadyHere = (nSize == 2);
m_fPacketCompressed = true; // sf@2005 - This missing line was causing RC19 file reception bug...
if (nLen > m_pCC->m_filechunkbufsize) return false;
// sf@2004 - Delta Transfer - Empty packet
if (fAlreadyHere)
{
DWORD dwPtr = SetFilePointer(m_hDestFile, nLen, NULL, FILE_CURRENT);
if (dwPtr == 0xFFFFFFFF)
fRes = false;
}
else
{
try{
m_pCC->ReadExact((char *)m_pCC->m_filechunkbuf, nLen);
} catch (QuietException)
{
m_fFileDownloadError = true;
return false;
}
if (nSize == 0)
m_fPacketCompressed = false;
unsigned int nRawBytes = m_nBlockSize + 1024;
if (m_fPacketCompressed)
{
// Decompress incoming data
m_pCC->CheckFileZipBufferSize(nRawBytes);
int nRetU = uncompress( (unsigned char*)m_pCC->m_filezipbuf,// Dest
(unsigned long *)&nRawBytes,// Dest len
(unsigned char*)m_pCC->m_filechunkbuf, // Src
nLen // Src len
);
if (nRetU != 0)
{
// vnclog.Print(0, VNCLOG(_T("uncompress error in ReceiveFile: %d")), nRet);
m_fFileDownloadError = true;
// break;
}
Sleep(5);
}
fRes = WriteFile(m_hDestFile,
m_fPacketCompressed ? m_pCC->m_filezipbuf : m_pCC->m_filechunkbuf,
m_fPacketCompressed ? nRawBytes : nLen,
&m_dwNbBytesWritten,
NULL);
}
if (!fRes)
{
// TODO: Ask the server to stop the transfer
m_fFileDownloadError = true;
}
m_dwTotalNbBytesWritten += (fAlreadyHere ? nLen : m_dwNbBytesWritten);
m_dwTotalNbBytesNotReallyWritten += (fAlreadyHere ? nLen : 0);
m_dwNbReceivedPackets++;
// Refresh of the progress bar
SetGauge(hWnd, m_dwTotalNbBytesWritten);
PseudoYield(GetParent(hWnd));
// We still support the *dirty* old "Abort" method (for backward compatibility wirh UltraVNC Servers <=RC18)
if (m_fOldFTProtocole)
{
// Every 10 packets, test if the transfer must be stopped
m_nPacketCount++;
if (m_nPacketCount > 10)
{
m_fAborted = true;
rfbFileTransferMsg ft;
ft.type = rfbFileTransfer;
ft.contentType = rfbFilePacket;
ft.contentParam = 0;
ft.length = 0;
if (m_fAbort || m_fFileDownloadError)
{
// Ask the server to stop the transfer
ft.size = Swap32IfLE(-1);
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg/*, rfbFileTransfer*/);
}
else
{
// Tell the server to continue the transfer
ft.size = Swap32IfLE(0);
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg/*, rfbFileTransfer*/);
}
m_nPacketCount = 0;
}
}
else // New V2 FT Protocole
{
// Now abort the file transfer if required by the user
if (m_fAbort && !m_fAborted)
{
m_fAborted = true;
rfbFileTransferMsg ft;
ft.type = rfbFileTransfer;
ft.contentType = rfbAbortFileTransfer;
ft.contentParam = 0;
ft.length = 0;
ft.size = 0;
m_pCC->WriteExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
}
}
// FT Backward compatibility DIRTY hack for DSMPlugin mode...
if (m_fOldFTProtocole && m_pCC->m_fUsePlugin)
{
m_pCC->m_nTO = 0;
ProcessFileTransferMsg();
}
return true;
}
//
// Finish File Download
//
bool FileTransfer::FinishFileReception()
{
// vnclog.Print(0, VNCLOG(_T("FinishFileReception")));
if (!m_fFileDownloadRunning) return false;
m_fFileDownloadRunning = false;
// sf@2004 - Delta transfer
SetEndOfFile(m_hDestFile);
// TODO : check dwNbReceivedPackets and dwTotalNbBytesWritten or test a checksum
FlushFileBuffers(m_hDestFile);
char szStatus[512];
if (m_FilesList.size() > 0)
{
/*check for invalid m_FileList
some routines clear the list.
Before an error occured because HighlightTransferedFiles cleared the list.
*/
try
{
if (m_iFile == m_FilesList.end())
m_iFile--; //throws error if m_FileList.size is zero
if (m_fFileDownloadError)
sprintf(szStatus, " %s < %s > %s", sz_H19,m_iFile->destFile.c_str(),sz_H20);
else
sprintf(szStatus, " %s < %s > %s", sz_H17, m_iFile->destFile.c_str(),sz_H18);
}
catch (...)
{
sprintf(szStatus, " %s < ?? > %s", sz_H19,sz_H20);
}
}
SetStatus(szStatus);
// Set the DestFile Time Stamp
if (strlen(m_szIncomingFileTime))
{
FILETIME DestFileTime;
SYSTEMTIME FileTime;
FileTime.wMonth = atoi(m_szIncomingFileTime);
FileTime.wDay = atoi(m_szIncomingFileTime + 3);
FileTime.wYear = atoi(m_szIncomingFileTime + 6);
FileTime.wHour = atoi(m_szIncomingFileTime + 11);
FileTime.wMinute = atoi(m_szIncomingFileTime + 14);
FileTime.wMilliseconds = 0;
FileTime.wSecond = 0;
SystemTimeToFileTime(&FileTime, &DestFileTime);
// ToDo: hook error
SetFileTime(m_hDestFile, &DestFileTime, &DestFileTime, &DestFileTime);
}
if (m_hDestFile != INVALID_HANDLE_VALUE)
CloseHandle(m_hDestFile);
m_hDestFile = INVALID_HANDLE_VALUE;
// sf@2004 - Delta Transfer - Now we can keep the existing file data :)
if (m_fFileDownloadError && m_fOldFTProtocole) DeleteFile(m_iFile->destFile.c_str());
// sf@2003 - Directory Transfer trick
// If the file is an Ultra Directory Zip we unzip it here and we delete the
// received file
// Todo: make a better free space check (above) in this particular case. The free space must be at least
// 3 times the size of the directory zip file (this zip file is ~50% of the real directory size)
//UnzipPossibleDirectory(m_szDestFileName);
// SetStatus(szStatus);
UpdateWindow(hWnd);
// Sound notif
// MessageBeep(-1);
// Request the next file in the list
RequestNextFile();
return true;
}
//
// Unzip possible directory
// Todo: handle unzip error correctly...
//
//int FileTransfer::UnzipPossibleDirectory(LPSTR szFileName)
//{
//// vnclog.Print(0, VNCLOG(_T("UnzipPossibleDirectory")));
// if (!m_fFileDownloadError
// &&
// !strncmp(strrchr(szFileName, '\\') + 1, rfbZipDirectoryPrefix, strlen(rfbZipDirectoryPrefix))
// )
// {
// char szStatus[512];
// char szPath[MAX_PATH + MAX_PATH];
// char szDirName[MAX_PATH]; // Todo: improve this (size)
// strcpy(szPath, szFileName);
// // Todo: improve all this (p, p2, p3 NULL test or use a standard substring extraction function)
// char *p = strrchr(szPath, '\\') + 1;
// char *p2 = strchr(p, '-') + 1; // rfbZipDirectoryPrefix MUST have a "-" at the end...
// strcpy(szDirName, p2);
// char *p3 = strrchr(szDirName, '.');
// *p3 = '\0';
// if (p != NULL) *p = '\0';
// strcat(szPath, szDirName);
//
// // Create the Directory
// sprintf(szStatus, " %s < %s > %s", sz_H59 , szDirName, sz_H60);
// SetStatus(szStatus);
//
// bool fUnzip = m_pZipUnZip->UnZipDirectory(szPath, szFileName);
// if (fUnzip)
// sprintf(szStatus, " %s < %s > %s", sz_H61, szDirName, sz_H18);
// else
// sprintf(szStatus, " %s < %s >. %s", sz_H62, szDirName, sz_H63);
// SetStatus(szStatus);
// DeleteFile(szFileName);
// }
// return 0;
//}
//
// Finish File Download
//
bool FileTransfer::AbortFileReception()
{
// vnclog.Print(0, VNCLOG(_T("AbortFileReception")));
if (!m_fFileDownloadRunning) return false;
m_fFileDownloadError = true;
FlushFileBuffers(m_hDestFile);
char szStatus[512];
sprintf(szStatus, " %s < %s > %s", sz_H19, m_iFile->destFile.c_str(),sz_H20);
m_fFileDownloadRunning = false;
return true;
}
//
// Offer a file
//
bool FileTransfer::OfferLocalFile()
{
// vnclog.Print(0, VNCLOG(_T("OfferLocalFile")));
if (!m_fFTAllowed) return false;
char szStatus[512];
if(m_iFile->sourceFile[m_iFile->sourceFile.length()-1] == '\\')
{
CreateRemoteDirectory((char*)m_iFile->destFile.c_str());
m_fCreateDirPending = true;
return true;
}
// Open local src file
m_hSrcFile = CreateFile(
m_iFile->sourceFile.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
if (m_hSrcFile == INVALID_HANDLE_VALUE)
{
sprintf(szStatus, " %s < %s >", sz_H21, m_iFile->sourceFile.c_str());
SetStatus(szStatus);
DWORD TheError = GetLastError();
return false;
}
// Size of src file
ULARGE_INTEGER n2SrcSize;
bool bSize = MyGetFileSize((char*)m_iFile->sourceFile.c_str(), &n2SrcSize);
// if (dwSrcSize == -1)
if (!bSize)
{
sprintf(szStatus, " %s < %s >", sz_H21, m_iFile->sourceFile.c_str());
SetStatus(szStatus);
if (m_hSrcFile != INVALID_HANDLE_VALUE)
CloseHandle(m_hSrcFile);
m_hSrcFile = INVALID_HANDLE_VALUE;
return false;
}
char szFFS[96];
GetFriendlyFileSizeString(n2SrcSize.QuadPart, szFFS);
sprintf(szStatus, " %s < %s > (%s) >>>", sz_H22, m_iFile->sourceFile.c_str(), szFFS);
SetStatus(szStatus);
m_nnFileSize = n2SrcSize.QuadPart;
SetTotalSize(hWnd, (DWORD)m_nnFileSize); // In bytes
SetGauge(hWnd, 0); // In bytes
UpdateWindow(hWnd);
// Add the File Time Stamp to the filename
FILETIME SrcFileModifTime;
BOOL fRes = GetFileTime(m_hSrcFile, NULL, NULL, &SrcFileModifTime);
if (!fRes)
{
sprintf(szStatus, " %s < %s >", sz_H23, m_iFile->sourceFile.c_str());
SetS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -