⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vncclient.cpp

📁 tightvnc源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				path_file[msg.fdr.fNameSize] = '\0';
				ConvertPath(path_file);
				strcpy(m_client->m_DownloadFilename, path_file);

				HANDLE hFile;
				DWORD sz_rfbFileSize;
				DWORD sz_rfbBlockSize = 8192;
				DWORD dwNumberOfBytesRead = 0;
				DWORD dwNumberOfAllBytesRead = 0;
				WIN32_FIND_DATA FindFileData;
				SetErrorMode(SEM_FAILCRITICALERRORS);
				hFile = FindFirstFile(path_file, &FindFileData);
				DWORD LastError = GetLastError();
				SetErrorMode(0);

				vnclog.Print(LL_CLIENTS, VNCLOG("file download requested: %s\n"),
							 path_file);

				if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || 
					(hFile == INVALID_HANDLE_VALUE) || (path_file[0] == '\0')) {
					FindClose(hFile);
					char reason[] = "Cannot open file, perhaps it is absent or is a directory";
					int reasonLen = strlen(reason);
					m_client->SendFileDownloadFailed(reasonLen, reason);
					break;
				}
				sz_rfbFileSize = FindFileData.nFileSizeLow;
				FindClose(hFile);
				m_client->m_modTime = m_client->FiletimeToTime70(FindFileData.ftLastWriteTime);
				if (sz_rfbFileSize == 0) {
					m_client->SendFileDownloadData(m_client->m_modTime);
				} else {
					if (sz_rfbFileSize <= sz_rfbBlockSize) sz_rfbBlockSize = sz_rfbFileSize;
					SetErrorMode(SEM_FAILCRITICALERRORS);
					m_client->m_hFileToRead = CreateFile(path_file, GENERIC_READ, FILE_SHARE_READ, NULL,	OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
					SetErrorMode(0);
					if (m_client->m_hFileToRead != INVALID_HANDLE_VALUE) {
						m_client->m_bDownloadStarted = TRUE;
						m_client->SendFileDownloadPortion();
					}
				}
			}
			break;

		case rfbFileUploadRequest:
			if (!m_server->FileTransfersEnabled() || !m_client->IsInputEnabled()) {
				connected = FALSE;
				break;
			}
			if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbFileUploadRequestMsg-1))
			{
				msg.fupr.fNameSize = Swap16IfLE(msg.fupr.fNameSize);
				msg.fupr.position = Swap32IfLE(msg.fupr.position);
				if (msg.fupr.fNameSize > MAX_PATH) {
					m_socket->ReadExact(NULL, msg.fupr.fNameSize);
					char reason[] = "Path length exceeds MAX_PATH value";
					int reasonLen = strlen(reason);
					m_client->SendFileUploadCancel(reasonLen, reason);
					break;
				}
				m_socket->ReadExact(m_client->m_UploadFilename, msg.fupr.fNameSize);
				m_client->m_UploadFilename[msg.fupr.fNameSize] = '\0';
				ConvertPath(m_client->m_UploadFilename);
				vnclog.Print(LL_CLIENTS, VNCLOG("file upload requested: %s\n"),
							 m_client->m_UploadFilename);
				m_client->m_hFileToWrite = CreateFile(m_client->m_UploadFilename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
				m_client->m_bUploadStarted = TRUE;
				if (m_client->m_hFileToWrite == INVALID_HANDLE_VALUE) {
					char reason[] = "Could not create file";
					int reasonLen = strlen(reason);
					m_client->SendFileUploadCancel(reasonLen, reason);
				}
				DWORD dwError = GetLastError();
				/*
				SYSTEMTIME systime;
				FILETIME filetime;
				GetSystemTime(&systime);
				SystemTimeToFileTime(&systime, &filetime);
				m_client->beginUploadTime = m_client->FiletimeToTime70(filetime);
				*/        
				/*
				DWORD dwFilePtr;
				if (msg.fupr.position > 0) {
					dwFilePtr = SetFilePointer(m_hFiletoWrite, msg.fupr.position, NULL, FILE_BEGIN);
					if ((dwFilePtr == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR)) {
						char reason[] = "Invalid file pointer position";
						int reasonLen = strlen(reason);
						m_client->SendFileUploadCancel(reasonLen, reason);
						CloseHandle(m_hFiletoWrite);
						break;
					}
				}
				*/
			}				
			break;

		case rfbFileUploadData:
			if (!m_server->FileTransfersEnabled() || !m_client->IsInputEnabled()) {
				connected = FALSE;
				break;
			}
			if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbFileUploadDataMsg-1))
			{
				msg.fud.realSize = Swap16IfLE(msg.fud.realSize);
				msg.fud.compressedSize = Swap16IfLE(msg.fud.compressedSize);
				if ((msg.fud.realSize == 0) && (msg.fud.compressedSize == 0)) {
					CARD32 mTime;
					m_socket->ReadExact((char *) &mTime, sizeof(CARD32));
					mTime = Swap32IfLE(mTime);
					FILETIME Filetime;
					m_client->Time70ToFiletime(mTime, &Filetime);
					if (!SetFileTime(m_client->m_hFileToWrite, &Filetime, &Filetime, &Filetime)) {
						vnclog.Print(LL_INTINFO, VNCLOG("SetFileTime() failed\n"));
					}
//					DWORD dwFileSize = GetFileSize(m_client->m_hFileToWrite, NULL);
					CloseHandle(m_client->m_hFileToWrite);
					m_client->m_bUploadStarted = FALSE;
//					SYSTEMTIME systime;
//					FILETIME filetime;
//					GetSystemTime(&systime);
//					SystemTimeToFileTime(&systime, &filetime);
//					m_client->endUploadTime = m_client->FiletimeToTime70(filetime);
//					unsigned int uploadTime = m_client->endUploadTime - m_client->beginUploadTime + 1;
//					DWORD dwBytePerSecond = dwFileSize / uploadTime;
//					vnclog.Print(LL_CLIENTS, VNCLOG("file upload complete: %s; Speed (B/s) = %d; FileSize = %d, UploadTime = %d\n"),
//								 m_client->m_UploadFilename, dwBytePerSecond, dwFileSize, uploadTime);
					vnclog.Print(LL_CLIENTS, VNCLOG("file upload complete: %s;\n"),
								 m_client->m_UploadFilename);
					break;
				}
				DWORD dwNumberOfBytesWritten;
				char *pBuff = new char [msg.fud.compressedSize];
				m_socket->ReadExact(pBuff, msg.fud.compressedSize);
				if (msg.fud.compressedLevel != 0) {
					char reason[] = "Server does not support data compression on upload";
					int reasonLen = strlen(reason);
					m_client->SendFileUploadCancel(reasonLen, reason);
					m_client->CloseUndoneFileTransfer();
					break;
				}
				BOOL bResult = WriteFile(m_client->m_hFileToWrite, pBuff, msg.fud.compressedSize, &dwNumberOfBytesWritten, NULL);
				if ((dwNumberOfBytesWritten != msg.fud.compressedSize) || !bResult) {
					char reason[] = "Error writing file data";
					int reasonLen = strlen(reason);
					m_client->SendFileUploadCancel(reasonLen, reason);
					m_client->CloseUndoneFileTransfer();
					break;
				}
				delete [] pBuff;
			}
			break;

		case rfbFileDownloadCancel:
			if (!m_server->FileTransfersEnabled() || !m_client->IsInputEnabled()) {
				connected = FALSE;
				break;
			}
			if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbFileDownloadCancelMsg-1))
			{
				msg.fdc.reasonLen = Swap16IfLE(msg.fdc.reasonLen);
				char *reason = new char[msg.fdc.reasonLen + 1];
				m_socket->ReadExact(reason, msg.fdc.reasonLen);
				reason[msg.fdc.reasonLen] = '\0';
				m_client->CloseUndoneFileTransfer();
				delete [] reason;
			}
			break;

		case rfbFileUploadFailed:
			if (!m_server->FileTransfersEnabled() || !m_client->IsInputEnabled()) {
				connected = FALSE;
				break;
			}
			if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbFileUploadFailedMsg-1))
			{
				msg.fuf.reasonLen = Swap16IfLE(msg.fuf.reasonLen);
				char *reason = new char[msg.fuf.reasonLen + 1];
				m_socket->ReadExact(reason, msg.fuf.reasonLen);
				reason[msg.fuf.reasonLen] = '\0';
				m_client->CloseUndoneFileTransfer();
				delete [] reason;
			}
			break;

		case rfbFileCreateDirRequest:
			if (!m_server->FileTransfersEnabled() || !m_client->IsInputEnabled()) {
				connected = FALSE;
				break;
			}
			if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbFileCreateDirRequestMsg-1))
			{
				msg.fcdr.dNameLen = Swap16IfLE(msg.fcdr.dNameLen);
				char *dirName = new char[msg.fcdr.dNameLen + 1];
				m_socket->ReadExact(dirName, msg.fcdr.dNameLen);
				dirName[msg.fcdr.dNameLen] = '\0';
				dirName = ConvertPath(dirName);
				CreateDirectory((LPCTSTR) dirName, NULL);
				delete [] dirName;
			}

			break;

		default:
			// Unknown message, so fail!
			vnclog.Print(LL_CLIENTS, VNCLOG("invalid message received : %d\n"),
						 (int)msg.type);
			connected = FALSE;
		}
	}

	// Move into the thread's original desktop
	vncService::SelectHDESK(home_desktop);

	// Quit this thread.  This will automatically delete the thread and the
	// associated client.
	vnclog.Print(LL_CLIENTS, VNCLOG("client disconnected : %s (id %hd)\n"),
				 m_client->GetClientName(), m_client->GetClientId());

	// Remove the client from the server, just in case!
	m_server->RemoveClient(m_client->GetClientId());
}

