📄 vncclient.cpp
字号:
m_client->m_fPalmVNCScaling = true;
case rfbSetScale: // Specific PalmVNC SetScaleFactor
{
// m_client->m_fPalmVNCScaling = false;
// Read the rest of the message
if (m_client->m_fPalmVNCScaling)
{
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbPalmVNCSetScaleFactorMsg - nTO))
{
connected = FALSE;
break;
}
}
else
{
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetScaleMsg - nTO))
{
connected = FALSE;
break;
}
}
// Only accept reasonable scales...
if (msg.ssc.scale < 1 || msg.ssc.scale > 9) break;
m_client->m_nScale = msg.ssc.scale;
{
omni_mutex_lock l(m_client->GetUpdateLock());
if (!m_client->m_encodemgr.m_buffer->SetScale(msg.ssc.scale))
{
connected = FALSE;
break;
}
m_client->fNewScale = true;
InvalidateRect(NULL,NULL,TRUE);
m_client->TriggerUpdateThread();
}
}
break;
// Set Server Input
case rfbSetServerInput:
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetServerInputMsg - nTO))
{
connected = FALSE;
break;
}
if (m_client->m_keyboardenabled)
{
if (msg.sim.status==1) m_client->m_encodemgr.m_buffer->m_desktop->SetDisableInput(true);
if (msg.sim.status==0) m_client->m_encodemgr.m_buffer->m_desktop->SetDisableInput(false);
}
break;
// Set Single Window
case rfbSetSW:
if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetSWMsg - nTO))
{
connected = FALSE;
break;
}
if (Swap16IfLE(msg.sw.x)<5 && Swap16IfLE(msg.sw.y)<5)
{
m_client->m_encodemgr.m_buffer->m_desktop->SetSW(1,1);
break;
}
m_client->m_encodemgr.m_buffer->m_desktop->SetSW(
(Swap16IfLE(msg.sw.x) + m_client->m_SWOffsetx+m_client->m_ScreenOffsetx) * m_client->m_nScale,
(Swap16IfLE(msg.sw.y) + m_client->m_SWOffsety+m_client->m_ScreenOffsety) * m_client->m_nScale);
break;
// Modif sf@2002 - TextChat
case rfbTextChat:
m_client->m_pTextChat->ProcessTextChatMsg(nTO);
break;
// Modif sf@2002 - FileTransfer
// File Transfer Message
case rfbFileTransfer:
{
// sf@2004 - An unlogged user can't access to FT
bool fUserOk = true;
if (m_server->FTUserImpersonation())
{
fUserOk = m_client->DoFTUserImpersonation();
}
omni_mutex_lock l(m_client->GetUpdateLock());
// Read the rest of the message:
m_client->m_fFileTransferRunning = TRUE;
if (m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbFileTransferMsg - nTO))
{
switch (msg.ft.contentType)
{
// A new file is received from the client
// case rfbFileHeader:
case rfbFileTransferOffer:
{
omni_mutex_lock l(m_client->GetUpdateLock());
if (!m_server->FileTransferEnabled() || !fUserOk) break;
// bool fError = false;
const UINT length = Swap32IfLE(msg.ft.length);
memset(m_client->m_szFullDestName, 0, sizeof(m_client->m_szFullDestName));
if (length > sizeof(m_client->m_szFullDestName)) break;
// Read in the Name of the file to create
if (!m_socket->ReadExact(m_client->m_szFullDestName, length))
{
//MessageBox(NULL, "1. Abort !", "Ultra WinVNC", MB_OK);
// vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Failed to receive FileName from Viewer. Abort !\n"));
break;
}
// sf@2004 - Improving huge files size handling
CARD32 sizeL = Swap32IfLE(msg.ft.size);
CARD32 sizeH = 0;
CARD32 sizeHtmp = 0;
if (!m_socket->ReadExact((char*)&sizeHtmp, sizeof(CARD32)))
{
//MessageBox(NULL, "2. Abort !", "Ultra WinVNC", MB_OK);
//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Failed to receive SizeH from Viewer. Abort !\n"));
break;
}
sizeH = Swap32IfLE(sizeHtmp);
// Parse the FileTime
char *p = strrchr(m_client->m_szFullDestName, ',');
if (p == NULL)
m_client->m_szFileTime[0] = '\0';
else
{
strcpy(m_client->m_szFileTime, p+1);
*p = '\0';
}
// sf@2004 - Directory Delta Transfer
// If the offered file is a zipped directory, we test if it already exists here
// and create the zip accordingly. This way we can generate the checksums for it.
// m_client->CheckAndZipDirectoryForChecksuming(m_client->m_szFullDestName);
// Create Local Dest file
m_client->m_hDestFile = CreateFile(m_client->m_szFullDestName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
// sf@2004 - Delta Transfer
bool fAlreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);
DWORD dwDstSize = (DWORD)0; // Dummy size, actually a return value
if (m_client->m_hDestFile == INVALID_HANDLE_VALUE)
dwDstSize = 0xFFFFFFFF;
else
dwDstSize = 0x00;
// Also check the free space on destination drive
ULARGE_INTEGER lpFreeBytesAvailable;
ULARGE_INTEGER lpTotalBytes;
ULARGE_INTEGER lpTotalFreeBytes;
unsigned long dwFreeKBytes;
char *szDestPath = new char [length + 1 + 64];
if (szDestPath == NULL) break;
memset(szDestPath, 0, length + 1 + 64);
strcpy(szDestPath, m_client->m_szFullDestName);
*strrchr(szDestPath, '\\') = '\0'; // We don't handle UNCs for now
// loadlibrary
// needed for 95 non OSR2
// Possible this will block filetransfer, but at least server will start
PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX)GetProcAddress( GetModuleHandle("kernel32.dll"),"GetDiskFreeSpaceExA");
if (pGetDiskFreeSpaceEx)
{
if (!pGetDiskFreeSpaceEx((LPCTSTR)szDestPath,
&lpFreeBytesAvailable,
&lpTotalBytes,
&lpTotalFreeBytes)
)
dwDstSize = 0xFFFFFFFF;
}
delete [] szDestPath;
dwFreeKBytes = (unsigned long) (Int64ShraMod32(lpFreeBytesAvailable.QuadPart, 10));
__int64 nnFileSize = (((__int64)sizeH) << 32 ) + sizeL;
if ((__int64)dwFreeKBytes < (__int64)(nnFileSize / 1000)) dwDstSize = 0xFFFFFFFF;
// Allocate buffer for file packets
m_client->m_pBuff = new char [sz_rfbBlockSize + 1024];
if (m_client->m_pBuff == NULL)
dwDstSize = 0xFFFFFFFF;
// Allocate buffer for DeCompression
m_client->m_pCompBuff = new char [sz_rfbBlockSize];
if (m_client->m_pCompBuff == NULL)
dwDstSize = 0xFFFFFFFF;
rfbFileTransferMsg ft;
ft.type = rfbFileTransfer;
// sf@2004 - Delta Transfer
if (fAlreadyExists && dwDstSize != 0xFFFFFFFF)
{
ULARGE_INTEGER n2SrcSize;
bool bSize = m_client->MyGetFileSize(m_client->m_szFullDestName, &n2SrcSize);
//DWORD dwFileSize = GetFileSize(m_client->m_hDestFile, NULL);
//if (dwFileSize != 0xFFFFFFFF)
if (bSize)
{
int nCSBufferSize = (4 * (int)(n2SrcSize.QuadPart / sz_rfbBlockSize)) + 1024;
char* lpCSBuff = new char [nCSBufferSize];
if (lpCSBuff != NULL)
{
int nCSBufferLen = m_client->GenerateFileChecksums( m_client->m_hDestFile,
lpCSBuff,
nCSBufferSize);
if (nCSBufferLen != -1)
{
ft.contentType = rfbFileChecksums;
ft.size = Swap32IfLE(nCSBufferSize);
ft.length = Swap32IfLE(nCSBufferLen);
m_socket->SendExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
m_socket->SendExact((char *)lpCSBuff, nCSBufferLen);
}
}
}
}
ft.contentType = rfbFileAcceptHeader;
ft.size = Swap32IfLE(dwDstSize); // File Size in bytes, 0xFFFFFFFF (-1) means error
ft.length = Swap32IfLE(strlen(m_client->m_szFullDestName));
m_socket->SendExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
m_socket->SendExact((char *)m_client->m_szFullDestName, strlen(m_client->m_szFullDestName));
if (dwDstSize == 0xFFFFFFFF)
{
CloseHandle(m_client->m_hDestFile);
if (m_client->m_pCompBuff != NULL)
delete m_client->m_pCompBuff;
if (m_client->m_pBuff != NULL)
delete m_client->m_pBuff;
//MessageBox(NULL, "3. Abort !", "Ultra WinVNC", MB_OK);
//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Wrong Dest File size. Abort !\n"));
break;
}
m_client->m_dwFileSize = Swap32IfLE(msg.ft.size);
m_client->m_dwNbPackets = (DWORD)(m_client->m_dwFileSize / sz_rfbBlockSize);
m_client->m_dwNbReceivedPackets = 0;
m_client->m_dwNbBytesWritten = 0;
m_client->m_dwTotalNbBytesWritten = 0;
m_client->m_fFileDownloadError = false;
m_client->m_fFileDownloadRunning = true;
}
break;
// The client requests a File
case rfbFileTransferRequest:
{
omni_mutex_lock l(m_client->GetUpdateLock());
if (!m_server->FileTransferEnabled() || !fUserOk) break;
m_client->m_fCompressionEnabled = (Swap32IfLE(msg.ft.size) == 1);
const UINT length = Swap32IfLE(msg.ft.length);
memset(m_client->m_szSrcFileName, 0, sizeof(m_client->m_szSrcFileName));
if (length > sizeof(m_client->m_szSrcFileName)) break;
// Read in the Name of the file to create
if (!m_socket->ReadExact(m_client->m_szSrcFileName, length))
{
//MessageBox(NULL, "4. Abort !", "Ultra WinVNC", MB_OK);
//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Cannot read requested filename. Abort !\n"));
break;
}
// sf@2003 - Directory Transfer trick
// If the file is an Ultra Directory Zip Request we zip the directory here
// and we give it the requested name for transfer
int nDirZipRet = m_client->ZipPossibleDirectory(m_client->m_szSrcFileName);
if (nDirZipRet == -1)
{
//MessageBox(NULL, "5. Abort !", "Ultra WinVNC", MB_OK);
//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Failed to zip requested dir. Abort !\n"));
break;
}
// Open source file
m_client->m_hSrcFile = CreateFile(
m_client->m_szSrcFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL
);
// DWORD dwSrcSize = (DWORD)0;
ULARGE_INTEGER n2SrcSize;
if (m_client->m_hSrcFile == INVALID_HANDLE_VALUE)
{
DWORD TheError = GetLastError();
// dwSrcSize = 0xFFFFFFFF;
n2SrcSize.LowPart = 0xFFFFFFFF;
}
else
{
// Source file size
bool bSize = m_client->MyGetFileSize(m_client->m_szSrcFileName, &n2SrcSize);
// dwSrcSize = GetFileSize(m_client->m_hSrcFile, NULL);
// if (dwSrcSize == 0xFFFFFFFF)
if (!bSize)
{
CloseHandle(m_client->m_hSrcFile);
n2SrcSize.LowPart = 0xFFFFFFFF;
}
else
{
// Add the File Time Stamp to the filename
FILETIME SrcFileModifTime;
BOOL fRes = GetFileTime(m_client->m_hSrcFile, NULL, NULL, &SrcFileModifTime);
if (fRes)
{
char szSrcFileTime[18];
// sf@2003 - Convert file time to local time
// We've made the choice off displaying all the files
// off client AND server sides converted in clients local
// time only. So we don't convert server's files times.
/*
FILETIME LocalFileTime;
FileTimeToLocalFileTime(&SrcFileModifTime, &LocalFileTime);
*/
SYSTEMTIME FileTime;
FileTimeToSystemTime(&SrcFileModifTime/*&LocalFileTime*/, &FileTime);
wsprintf(szSrcFileTime,"%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
FileTime.wMonth,
FileTime.wDay,
FileTime.wYear,
FileTime.wHour,
FileTime.wMinute
);
strcat(m_client->m_szSrcFileName, ",");
strcat(m_client->m_szSrcFileName, szSrcFileTime);
}
}
}
// sf@2004 - Delta Transfer
if (m_client->m_lpCSBuffer != NULL)
{
delete [] m_client->m_lpCSBuffer;
m_client->m_lpCSBuffer = NULL;
}
m_client->m_nCSOffset = 0;
m_client->m_nCSBufferSize = 0;
// Send the FileTransferMsg with rfbFileHeader
rfbFileTransferMsg ft;
ft.type = rfbFileTransfer;
ft.contentType = rfbFileHeader;
ft.size = Swap32IfLE(n2SrcSize.LowPart); // File Size in bytes, 0xFFFFFFFF (-1) means error
ft.length = Swap32IfLE(strlen(m_client->m_szSrcFileName));
m_socket->SendExact((char *)&ft, sz_rfbFileTransferMsg, rfbFileTransfer);
m_socket->SendExact((char *)m_client->m_szSrcFileName, strlen(m_client->m_szSrcFileName));
// sf@2004 - Improving huge file size handling
CARD32 sizeH = Swap32IfLE(n2SrcSize.HighPart);
m_socket->SendExact((char *)&sizeH, sizeof(CARD32));
// delete [] szSrcFileName;
if (n2SrcSize.LowPart == 0xFFFFFFFF)
{
//MessageBox(NULL, "6. Abort !", "Ultra WinVNC", MB_OK);
//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Wrong Src File size. Abort !\n"));
break; // If error, we don't send anything else
}
}
break;
// sf@2004 - Delta Transfer
// Destination file already exists - the viewer sends the checksums
case rfbFileChecksums:
m_client->ReceiveDestinationFileChecksums(Swap32IfLE(msg.ft.size), Swap32IfLE(msg.ft.length));
break;
// Destination file (viewer side) is ready for reception (size > 0) or not (size = -1)
case rfbFileHeader:
{
// Check if the file has been created on client side
if (Swap32IfLE(msg.ft.size) == -1)
{
CloseHandle(m_client->m_hSrcFile);
// MessageBox(NULL, "7. Abort !", "Ultra WinVNC", MB_OK);
//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: File not created on client side. Abort !\n"));
break;
}
// Allocate buffer for file packets
m_client->m_pBuff = new char [sz_rfbBlockSize];
if (m_client->m_pBuff == NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -