📄 vncserver.cpp
字号:
// Yes, so remove the client and kill it
m_authClients.erase(i);
m_clientmap[clientid] = NULL;
done = TRUE;
break;
}
}
}
// Signal that a client has quit
m_clientquitsig->signal();
} // Unlock the clientLock
// If so configured, beep to indicate the old connection is
// gone.
if (GetBeepDisconnect())
{
MessageBeep(MB_OK);
}
// Are there any authorised clients connected?
if (m_authClients.empty() && (m_desktop != NULL))
{
vnclog.Print(LL_STATE, VNCLOG("deleting desktop server\n"));
// Are there locksettings set?
if (LockSettings() == 1)
{
// Yes - lock the machine on disconnect!
vncService::LockWorkstation();
} else if (LockSettings() > 1)
{
char username[UNLEN+1];
vncService::CurrentUser((char *)&username, sizeof(username));
if (strcmp(username, "") != 0)
{
// Yes - force a user logoff on disconnect!
if (!ExitWindowsEx(EWX_LOGOFF, 0))
vnclog.Print(LL_CONNERR, VNCLOG("client disconnect - failed to logoff user!\n"));
}
}
// Delete the screen server
delete m_desktop;
m_desktop = NULL;
}
// Notify anyone interested of the change
DoNotify(WM_SRV_CLIENT_DISCONNECT, 0, 0);
vnclog.Print(LL_INTINFO, VNCLOG("RemoveClient() done\n"));
}
// NOTIFICATION HANDLING!
// Connect/disconnect notification
BOOL
vncServer::AddNotify(HWND hwnd)
{
omni_mutex_lock l(m_clientsLock);
// Add the window handle to the list
m_notifyList.push_front(hwnd);
return TRUE;
}
BOOL
vncServer::RemNotify(HWND hwnd)
{
omni_mutex_lock l(m_clientsLock);
// Remove the window handle from the list
vncNotifyList::iterator i;
for (i=m_notifyList.begin(); i!=m_notifyList.end(); i++)
{
if ((*i) == hwnd)
{
// Found the handle, so remove it
m_notifyList.erase(i);
return TRUE;
}
}
return FALSE;
}
// Send a notification message
void
vncServer::DoNotify(UINT message, WPARAM wparam, LPARAM lparam)
{
omni_mutex_lock l(m_clientsLock);
// Send the given message to all the notification windows
vncNotifyList::iterator i;
for (i=m_notifyList.begin(); i!=m_notifyList.end(); i++)
{
PostMessage((*i), message, wparam, lparam);
}
}
// Client->Desktop update signalling
void
vncServer::RequestUpdate()
{
omni_mutex_lock l(m_desktopLock);
if (m_desktop != NULL)
{
m_desktop->RequestUpdate();
}
}
// Update handling
void
vncServer::TriggerUpdate()
{
vncClientList::iterator i;
omni_mutex_lock l(m_clientsLock);
// Post this update to all the connected clients
for (i = m_authClients.begin(); i != m_authClients.end(); i++)
{
// Post the update
GetClient(*i)->TriggerUpdate();
}
}
void
vncServer::UpdateRect(RECT &rect)
{
vncClientList::iterator i;
omni_mutex_lock l(m_clientsLock);
// Post this update to all the connected clients
for (i = m_authClients.begin(); i != m_authClients.end(); i++)
{
// Post the update
GetClient(*i)->UpdateRect(rect);
}
}
void
vncServer::UpdateRegion(vncRegion ®ion)
{
vncClientList::iterator i;
omni_mutex_lock l(m_clientsLock);
// Post this update to all the connected clients
for (i = m_authClients.begin(); i != m_authClients.end(); i++)
{
// Post the update
GetClient(*i)->UpdateRegion(region);
}
}
void
vncServer::CopyRect(RECT &dest, POINT &source)
{
vncClientList::iterator i;
omni_mutex_lock l(m_clientsLock);
// Post this update to all the connected clients
for (i = m_authClients.begin(); i != m_authClients.end(); i++)
{
// Post the update
GetClient(*i)->CopyRect(dest, source);
}
}
void
vncServer::UpdateMouse()
{
vncClientList::iterator i;
omni_mutex_lock l(m_clientsLock);
// Post this mouse update to all the connected clients
for (i = m_authClients.begin(); i != m_authClients.end(); i++)
{
// Post the update
GetClient(*i)->UpdateMouse();
}
}
void
vncServer::UpdateClipText(LPSTR text)
{
vncClientList::iterator i;
omni_mutex_lock l(m_clientsLock);
// Post this update to all the connected clients
for (i = m_authClients.begin(); i != m_authClients.end(); i++)
{
// Post the update
GetClient(*i)->UpdateClipText(text);
}
}
void
vncServer::UpdatePalette()
{
vncClientList::iterator i;
omni_mutex_lock l(m_clientsLock);
// Post this update to all the connected clients
for (i = m_authClients.begin(); i != m_authClients.end(); i++)
{
// Post the update
GetClient(*i)->UpdatePalette();
}
}
void
vncServer::UpdateLocalClipText(LPSTR text)
{
omni_mutex_lock l(m_desktopLock);
if (m_desktop != NULL)
m_desktop->SetClipText(text);
}
// Changing hook settings
void
vncServer::DontSetHooks(BOOL enable)
{
m_dont_set_hooks = enable;
if (m_desktop != NULL)
m_desktop->TryActivateHooks();
}
// Changing use driver settings
void
vncServer::DontUseDriver(BOOL enable)
{
m_dont_use_driver = enable;
}
void
vncServer::DriverDirectAccess(BOOL enable)
{
m_driver_direct_access_en = enable;
}
// Name and port number handling
void
vncServer::SetName(const char * name)
{
// Set the name of the desktop
if (m_name != NULL)
{
free(m_name);
m_name = NULL;
}
m_name = strdup(name);
}
void
vncServer::SetPorts(const UINT port_rfb, const UINT port_http)
{
if (m_port != port_rfb || m_port_http != port_http) {
// Set port numbers to use
m_port = port_rfb;
m_port_http = port_http;
// If there is already a listening socket then close and re-open it...
BOOL socketon = SockConnected();
SockConnect(FALSE);
if (socketon)
SockConnect(TRUE);
}
}
void
vncServer::SetPassword(BOOL activate, const char *passwd)
{
ResetPasswordsValidityInfo();
m_password_set = activate;
memcpy(m_password, passwd, MAXPWLEN);
}
BOOL
vncServer::GetPassword(char *passwd)
{
memcpy(passwd, m_password, MAXPWLEN);
return m_password_set;
}
void
vncServer::SetPasswordViewOnly(BOOL activate, const char *passwd)
{
ResetPasswordsValidityInfo();
m_password_viewonly_set = activate;
memcpy(m_password_viewonly, passwd, MAXPWLEN);
}
BOOL
vncServer::GetPasswordViewOnly(char *passwd)
{
memcpy(passwd, m_password_viewonly, MAXPWLEN);
return m_password_viewonly_set;
}
BOOL
vncServer::ValidPasswordsSet()
{
if (!m_valid_passwords_set_cached) {
m_valid_passwords_set = ValidPasswordsSet_nocache();
m_valid_passwords_set_cached = TRUE;
}
return m_valid_passwords_set;
}
BOOL
vncServer::ValidPasswordsSet_nocache()
{
char passwd1[MAXPWLEN];
char passwd2[MAXPWLEN];
BOOL set1 = GetPassword(passwd1);
BOOL set2 = GetPasswordViewOnly(passwd2);
if (!set1 && !set2)
return FALSE; // no passwords set, connections impossible
if (!AuthRequired())
return TRUE; // passwords may be empty, but we allow that
vncPasswd::ToText plain1(passwd1);
vncPasswd::ToText plain2(passwd2);
BOOL empty1 = !set1 || (strlen(plain1) == 0);
BOOL empty2 = !set2 || (strlen(plain2) == 0);
if (empty1 && empty2)
return FALSE; // both passwords empty or unset, not allowed
return TRUE; // at least one non-empty password
}
BOOL
vncServer::ValidPasswordsEmpty()
{
if (!m_valid_passwords_empty_cached) {
m_valid_passwords_empty = ValidPasswordsEmpty_nocache();
m_valid_passwords_empty_cached = TRUE;
}
return m_valid_passwords_empty;
}
BOOL
vncServer::ValidPasswordsEmpty_nocache()
{
if (AuthRequired())
return FALSE; // empty passwords disallowed, always fail
char passwd1[MAXPWLEN];
char passwd2[MAXPWLEN];
BOOL set1 = GetPassword(passwd1);
BOOL set2 = GetPasswordViewOnly(passwd2);
if (!set1 && !set2)
return FALSE; // no passwords set, connections impossible
vncPasswd::ToText plain1(passwd1);
vncPasswd::ToText plain2(passwd2);
BOOL empty1 = !set1 || (strlen(plain1) == 0);
BOOL empty2 = !set2 || (strlen(plain2) == 0);
if (empty1 && empty2)
return TRUE; // there are no passwords that are non-empty
return FALSE; // at least one non-empty password
}
// Remote input handling
void
vncServer::EnableRemoteInputs(BOOL enable)
{
m_enable_remote_inputs = enable;
}
BOOL vncServer::RemoteInputsEnabled()
{
return m_enable_remote_inputs;
}
// Local input handling
void
vncServer::DisableLocalInputs(BOOL disable)
{
if ( m_disable_local_inputs != disable )
{
m_disable_local_inputs = disable;
if ( AuthClientCount() != 0 )
m_desktop->SetLocalInputDisableHook(disable);
}
}
BOOL vncServer::LocalInputsDisabled()
{
return m_disable_local_inputs;
}
void vncServer::LocalInputPriority(BOOL disable)
{
if( m_local_input_priority != disable )
{
m_local_input_priority = disable;
m_remote_mouse = 0;
m_remote_keyboard = 0;
if ( AuthClientCount() != 0 )
m_desktop->SetLocalInputPriorityHook(disable);
}
}
// Socket connection handling
BOOL
vncServer::SockConnect(BOOL On)
{
// Are we being asked to switch socket connects on or off?
if (On)
{
// Is there a listening socket?
if (m_socketConn == NULL)
{
m_socketConn = new vncSockConnect();
if (m_socketConn == NULL)
return FALSE;
// Are we to use automatic port selection?
if (m_autoportselect)
{
BOOL ok = FALSE;
// Yes, so cycle through the ports, looking for a free one!
for (int i = 0; i < 99; i++)
{
m_port = DISPLAY_TO_PORT(i);
m_port_http = DISPLAY_TO_HPORT(i);
vnclog.Print(LL_CLIENTS, VNCLOG("trying port number %d\n"), m_port);
// Attempt to connect to the port
VSocket tempsock;
if (tempsock.Create())
{
if (!tempsock.Connect("localhost", m_port))
{
// Couldn't connect, so this port is probably usable!
if (m_socketConn->Init(this, m_port))
{
ok = TRUE;
break;
}
}
}
}
if (!ok)
{
delete m_socketConn;
m_socketConn = NULL;
return FALSE;
}
} else
{
// No autoportselect
if (!m_socketConn->Init(this, m_port))
{
delete m_socketConn;
m_socketConn = NULL;
return FALSE;
}
}
// Now let's start the HTTP connection stuff
if (m_port_http == m_port) {
vnclog.Print(LL_INTERR, VNCLOG("cannot start both RFB and HTTP servers "
"on the same port\n"));
}
if (m_httpConn == NULL && m_httpd_enabled && m_port_http != m_port) {
m_httpConn = new vncHTTPConnect;
if (m_httpConn != NULL) {
// Start up the HTTP server
if (!m_httpConn->Init(this, m_port_http,
m_httpd_params_enabled)) {
delete m_httpConn;
m_httpConn = NULL;
return FALSE;
}
}
}
}
}
else
{
// *** JNW - Trying to fix up a lock-up when the listening socket closes
#ifndef HORIZONLIVE
KillAuthClients();
KillUnauthClients();
WaitUntilAuthEmpty();
WaitUntilUnauthEmpty();
#endif
// Is there a listening socket?
if (m_socketConn != NULL)
{
// Close the socket
delete m_socketConn;
m_socketConn = NULL;
}
// Is there an HTTP socket active?
if (m_httpConn != NULL)
{
// Close the socket
delete m_httpConn;
m_httpConn = NULL;
}
}
return TRUE;
}
BOOL
vncServer::SockConnected()
{
return m_socketConn != NULL;
}
BOOL
vncServer::SetHttpdEnabled(BOOL enable_httpd, BOOL enable_params)
{
if (enable_httpd != m_httpd_enabled) {
m_httpd_enabled = enable_httpd;
m_httpd_params_enabled = enable_params;
BOOL socketConn = SockConnected();
SockConnect(FALSE);
SockConnect(socketConn);
} else {
if (enable_params != m_httpd_params_enabled) {
m_httpd_params_enabled = enable_params;
if (SockConnected()) {
SockConnect(FALSE);
SockConnect(TRUE);
}
}
}
return TRUE;
}
BOOL
vncServer::SetLoopbackOnly(BOOL loopbackOnly)
{
if (loopbackOnly != m_loopbackOnly)
{
m_loopbackOnly = loopbackOnly;
BOOL socketConn = SockConnected();
SockConnect(FALSE);
SockConnect(socketConn);
}
return TRUE;
}
BOOL
vncServer::LoopbackOnly()
{
return m_loopbackOnly;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -