// Add the mouse pointer to the buffer
void vncDesktop::CaptureMouse(BYTE *scrBuff, UINT scrBuffSize)
{
POINT CursorPos;
ICONINFO IconInfo;
// If the mouse cursor handle is invalid then forget it
if (m_hcursor == NULL) return;
// Get the cursor position
if (!GetCursorPos(&CursorPos)) return;
// Translate position for hotspot
if (GetIconInfo(m_hcursor, &IconInfo))
{
CursorPos.x -= ((int) IconInfo.xHotspot);
CursorPos.y -= ((int) IconInfo.yHotspot);
CursorPos.x -= m_ScreenOffsetx;
CursorPos.y -= m_ScreenOffsety;
if (IconInfo.hbmMask != NULL) DeleteObject(IconInfo.hbmMask);
if (IconInfo.hbmColor != NULL) DeleteObject(IconInfo.hbmColor);
}
// Select the memory bitmap into the memory DC
HBITMAP oldbitmap;
if ((oldbitmap = (HBITMAP) SelectObject(m_hmemdc, m_membitmap)) == NULL) return;
// Draw the cursor
DrawIconEx(
m_hmemdc, // handle to device context
CursorPos.x, CursorPos.y,
m_hcursor, // handle to icon to draw
0,0, // width of the icon
0, // index of frame in animated cursor
NULL, // handle to background brush
DI_NORMAL | DI_COMPAT // icon-drawing flags
);
// Select the old bitmap back into the memory DC
SelectObject(m_hmemdc, oldbitmap);
// Save the bounding rectangle
m_cursorpos.tl = CursorPos;
m_cursorpos.br = rfb::Point(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)).translate(CursorPos);
// Clip the bounding rect to the screen
// Copy the mouse cursor into the screen buffer, if any of it is visible
m_cursorpos = m_cursorpos.intersect(m_bmrect);
if (!m_cursorpos.is_empty()) CopyToBuffer(m_cursorpos, scrBuff, scrBuffSize);
}
// CURSOR HANDLING
// Obtain cursor image da
// The length of databuf[] should be at least (width * height * 4).
BOOL vncDesktop::GetRichCursorData(BYTE *databuf, HCURSOR hcursor, int width, int height)
{
// Protect the memory bitmap (is it really necessary here?)
omni_mutex_lock l(m_update_lock);
// Create bitmap, select it into memory DC
HBITMAP membitmap = CreateCompatibleBitmap(m_hrootdc, width, height);
if (membitmap == NULL) return FALSE;
HBITMAP oldbitmap = (HBITMAP) SelectObject(m_hmemdc, membitmap);
if (oldbitmap == NULL)
{
DeleteObject(membitmap);
return FALSE;
}
// Draw the cursor
DrawIconEx(m_hmemdc, 0, 0, hcursor, 0, 0, 0, NULL, DI_IMAGE);
SelectObject(m_hmemdc, oldbitmap);
// Prepare BITMAPINFO structure (copy most m_bminfo fields)
BITMAPINFO *bmi = (BITMAPINFO *)calloc(1, sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD));
memcpy(bmi, &m_bminfo.bmi, sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD));
bmi->bmiHeader.biWidth = width;
bmi->bmiHeader.biHeight = -height;
// Clear da
memset(databuf, 0x00, width * height * 4);
int lines = GetDIBits(m_hmemdc, membitmap, 0, height, databuf, bmi, DIB_RGB_COLORS);
// Cleanup
free(bmi);
DeleteObject(membitmap);
return (lines != 0);
}
// Return the current mouse pointer position
rfb::Rect vncDesktop::MouseRect()
{
return m_cursorpos;
}
void vncDesktop::SetCursor(HCURSOR cursor)
{
if (cursor == NULL)
m_hcursor = m_hdefcursor;
else
{
m_hOldcursor = m_hcursor; // sf@2002
m_hcursor = cursor;
}
}
// Manipulation of the clipboard
void vncDesktop::SetClipText(char* rfbStr)
{
int len = strlen(rfbStr);
char* winStr = new char[len*2+1];
int j = 0;
for (int i = 0; i < len; i++)
{
if (rfbStr[i] == 10) winStr[j++] = 13;
winStr[j++] = rfbStr[i];
}
winStr[j++] = 0;
// Open the system clipboard
if (OpenClipboard(m_hwnd))
{
// Empty it
if (EmptyClipboard())
{
HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, j);
if (hMem != NULL)
{
LPSTR pMem = (char*)GlobalLock(hMem);
// Get the da
strcpy(pMem, winStr);
// Tell the clipboard
GlobalUnlock(hMem);
SetClipboardData(CF_TEXT, hMem);
}
}
}
delete [] winStr;
// Now close it
CloseClipboard();
}
// INTERNAL METHODS
inline void vncDesktop::MaskToMaxAndShift(DWORD mask, CARD16 &max, CARD8 &shift)
{
for (shift = 0; (mask & 1) == 0; shift++) mask >>= 1;
max = (CARD16) mask;
}
// Copy da
void vncDesktop::CopyToBuffer(const rfb::Rect &rect, BYTE *destbuff, UINT destbuffsize)
{
// Finish drawing anything in this thread, Wish we could do this for the whole system - maybe we should do something with LockWindowUpdate here.
GdiFlush();
// Are we being asked to blit from the DIBsection to itself?
if (destbuff == m_DIBbits) return; // Yes. Ignore the request!
int y_inv;
BYTE * destbuffpos;
// Calculate the scanline-ordered y position to copy from
y_inv = m_scrinfo.framebufferHeight-rect.tl.y-(rect.br.y-rect.tl.y);
// Calculate where in the output buffer to put the da
destbuffpos = destbuff + (m_bytesPerRow * rect.tl.y);
// Set the number of bytes for GetDIBits to actually write
// NOTE : GetDIBits pads the destination buffer if biSizeImage < no. of bytes required
m_bminfo.bmi.bmiHeader.biSizeImage = (rect.br.y-rect.tl.y) * m_bytesPerRow;
// Get the actual bits from the bitmap into the bit buffer
// If fast (DIBsection) blits are disabled then use the old GetDIBits technique
if (m_DIBbits == NULL)
{
GetDIBits(m_hmemdc, m_membitmap, y_inv, (rect.br.y-rect.tl.y), destbuffpos, &m_bminfo.bmi, DIB_RGB_COLORS); //0
}
else
{
// Fast blits are enabled. [I have a sneaking suspicion this will never get used, unless
// something weird goes wrong in the co
int bytesPerPixel = m_scrinfo.format.bitsPerPixel / 8;
BYTE *srcbuffpos = (BYTE*)m_DIBbits;
srcbuffpos += (m_bytesPerRow * rect.tl.y) + (bytesPerPixel * rect.tl.x);
destbuffpos += bytesPerPixel * rect.tl.x;
int widthBytes = (rect.br.x-rect.tl.x) * bytesPerPixel;
for(int y = rect.tl.y; y < rect.br.y; y++)
{
memcpy(destbuffpos, srcbuffpos, widthBytes);
srcbuffpos += m_bytesPerRow;
destbuffpos += m_bytesPerRow;
}
}
}
// Routine to find out which windows have moved
// If copyrect detection isn't perfect then this call returns
// the copyrect destination region, to allow the caller to check for mistakes
bool vncDesktop::CalcCopyRects(rfb::UpdateTracker &tracker)
{
HWND foreground = GetForegroundWindow();
RECT foreground_rect;
// Actually, we just compare the new and old foreground window & its position
if (foreground != m_foreground_window)
{
m_foreground_window=foreground;
// Is the window invisible or can we not get its rect?
if (!IsWindowVisible(foreground) || !GetWindowRect(foreground, &foreground_rect))
{
//Buffer coordinates
m_foreground_window_rect.clear();
}
else
{
foreground_rect.left-=m_ScreenOffsetx;
foreground_rect.right-=m_ScreenOffsetx;
foreground_rect.top-=m_ScreenOffsety;
foreground_rect.bottom-=m_ScreenOffsety;
m_foreground_window_rect = foreground_rect;
}
}
else
{
// Same window is in the foreground - let's see if it's moved
RECT destrect;
rfb::Rect dest;
rfb::Point source;
// Get the window rectangle
if (IsWindowVisible(foreground) && GetWindowRect(foreground, &destrect))
{
//screen to buffer coordinates
destrect.left-=m_ScreenOffsetx;
destrect.right-=m_ScreenOffsetx;
destrect.top-=m_ScreenOffsety;
destrect.bottom-=m_ScreenOffsety;
rfb::Rect old_foreground_window_rect = m_foreground_window_rect;
source = m_foreground_window_rect.tl;
m_foreground_window_rect = dest = destrect;
if (!dest.is_empty() && !old_foreground_window_rect.is_empty())
{
// Got the destination position. Now send to clients!
if (!source.equals(dest.tl))
{
rfb::Point delta;
delta= rfb::Point(dest.tl.x-source.x, dest.tl.y-source.y);
// Clip the destination rectangle
dest = dest.intersect(m_bmrect);
if (dest.is_empty()) return false;
// Clip the source rectangle
dest = dest.translate(delta.negate()).intersect(m_bmrect);
m_buffer.ClearCacheRect(dest);
dest = dest.translate(delta);
m_buffer.ClearCacheRect(dest);
if (!dest.is_empty())
{
tracker.add_copied(dest, delta);
return true;
}
}
}
}
else
m_foreground_window_rect.clear();
}
return false;
}
// Window procedure for the Desktop window
LRESULT CALLBACK DesktopWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
vncDesktop *_this = (vncDesktop*)GetWindowLong(hwnd, GWL_USERDATA);
switch (iMsg)
{
///ddihook
case WM_SYSCOMMAND:
// User has clicked an item on the tray menu
return DefWindowProc(hwnd, iMsg, wParam, lParam);
case WM_POWER:
case WM_POWERBROADCAST:
// User has clicked an item on the tray menu
return DefWindowProc(hwnd, iMsg, wParam, lParam);
case WM_COPYDATA:
_this->pMyCDS= (PCOPYDATASTRUCT) lParam;
if (_this->pMyCDS->dwData==112233)
{
DWORD mysize=_this->pMyCDS->cbData;
char mytext[1024];
char *myptr;
char split[4][6];
strcpy(mytext,(LPCSTR)_this->pMyCDS->lpData);
myptr=mytext;
for (int j =0; j<(mysize/20);j++)
{
for (int i=0;i<4;i++)
{
strcpy(split[i]," ");
strncpy(split[i],myptr,4);
myptr=myptr+5;
}
_this->QueueRect(rfb::Rect(atoi(split[0]), atoi(split[1]), atoi(split[2]), atoi(split[3])));
}
}
return 0;
case WM_DISPLAYCHANGE:
// The display resolution is changing
// We must kick off any clients since their screen size will be wrong
// WE change the clients screensize, if they support it.
// We First check if the Resolution changed is caused by a temp resolution switch
// For a temp resolution we don't use the driver, to fix the mirror driver
// to the new change, a resolution switch is needed, preventing screensaver locking.
if (_this->m_videodriver != NULL)
{
_this->Temp_Resolution=_this->m_videodriver->Tempres();
_this->m_videodriver->Temp_Resolution=_this->m_videodriver->Tempres();
}
else _this->Temp_Resolution=false;
if (_this->m_videodriver != NULL) //Video driver active
{
if (!_this->m_videodriver->blocked)
{
_this->m_displaychanged = TRUE;
if ( _this->Temp_Resolution)
_this->m_hookdriver=false;
else
{
_this->m_hookdriver=true;
_this->m_videodriver->blocked=true;
}
}
else
{
//Remove display change, cause by driver activation
_this->m_videodriver->blocked=false;
}
}
else
{
_this->m_displaychanged = TRUE;
_this->m_hookdriver=true;
}
return 0;
case WM_SYSCOLORCHANGE:
case WM_PALETTECHANGED:
// The palette colours have changed, so tell the server Get the system palette
if (!_this->SetPalette()) PostQuitMessage(0);
// Update any palette-based clients, too
_this->m_server->UpdatePalette();
return 0;
case WM_CHANGECBCHAIN:
// The clipboard chain has changed - check our nextviewer handle
if ((HWND)wParam == _this->m_hnextviewer)
_this->m_hnextviewer = (HWND)lParam;
else if (_this->m_hnextviewer != NULL)
SendMessage(_this->m_hnextviewer, WM_CHANGECBCHAIN, wParam, lParam);
return 0;
case WM_DRAWCLIPBOARD:
// The clipboard contents have changed
if((GetClipboardOwner() != _this->Window()) && _this->m_initialClipBoardSeen && _this->m_clipboard_active)
{
LPSTR cliptext = NULL;
// Open the clipboard
if (OpenClipboard(_this->Window()))
{
// Get the clipboard da
HGLOBAL cliphandle = GetClipboardData(CF_TEXT);
if (cliphandle != NULL)
{
LPSTR clipdata = (LPSTR) GlobalLock(cliphandle);
// Copy it into a new buffer
if (clipdata == NULL)
cliptext = NULL;
else
cliptext = strdup(clipdata);
// Release the buffer and close the clipboard
GlobalUnlock(cliphandle);
}
CloseClipboard();
}
if (cliptext != NULL)
{
int cliplen = strlen(cliptext);
LPSTR unixtext = (char *)malloc(cliplen+1);
// Replace CR-LF with LF - never send CR-LF on the wire, since Unix won't like it
int unixpos=0;
for (int x=0; x<cliplen; x++)
{
if (cliptext[x] != '\x0d')
{
unixtext[unixpos] = cliptext[x];
unixpos++;
}
}
unixtext[unixpos] = 0;
// Free the clip text
free(cliptext);
cliptext = NULL;
// Now send the unix text to the server
_this->m_server->UpdateClipText(unixtext);
free(unixtext);
}
}
_this->m_initialClipBoardSeen = TRUE;
if (_this->m_hnextviewer != NULL)
{
// Pass the message to the next window in clipboard viewer chain.
return SendMessage(_this->m_hnextviewer, WM_DRAWCLIPBOARD, 0,0);
}
return 0;
default:
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
return 0;
}
// Modif rdv@2002 Dis/enable input
void vncDesktop::SetDisableInput(bool enabled)
{
typedef DWORD (WINAPI *PSLWA)(HWND, DWORD, BYTE, DWORD);
PSLWA pSetLayeredWindowAttributes;
HMODULE hDLL = LoadLibrary ("user32");
pSetLayeredWindowAttributes = (PSLWA) GetProcAddress(hDLL,"SetLayeredWindowAttributes");
if (!pSetLayeredWindowAttributes) m_server->BlackAlphaBlending(false);
if (VideoBuffer())m_server->BlackAlphaBlending(false);
//BlockInput block everything on non w2k and XP, if hookdll is used, he take care of input blocking
if (OSVersion()==1)
{
if (pbi) (*pbi)(enabled);
}
else
{
m_server->DisableLocalInputs(enabled);
On_Off_hookdll=true;
}
// Also Turn Off the Monitor if allowed ("Blank Screen", "Blank Monitor")
if (m_server->BlankMonitorEnabled())
if (enabled)
{
if (!m_server->BlackAlphaBlending())
{
SetProcessShutdownParameters(0x100, 0);
SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0, &OldPowerOffTimeout, 0);
SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 100, NULL, 0);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 1, NULL, 0);
SendMessage(m_hwnd,WM_SYSCOMMAND,SC_MONITORPOWER,(LPARAM)2);
}
else
{
HANDLE ThreadHandle2;
DWORD dwTId;
ThreadHandle2 = CreateThread(NULL, 0, BlackWindow, NULL, 0, &dwTId);
CloseHandle(ThreadHandle2);
OldCaptureBlending=m_fCaptureAlphaBlending;
m_fCaptureAlphaBlending=false;
}
}
else // Monitor On
{
if (!m_server->BlackAlphaBlending())
{
if (OldPowerOffTimeout!=0) SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, OldPowerOffTimeout, NULL, 0);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, NULL, 0);
SendMessage(m_hwnd,WM_SYSCOMMAND,SC_MONITORPOWER,(LPARAM)-1);
OldPowerOffTimeout=0;
}
else
{
HWND Blackhnd = FindWindow(("blackscreen"), 0);
if (Blackhnd) PostMessage(Blackhnd, WM_CLOSE, 0, 0);
m_fCaptureAlphaBlending=OldCaptureBlending;
}
}
}
void vncDesktop::SetSW(int x,int y)
{
POINT point;
point.x=x;
point.y=y;
if (x <= 5 && y<=5 && x>-5 && y>-5)
{
switch(asked_display)
{
case 1:
m_buffer.Display(-1);
m_buffer.Display(2);
m_Single_hWnd=NULL;
break;
case 2:
m_buffer.Display(1);
m_buffer.Display(2);
m_Single_hWnd=NULL;
break;
case 3:
m_buffer.Display(1);
m_buffer.Display(-2);
m_Single_hWnd=NULL;
break;
}
return;
}
m_Single_hWnd=WindowFromPoint(point);
if (m_Single_hWnd==GetDesktopWindow())
{
LPGETMONITORINFO GetMonitorInfo=NULL;
LPMONITOTFROMPOINT MonitorFromPoint=NULL;
MONITORINFO monitorinfo;
monitorinfo.cbSize=sizeof(MONITORINFO);
GetMonitorInfo=(LPGETMONITORINFO) GetProcAddress(LoadLibrary("user32.dll"), "GetMonitorInfoA");
MonitorFromPoint=(LPMONITOTFROMPOINT) GetProcAddress(LoadLibrary("user32.dll"), "MonitorFromPointA");
if (GetMonitorInfo && MonitorFromPoint)
{
HMONITOR hmonitor=MonitorFromPoint(point,MONITOR_DEFAULTTONEAREST);
GetMonitorInfo(hmonitor,&monitorinfo);
if (monitorinfo.dwFlags ==MONITORINFOF_PRIMARY)
{
m_buffer.Display(1);
m_buffer.Display(-2);
m_Single_hWnd=NULL;
}
else
{
m_buffer.Display(-1);
m_buffer.Display(2);
m_Single_hWnd=NULL;
}
}
return;
}
if (m_Single_hWnd==NULL) m_server->SingleWindow(false);
else
{
HWND parent;
while((parent=GetParent(m_Single_hWnd))!=NULL) m_Single_hWnd=parent;
m_server->SingleWindow(true);
}
}
BOOL vncDesktop::VideoBuffer()
{
//Always access the shared mememory thru this function
if (m_videodriver==NULL) return FALSE;
if (IsBadReadPtr(m_videodriver,1)) return FALSE;
// If we reach this place, the driver was active
if (m_videodriver->driver_succes) return true;
if (!m_videodriver->driver_succes && Temp_Resolution) return false;
if (!m_videodriver->driver_succes && !Temp_Resolution)
{
m_videodriver->StopMirroring();
m_hookswitch=true;
Hookdll_Changed=true;
return FALSE;
}
return FALSE;
}
DWORD WINAPI Warningbox_non_locked(LPVOID lpParam)
{
MessageBox(NULL,"Current driver to old for this version \nUpdate driver or disable Video hook driver\n in the server properties window","",0);
return 0;
}
BOOL vncDesktop::InitVideoDriver()
{
omni_mutex_lock l(m_videodriver_lock);
if(OSVersion()!=1 ) return true; //we need w2k or xp
// First check driver version
if (m_videodriver!=NULL)
{
if (m_videodriver!=NULL) delete m_videodriver;
}
m_videodriver=new vncVideoDriver;
//try to use the mirror driver if he is still active
if (m_videodriver->IsMirrorDriverActive())
{
// This should normal not happen
m_videodriver->StartMirroring();
m_hookdriver=true;
m_hookdll=false;
}
else // no drivers where active, so start the mirror driver
{
Checkmonitors();
nr_monitors=GetNrMonitors();
if (nr_monitors==1)
{
m_ScreenOffsetx=mymonitor[0].offsetx;
m_ScreenOffsety=mymonitor[0].offsety;
m_videodriver->Activate_video_driver(true,mymonitor[0].offsetx,mymonitor[0].offsety,mymonitor[0].Width,mymonitor[0].Height);
}
if (nr_monitors>1)
{
m_ScreenOffsetx=mymonitor[2].offsetx;
m_ScreenOffsety=mymonitor[2].offsety;
m_videodriver->Activate_video_driver(true,mymonitor[2].offsetx,mymonitor[2].offsety,mymonitor[2].Width,mymonitor[2].Height);
}
m_videodriver->StartMirroring();
m_hookdriver=true;
m_hookdll=false;
}
// check if driver has mapped the shared memory
if (!m_videodriver->driver_succes)
{
if (m_videodriver!=NULL) delete m_videodriver;
m_videodriver=NULL;
// If driver selected and fialed to start default to hookdll
m_hookdriver=false;
m_hookdll=true;
//Necessary for the following InitHookSettings() call Remember old states
DriverWantedSet=true;
DriverWanted=m_server->Driver();
HookWanted=m_server->Hook();
m_server->Driver(false);
m_server->Hook(true);
return false;
}
if (m_videodriver->driver_succes)
{
if (!m_videodriver->driver_succes)
{
delete m_videodriver;
m_videodriver=NULL;
// If driver selected and fialed to start default to hookdll
m_hookdriver=false;
m_hookdll=true;
return false;
}
InvalidateRect(NULL,NULL,TRUE);
return true;
}
return true;
}
void vncDesktop::ShutdownVideoDriver()
{
if(OSVersion()!=1) return;
if (m_videodriver==NULL) return;
if (m_videodriver!=NULL)
{
delete m_videodriver;
m_videodriver=NULL;
}
StopDriverWatches=true;
}
// This proc sets the Desktop update handling params depending
// on tranitted settings and internal constraints.
// It is called from several places (InitHookSettings(), SetHookings() and from Desktop thread loop).
void vncDesktop::SethookMechanism(BOOL hookall,BOOL hookdriver)
{
m_hookswitch=false;
// Force at least on
if (!hookall && !hookdriver && !m_server->PollFullScreen())
{
hookall = TRUE;
m_server->PollFullScreen(TRUE);
}
// 9,x case
if(OSVersion()==4 || OSVersion()==5)
{
m_hookdriver=false;//(user driver updates)
m_hookdll=false;//(use hookdll updates)
if (hookall || hookdriver) m_hookdll=true;
//always try to stop the ddihook before starting
StartStopddihook(false);ddihook=false;
if (hookdriver) StartStopddihook(true);
// same for the hookdll
BOOL old_On_Off_hookdll=On_Off_hookdll;
if (hookdriver || hookall) On_Off_hookdll=true;
else On_Off_hookdll=false;
if (old_On_Off_hookdll!=On_Off_hookdll) Hookdll_Changed=true;
else Hookdll_Changed=false;
}
// W2k-XP case
else if(OSVersion()==1)
{
// We forbid hoodll and hookdriver at the same time (pointless and high CPU load)
if (!hookall && !hookdriver) {m_hookdll=false;m_hookdriver=false;}
if (hookall && hookdriver) {m_hookdll=false;m_hookdriver=true;}
if (hookall && !hookdriver) {m_hookdll=true;m_hookdriver=false;}
if (!hookall && hookdriver) {m_hookdll=false;m_hookdriver=true;}
BOOL old_On_Off_hookdll=On_Off_hookdll;
if (m_hookdll) On_Off_hookdll=true;
else On_Off_hookdll=false;
if (old_On_Off_hookdll!=On_Off_hookdll) Hookdll_Changed=true;
else Hookdll_Changed=false;
if ((m_hookdriver && !VideoBuffer()) || (!m_hookdriver && VideoBuffer())) m_hookswitch=true;
}
else //NT4
{
if (!hookall && !hookdriver) {m_hookdll=false;m_hookdriver=false;}
if (hookall && hookdriver) {m_hookdll=true;m_hookdriver=false;}
if (hookall && !hookdriver) {m_hookdll=true;m_hookdriver=false;}
if (!hookall && hookdriver) {m_hookdll=false;m_hookdriver=false;}
BOOL old_On_Off_hookdll=On_Off_hookdll;
if (m_hookdll) On_Off_hookdll=true;
else On_Off_hookdll=false;
if (old_On_Off_hookdll!=On_Off_hookdll) Hookdll_Changed=true;
else Hookdll_Changed=false;
}
}
void vncDesktop::StartStopddihook(BOOL enabled)
{
if (enabled)
{
STARTUPINFO ssi;
PROCESS_INFORMATION ppi;
m_hddihook=NULL;
char szCurrentDir[MAX_PATH];
if (GetModuleFileName(NULL, szCurrentDir, MAX_PATH))
{
char* p = strrchr(szCurrentDir, '\\');
if (p == NULL) return;
*p = '\0';
strcat (szCurrentDir,"\\16bithlp.exe");
}
ZeroMemory( &ssi, sizeof(ssi) );
ssi.cb = sizeof(ssi);
if( !CreateProcess( NULL,szCurrentDir, NULL,NULL,FALSE,NULL,NULL,NULL,&ssi,&ppi))
ddihook=false;
else
{
ddihook=true;
WaitForInputIdle(ppi.hProcess, 10000);
m_hddihook=ppi.hProcess;
}
}
else
{
if (m_hddihook != NULL)
{
TerminateProcess(m_hddihook,0);
m_hddihook=NULL;
ddihook=false;
}
}
}
void vncDesktop::StartStophookdll(BOOL enabled)
{
if (enabled)
{
if (SetHooks)
{
if (!SetHooks(GetCurrentThreadId(), RFB_SCREEN_UPDATE, RFB_COPYRECT_UPDATE, RFB_MOUSE_UPDATE, ddihook))
{
m_server->PollFullScreen(TRUE);
m_hookinited = FALSE;
}
else
m_hookinited = TRUE;
}
if (SetKeyboardFilterHook) SetKeyboardFilterHook(m_server->LocalInputsDisabled());
if (SetMouseFilterHook) SetMouseFilterHook(m_server->LocalInputsDisabled());
}
else if (m_hookinited)
{
if (UnSetHooks) UnSetHooks(GetCurrentThreadId());
}
}
void vncDesktop::InitHookSettings()
{
SethookMechanism(m_server->Hook(),m_server->Driver());
}
评论