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);
// Set this process to be the last application to be shut down.
SetProcessShutdownParameters(0x100, 0);
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;
}
// Check the protocol version
int major, minor;
sscanf((char *)&protocol_ver, "RFB %03d.%03d/n", &major, &minor);
// 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;
}
// Disable Nagle's algorithm
BOOL nodelayval = TRUE;
setsockopt(m_sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelayval, sizeof(BOOL));
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
};
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);
....
}
GetRgnBox 获取HRGN的边界矩形
GetRegionData 可以将一个HRGN分解为一个RECT数组,见RGNDATA结构体说明
CombineRgn 对HRGN操作RGN_AND,RGN_COPY,RGN_DIFF,RGN_OR或是RGN_XOR
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 |
其服务端的主要功能模块结构如下:
其核心框架就是四个类vncClient,vncServer,vncDesktop和vncBuffer.下面我就这四个类之间的联系和用途来作一下简单的分析:
vncServer:
vncServer 主要是做如下的一些工作:容许vncClient动态的添加和删除;将本地vncDesktop对象内部状态的任何改变"传播"到各个客户端;传播客户端 的鼠标和键盘事件到本地的vncDesktop对象。同时,其还创建了vncSockConnect,vncCORBAConnect和 vncHTTPConnect来接受Socket,Corba和HTTP的连接。 vncServer为每个连接上来的客户端分配了一个ClientID(其实就是内部客户对象数组的Index),并且提供了对客户端管理的众多函数:
virtual void DisableClients(BOOL state);同时,vncServer还提供了对客户Teleport,Capability,KeyboardEnabled,PointerEnabled,Name,Authenticated属性的get/set方法。
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);
virtual void TriggerUpdate();vncDesktop:
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();