CBTFile::CBTFile(const void* Data): SelfAllocated(false), Version(BT_INVALID), MinHeight(NoDataF), MaxHeight(NoDataF) { n_assert2(Data, "NULL data in constructor of CBTFile"); Header = (CHeaderUnion*)Data; HeightsF = (float*)((char*)Data + sizeof(CHeaderUnion)); InitVersion(); n_assert(Version != BT_INVALID); }
CRDVApp::CRDVApp() { // Initialize the O/S version information InitVersion(); // Output the licensing disclaimer DebugMsg("Remote Desktop System, Copyright (C) 2000-2009 GravyLabs LLC\n"); DebugMsg("GravyLabs LLC can be reached at [email protected]\n"); DebugMsg("Remote Desktop System comes with ABSOLUTELY NO WARRANTY\n"); DebugMsg("This is free software, and you are welcome to redistribute it\n"); DebugMsg("under of the GNU General Public License as published by\n"); DebugMsg("the Free Software Foundation; version 2 of the License.\n"); }
int CLocalizingMgr::InitVersion(const char* szNationName,const int iIsFreeBeta)//단 한번만 호출 하도록 하십시요. { return InitVersion(ConvertNameToCode(szNationName),iIsFreeBeta); }
void vncClientThread::run(void *arg) { // All this thread does is go into a socket-recieve loop, // waiting for stuff on the given socket // IMPORTANT : ALWAYS call RemoveClient on the server before quitting // this thread. vnclog.Print(LL_CLIENTS, VNCLOG("client connected : %s (%hd)\n"), m_client->GetClientName(), m_client->GetClientId()); // Save the handle to the thread's original desktop HDESK home_desktop = GetThreadDesktop(GetCurrentThreadId()); // To avoid people connecting and then halting the connection, set a timeout if (!m_socket->SetTimeout(30000)) vnclog.Print(LL_INTERR, VNCLOG("failed to set socket timeout(%d)\n"), GetLastError()); // Initially blacklist the client so that excess connections from it get dropped m_server->AddAuthHostsBlacklist(m_client->GetClientName()); // LOCK INITIAL SETUP // All clients have the m_protocol_ready flag set to FALSE initially, to prevent // updates and suchlike interfering with the initial protocol negotiations. // GET PROTOCOL VERSION if (!InitVersion()) { m_server->RemoveClient(m_client->GetClientId()); return; } vnclog.Print(LL_INTINFO, VNCLOG("negotiated version\n")); // AUTHENTICATE LINK if (!InitAuthenticate()) { m_server->RemoveClient(m_client->GetClientId()); return; } // Authenticated OK - remove from blacklist and remove timeout m_server->RemAuthHostsBlacklist(m_client->GetClientName()); m_socket->SetTimeout(m_server->AutoIdleDisconnectTimeout()*1000); vnclog.Print(LL_INTINFO, VNCLOG("authenticated connection\n")); // INIT PIXEL FORMAT // Get the screen format m_client->m_fullscreen = m_client->m_encodemgr.GetSize(); // Get the name of this desktop char desktopname[MAX_COMPUTERNAME_LENGTH+1]; DWORD desktopnamelen = MAX_COMPUTERNAME_LENGTH + 1; if (GetComputerName(desktopname, &desktopnamelen)) { // Make the name lowercase for (int x=0; x<strlen(desktopname); x++) { desktopname[x] = tolower(desktopname[x]); } } else { strcpy(desktopname, "WinVNC"); } // Send the server format message to the client rfbServerInitMsg server_ini; server_ini.format = m_client->m_encodemgr.m_buffer->GetLocalFormat(); // Endian swaps server_ini.framebufferWidth = Swap16IfLE(m_client->m_fullscreen.br.x); server_ini.framebufferHeight = Swap16IfLE(m_client->m_fullscreen.br.y); server_ini.format.redMax = Swap16IfLE(server_ini.format.redMax); server_ini.format.greenMax = Swap16IfLE(server_ini.format.greenMax); server_ini.format.blueMax = Swap16IfLE(server_ini.format.blueMax); server_ini.nameLength = Swap32IfLE(strlen(desktopname)); if (!m_socket->SendExact((char *)&server_ini, sizeof(server_ini))) { m_server->RemoveClient(m_client->GetClientId()); return; } if (!m_socket->SendExact(desktopname, strlen(desktopname))) { m_server->RemoveClient(m_client->GetClientId()); return; } vnclog.Print(LL_INTINFO, VNCLOG("sent pixel format to client\n")); // UNLOCK INITIAL SETUP // Initial negotiation is complete, so set the protocol ready flag m_client->EnableProtocol(); // Add a fullscreen update to the client's update list { omni_mutex_lock l(m_client->GetUpdateLock()); m_client->m_update_tracker.add_changed(m_client->m_fullscreen); } // Clear the CapsLock and NumLock keys if (m_client->m_keyboardenabled) { ClearKeyState(VK_CAPITAL); // *** JNW - removed because people complain it's wrong //ClearKeyState(VK_NUMLOCK); ClearKeyState(VK_SCROLL); } // MAIN LOOP // Set the input thread to a high priority set_priority(omni_thread::PRIORITY_HIGH); BOOL connected = TRUE; while (connected) { rfbClientToServerMsg msg; // Ensure that we're running in the correct desktop if (!vncService::InputDesktopSelected()) if (!vncService::SelectDesktop(NULL)) break; // Try to read a message ID if (!m_socket->ReadExact((char *)&msg.type, sizeof(msg.type))) { connected = FALSE; break; } // What to do is determined by the message id switch(msg.type) { case rfbSetPixelFormat: // Read the rest of the message: if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbSetPixelFormatMsg-1)) { connected = FALSE; break; } // Swap the relevant bits. msg.spf.format.redMax = Swap16IfLE(msg.spf.format.redMax); msg.spf.format.greenMax = Swap16IfLE(msg.spf.format.greenMax); msg.spf.format.blueMax = Swap16IfLE(msg.spf.format.blueMax); // Prevent updates while the pixel format is changed m_client->DisableProtocol(); // Tell the buffer object of the change if (!m_client->m_encodemgr.SetClientFormat(msg.spf.format)) { vnclog.Print(LL_CONNERR, VNCLOG("remote pixel format invalid\n")); connected = FALSE; } // Set the palette-changed flag, just in case... m_client->m_palettechanged = TRUE; // Re-enable updates m_client->EnableProtocol(); break; case rfbSetEncodings: // Read the rest of the message: if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbSetEncodingsMsg-1)) { connected = FALSE; break; } // Prevent updates while the encoder is changed m_client->DisableProtocol(); // Read in the preferred encodings msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings); { int x; BOOL encoding_set = FALSE; // By default, don't use copyrect! m_client->m_update_tracker.enable_copyrect(false); for (x=0; x<msg.se.nEncodings; x++) { CARD32 encoding; // Read an encoding in if (!m_socket->ReadExact((char *)&encoding, sizeof(encoding))) { connected = FALSE; break; } // Is this the CopyRect encoding (a special case)? if (Swap32IfLE(encoding) == rfbEncodingCopyRect) { m_client->m_update_tracker.enable_copyrect(true); continue; } // Have we already found a suitable encoding? if (!encoding_set) { // No, so try the buffer to see if this encoding will work... if (m_client->m_encodemgr.SetEncoding(Swap32IfLE(encoding))) encoding_set = TRUE; } } // If no encoding worked then default to RAW! if (!encoding_set) { vnclog.Print(LL_INTINFO, VNCLOG("defaulting to raw encoder\n")); if (!m_client->m_encodemgr.SetEncoding(Swap32IfLE(rfbEncodingRaw))) { vnclog.Print(LL_INTERR, VNCLOG("failed to select raw encoder!\n")); connected = FALSE; } } } // Re-enable updates m_client->EnableProtocol(); break; case rfbFramebufferUpdateRequest: // Read the rest of the message: if (!m_socket->ReadExact(((char *) &msg)+1, sz_rfbFramebufferUpdateRequestMsg-1)) { connected = FALSE; break; } { rfb::Rect update; // Get the specified rectangle as the region to send updates for. update.tl.x = Swap16IfLE(msg.fur.x); update.tl.y = Swap16IfLE(msg.fur.y); update.br.x = update.tl.x + Swap16IfLE(msg.fur.w); update.br.y = update.tl.y + Swap16IfLE(msg.fur.h); rfb::Region2D update_rgn = update; if (update_rgn.is_empty()) { vnclog.Print(LL_INTERR, VNCLOG("FATAL! client update region is empty!\n")); connected = FALSE; break; } { omni_mutex_lock l(m_client->GetUpdateLock()); // Add the requested area to the incremental update cliprect m_client->m_incr_rgn = m_client->m_incr_rgn.union_(update_rgn); // Is this request for a full update? if (!msg.fur.incremental) { // Yes, so add the region to the update tracker m_client->m_update_tracker.add_changed(update_rgn); // Tell the desktop grabber to fetch the region's latest state m_client->m_encodemgr.m_buffer->m_desktop->QueueRect(update); } // Kick the update thread (and create it if not there already) m_client->TriggerUpdateThread(); } } break; case rfbKeyEvent: // Read the rest of the message: if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbKeyEventMsg-1)) { if (m_client->m_keyboardenabled) { msg.ke.key = Swap32IfLE(msg.ke.key); // Get the keymapper to do the work vncKeymap::keyEvent(msg.ke.key, msg.ke.down); m_client->m_remoteevent = TRUE; } } break; case rfbPointerEvent: // Read the rest of the message: if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbPointerEventMsg-1)) { if (m_client->m_pointerenabled) { // Convert the coords to Big Endian msg.pe.x = Swap16IfLE(msg.pe.x); msg.pe.y = Swap16IfLE(msg.pe.y); // Work out the flags for this event DWORD flags = MOUSEEVENTF_ABSOLUTE; long data = 0; if (msg.pe.x != m_client->m_ptrevent.x || msg.pe.y != m_client->m_ptrevent.y) flags |= MOUSEEVENTF_MOVE; if ( (msg.pe.buttonMask & rfbButton1Mask) != (m_client->m_ptrevent.buttonMask & rfbButton1Mask) ) { if (GetSystemMetrics(SM_SWAPBUTTON)) flags |= (msg.pe.buttonMask & rfbButton1Mask) ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; else flags |= (msg.pe.buttonMask & rfbButton1Mask) ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; } if ( (msg.pe.buttonMask & rfbButton2Mask) != (m_client->m_ptrevent.buttonMask & rfbButton2Mask) ) { flags |= (msg.pe.buttonMask & rfbButton2Mask) ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP; } if ( (msg.pe.buttonMask & rfbButton3Mask) != (m_client->m_ptrevent.buttonMask & rfbButton3Mask) ) { if (GetSystemMetrics(SM_SWAPBUTTON)) flags |= (msg.pe.buttonMask & rfbButton3Mask) ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; else flags |= (msg.pe.buttonMask & rfbButton3Mask) ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; } // Mouse wheel support if (msg.pe.buttonMask & rfbWheelUpMask) { flags |= MOUSEEVENTF_WHEEL; data = WHEEL_DELTA; } if (msg.pe.buttonMask & rfbWheelDownMask) { flags |= MOUSEEVENTF_WHEEL; data = -WHEEL_DELTA; } // Generate coordinate values unsigned long x = (msg.pe.x * 65535) / (m_client->m_fullscreen.br.x); unsigned long y = (msg.pe.y * 65535) / (m_client->m_fullscreen.br.y); // Do the pointer event ::mouse_event(flags, (DWORD) x, (DWORD) y, data, 0); // Save the old position m_client->m_ptrevent = msg.pe; // Flag that a remote event occurred m_client->m_remoteevent = TRUE; // Tell the desktop hook system to grab the screen... m_client->m_encodemgr.m_buffer->m_desktop->TriggerUpdate(); } } break; case rfbClientCutText: // Read the rest of the message: if (m_socket->ReadExact(((char *) &msg)+1, sz_rfbClientCutTextMsg-1)) { // Allocate storage for the text const UINT length = Swap32IfLE(msg.cct.length); char *text = new char [length+1]; if (text == NULL) break; text[length] = 0; // Read in the text if (!m_socket->ReadExact(text, length)) { delete [] text; break; } // Get the server to update the local clipboard m_server->UpdateLocalClipText(text); // Free the clip text we read delete [] text; } break; default: // Unknown message, so fail! 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 (%hd)\n"), m_client->GetClientName(), m_client->GetClientId()); // Disable the protocol to ensure that the update thread // is not accessing the desktop and buffer objects m_client->DisableProtocol(); // Finally, it's safe to kill the update thread here if (m_client->m_updatethread) { m_client->m_updatethread->Kill(); m_client->m_updatethread->join(NULL); } // Remove the client from the server // This may result in the desktop and buffer being destroyed // It also guarantees that the client will not be passed further // updates m_server->RemoveClient(m_client->GetClientId()); }