// The vncClient itself

vncClient::vncClient()
{
	vnclog.Print(LL_INTINFO, VNCLOG("vncClient() executing...\n"));

	m_socket = NULL;
	m_client_name = 0;
	m_server_name = 0;
	m_buffer = NULL;

	m_keyboardenabled = FALSE;
	m_pointerenabled = FALSE;
	m_inputblocked = FALSE;

	m_copyrect_use = FALSE;

	m_mousemoved = FALSE;
	m_ptrevent.buttonMask = 0;
	m_ptrevent.x = 0;
	m_ptrevent.y = 0;

	m_cursor_update_pending = FALSE;
	m_cursor_update_sent = FALSE;
	m_cursor_pos_changed = FALSE;
	m_pointer_event_time = (time_t)0;
	m_cursor_pos.x = -1;
	m_cursor_pos.y = -1;

	m_thread = NULL;
	m_updatewanted = FALSE;

	m_palettechanged = FALSE;

	m_copyrect_set = FALSE;

	m_remoteevent = FALSE;

	m_bDownloadStarted = FALSE;
	m_bUploadStarted = FALSE;

	// IMPORTANT: Initially, client is not protocol-ready.
	m_protocol_ready = FALSE;
	m_fb_size_changed = FALSE;

	m_use_NewFBSize = FALSE;

}

