WinVNC模块:
一。WinMain函数
1.初始化VSocketSystem套接字,初始化化log为winvnc.log文件,转换命令行参数为小写,解析命令行参数。没有命令行参数则进入WinVNCAppMain。
在函数WinVNCAppMain中:设置进程为关机时最后关闭。创建全局锁,确定只有一个进程实例在运行。
2.vncServer初始化:初始化成员变量,清空密码。如果版本大于4.10,获取屏幕分辨率。
3.vncMenu初始化:获取当前登录账户名,注册窗口类,窗口过程为vncMenu::WndProc。此窗口为tray窗口,设置右键点击的菜单,初始化属性页,初始化CMatchWindow,
窗口的过程为CMatchWindow::WndProc。在vncProperties::Load内根据注册表键值或者配置文件设置socket,http,是否回环等设置,读取注册表
设置用户的偏好设置,密码等。调用vncProperties::ApplyUserPrefs设置vncServer的偏好设置。此函数内部调用vncServer::SockConnect初始化socket连接,创建99个socket,
绑定5900端口,开始监听,开启新线程进入vncSockConnectThread::run_undetached开始监听。开启界面消息循环。
二。当有客户连接时
1.进入函数vncSockConnectThread::run_undetached,这是一个死循环等待客户端连接。进入函数vncServer::AddClient等待连接。进入函数vncClient::Init,
创建线程进入vncClientThread::run处理。
2.在vncClientThread::run中认证:判断黑白客户端名单,向客户端发送RFB协议版本号校验,进行RFB认证安全类型。服务器发送16位随机数,客户端使用DES对验证进行加密,使用用户密码作为密钥,把加密后的16字节返回给服务器。服务器对安全认证进行确认,返回值为无符号32位整数,如果为0则表示成功,1表示失败。如果不成功,服务器直接关闭连接。
3.在vncClientThread::run中进行消息发送:客户端发送一个字节的初始化消息。服务器发送初始化消息,通过rfbServerInitMsg格式告知客户端服务器的帧缓存的高、宽、象素格式和桌面相关的名称。客户端发送设置像素格式,客户端发送设置编码格式,服务端发送确认编码格式。
4.在vncClientThread::run中死循环接收客户端发送的请求消息。
三。客户端发送的消息格式
进入函数VSocket::ReadExact等待客户端发送的消息。
1.rfbClientCutText代表客户端的剪切板里有内容,更新到服务端的剪切板。
2.rfbFramebufferUpdateRequest代表服务端有屏幕更新,
3.rfbKeyEvent客户端发送了按键事件,进入vncKeymap::keyEvent处理按键事件。进入函数keyEvent,调用函数keybd_event进行模拟按键。
VNCHooks模块: 负责VNC图像更新机制
一.SetHook:添加三种类型的hook。CallWindow Hook,GetMessage Hook,SYSMSGFILTER Hook(负责所有窗口的消息,包括非客户区).
hook消息统一进入函数HookHandle函数处理。该函数向主窗口发送UpdateRectMessage消息,告知窗口,有屏幕更新。
二.SetKeyboardFilterHook。添加键盘hook。
三。SetMouseFilterHook。设置鼠标hook。
四。进入函数vncDesktopThread::run_undetached处理消息,该函数死循环等待屏幕,键盘,鼠标的更新消息。
1.如果是屏幕更新,创建一个矩形区域,设置位置,然后添加到m_changed_rgn成员变量中。
2.在函数vncDesktop::CheckUpdates中,不断检查更新,这个函数在vncDesktopThread::run_undetached中死循环一直调用。
如果是polling模式,进入vncDesktop::PerformPolling函数,依次进入函数CheckRects等处理
如果是采用全屏扫描方式,默认是hook方式获取屏幕变化,在PerformPolling函数中进入PollArea函数处理。
VNC的编码模块(Hextile, RRE):