Beispiel #1
0
CellFile* LoadBmpCellFile(BYTE *buf1, int width, int height)
{
    BYTE* buf2 = new BYTE[(width*height*2)+height], *dest = buf2;

    for (int i = 0; i < height; ++i)
    {
        BYTE *src = buf1 + (i * ((width + 3)&-4)), *limit = src + width;
        while (src < limit)
        {
            BYTE *start = src, *limit2 = min(limit, src+0x7f), trans = !*src;
            do
                src++;
            while ((trans == (BYTE)!*src) && (src < limit2));

            if (!trans || (src < limit))
                *dest++ = (trans?0x80:0)+(src-start);
            if (!trans)
                while (start < src)
                    *dest++ = *start++;
        }
        *dest++ = 0x80;
    }

    static DWORD dc6head[] = { 6, 1, 0, 0xeeeeeeee, 1, 1, 0x1c,  0, -1, -1, 0, 0, 0, -1, -1 };
    dc6head[8] = width;
    dc6head[9] = height;
    BYTE* ret = new BYTE[dc6head[13] = sizeof(dc6head) + (dc6head[14] = dest - buf2) + 3];
    memset(memcpy2(memcpy2(ret, dc6head, sizeof(dc6head)), buf2, dc6head[14]), 0xee, 3);
    delete[] buf2;
    
    return (CellFile *)ret;
}
Beispiel #2
0
void CChatSelector::SendMessagePacket(CChatItem &ci, const CString &strMessage)
{
	uint16	uMessageLen = strMessage.GetLength();
	Packet	*pPacket = new Packet(OP_MESSAGE, uMessageLen + 2);

	memcpy2(pPacket->m_pcBuffer, &uMessageLen, 2);							//<messagelen 2>
	memcpy2(pPacket->m_pcBuffer + 2, strMessage.GetString(), uMessageLen);	//(<messagechar 1>)*messagelen
	g_App.m_pUploadQueue->AddUpDataOverheadOther(pPacket->m_dwSize);
#ifdef OLD_SOCKETS_ENABLED
	ci.m_pClient->m_pRequestSocket->SendPacket(pPacket, true, true);
#endif //OLD_SOCKETS_ENABLED
}
Beispiel #3
0
static int fb_write(int c) {
    uint16 *t = fb;

    if(!t)
        t = vram_s;

    if(c != '\n') {
        bfont_draw(t + cur_y * fb_w + cur_x, fb_w, 1, c);
        cur_x += FONT_CHAR_WIDTH;
    }

    /* If we have a newline or we've gone past the end of the line, advance down
       one line. */
    if(c == '\n' || cur_x + FONT_CHAR_WIDTH > max_x) {
        cur_y += FONT_CHAR_HEIGHT;
        cur_x = min_x;

        /* If going down a line put us over the edge of the screen, move
           everything up a line, fixing the problem. */
        if(cur_y + FONT_CHAR_HEIGHT > max_y) {
            memcpy2(t + min_y * fb_w, t + (min_y + FONT_CHAR_HEIGHT) * fb_w,
                    (cur_y - min_y - FONT_CHAR_HEIGHT) * fb_w * 2);
            cur_y -= FONT_CHAR_HEIGHT;
            memset2(t + cur_y * fb_w, 0, FONT_CHAR_HEIGHT * fb_w * 2);
        }
    }

    return 1;
}
Beispiel #4
0
void CWebSocket::SendData(const void* pData, DWORD dwDataSize)
{
	EMULE_TRY

	ASSERT(pData);
	if (m_bValid && m_bCanSend)
	{
		if (!m_pHead)
		{
			// try to send it directly
			//-- remember: in "nRes" could be "-1" after "send" call
			int nRes = send(m_hSocket, (const char*) pData, dwDataSize, 0);

			if (((nRes < 0) || (nRes > (signed) dwDataSize)) && (WSAEWOULDBLOCK != WSAGetLastError()))
			{
				m_bValid = false;
			}
			else
			{
				//-- in nRes still could be "-1" (if WSAEWOULDBLOCK occured)
				//-- next to line should be like this:
				((const char*&) pData) += (nRes == -1 ? 0 : nRes);
				dwDataSize -= (nRes == -1 ? 0 : nRes);
				//-- ... and not like this:
				//-- ((const char*&) pData) += nRes;
				//-- dwDataSize -= nRes;
			}
		}

		if (dwDataSize && m_bValid)
		{
			// push it to our tails
			CChunk* pChunk = new CChunk;
			if (pChunk != NULL)
			{
				pChunk->m_pNext = NULL;
				pChunk->m_dwSize = dwDataSize;
				if ((pChunk->m_pData = new char[dwDataSize]) != NULL)
				{
					//-- data should be copied into "pChunk->m_pData" anyhow
					memcpy2(pChunk->m_pData, pData, dwDataSize);

					// push it to the end of our queue
					pChunk->m_pToSend = pChunk->m_pData;
					if (m_pTail)
						m_pTail->m_pNext = pChunk;
					else
						m_pHead = pChunk;
					m_pTail = pChunk;
				} else
					delete pChunk; // oops, no memory (???)
			}
		}
	}
	EMULE_CATCH2
}
Beispiel #5
0
int CRollupCtrl::SetItemHeights(int iItem, double *pHeights, unsigned uiSize)
{
	RollupEntry *pEntry;

	if ((static_cast<unsigned>(iItem) >= static_cast<unsigned>(m_List.GetSize())) || (uiSize > sizeof(pEntry->adSizes)))
		return -1;

	pEntry = m_List.GetAt(iItem);
	memcpy2(pEntry->adSizes, pHeights, uiSize);
	return 0;
}
Beispiel #6
0
void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
    const md5_byte_t *p = data;
    int left = nbytes;
    int offset = (pms->count[0] >> 3) & 63;
    md5_word_t nbits = (md5_word_t)(nbytes << 3);

    if (nbytes <= 0)
	return;

    /* Update the message length. */
    pms->count[1] += nbytes >> 29;
    pms->count[0] += nbits;
    if (pms->count[0] < nbits)
	pms->count[1]++;

    /* Process an initial partial block. */
    if (offset) {
	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);

	memcpy2(pms->buf + offset, p, copy);
	if (offset + copy < 64)
	    return;
	p += copy;
	left -= copy;
	md5_process(pms, pms->buf);
    }

    /* Process full blocks. */
    for (; left >= 64; p += 64, left -= 64)
	md5_process(pms, p);

    /* Process a final partial block. */
    if (left)
	memcpy2(pms->buf, p, left);
}
Beispiel #7
0
void copy_smart( void *dst, void *src, Huint bytes )
{
    double          sc;
    hthread_time_t  start;
    hthread_time_t  finish;

    hthread_time_get( &start );
    memcpy2( dst, src, bytes );
    hthread_time_get( &finish );

    hthread_time_diff( finish, finish, start );
    sc = hthread_time_sec(finish);

    printf( "Smart Copy:  %f secs\n", sc );
}
Beispiel #8
0
BOOL CEnBitmap::GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize)
{ 
	HRSRC		hResInfo;
	HANDLE		hRes;
	LPSTR		lpRes	= NULL; 
	bool		bResult	= FALSE;

	// Find the resource
	hResInfo = FindResource(hInst, lpName, lpType);

	if (hResInfo == NULL) 
		return false;

	// Load the resource
	hRes = LoadResource(hInst, hResInfo);

	if (hRes == NULL) 
		return false;

	// Lock the resource
	lpRes = (char*)LockResource(hRes);

	if (lpRes != NULL)
	{ 
		if (pResource == NULL)
		{
			nBufSize = SizeofResource(hInst, hResInfo);
			bResult = true;
		}
		else
		{
			if (nBufSize >= (int)SizeofResource(hInst, hResInfo))
			{
				memcpy2(pResource, lpRes, nBufSize);
				bResult = true;
			}
		} 

		UnlockResource(hRes);  
	}

	// Free the resource
	FreeResource(hRes);

	return bResult;
}
Beispiel #9
0
IPicture* CEnBitmap::LoadFromBuffer(BYTE* pBuff, int nSize)
{
	HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize);
	void* pData = GlobalLock(hGlobal);
	memcpy2(pData, pBuff, nSize);
	GlobalUnlock(hGlobal);

	IStream* pStream = NULL;
	IPicture* pPicture = NULL;

	if (CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK)
	{
		OleLoadPicture(pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&pPicture);
		pStream->Release();
	}

	return pPicture; // caller releases
}
Beispiel #10
0
void CEMSocket::SendPacket(Packet *pPacket, bool bDeletePacket/*=true*/, bool bControlPacket/*=true*/)
{
//	EMTrace("CEMSocket::OnSenPacked1 linked: %i, controlcount %i, standardcount %i, isbusy: %i",m_bLinkedPackets, m_controlPacketQueue.GetCount(), m_standardPacketQueue.GetCount(), IsBusy());
	if (!bDeletePacket)
	{
		ASSERT (!pPacket->IsSplit());

		Packet		*pPacketCopy = new Packet(pPacket->m_eOpcode,pPacket->m_dwSize);

		memcpy2(pPacketCopy->m_pcBuffer,pPacket->m_pcBuffer,pPacket->m_dwSize);
		pPacket = pPacketCopy;
	}			
	if (!IsConnected() || IsBusy() || (m_bLinkedPackets && bControlPacket))
	{
		if (bControlPacket)
			m_controlPacketQueue.AddTail(pPacket);
		else
			m_standardPacketQueue.AddTail(pPacket);
		return;
	}

	bool		bCheckControlQueue = false;

	if (pPacket->IsLastSplit())
	{
		m_bLinkedPackets = false;
		bCheckControlQueue = true;
	}
	else if (pPacket->IsSplit())
	{
		m_bLinkedPackets = true;
	}
	else if (m_bLinkedPackets)
	{
		ASSERT(false);
	}
//	EMTrace("CEMSocket::OnSenPacked2 linked: %i, controlcount %i, standardcount %i, isbusy: %i",m_bLinkedPackets, m_controlPacketQueue.GetCount(), m_standardPacketQueue.GetCount(), IsBusy());
	Send(pPacket->DetachPacket(), pPacket->GetRealPacketSize());
	delete pPacket;
	if (!IsBusy() && bCheckControlQueue)
		OnSend(0);
}
Beispiel #11
0
//Funcion que inicializa la tarea IDLE
void SetupScheduler(void)
{
	void* idleprocess;
	int i;

	for (i = 0; i < 64; i++)
		procesos[i].free = 1;
	
	idleprocess= Malloc(0x200);
	idle.pid=0;
	idle.foreground=0;
	idle.priority=4;
	memcpy2(idle.name,"Idle",5);
	idle.sleep=0;
	idle.blocked=0;
	idle.tty=0;
	idle.stackstart=(int)idleprocess;
	idle.stacksize=0x200;
	procesos[i].parent=0;
	idle.lastCalled=0;
	idle.ESP=LoadStackFrame(Idle,0,0,(int)(idleprocess+0x1FF),Cleaner);
	
	return;
}
Beispiel #12
0
static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
    md5_word_t
	a = pms->abcd[0], b = pms->abcd[1],
	c = pms->abcd[2], d = pms->abcd[3];
    md5_word_t t;
#if BYTE_ORDER > 0
    /* Define storage only for big-endian CPUs. */
    md5_word_t X[16];
#else
    /* Define storage for little-endian or both types of CPUs. */
    md5_word_t xbuf[16];
    const md5_word_t *X;
#endif

    {
#if BYTE_ORDER == 0
	/*
	 * Determine dynamically whether this is a big-endian or
	 * little-endian machine, since we can use a more efficient
	 * algorithm on the latter.
	 */
	static const int w = 1;

	if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0		/* little-endian */
	{
	    /*
	     * On little-endian machines, we can process properly aligned
	     * data without copying it.
	     */
	    if (!((data - (const md5_byte_t *)0) & 3)) {
		/* data are properly aligned */
		X = (const md5_word_t *)data;
	    } else {
		/* not aligned */
		memcpy2(xbuf, data, 64);
		X = xbuf;
	    }
	}
#endif
#if BYTE_ORDER == 0
	else			/* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0		/* big-endian */
	{
	    /*
	     * On big-endian machines, we must arrange the bytes in the
	     * right order.
	     */
	    const md5_byte_t *xp = data;
	    int i;

#  if BYTE_ORDER == 0
	    X = xbuf;		/* (dynamic only) */
#  else
#    define xbuf X		/* (static only) */
#  endif
	    for (i = 0; i < 16; ++i, xp += 4)
		xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
	}
#endif
    }

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))

    /* Round 1. */
    /* Let [abcd k s i] denote the operation
       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + F(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d,  0,  7,  T1);
    SET(d, a, b, c,  1, 12,  T2);
    SET(c, d, a, b,  2, 17,  T3);
    SET(b, c, d, a,  3, 22,  T4);
    SET(a, b, c, d,  4,  7,  T5);
    SET(d, a, b, c,  5, 12,  T6);
    SET(c, d, a, b,  6, 17,  T7);
    SET(b, c, d, a,  7, 22,  T8);
    SET(a, b, c, d,  8,  7,  T9);
    SET(d, a, b, c,  9, 12, T10);
    SET(c, d, a, b, 10, 17, T11);
    SET(b, c, d, a, 11, 22, T12);
    SET(a, b, c, d, 12,  7, T13);
    SET(d, a, b, c, 13, 12, T14);
    SET(c, d, a, b, 14, 17, T15);
    SET(b, c, d, a, 15, 22, T16);
#undef SET

     /* Round 2. */
     /* Let [abcd k s i] denote the operation
          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + G(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
     /* Do the following 16 operations. */
    SET(a, b, c, d,  1,  5, T17);
    SET(d, a, b, c,  6,  9, T18);
    SET(c, d, a, b, 11, 14, T19);
    SET(b, c, d, a,  0, 20, T20);
    SET(a, b, c, d,  5,  5, T21);
    SET(d, a, b, c, 10,  9, T22);
    SET(c, d, a, b, 15, 14, T23);
    SET(b, c, d, a,  4, 20, T24);
    SET(a, b, c, d,  9,  5, T25);
    SET(d, a, b, c, 14,  9, T26);
    SET(c, d, a, b,  3, 14, T27);
    SET(b, c, d, a,  8, 20, T28);
    SET(a, b, c, d, 13,  5, T29);
    SET(d, a, b, c,  2,  9, T30);
    SET(c, d, a, b,  7, 14, T31);
    SET(b, c, d, a, 12, 20, T32);
#undef SET

     /* Round 3. */
     /* Let [abcd k s t] denote the operation
          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + H(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
     /* Do the following 16 operations. */
    SET(a, b, c, d,  5,  4, T33);
    SET(d, a, b, c,  8, 11, T34);
    SET(c, d, a, b, 11, 16, T35);
    SET(b, c, d, a, 14, 23, T36);
    SET(a, b, c, d,  1,  4, T37);
    SET(d, a, b, c,  4, 11, T38);
    SET(c, d, a, b,  7, 16, T39);
    SET(b, c, d, a, 10, 23, T40);
    SET(a, b, c, d, 13,  4, T41);
    SET(d, a, b, c,  0, 11, T42);
    SET(c, d, a, b,  3, 16, T43);
    SET(b, c, d, a,  6, 23, T44);
    SET(a, b, c, d,  9,  4, T45);
    SET(d, a, b, c, 12, 11, T46);
    SET(c, d, a, b, 15, 16, T47);
    SET(b, c, d, a,  2, 23, T48);
#undef SET

     /* Round 4. */
     /* Let [abcd k s t] denote the operation
          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
  t = a + I(b,c,d) + X[k] + Ti;\
  a = ROTATE_LEFT(t, s) + b
     /* Do the following 16 operations. */
    SET(a, b, c, d,  0,  6, T49);
    SET(d, a, b, c,  7, 10, T50);
    SET(c, d, a, b, 14, 15, T51);
    SET(b, c, d, a,  5, 21, T52);
    SET(a, b, c, d, 12,  6, T53);
    SET(d, a, b, c,  3, 10, T54);
    SET(c, d, a, b, 10, 15, T55);
    SET(b, c, d, a,  1, 21, T56);
    SET(a, b, c, d,  8,  6, T57);
    SET(d, a, b, c, 15, 10, T58);
    SET(c, d, a, b,  6, 15, T59);
    SET(b, c, d, a, 13, 21, T60);
    SET(a, b, c, d,  4,  6, T61);
    SET(d, a, b, c, 11, 10, T62);
    SET(c, d, a, b,  2, 15, T63);
    SET(b, c, d, a,  9, 21, T64);
#undef SET

     /* Then perform the following additions. (That is increment each
        of the four registers by the value it had before this block
        was started.) */
    pms->abcd[0] += a;
    pms->abcd[1] += b;
    pms->abcd[2] += c;
    pms->abcd[3] += d;
}
Beispiel #13
0
void CWebSocket::OnReceived(void* pData, DWORD dwSize)
{
	EMULE_TRY

	const UINT SIZE_PRESERVE = 0x1000;

	if (m_dwBufSize < dwSize + m_dwRecv)
	{
	//	Reallocate
		char	*pNewBuf = new char[m_dwBufSize = dwSize + m_dwRecv + SIZE_PRESERVE];

		if (pNewBuf == NULL)
		{
			m_bValid = false; //	Internal problem
			return;
		}

		if (m_pBuf != NULL)
		{
			memcpy2(pNewBuf, m_pBuf, m_dwRecv);
			delete[] m_pBuf;
		}

		m_pBuf = pNewBuf;
	}
	memcpy2(m_pBuf + m_dwRecv, pData, dwSize);
	m_dwRecv += dwSize;

//	Check if we have all that we want
	if (m_dwHttpHeaderLen == 0)
	{
	//	Try to find it
		bool	bPrevEndl = false;

		for (DWORD dwPos = 0; dwPos < m_dwRecv; dwPos++)
		{
			if ('\n' == m_pBuf[dwPos])
			{
				if (bPrevEndl)
				{
				//	We just found the end of the http header
				//	Now write the message's position into two first DWORDs of the buffer
					m_dwHttpHeaderLen = dwPos + 1;

				//	Try to find now the 'Content-Length' header
					for (dwPos = 0; dwPos < m_dwHttpHeaderLen;)
					{
						char	*pPtr = reinterpret_cast<char*>(memchr(m_pBuf + dwPos, '\n', m_dwHttpHeaderLen - dwPos));

						if (pPtr == NULL)
							break;

						DWORD	dwNextPos = pPtr - m_pBuf;

					//	Check this header
						static const char	acMatch[] = "content-length";

						if (strnicmp(m_pBuf + dwPos, acMatch, sizeof(acMatch) - 1) == 0)
						{
							dwPos += sizeof(acMatch) - 1;
							pPtr = reinterpret_cast<char *>(memchr(m_pBuf + dwPos, ':', m_dwHttpHeaderLen - dwPos));
							if (pPtr != NULL)
								m_dwHttpContentLen = atol(pPtr + 1);

							break;
						}
						dwPos = dwNextPos + 1;
					}
					break;
				}
				else
					bPrevEndl = true;
			}
			else if ('\r' != m_pBuf[dwPos])
				bPrevEndl = false;
		}
	}

	if ((m_dwHttpHeaderLen != 0) && !m_bCanRecv && (m_dwHttpContentLen == 0))
		m_dwHttpContentLen = m_dwRecv - m_dwHttpHeaderLen; // of course

	if ((m_dwHttpHeaderLen != 0) && (m_dwHttpContentLen < m_dwRecv) && ((m_dwHttpContentLen == 0) || (m_dwHttpHeaderLen + m_dwHttpContentLen <= m_dwRecv)))
	{
		OnRequestReceived(m_pBuf, m_dwHttpHeaderLen, m_pBuf + m_dwHttpHeaderLen, m_dwHttpContentLen);

		if (m_bCanRecv && (m_dwRecv > m_dwHttpHeaderLen + m_dwHttpContentLen))
		{
		//	Move our data
			m_dwRecv -= m_dwHttpHeaderLen + m_dwHttpContentLen;
			MoveMemory(m_pBuf, m_pBuf + m_dwHttpHeaderLen + m_dwHttpContentLen, m_dwRecv);
		}
		else
			m_dwRecv = 0;

		m_dwHttpHeaderLen = 0;
		m_dwHttpContentLen = 0;
	}
	EMULE_CATCH2
}
Beispiel #14
0
int RunElf(char *name)
{
	int fd,size,i;
	u8 *boot_elf = (u8 *) 0;//&_end;
	elf_header_t *eh = &elfh;
	elf_pheader_t *eph;
	char *argv[1];
	void *pdata;
	fd=-1;
	if(name[0]=='m' && name[1]=='c') // if mc, test mc0 and mc1
	{
		if((fd = fioOpen(name,1)) < 0) 
		{
			name[2]='1';
		}
	}
	if(fd < 0)
		if((fd = fioOpen(name,1)) < 0) 
		{
			return -1;
		}
		size = fioLseek(fd, 0, SEEK_END);
		if(!size) {
			fioClose(fd);
			return -2;
		}

		fioLseek(fd, 0, 0);
		fioRead(fd, eh, sizeof(elf_header_t)); // read the elf header

		// crazy code for crazy man :P
		boot_elf=(u8 *)0x1800000-size-256; 
		//if((eh->entry+size)>=boot_elf) boot_elf=(u8 *)eh->entry-size-256;
		boot_elf=(u8 *) (((unsigned)boot_elf) &0xfffffff0);

		// read rest file elf
		fioRead(fd, boot_elf+sizeof(elf_header_t), size-sizeof(elf_header_t));
		fioClose(fd);

		// mrbrown machine gun ;)
		eph = (elf_pheader_t *)(boot_elf + eh->phoff);
		// Scan through the ELF's program headers and copy them into RAM, then
		// zero out any non-loaded regions.
		for (i = 0; i < eh->phnum; i++) {
	   	   if (eph[i].type != ELF_PT_LOAD)
			   continue;
			   
		pdata = (void *)(boot_elf + eph[i].offset);
		memcpy2((unsigned char *)eph[i].vaddr, (unsigned char *)pdata, (int)eph[i].filesz);

		if (eph[i].memsz > eph[i].filesz)
			memset2((unsigned char *)eph[i].vaddr + eph[i].filesz, (unsigned char)0, (int)eph[i].memsz - eph[i].filesz);
	}

	// Let's go.
	argv[0] = name;

	fioExit();
	Reset();
	FlushCache(0);
	FlushCache(2);
	ExecPS2((void *)eh->entry, 0, 1, argv);
	return 0;
}
Beispiel #15
0
void CEMSocket::OnReceive(int iErrorCode)
{
//	The 2 meg size was taken from another place     // MOREVIT - Um, what??
	static char g_arrcReadBuffer[2102400];			// 16*TCP window (16*131400)

//	Check for an error code
	if (iErrorCode != 0)
	{
		OnError(iErrorCode);
		return;
	}
	
//	Check current connection state
	if (m_eConnectionState == ES_DISCONNECTED)
		return;
	else
		m_eConnectionState = ES_CONNECTED; // ES_DISCONNECTED, ES_NOTCONNECTED, ES_CONNECTED

//	* CPU load improvement
	if (m_bEnableDownloadLimit && m_dwDownloadLimit == 0)
	{
		EMTrace("CEMSocket::OnReceive blocked by limit");
		m_bPendingOnReceive = true;
		return;
	}

//	Determine the maximum amount of data we can read, allowing for the download limit (if any)
//	Remark: an overflow can not occur here
	uint32		dwReadMax = sizeof(g_arrcReadBuffer) - m_dwPendingHeaderSize;

	if (m_bEnableDownloadLimit && dwReadMax > m_dwDownloadLimit)
		dwReadMax = m_dwDownloadLimit;

//	We attempt to read up to 2 megs at a time (minus whatever is in our internal read buffer)
	uint32		dwNumBytesReceived = Receive(g_arrcReadBuffer + m_dwPendingHeaderSize, dwReadMax);

	if (dwNumBytesReceived == SOCKET_ERROR || dwNumBytesReceived == 0)
	{
	//	TODO: Get error information from GetLastError()?
		return;
	}

//	* Bandwidth control
	if (m_bEnableDownloadLimit)
	{
	//	Reduce the download limit by the number of bytes received.
		m_dwDownloadLimit -= dwNumBytesReceived;
	}

//	* CPU load improvement
//	Detect if the socket's buffer is empty (or the size did match...)
	m_bPendingOnReceive = (dwNumBytesReceived == dwReadMax);

//	Copy back the partial header into the global read buffer for processing
	if (m_dwPendingHeaderSize > 0)
	{
		memcpy(g_arrcReadBuffer, m_arrcPendingHeader, m_dwPendingHeaderSize);
		dwNumBytesReceived += m_dwPendingHeaderSize;
		m_dwPendingHeaderSize = 0;
	}

	char		*pcReadBuffer = g_arrcReadBuffer; // floating index initialized with begin of buffer
	const char	*pcReadBufferEnd = g_arrcReadBuffer + dwNumBytesReceived; // end of buffer

//	Loop, processing packets until we run out of them
	while ( (pcReadBufferEnd - pcReadBuffer >= PACKET_HEADER_SIZE)
		 || ((m_pPendingPacket != NULL) && (pcReadBufferEnd - pcReadBuffer > 0)) )
	{ 
	// Two possibilities here: 
	//
	// 1. There is no pending incoming packet
	// 2. There is already a partial pending incoming packet
	//
	// It's important to remember that emule exchange two kinds of packet
	// - The control packet
	// - The data packet for the transport of the block
	// 
	// The biggest part of the traffic is done with the data packets. 
	// The default size of one block is 10240 bytes (or less if compressed), but the
	// maximal size for one packet on the network is 1300 bytes. It's the reason
	// why most of the Blocks are splitted before to be sent. 
	//
	// Conclusion: When the download limit is disabled, this method can be at least 
	// called 8 times (10240/1300) by the lower layer before a split packet is 
	// rebuild and transferred to the above layer for processing.
	//
	// The purpose of this algorithm is to limit the amount of data exchanged between buffers

		if (m_pPendingPacket == NULL)
		{
		//	Recheck current connection state as it can be changed after data reception
			if (m_eConnectionState == ES_DISCONNECTED)
				return;
		//	Check the header data
			PacketHeader_Struct	*pNewHeader = reinterpret_cast<PacketHeader_Struct*>(pcReadBuffer);

		//	Bugfix: We still need to check for a valid protocol
		//	Remark: the default eMule v0.26b had removed this test......
			switch (pNewHeader->byteEDonkeyProtocol)
			{
				case OP_EDONKEYPROT:
				case OP_PACKEDPROT:
				case OP_EMULEPROT:
					break;
				default:
					EMTrace("%s: ERROR - Wrong protocol in packet header", __FUNCTION__);
					OnError(ERR_WRONGHEADER);
					return;
			}

		//	Security: Check for buffer overflow (2MB)
			if ((pNewHeader->dwPacketLength - 1) > sizeof(g_arrcReadBuffer))
			{
				OnError(ERR_TOOBIG);
				return;
			}

		//	Create new packet container
			m_pPendingPacket = new Packet(pNewHeader);
		//	Only the header is initialized so far. Advance past it
			pcReadBuffer += sizeof(PacketHeader_Struct);

		//	Init data buffer
			m_pPendingPacket->m_pcBuffer = new char[m_pPendingPacket->m_dwSize + 1];
			m_dwPendingPacketSize = 0;
		}

	//	Bytes ready to be copied into packet's internal buffer
		ASSERT(pcReadBuffer <= pcReadBufferEnd);
		uint32 dwBytesToCopy = ((m_pPendingPacket->m_dwSize - m_dwPendingPacketSize) < static_cast<uint32>(pcReadBufferEnd - pcReadBuffer))
							 ? (m_pPendingPacket->m_dwSize - m_dwPendingPacketSize)
							 : static_cast<uint32>(pcReadBufferEnd - pcReadBuffer);

	//	Copy bytes from Global buffer to packet's internal buffer
		memcpy2(&m_pPendingPacket->m_pcBuffer[m_dwPendingPacketSize], pcReadBuffer, dwBytesToCopy);
		m_dwPendingPacketSize += dwBytesToCopy;
		pcReadBuffer += dwBytesToCopy;

	//	Check if packet is complete
		ASSERT(m_pPendingPacket->m_dwSize >= m_dwPendingPacketSize);
		if (m_pPendingPacket->m_dwSize == m_dwPendingPacketSize)
		{
#ifdef EMSOCKET_DEBUG
			EMTrace("CEMSocket::PacketReceived on %d, opcode=%X, realSize=%d", 
				    static_cast<SOCKET>(this), m_pPendingPacket->m_eOpcode, m_pPendingPacket->GetRealPacketSize());
#endif EMSOCKET_DEBUG

		//	Process packet
			m_bInPacketReceived = true;
			PacketReceived(m_pPendingPacket);
			m_bInPacketReceived = false;
			delete m_pPendingPacket;
			m_pPendingPacket = NULL;
			m_dwPendingPacketSize = 0;
		}
	}

	// Finally, if there is any data left over, save it for next time
	ASSERT(pcReadBuffer <= pcReadBufferEnd);
	ASSERT(pcReadBufferEnd - pcReadBuffer < sizeof(PacketHeader_Struct));
	if (pcReadBuffer != pcReadBufferEnd)
	{
		// Keep the partial head
		m_dwPendingHeaderSize = pcReadBufferEnd - pcReadBuffer;
		memcpy(m_arrcPendingHeader, pcReadBuffer, m_dwPendingHeaderSize);
	}	
}