登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

VNC Desktop 2  

2009-09-18 09:26:42|  分类: VNC |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

// 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 data in server's local format.
// 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 data buffer and extract RGB data
 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 data
        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 data from the memory bitmap into a buffer
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 data
 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 code.  It's here to keep the function general, though!]
  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 data
    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 one updates handling method !
 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());
}

  评论这张
 
阅读(1948)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018