00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "EDPacket.h"
00026 #include "Buffer.h"
00027 #include "ZLib.h"
00028
00029 #ifdef _DEBUG
00030 #undef THIS_FILE
00031 static char THIS_FILE[]=__FILE__;
00032 #define new DEBUG_NEW
00033 #endif
00034
00035 CEDPacket::CEDPacketPool CEDPacket::POOL;
00036
00037
00039
00040
00041 CEDPacket::CEDPacket() : CPacket( PROTOCOL_ED2K )
00042 {
00043 }
00044
00045 CEDPacket::~CEDPacket()
00046 {
00047 }
00048
00050
00051
00052 CString CEDPacket::ReadEDString(DWORD ServerFlags)
00053 {
00054 int nLen = ReadShortLE();
00055 if ( ServerFlags & ED2K_SERVER_TCP_UNICODE )
00056 return ReadStringUTF8( nLen );
00057 else
00058 return ReadString( nLen );
00059 }
00060
00061 void CEDPacket::WriteEDString(LPCTSTR psz, DWORD ServerFlags)
00062 {
00063 int nLen;
00064 if ( ServerFlags & ED2K_SERVER_TCP_UNICODE )
00065 {
00066 nLen = GetStringLenUTF8( psz );
00067 WriteShortLE( nLen );
00068 WriteStringUTF8( psz, FALSE );
00069 }
00070 else
00071 {
00072 nLen = GetStringLen( psz );
00073 WriteShortLE( nLen );
00074 WriteString( psz, FALSE );
00075 }
00076 ASSERT( nLen <= 0xFFFF );
00077 }
00078
00079 CString CEDPacket::ReadEDString(BOOL bUnicode)
00080 {
00081 int nLen = ReadShortLE();
00082 if ( bUnicode )
00083 return ReadStringUTF8( nLen );
00084 else
00085 return ReadString( nLen );
00086 }
00087
00088 void CEDPacket::WriteEDString(LPCTSTR psz, BOOL bUnicode)
00089 {
00090 int nLen;
00091 if ( bUnicode )
00092 {
00093 nLen = GetStringLenUTF8( psz );
00094 WriteShortLE( nLen );
00095 WriteStringUTF8( psz, FALSE );
00096 }
00097 else
00098 {
00099 nLen = GetStringLen( psz );
00100 WriteShortLE( nLen );
00101 WriteString( psz, FALSE );
00102 }
00103 ASSERT( nLen <= 0xFFFF );
00104 }
00105
00106
00107 CString CEDPacket::ReadLongEDString(BOOL bUnicode)
00108 {
00109 DWORD nLen = ReadLongLE();
00110 if ( bUnicode )
00111 return ReadStringUTF8( nLen );
00112 else
00113 return ReadString( nLen );
00114 }
00115
00116 void CEDPacket::WriteLongEDString(LPCTSTR psz, BOOL bUnicode)
00117 {
00118 DWORD nLen;
00119 if ( bUnicode )
00120 {
00121 nLen = GetStringLenUTF8( psz );
00122 WriteLongLE( nLen );
00123 WriteStringUTF8( psz, FALSE );
00124 }
00125 else
00126 {
00127 nLen = GetStringLen( psz );
00128 WriteLongLE( nLen );
00129 WriteString( psz, FALSE );
00130 }
00131 ASSERT( nLen <= 0xFFFF );
00132 }
00133
00135
00136
00137 void CEDPacket::ToBuffer(CBuffer* pBuffer) const
00138 {
00139 ED2K_TCP_HEADER pHeader;
00140 pHeader.nProtocol = m_nEdProtocol;
00141 pHeader.nLength = m_nLength + 1;
00142 pHeader.nType = m_nType;
00143 pBuffer->Add( &pHeader, sizeof(pHeader) );
00144 pBuffer->Add( m_pBuffer, m_nLength );
00145 }
00146
00147 void CEDPacket::ToBufferUDP(CBuffer* pBuffer) const
00148 {
00149 ED2K_UDP_HEADER pHeader;
00150 pHeader.nProtocol = m_nEdProtocol;
00151 pHeader.nType = m_nType;
00152 pBuffer->Add( &pHeader, sizeof(pHeader) );
00153 pBuffer->Add( m_pBuffer, m_nLength );
00154 }
00155
00156 CEDPacket* CEDPacket::ReadBuffer(CBuffer* pBuffer, BYTE nEdProtocol)
00157 {
00158 ED2K_TCP_HEADER* pHeader = reinterpret_cast<ED2K_TCP_HEADER*>(pBuffer->m_pBuffer);
00159 if ( pBuffer->m_nLength < sizeof(*pHeader) ) return NULL;
00160 if ( pHeader->nProtocol != ED2K_PROTOCOL_EDONKEY &&
00161 pHeader->nProtocol != ED2K_PROTOCOL_EMULE &&
00162 pHeader->nProtocol != ED2K_PROTOCOL_PACKED ) return NULL;
00163 if ( pBuffer->m_nLength < sizeof(*pHeader) + pHeader->nLength - 1 ) return NULL;
00164 CEDPacket* pPacket = CEDPacket::New( pHeader );
00165 pBuffer->Remove( sizeof(*pHeader) + pHeader->nLength - 1 );
00166 if ( pPacket->InflateOrRelease( nEdProtocol ) ) return NULL;
00167 return pPacket;
00168 }
00169
00171
00172
00173 BOOL CEDPacket::Deflate()
00174 {
00175 if ( m_nEdProtocol != ED2K_PROTOCOL_EDONKEY &&
00176 m_nEdProtocol != ED2K_PROTOCOL_EMULE ) return FALSE;
00177
00178 DWORD nOutput = 0;
00179 BYTE* pOutput = CZLib::Compress( m_pBuffer, m_nLength, &nOutput );
00180
00181 if ( pOutput != NULL )
00182 {
00183 if ( nOutput >= m_nLength )
00184 {
00185 delete [] pOutput;
00186 return FALSE;
00187 }
00188
00189 m_nEdProtocol = ED2K_PROTOCOL_PACKED;
00190
00191 CopyMemory( m_pBuffer, pOutput, nOutput );
00192 m_nLength = nOutput;
00193
00194 delete [] pOutput;
00195
00196 return TRUE;
00197 }
00198 else
00199 {
00200 return FALSE;
00201 }
00202 }
00203
00204 BOOL CEDPacket::InflateOrRelease(BYTE nEdProtocol)
00205 {
00206 if ( m_nEdProtocol != ED2K_PROTOCOL_PACKED ) return FALSE;
00207
00208 DWORD nOutput = 0;
00209 BYTE* pOutput = CZLib::Decompress( m_pBuffer, m_nLength, &nOutput );
00210
00211 if ( pOutput != NULL )
00212 {
00213 m_nEdProtocol = nEdProtocol;
00214
00215 if ( m_nBuffer >= nOutput )
00216 {
00217 CopyMemory( m_pBuffer, pOutput, nOutput );
00218 m_nLength = nOutput;
00219 delete [] pOutput;
00220 }
00221 else
00222 {
00223 delete [] m_pBuffer;
00224 m_pBuffer = pOutput;
00225 m_nLength = nOutput;
00226 m_nBuffer = nOutput;
00227 }
00228
00229 return FALSE;
00230 }
00231 else
00232 {
00233 Release();
00234 return TRUE;
00235 }
00236 }
00237
00239
00240
00241 LPCTSTR CEDPacket::GetType() const
00242 {
00243 static TCHAR szTypeBuffer[16];
00244 _stprintf( szTypeBuffer, _T("0x%x"), int( m_nType ) );
00245 return szTypeBuffer;
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 }
00256
00257 void CEDPacket::Debug(LPCTSTR pszReason) const
00258 {
00259 #ifdef _DEBUG
00260 if ( m_nType == ED2K_C2C_SENDINGPART ) return;
00261 if ( m_nType == ED2K_C2C_HASHSETANSWER ) return;
00262 if ( m_nType == ED2K_C2C_COMPRESSEDPART ) return;
00263
00264 CString strOutput;
00265 strOutput.Format( L"[ED2K]: '%s' %s %s", pszReason, GetType(), (LPCTSTR)ToASCII() );
00266 CPacket::Debug( strOutput );
00267
00268 #endif
00269 }
00270
00271
00273
00274
00275 CEDTag::CEDTag()
00276 {
00277 m_nType = ED2K_TAG_NULL;
00278 m_nKey = 0;
00279 }
00280
00281 CEDTag::CEDTag(BYTE nKey)
00282 {
00283 m_nType = ED2K_TAG_HASH;
00284 m_nKey = nKey;
00285 }
00286
00287 CEDTag::CEDTag(BYTE nKey, DWORD nValue)
00288 {
00289 m_nType = ED2K_TAG_INT;
00290 m_nKey = nKey;
00291 m_nValue = nValue;
00292 }
00293
00294 CEDTag::CEDTag(BYTE nKey, LPCTSTR pszValue)
00295 {
00296 m_nType = ED2K_TAG_STRING;
00297 m_nKey = nKey;
00298 m_sValue = pszValue;
00299 }
00300
00301 CEDTag::CEDTag(LPCTSTR pszKey)
00302 {
00303 m_nType = ED2K_TAG_HASH;
00304 m_sKey = pszKey;
00305 m_nKey = 0;
00306 }
00307
00308 CEDTag::CEDTag(LPCTSTR pszKey, DWORD nValue)
00309 {
00310 m_nType = ED2K_TAG_INT;
00311 m_sKey = pszKey;
00312 m_nKey = 0;
00313 m_nValue = nValue;
00314 }
00315
00316 CEDTag::CEDTag(LPCTSTR pszKey, LPCTSTR pszValue)
00317 {
00318 m_nType = ED2K_TAG_STRING;
00319 m_sKey = pszKey;
00320 m_nKey = 0;
00321 m_sValue = pszValue;
00322 }
00323
00325
00326
00327 void CEDTag::Clear()
00328 {
00329 m_nType = ED2K_TAG_NULL;
00330 m_nKey = 0;
00331 m_nValue = 0;
00332 m_sKey.Empty();
00333 m_sValue.Empty();
00334 }
00335
00337
00338
00339 void CEDTag::Write(CEDPacket* pPacket, DWORD ServerFlags)
00340 {
00341 BOOL bSmallTags = ServerFlags & ED2K_SERVER_TCP_SMALLTAGS, bUnicode = ServerFlags & ED2K_SERVER_TCP_UNICODE;
00342 DWORD nPos = pPacket->m_nLength;
00343 pPacket->WriteByte( m_nType );
00344
00345 if ( int nKeyLen = m_sKey.GetLength() )
00346 {
00347 pPacket->WriteEDString( m_sKey, ServerFlags );
00348 }
00349 else
00350 {
00351 if ( ! bSmallTags ) pPacket->WriteShortLE( 1 );
00352 pPacket->WriteByte( m_nKey );
00353 }
00354
00355 if ( m_nType == ED2K_TAG_STRING )
00356 {
00357 if ( bSmallTags )
00358 {
00359 int nLength;
00360 if ( bUnicode )
00361 nLength = pPacket->GetStringLenUTF8( m_sValue );
00362 else
00363 nLength = pPacket->GetStringLen( m_sValue );
00364
00365 if ( ( nLength <= 16 ) )
00366 {
00367
00368
00369 (BYTE)pPacket->m_pBuffer[nPos] = 0x80 | ( ( ED2K_TAG_SHORTSTRING - 1 ) + nLength ) ;
00370
00371
00372 if ( bUnicode ) pPacket->WriteStringUTF8( m_sValue, FALSE );
00373 else pPacket->WriteString( m_sValue, FALSE );
00374 }
00375 else
00376 {
00377
00378 (BYTE)pPacket->m_pBuffer[nPos] = 0x80 | ED2K_TAG_STRING ;
00379
00380
00381 pPacket->WriteEDString( m_sValue, ServerFlags );
00382 }
00383 }
00384 else
00385 {
00386
00387 pPacket->WriteEDString( m_sValue, ServerFlags );
00388 }
00389 }
00390 else if ( m_nType == ED2K_TAG_INT )
00391 {
00392 if ( bSmallTags )
00393 {
00394 if ( m_nValue <= 0xFF)
00395 {
00396 (BYTE)pPacket->m_pBuffer[nPos] = 0x80 | ED2K_TAG_UINT8;
00397
00398 pPacket->WriteByte( (BYTE)m_nValue );
00399 }
00400 else if ( m_nValue <= 0xFFFF)
00401 {
00402 (BYTE)pPacket->m_pBuffer[nPos] = 0x80 | ED2K_TAG_UINT16;
00403
00404 pPacket->WriteShortLE( (WORD)m_nValue );
00405 }
00406 else
00407 {
00408 (BYTE)pPacket->m_pBuffer[nPos] = 0x80 | ED2K_TAG_INT;
00409
00410 pPacket->WriteLongLE( m_nValue );
00411 }
00412 }
00413 else
00414 {
00415
00416 pPacket->WriteLongLE( m_nValue );
00417 }
00418 }
00419 }
00420
00422
00423
00424 BOOL CEDTag::Read(CEDPacket* pPacket, DWORD ServerFlags)
00425 {
00426 int nLen;
00427
00428 Clear();
00429
00430 if ( pPacket->GetRemaining() < 3 ) return FALSE;
00431 m_nType = pPacket->ReadByte();
00432
00433 if ( m_nType & 0x80 )
00434 {
00435
00436
00437 m_nType -= 0x80;
00438
00439 nLen = 1;
00440 }
00441 else
00442 {
00443 nLen = pPacket->ReadShortLE();
00444 }
00445
00446 if ( m_nType < ED2K_TAG_HASH || m_nType > ( ED2K_TAG_SHORTSTRING + 15 ) ) return FALSE;
00447
00448
00449 if ( pPacket->GetRemaining() < nLen ) return FALSE;
00450
00451 if ( nLen == 1 )
00452 {
00453 m_nKey = pPacket->ReadByte();
00454 }
00455 else if ( nLen > 1 )
00456 {
00457 if ( ServerFlags & ED2K_SERVER_TCP_UNICODE )
00458 m_sKey = pPacket->ReadStringUTF8( nLen );
00459 else
00460 m_sKey = pPacket->ReadString( nLen );
00461 }
00462
00463 if ( m_nType == ED2K_TAG_STRING )
00464 {
00465 if ( pPacket->GetRemaining() < 2 ) return FALSE;
00466 nLen = pPacket->ReadShortLE();
00467 if ( pPacket->GetRemaining() < nLen ) return FALSE;
00468 if ( ServerFlags & ED2K_SERVER_TCP_UNICODE )
00469 m_sValue = pPacket->ReadStringUTF8( nLen );
00470 else
00471 m_sValue = pPacket->ReadString( nLen );
00472 }
00473 else if ( m_nType == ED2K_TAG_INT )
00474 {
00475 if ( pPacket->GetRemaining() < 4 ) return FALSE;
00476 m_nValue = pPacket->ReadLongLE();
00477 }
00478 else if ( m_nType == ED2K_TAG_FLOAT )
00479 {
00480 if ( pPacket->GetRemaining() < 4 ) return FALSE;
00481 m_nValue = pPacket->ReadLongLE();
00482 }
00483 else if ( m_nType == ED2K_TAG_UINT16 )
00484 {
00485 if ( pPacket->GetRemaining() < 2 ) return FALSE;
00486 m_nValue = pPacket->ReadShortLE();
00487 }
00488 else if ( m_nType == ED2K_TAG_UINT8 )
00489 {
00490 if ( pPacket->GetRemaining() < 1 ) return FALSE;
00491 m_nValue = pPacket->ReadByte();
00492 }
00493 else if ( ( m_nType >= ED2K_TAG_SHORTSTRING ) && ( m_nType <= ED2K_TAG_SHORTSTRING + 15 ) )
00494 {
00495 nLen = ( m_nType - (ED2K_TAG_SHORTSTRING - 1) );
00496 if ( pPacket->GetRemaining() < nLen ) return FALSE;
00497
00498 if ( ServerFlags & ED2K_SERVER_TCP_UNICODE )
00499 m_sValue = pPacket->ReadStringUTF8( nLen );
00500 else
00501 m_sValue = pPacket->ReadString( nLen );
00502 }
00503 else if ( m_nType == ED2K_TAG_BLOB )
00504 {
00505 nLen = pPacket->ReadLongLE();
00506 m_sValue = pPacket->ReadString( nLen );
00507 }
00508 else
00509 {
00510 theApp.Message( MSG_DEBUG, _T("Unrecognised ed2k packet") );
00511 }
00512
00513 return TRUE;
00514 }
00515
00517
00518
00519 BOOL CEDTag::Read(CFile* pFile)
00520 {
00521 Clear();
00522
00523 if ( pFile->Read( &m_nType, sizeof(m_nType) ) != sizeof(m_nType) ) return FALSE;
00524 if ( m_nType < ED2K_TAG_HASH || m_nType > ED2K_TAG_INT ) return FALSE;
00525
00526 WORD nLen;
00527 if ( pFile->Read( &nLen, sizeof(nLen) ) != sizeof(nLen) ) return FALSE;
00528
00529 if ( nLen == 1 )
00530 {
00531 if ( pFile->Read( &m_nKey, sizeof(m_nKey) ) != sizeof(m_nKey) ) return FALSE;
00532 }
00533 else if ( nLen > 1 )
00534 {
00535 LPSTR psz = new CHAR[ nLen + 1 ];
00536
00537 if ( pFile->Read( psz, nLen ) == nLen )
00538 {
00539 psz[ nLen ] = 0;
00540 m_sKey = psz;
00541 delete [] psz;
00542 }
00543 else
00544 {
00545 delete [] psz;
00546 return FALSE;
00547 }
00548 }
00549
00550 if ( m_nType == ED2K_TAG_STRING )
00551 {
00552 if ( pFile->Read( &nLen, sizeof(nLen) ) != sizeof(nLen) ) return FALSE;
00553
00554 LPSTR psz = new CHAR[ nLen + 1 ];
00555
00556 if ( pFile->Read( psz, nLen ) == nLen )
00557 {
00558
00559 int nWide = MultiByteToWideChar( CP_UTF8, 0, psz, nLen, NULL, 0 );
00560 MultiByteToWideChar( CP_UTF8, 0, psz, nLen, m_sValue.GetBuffer( nWide ), nWide );
00561 m_sValue.ReleaseBuffer( nWide );
00562
00563
00564
00565
00566 delete [] psz;
00567 }
00568 else
00569 {
00570 delete [] psz;
00571 return FALSE;
00572 }
00573 }
00574 else if ( m_nType == ED2K_TAG_INT )
00575 {
00576 if ( pFile->Read( &m_nValue, sizeof(m_nValue) ) != sizeof(m_nValue) ) return FALSE;
00577 }
00578
00579 return TRUE;
00580 }
00581
00583
00584
00585 ED2K_PACKET_DESC CEDPacket::m_pszTypes[] =
00586 {
00587 { ED2K_C2S_LOGINREQUEST, _T("Login") },
00588 { ED2K_C2S_GETSERVERLIST, _T("GetServerList") },
00589 { ED2K_C2S_OFFERFILES, _T("ShareFiles") },
00590 { ED2K_C2S_SEARCHREQUEST, _T("Search") },
00591 { ED2K_C2S_SEARCHUSER, _T("Browse") },
00592 { ED2K_C2S_GETSOURCES, _T("FindSource") },
00593 { ED2K_C2S_CALLBACKREQUEST, _T("Push1") },
00594 { ED2K_C2S_MORERESULTS, _T("Continue") },
00595 { ED2K_S2C_REJECTED, _T("Rejected") },
00596 { ED2K_S2C_SERVERMESSAGE, _T("Message") },
00597 { ED2K_S2C_IDCHANGE, _T("ClientID") },
00598 { ED2K_S2C_SERVERLIST, _T("ServerList") },
00599 { ED2K_S2C_SEARCHRESULTS, _T("Results") },
00600 { ED2K_S2C_FOUNDSOURCES, _T("Sources") },
00601 { ED2K_S2C_SERVERSTATUS, _T("Status") },
00602 { ED2K_S2C_SERVERIDENT, _T("Identity") },
00603 { ED2K_S2C_CALLBACKREQUESTED, _T("Push2") },
00604
00605 { ED2K_C2SG_SERVERSTATUSREQUEST,_T("GetStatus") },
00606 { ED2K_S2CG_SERVERSTATUS, _T("Status") },
00607 { ED2K_C2SG_SEARCHREQUEST, _T("Search") },
00608 { ED2K_S2CG_SEARCHRESULT, _T("Result") },
00609 { ED2K_C2SG_GETSOURCES, _T("FindSource") },
00610 { ED2K_S2CG_FOUNDSOURCES, _T("Sources") },
00611 { ED2K_C2SG_CALLBACKREQUEST, _T("Push1") },
00612
00613 { ED2K_C2C_HELLO, _T("Handshake1") },
00614 { ED2K_C2C_HELLOANSWER, _T("Handshake2") },
00615 { ED2K_C2C_FILEREQUEST, _T("FileRequest") },
00616 { ED2K_C2C_FILEREQANSWER, _T("FileName") },
00617 { ED2K_C2C_FILENOTFOUND, _T("FileNotFound") },
00618 { ED2K_C2C_FILESTATUS, _T("FileStatus") },
00619 { ED2K_C2C_QUEUEREQUEST, _T("EnqueueMe") },
00620 { ED2K_C2C_QUEUERELEASE, _T("DequeueMe") },
00621 { ED2K_C2C_QUEUERANK, _T("QueueRank") },
00622 { ED2K_C2C_STARTUPLOAD, _T("StartUpload") },
00623 { ED2K_C2C_FINISHUPLOAD, _T("UploadFinished") },
00624 { ED2K_C2C_REQUESTPARTS, _T("RequestFrag") },
00625 { ED2K_C2C_SENDINGPART, _T("Fragment") },
00626 { ED2K_C2C_FILESTATUSREQUEST, _T("GetStatus") },
00627 { ED2K_C2C_HASHSETREQUEST, _T("GetHashset") },
00628 { ED2K_C2C_HASHSETANSWER, _T("Hashset") },
00629 { ED2K_C2C_ASKSHAREDFILES, _T("Browse") },
00630 { ED2K_C2C_ASKSHAREDFILESANSWER,_T("BrowseResp") },
00631 { ED2K_C2C_MESSAGE, _T("Message") },
00632
00633 { 0, NULL }
00634 };