vncClient::~vncClient()
{
	vnclog.Print(LL_INTINFO, VNCLOG("~vncClient() executing...\n"));

	// We now know the thread is dead, so we can clean up
	if (m_client_name != 0) {
		free(m_client_name);
		m_client_name = 0;
	}
	if (m_server_name != 0) {
		free(m_server_name);
		m_server_name = 0;
	}

	// If we have a socket then kill it
	if (m_socket != NULL)
	{
		vnclog.Print(LL_INTINFO, VNCLOG("deleting socket\n"));

		delete m_socket;
		m_socket = NULL;
	}

	// Kill the screen buffer
	if (m_buffer != NULL)
	{
		vnclog.Print(LL_INTINFO, VNCLOG("deleting buffer\n"));

		delete m_buffer;
		m_buffer = NULL;
	}
}

// Init
BOOL
vncClient::Init(vncServer *server,
				VSocket *socket,
				BOOL reverse,
				BOOL shared,
				vncClientId newid)
{
	// Save the server id;
	m_server = server;

	// Save the socket
	m_socket = socket;

	// Save the name/ip of the connecting client
	char *name = m_socket->GetPeerName();
	if (name != 0)
		m_client_name = strdup(name);
	else
		m_client_name = strdup("<unknown>");

	// Save the server name/ip
	name = m_socket->GetSockName();
	if (name != 0)
		m_server_name = strdup(name);
	else
		m_server_name = strdup("<unknown>");

	// Save the client id
	m_id = newid;

	// Spawn the child thread here
	m_thread = new vncClientThread;
	if (m_thread == NULL)
		return FALSE;
	return ((vncClientThread *)m_thread)->Init(this, m_server, m_socket, reverse, shared);

	return FALSE;
}

void
vncClient::Kill()
{
	// Close file transfer
	CloseUndoneFileTransfer();

	// Close the socket
	if (m_socket != NULL)
		m_socket->Close();
}

// Client manipulation functions for use by the server
void
vncClient::SetBuffer(vncBuffer *buffer)
{
	// Until authenticated, the client object has no access
	// to the screen buffer.  This means that there only need
	// be a buffer when there's at least one authenticated client.
	m_buffer = buffer;
}


void
vncClient::TriggerUpdate()
{
	// Lock the updates stored so far
	omni_mutex_lock l(m_regionLock);
	if (!m_protocol_ready)
		return;

	if (m_updatewanted)
	{
		// Check if cursor shape update has to be sent
		m_cursor_update_pending = m_buffer->IsCursorUpdatePending();

		// Send an update if one is waiting
		if (!m_changed_rgn.IsEmpty() ||
			!m_full_rgn.IsEmpty() ||
			m_copyrect_set ||
			m_cursor_update_pending ||
			m_cursor_pos_changed ||
			(m_mousemoved && !m_use_PointerPos))
		{
			// Has the palette changed?
			if (m_palettechanged)
			{
				m_palettechanged = FALSE;
				if (!SendPalette())
					return;
			}

			// Now send the update
			m_updatewanted = !SendUpdate();
		}
	}
}

void
vncClient::UpdateMouse()
{
	if (!m_mousemoved && !m_cursor_update_sent)	{
		omni_mutex_lock l(m_regionLock);

		if (IntersectRect(&m_oldmousepos, &m_oldmousepos, &m_server->GetSharedRect()))
			m_changed_rgn.AddRect(m_oldmousepos);

		m_mousemoved = TRUE;
	} else if (m_use_PointerPos) {
		omni_mutex_lock l(m_regionLock);

		SetCursorPosChanged();
	}
}

void
vncClient::UpdateRect(RECT &rect)
{
	// Add the rectangle to the update region
	if (IsRectEmpty(&rect))
		return;

	omni_mutex_lock l(m_regionLock);

	if (IntersectRect(&rect, &rect, &m_server->GetSharedRect()))
		m_changed_rgn.AddRect(rect);
}

void
vncClient::UpdateRegion(vncRegion &region)
{
	// Merge our current update region with the supplied one
	if (region.IsEmpty())
		return;

	{
		omni_mutex_lock l(m_regionLock);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -