TightVNC analysis document

Source: Internet
Author: User
Tags tightvnc

System Shell:
1.1 iactivedesktop
Allows a client program to manage the desktop items and wallpaper on a local computer.

#include 

IActiveDesktop* active_desktop = 0;
CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
IID_IActiveDesktop, (void**)&active_desktop);


1.2 setprocessshutdownparameters
The setprocessshutdownparameters
Function sets shutdown parameters for the currently calling process.
This function sets a shutdown order for a process relative to the other
Processes in the system.

// Set this process to be the last application to be shut down.
SetProcessShutdownParameters(0x100, 0);


1.3 one instance running by mutex
Use Win32 mutex object to insure that only one instance is currently running in our OS.

const char mutexname [] = "WinVNC_Win32_Instance_Mutex";

BOOL vncInstHandler::Init()
{
// Create the named mutex
HANDLE mutex = CreateMutex(NULL, FALSE, mutexname);
if (mutex == NULL)
return FALSE;

// Check that the mutex didn't already exist
if (GetLastError() == ERROR_ALREADY_EXISTS)
return FALSE;

return TRUE;
}


1.4 sscanf
Read formatted data from a string.

// Check the protocol version
int major, minor;
sscanf((char *)&protocol_ver, "RFB %03d.%03d/n", &major, &minor);


1.5 Kill Screen Saver

// How to kill the screen saver depends on the OS
switch (osversioninfo.dwPlatformId)
case VER_PLATFORM_WIN32_WINDOWS:
HWND hsswnd = FindWindow ("WindowsScreenSaverClass", NULL);
if (hsswnd != NULL)
PostMessage(hsswnd, WM_CLOSE, 0, 0);
break;

case VER_PLATFORM_WIN32_NT:
HDESK hDesk = OpenDesktop(
"Screen-saver",
0,
FALSE,
DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS
);
if (hDesk != NULL)
{
EnumDesktopWindows(hDesk, (WNDENUMPROC) &KillScreenSaverFunc, 0);
CloseDesktop(hDesk);
// Pause long enough for the screen-saver to close
//Sleep(2000);
// Reset the screen saver so it can run again
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE);
}
break;
}


1.6 disable Nagle Algorithm
Nagle
Algorithm is mainly used to optimize the sending of small data packets. It is used to buffer small data packets in the IP stack and accumulate a certain number of small data packets for sending together. This reduces the number of system packages.
Amount, Nagle
Algorithm also has a timeout mechanism internally, but the timeout length cannot be set externally. And for the implementation of each IP stack, this timeout
Span has an implementation-related value.

// Disable Nagle's algorithm
BOOL nodelayval = TRUE;
setsockopt(m_sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelayval, sizeof(BOOL));

Screen capture:
2.1 poll Schema
Poll
The method is the simplest one. It is also the first solution that you come up with when considering screenshots. To obtain the System screen, poll will poll the System screen every 33 Ms and add the changed part
Add to an updateregion. To obtain the rect of these screen changes, the system also adopted an optimization polling algorithm to divide the screen into 32*32
Pixel's small rectangular block, the algorithm provides an order for round-robin of Each rectangular block:

const int pollingOrder[32] = {
0, 16, 8, 24, 4, 20, 12, 28,
10, 26, 18, 2, 22, 6, 30, 14,
1, 17, 9, 25, 7, 23, 15, 31,
19, 3, 27, 11, 29, 13, 5, 21
};

How to obtain the current screen mouse image:
Step 1: Obtain the hcursor of the screen mouse
Getcursorpos
Screen mouse position, then windowfrompoint to get the mouse owner window, getwindowthreadprocessid to get the relevant thread ID, compare this ID
The ID returned by getcurrentthreadid. If it is the same as that returned by getcurrentthreadid, use getcursor to directly obtain the hcursor of the mouse; otherwise, use
Attachthreadinput connects to the input mechanism of the target thread, and then calls getcursor to obtain the hcursor of the mouse.
Step 2: Obtain the bitmap of hcursor

int :GetCursorSendBuffer(BYTE *pBuffer, int nSize)
{
....
ICONINFO IconInfo;
GetIconInfo(hcursor, &IconInfo);

BITMAP bmMask;
GetObject(IconInfo.hbmMask, sizeof(BITMAP), (LPVOID)&bmMask);
GetBitmapBits(IconInfo.hbmMask,bmMask.bmWidthBytes * bmMask.bmHeight, m_mBits);
....
}


It is necessary to introduce the APIS related to hrgn operations.

Getrgnbox obtains the border rectangle of hrgn.
Getregiondata can divide an hrgn into a rect array. For details, see the rgndata struct description.
Combinergn: rgn_and, rgn_copy, rgn_diff, rgn_or rgn_xor

2.2 TightVNC
TightVNC (tight Virtual Network Computing) is an open source software for remote desktop control. For more information, see http://www.tightvnc.com. I downloaded the TightVNC code and analyzed some of its server code. There are many files in WinVNC, But we divide them according to their respective functions. The structure is as follows:

Kernel Vncbuffer. cpp vncclient. cpp vncdesktop. cpp vncserver. cpp WinVNC. cpp
Gui Vncabout. cpp vncacceptdialog. cpp vncadvancedproperties. cpp vncconndialog. cpp vncmenu. cpp vncproperties. cpp vnctimedmsgbox. cpp
Misc D3des. c
Log. cpp MINMAX. cpp rectlist. cpp stdhdrs. cpp tableinitcmtemplate. cpp
Tableinittctemplate. cpp tabletranstemplate. cpp translate. cpp vncauth. c
Vncinsthandler. cpp vnckeymap. cpp vncregion. cpp <vncservice. cpp
Network Vsocket. cpp vncsockconnect. cpp vnchttpconnect. cpp rfbproto. h
Encoding Vncencodecorre. cpp vncencodehext. cpp vncencoder. cpp vncencoderre. cpp vncencodetight. cpp vncencodezlib. cpp vncencodezlibhex. cpp

The main functional modules of the server are as follows:
The core framework is four categories: vncclient, vncserver, vncdesktop, and vncbuffer. Below I will make a simple analysis on the connection and usage between these four categories:
Vncserver:
Vncserver
The main task is to allow vncclient to be dynamically added and deleted, "spread" any changes to the internal status of the local vncdesktop object to various clients, and spread the client.
To the local vncdesktop object. At the same time, it also creates vncsockconnect, vnccorbaconnect and
Vnchttpconnect is used to accept connections between socket, CORBA, and HTTP.
Vncserver assigns a clientid (in fact, the index of the internal customer object array) to each connected client, and provides many functions for client management:

virtual void DisableClients(BOOL state);
virtual void KillClient(vncClientId client);
virtual void KillAuthClients();
virtual void KillUnauthClients();

virtual vncClient* GetClient(vncClientId clientid);
vncClientId AddClient(VSocket *socket, BOOL auth, BOOL shared);
virtual void RemoveClient(vncClientId client);

Vncserver also provides get/set methods for the attributes of teleport, capability, keyboardenabled, pointerenabled, name, and authenticated.
Next, let's take a look at how vncserver handles the two events, client connection and client authentication success:
Vncserver: addclient:
First
First, the vncserver in its internal vncclient
* M_clientmap [max_clients] array allocates an idle slot for the newly connected client and uses it as the client ID of this customer.
Then, assign a vncclient object for this connection, set the relevant attributes of the vncclient object based on the passed parameters, and then call vncclient: init
To pass the instance pointer and clientid Of The vncserver to the vncclient instance. Then, m_clientmap [clientid] =
The client adds the user to the list of unauthenticated users of the vncserver.
Vncserver: authenticated (vncclientid clientid ):
First
First, obtain the vncclient object based on clientid in the list of unauthenticated users, and extract it from the unauth list
. If you are the first vncserver user, create a vncdesktop object and call m_desktop-> Init (this) to initialize
Vncdesktop object. Next, assign this user a vncbuffer * buffer = new
Vncbuffer (m_desktop); and set this buffer by calling vncclient: setbuffer for vncclient.
Add the user to the auth list.
Vncserver provides an operation interface for the user list. These interfaces map vncserver method calls to function calls for the same method of each customer in the auth list. These methods include:

virtual void TriggerUpdate();
virtual void UpdateRect(RECT &rect);
virtual void UpdateRegion(vncRegion ion);
virtual void CopyRect(RECT &dest, POINT &source);
virtual void UpdateMouse();
virtual void UpdateClipText(LPSTR text);
virtual void UpdatePalette();

Vncdesktop:
Vncdesktop is
A globally unique object. According to the annotation, vncdesktop is mainly used to obtain data from the display buffer. At the same time, it also uses rfblib
DLL provides vncserver with information such as mouse movement and screen update. As mentioned above, when vncserver is connected to the first user, it is created when m_desktop is empty.
Create a vncdesktip object and call
Vncdesktop: Init (this) initializes it. In the implementation of vcndesktop: init, we find that it creates
Most vncdesktopthread and vncdesktop method calls are completed in this vncdesktopthread. Let's analyze this line.
What have Cheng done:
Vnc1_topthread: run_undetached (void * Arg ):
First
Call vncdesktop: startup to initialize the vncdesktop object (see vncdesktop: startup), and then process the desktop message,
Call m_server-> updatemouse () and m_server-> updateregion (rgncache)
Next, call vncserver: triggerupdate to send screen updates to each vncclient. Then, the registration messages rfb_screen_update and rfb_mouse_update are processed.

Vncclient:
Vncclient sends data. In the implementation of the vncclient: sendupdate function, we can see that vncclient calls sendrfbmsg to send the message first, then sendcursorshapeupdate sends the Mouse shape update and sendcursorposupdate sends the mouse POS, send sendcopyrect and call sendrectangles to send
Send the data of the rectangle to be updated. In fact, each client vncclient opens a thread when it calls vncclient: init initialization. Basically, the client behavior is
It is completed in vncclientthread: Run. This thread enters
A loop begins to accept and process messages sent from remote clients.
Rfbsetpixelformat, rfbsetencodings, rfbframebufferupdaterequest, rfbkeyevent, rfbpointerevent, rfbclientcuttext
Message.

Vncbuffer:
Vncbuffer is mainly used to process the encoding of sent data. It provides a local view of remote customers. It mainly uses the internal vncdesktop pointer to obtain relevant data.

Reference:

  • Http://www.tightvnc.com/
  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.