00001 // 00002 // Packet.cpp 00003 // 00004 // Copyright (c) Shareaza Development Team, 2002-2005. 00005 // This file is part of SHAREAZA (www.shareaza.com) 00006 // 00007 // Shareaza is free software; you can redistribute it 00008 // and/or modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 of 00010 // the License, or (at your option) any later version. 00011 // 00012 // Shareaza is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with Shareaza; if not, write to the Free Software 00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 // 00021 00022 // CPacket represents a packet on a peer-to-peer network, and CPacketPool keeps lists of them 00023 // http://wiki.shareaza.com/static/Developers.Code.CPacket 00024 00025 // Copy in the contents of these files here before compiling 00026 #include "StdAfx.h" 00027 #include "Shareaza.h" 00028 #include "Settings.h" 00029 #include "Network.h" 00030 #include "Packet.h" 00031 #include "ZLib.h" 00032 #include "SHA.h" 00033 #include "Buffer.h" 00034 #include "WndMain.h" 00035 #include "WndPacket.h" 00036 00037 // If we are compiling in debug mode, replace the text "THIS_FILE" in the code with the name of this file 00038 #ifdef _DEBUG 00039 #undef THIS_FILE 00040 static char THIS_FILE[]=__FILE__; 00041 #define new DEBUG_NEW 00042 #endif 00043 00044 // Buffers that hold 128 ASCII and 128 wide characters, used so MultiByteToWideChar can convert short text quickly 00045 CHAR CPacket::m_szSCHAR[PACKET_BUF_SCHAR + 1]; 00046 WCHAR CPacket::m_szWCHAR[PACKET_BUF_WCHAR + 1]; 00047 00049 // CPacket construction 00050 00051 // Takes a protocol id, like PROTOCOL_G1 for Gnutella 00052 // Makes a new CPacket object to represent a packet 00053 CPacket::CPacket(PROTOCOLID nProtocol) 00054 { 00055 // Save the given protocol id in the object 00056 m_nProtocol = nProtocol; 00057 00058 // This packet isn't in a list yet, and isn't being used at all yet 00059 m_pNext = NULL; // No packet next in a list 00060 m_nReference = 0; // No one needs this packet yet, the reference count starts at 0 00061 00062 // Start out memory pointers and lengths at null and 0 00063 m_pBuffer = NULL; // This is just a pointer to allocated bytes, not a CBuffer object that would take care of itself 00064 m_nBuffer = 0; 00065 m_nLength = 0; 00066 m_nPosition = 0; 00067 00068 // Assume the bytes of the packet are in big endian order 00069 m_bBigEndian = TRUE; 00070 } 00071 00072 // Delete this CPacket object 00073 CPacket::~CPacket() 00074 { 00075 // Make sure the reference count is zero 00076 ASSERT( m_nReference == 0 ); // If it's not, then this packet is being deleted when something still needs it 00077 00078 // If the packet points to some memory, delete it 00079 if ( m_pBuffer ) delete [] m_pBuffer; 00080 } 00081 00083 // CPacket reset 00084 00085 // Clear and reset the values of this packet object to use it again, just like it came from the constructor 00086 void CPacket::Reset() 00087 { 00088 // Make sure Reset is only called when nothing is referencing this packet object 00089 ASSERT( m_nReference == 0 ); 00090 00091 // Reset the member variables to null and 0 defaults 00092 m_pNext = NULL; 00093 m_nLength = 0; 00094 m_nPosition = 0; 00095 m_bBigEndian = TRUE; 00096 } 00097 00099 // CPacket position and seeking 00100 00101 // Takes a distance in bytes into the packet, and seekStart if that's forwards from the front, seekEnd if that's backwards from the end 00102 // Moves the position this packet object remembers to that distance from the start or end 00103 void CPacket::Seek(DWORD nPosition, int nRelative) 00104 { 00105 // Set the position forwards from the start 00106 if ( nRelative == seekStart ) 00107 { 00108 // Move the position in the object to the given position, making sure it's in the data 00109 m_nPosition = max( DWORD(0), min( m_nLength, nPosition ) ); 00110 00111 } // Set the position backwards from the end 00112 else 00113 { 00114 // Move the position in the object to m_nLength - nPosition from the start, which is nPosition from the end 00115 m_nPosition = max( DWORD(0), min( m_nLength, m_nLength - nPosition ) ); 00116 } 00117 } 00118 00119 // Takes a number of bytes 00120 // Shortens the packet to that length 00121 void CPacket::Shorten(DWORD nLength) 00122 { 00123 // If the given length is within the data of the packet, shorten the packet and our position in it 00124 m_nLength = min( m_nLength, nLength ); // Record that there are only nLength bytes of packet data written in the buffer 00125 m_nPosition = min( m_nPosition, m_nLength ); // Make sure this doesn't move our position beyond the bytes of the packet 00126 } 00127 00129 // CPacket strings 00130 00131 // Takes the number of bytes to look at from our position in the packet as ASCII text 00132 // Reads those up to the next null terminator as text 00133 // Returns a string 00134 CString CPacket::ReadString(DWORD nMaximum) 00135 { 00136 // We'll convert the ASCII text in the packet into wide characters, and return them in this string 00137 CString strString; 00138 00139 // If maximum would have us read beyond the end of the packet, make it smaller to read to the end of the packet 00140 nMaximum = min( nMaximum, m_nLength - m_nPosition ); 00141 if ( ! nMaximum ) return strString; // If that would have us read nothing, return the new blank string 00142 00143 // Setup pointers to look at bytes in the packet 00144 LPCSTR pszInput = (LPCSTR)m_pBuffer + m_nPosition; // Point pszInput at our position inside the buffer 00145 LPCSTR pszScan = pszInput; // Start out pszScan at the same spot, it will find the next null terminator 00146 00147 // Loop for each byte in the packet at and beyond our position in it, searching for a null terminator 00148 DWORD nLength = 0; // When this loop is done, nLength will be the number of ASCII bytes we moved over before finding the null terminator 00149 for ( ; nLength < nMaximum ; nLength++ ) 00150 { 00151 // Move the position pointer in this CPacket object to the next byte 00152 m_nPosition++; 00153 00154 // If pszScan points to a 0 byte, exit the loop, otherwise move the pointer forward and keep going 00155 if ( ! *pszScan++ ) break; 00156 } 00157 00158 // Find out how many wide characters the ASCII bytes will become when converted 00159 int nWide = MultiByteToWideChar( 00160 CP_ACP, // Use the code page for ASCII 00161 0, // No character type options 00162 pszInput, // Pointer to ASCII text in the packet 00163 nLength, // Number of bytes to read there, the number of bytes before we found the null terminator 00164 NULL, // No output buffer, we just want to know how many wide characters one would need to hold 00165 0 ); 00166 00167 // Convert the ASCII bytes into wide characters 00168 MultiByteToWideChar( 00169 CP_ACP, // Use the UTF8 code page 00170 0, // No character type options 00171 pszInput, // Pointer to ASCII text 00172 nLength, // Number of bytes to read there, the number of bytes before we found the null terminator 00173 strString.GetBuffer( nWide ), // Get access to the string's buffer, telling it we will write in nWide wide characters 00174 nWide ); // Tell MultiByteToWideChar it can write nWide characters in the buffer 00175 00176 // Close the string and return it 00177 strString.ReleaseBuffer( nWide ); 00178 return strString; 00179 } 00180 00181 // Takes text, and true to also write a null terminator 00182 // Converts the text into ASCII bytes using the ASCII code page, and writes them into the end of the packet 00183 void CPacket::WriteString(LPCTSTR pszString, BOOL bNull) 00184 { 00185 // Find out how many ASCII bytes the wide characters will become when converted 00186 int nByte = WideCharToMultiByte( 00187 CP_ACP, // Use the ASCII code page 00188 0, // No special flags 00189 pszString, // Wide characters to convert 00190 -1, // The wide character text is null terminated, and the null terminator will be converted into a wide null terminator 00191 NULL, // No buffer given, we just want to know how big one would need to be 00192 0, // No buffer size given 00193 NULL, // No special options for unmappable characters 00194 NULL ); 00195 00196 // If our buffer of 128 ASCII characters is big enough, use it, otherwise allocate a new bigger buffer 00197 LPSTR pszByte = nByte <= PACKET_BUF_SCHAR ? m_szSCHAR : new CHAR[ nByte ]; 00198 00199 // Convert the wide characters into bytes of ASCII text 00200 WideCharToMultiByte( 00201 CP_ACP, // Use the ASCII code page 00202 0, // No special flags 00203 pszString, // Wide characters to convert 00204 -1, // The wide character text is null terminated 00205 pszByte, // Have WideCharToMultiByte write the ASCII bytes in our static or just allocated buffer 00206 nByte, // This is how much space it has 00207 NULL, // No special options for unmappable characters 00208 NULL ); 00209 00210 // Write the ASCII text into the end of the packet 00211 Write( pszByte, nByte - ( bNull ? 0 : 1 ) ); // If bNull is true, also write the null terminator which got converted 00212 00213 // If we needed a bigger buffer and allocated one, we have to remember to delete it 00214 if ( pszByte != m_szSCHAR ) delete [] pszByte; 00215 } 00216 00217 // Takes text 00218 // Determines how many bytes of ASCII text it would turn into when converted 00219 // Returns the number, 5 for "hello", that does not include a null terminator 00220 int CPacket::GetStringLen(LPCTSTR pszString) const 00221 { 00222 // If the text is blank, the length is 0 00223 if ( *pszString == 0 ) return 0; 00224 00225 // Find the number of characters in the text 00226 int nLength = _tcslen( pszString ); // Same as lstrlen, doesn't include null terminator 00227 00228 // Find out how many ASCII bytes the text would convert into, and return that number 00229 nLength = WideCharToMultiByte( CP_ACP, 0, pszString, nLength, NULL, 0, NULL, NULL ); 00230 return nLength; 00231 } 00232 00234 // CPacket UTF-8 strings 00235 00236 // Takes the number of bytes to look at from our position in the packet as ASCII text 00237 // Converts those up to the next null terminator into wide characters using the UTF8 code page 00238 // Returns the string of converted Unicode wide characters 00239 CString CPacket::ReadStringUTF8(DWORD nMaximum) 00240 { 00241 // We'll convert the ASCII text in the packet into wide characters using the UTF8 code page, and return them in this string 00242 CString strString; 00243 00244 // If maximum would have us read beyond the end of the packet, make it smaller to read to the end of the packet 00245 nMaximum = min( nMaximum, m_nLength - m_nPosition ); 00246 if ( ! nMaximum ) return strString; // If that would have us read nothing, return the new blank string 00247 00248 // Setup pointers to look at bytes in the packet 00249 LPCSTR pszInput = (LPCSTR)m_pBuffer + m_nPosition; // Point pszInput at our position inside the buffer 00250 LPCSTR pszScan = pszInput; // Start out pszScan at the same spot, it will find the next null terminator 00251 00252 // Loop for each byte in the packet at and beyond our position in it, searching for a null terminator 00253 DWORD nLength = 0; // When this loop is done, nLength will be the number of ASCII bytes we moved over before finding the null terminator 00254 for ( ; nLength < nMaximum ; nLength++ ) 00255 { 00256 // Move the position pointer in this CPacket object to the next byte 00257 m_nPosition++; 00258 00259 // If pszScan points to a 0 byte, exit the loop, otherwise move the pointer forward and keep going 00260 if ( ! *pszScan++ ) break; 00261 } 00262 00263 // Find out how many wide characters the ASCII bytes will become when converted 00264 int nWide = MultiByteToWideChar( 00265 CP_UTF8, // Use the UTF8 code page 00266 0, // No character type options 00267 pszInput, // Pointer to ASCII text in the packet 00268 nLength, // Number of bytes to read there, the number of bytes before we found the null terminator 00269 NULL, // No output buffer, we just want to know how many wide characters one would need to hold 00270 0 ); 00271 00272 // Convert the ASCII bytes into wide characters 00273 MultiByteToWideChar( 00274 CP_UTF8, // Use the UTF8 code page 00275 0, // No character type options 00276 pszInput, // Pointer to ASCII text 00277 nLength, // Number of bytes to read there, the number of bytes before we found the null terminator 00278 strString.GetBuffer( nWide ), // Get access to the string's buffer, telling it we will write in nWide wide characters 00279 nWide ); // Tell MultiByteToWideChar it can write nWide characters in the buffer 00280 00281 // Close the string and return it 00282 strString.ReleaseBuffer( nWide ); 00283 return strString; 00284 } 00285 00286 // Takes Unicode text, and true to also write a null terminator into the packet 00287 // Converts it into ASCII bytes using the UTF8 code page, and writes them into the end of the packet 00288 void CPacket::WriteStringUTF8(LPCTSTR pszString, BOOL bNull) 00289 { 00290 // Find out how many bytes of ASCII text the wide characters will become when converted with the UTF8 code page 00291 int nByte = WideCharToMultiByte( 00292 CP_UTF8, // Use the UTF8 code page 00293 0, // No special performance and mapping flags 00294 pszString, // Wide characters to convert 00295 -1, // The given text in null terminated, and we want the text and the null terminator converted 00296 NULL, // No buffer given, we just want to know how many bytes the converted ASCII text will take up 00297 0, 00298 NULL, // No special options for unmappable characters 00299 NULL ); 00300 00301 // If our buffer of 128 ASCII characters is big enough, use it, otherwise allocate a new bigger buffer 00302 LPSTR pszByte = nByte <= PACKET_BUF_SCHAR ? m_szSCHAR : new CHAR[ nByte ]; 00303 00304 // Convert the wide characters into bytes of ASCII text 00305 WideCharToMultiByte( 00306 CP_UTF8, // Use the UTF8 code page 00307 0, // No special performance and mapping flags 00308 pszString, // Wide characters to convert 00309 -1, // The given text in null terminated, and we want the text and the null terminator converted 00310 pszByte, // Have WideCharToMultiByte write the ASCII bytes in our static or just allocated buffer 00311 nByte, // This is how much space it has 00312 NULL, // No special options for unmappable characters 00313 NULL ); 00314 00315 // Write the ASCII text into the end of the packet 00316 Write( pszByte, nByte - ( bNull ? 0 : 1 ) ); // If bNull is true, also write the null terminator which got converted 00317 00318 // If we needed a bigger buffer and allocated one, we have to remember to delete it 00319 if ( pszByte != m_szSCHAR ) delete [] pszByte; 00320 } 00321 00322 // Takes text 00323 // Determines how many bytes of ASCII text it would turn into when converted with the UTF8 code page 00324 // Returns the number, which does not include a null terminator 00325 int CPacket::GetStringLenUTF8(LPCTSTR pszString) const 00326 { 00327 // If the text is blank, the length is 0 00328 if ( *pszString == 0 ) return 0; 00329 00330 // Find the number of characters in the text 00331 int nLength = _tcslen( pszString ); // Same as lstrlen, doesn't include null terminator 00332 00333 // Find out how many ASCII bytes the text would convert into using the UTF8 code page, and return that number 00334 nLength = WideCharToMultiByte( CP_UTF8, 0, pszString, nLength, NULL, 0, NULL, NULL ); 00335 return nLength; 00336 } 00337 00339 // CPacket ZLIB 00340 00341 // Takes a length of compressed data, access to a DWORD to write a size, and a guess as to how big the data will be decompressed 00342 // Uses zlib to decompress the next nLength bytes of data from our current position in the packet 00343 // Returns a pointer to the decompressed memory that CZLib allocated 00344 LPBYTE CPacket::ReadZLib(DWORD nLength, DWORD* pnOutput, DWORD nSuggest) 00345 { 00346 // The packet has m_nLength bytes, and we are at m_nPosition in it, make sure nLength can fit in the part afterwards 00347 if ( m_nLength - m_nPosition < nLength ) return NULL; 00348 00349 // Decompress the data 00350 *pnOutput = 0; // CZLib will write the size of the memory block it's returning here 00351 LPBYTE pOutput = CZLib::Decompress( // Use zlib, return a pointer to memory CZLib allocated 00352 m_pBuffer + m_nPosition, // The compressed data starts here 00353 nLength, // And is this long 00354 (DWORD*)pnOutput, // CZLib::Decompress will write the size of the memory it returns a pointer to here 00355 nSuggest ); // Tell zlib how big we expect the data to be when decompressed 00356 00357 // Move the position in the packet past the memory we just decompressed 00358 m_nPosition += nLength; 00359 00360 // Return a pointer to the memory that CZLib allocated 00361 return pOutput; 00362 } 00363 00364 // Takes a pointer to memory, and the number of bytes we can read there 00365 // Compresses that data, and writes it into the packet 00366 void CPacket::WriteZLib(LPCVOID pData, DWORD nLength) 00367 { 00368 // Compress the given data 00369 DWORD nOutput = 0; // CZLib will write the size of the memory it returns here 00370 BYTE* pOutput = CZLib::Compress( // Compress the data, getting a pointer to the memory CZLib allocated 00371 pData, // Compress the data at pData 00372 (DWORD)nLength, // Where there are nLength bytes 00373 &nOutput ); // CZLib will write the size of the memory it returns in nOutput 00374 00375 // Write the compressed bytes into the packet 00376 Write( pOutput, nOutput ); 00377 00378 // Remember to delete the memory the CZLib allocated and returned 00379 delete [] pOutput; 00380 } 00381 00383 // CPacket pointer access 00384 00385 // Takes the number of bytes to write, nLength, and where we want to write them, nOffset 00386 // Increases the size of the buffer and makes a gap to hold that many bytes there 00387 // Returns a pointer to the gap where the caller can insert the new data 00388 BYTE* CPacket::WriteGetPointer(DWORD nLength, DWORD nOffset) 00389 { 00390 // If the caller didn't specify an nOffset, the method's default is -1, make nOffset the end of the packet 00391 if ( nOffset == 0xFFFFFFFF ) nOffset = m_nLength; 00392 00393 // If adding nLength would go beyond the buffer, we need to make it bigger 00394 if ( m_nLength + nLength > m_nBuffer ) 00395 { 00396 // Increase the size of the buffer by the needed length, or 128 bytes, whichever is bigger 00397 m_nBuffer += max( nLength, DWORD(PACKET_GROW) ); // Packet grow is 128 bytes 00398 LPBYTE pNew = new BYTE[ m_nBuffer ]; // Allocate a new buffer of that size 00399 CopyMemory( pNew, m_pBuffer, m_nLength ); // Copy all the memory of the old buffer into the new bigger one 00400 if ( m_pBuffer ) delete [] m_pBuffer; // Free the old buffer 00401 m_pBuffer = pNew; // Point this packet object at its new, bigger buffer 00402 } 00403 00404 // If the offset isn't at the very end of the buffer 00405 if ( nOffset != m_nLength ) 00406 { 00407 // Shift the fragment beyond the offset into the buffer further to make a gap m_nLength big to hold the new data 00408 MoveMemory( 00409 m_pBuffer + nOffset + nLength, // Destination is beyond the offset and the length of what we're going to insert 00410 m_pBuffer + nOffset, // Source is at the offset 00411 m_nLength - nOffset ); // Size is the number of bytes written in the buffer beyond the offset 00412 } 00413 00414 // Record there are going to be nLength more bytes stored in the buffer 00415 m_nLength += nLength; 00416 00417 // Return a pointer to where the caller can write the nLength bytes 00418 return m_pBuffer + nOffset; 00419 } 00420 00422 // CPacket string conversion 00423 00424 // Ask this packet what type it is 00425 // Returns text 00426 LPCTSTR CPacket::GetType() const // Saying const indicates this method doesn't change the values of any member variables 00427 { 00428 // This is just a CPacket, not a G1Packet which would have a type 00429 return NULL; // Return blank 00430 } 00431 00432 // Express all the bytes of the packet as base 16 digits separated by spaces, like "08 C0 12 AF" 00433 // Returns a string 00434 CString CPacket::ToHex() const 00435 { 00436 // Setup the alphabet to use when endoing each byte in two hexadecimal characters, 0-9 and A-F 00437 LPCTSTR pszHex = _T("0123456789ABCDEF"); 00438 00439 // Make a string and open it to write the characters in it directly, for speed 00440 CString strDump; 00441 LPTSTR pszDump = strDump.GetBuffer( m_nLength * 3 ); // Each byte will become 3 characters 00442 00443 // Loop i down each byte in the packet 00444 for ( DWORD i = 0 ; i < m_nLength ; i++ ) 00445 { 00446 // Copy the byte at i into an integer called nChar 00447 int nChar = m_pBuffer[i]; 00448 00449 // If this isn't the very start, write a space into the text 00450 if ( i ) *pszDump++ = ' '; // Write a space at pszDump, then move the pszDump pointer forward to the next character 00451 00452 // Express the byte as two characters in the text, "00" through "FF" 00453 *pszDump++ = pszHex[ nChar >> 4 ]; 00454 *pszDump++ = pszHex[ nChar & 0x0F ]; 00455 } 00456 00457 // Write a null terminator beyond the characters we wrote, close direct memory access to the string, and return it 00458 *pszDump = 0; 00459 strDump.ReleaseBuffer(); 00460 return strDump; 00461 } 00462 00463 // Read the bytes of the packet as though they are ASCII characters, placing periods for those that aren't 00464 // Returns a string like "abc..fgh.i" 00465 CString CPacket::ToASCII() const 00466 { 00467 // Make a string and get direct access to its memory buffer 00468 CString strDump; 00469 LPTSTR pszDump = strDump.GetBuffer( m_nLength + 1 ); // We'll write a character for each byte, and 1 more for the null terminator 00470 00471 // Loop i down each byte in the packet 00472 for ( DWORD i = 0 ; i < m_nLength ; i++ ) 00473 { 00474 // Copy the byte at i into an integer called nChar 00475 int nChar = m_pBuffer[i]; 00476 00477 // If the byte is 32 or greater, read it as an ASCII character and copy that character into the string 00478 *pszDump++ = ( nChar >= 32 ? nChar : '.' ); // If it's 0-31, copy in a period instead 00479 } 00480 00481 // Write a null terminator beyond the characters we wrote, close direct memory access to the string, and return it 00482 *pszDump = 0; 00483 strDump.ReleaseBuffer(); 00484 return strDump; 00485 } 00486 00488 // CPacket debugging 00489 00490 // Classes that inherit from CPacket override this with their own Debug methods that record debugging information 00491 // Takes text that describes what happened 00492 void CPacket::Debug(LPCTSTR pszReason) const 00493 { 00494 // Only include these lines in the program if it is being compiled in debug mode 00495 #ifdef _DEBUG 00496 00497 theApp.Message( MSG_DEBUG, pszReason ); 00498 CString strOutput; 00499 00500 // Loop the index i down each byte in the packet buffer 00501 for ( DWORD i = 0 ; i < m_nLength ; i++ ) 00502 { 00503 // Read the byte there as an int called nChar 00504 int nChar = m_pBuffer[i]; 00505 00506 // Encode it as two base 16 characters followed by an ASCII character, like "00(.) " or "41(A) " 00507 // avoid % in order to avoid trouble with format functions 00508 CString strTmp; 00509 strTmp.Format( _T("%.2X(%c) "), nChar, ( nChar >= 32 && nChar != '%' ? nChar : '.' ) ); 00510 strOutput += strTmp; 00511 } 00512 00513 theApp.Message( MSG_DEBUG, LPCTSTR( strOutput ) ); 00514 00515 // Go back to including all the lines in the program 00516 #endif 00517 } 00518 00520 // CPacket smart dumping 00521 00522 // Takes a CNeighbour object, an IP address without a port number, and true if we are sending the packet, false if we received it 00523 // Gives this packet and related objects to each window in the tab bar for them to process it 00524 void CPacket::SmartDump(CNeighbour* pNeighbour, IN_ADDR* pUDP, BOOL bOutgoing) const 00525 { 00526 // Get exclusive access to the program's critical section while this method runs 00527 CSingleLock pLock( &theApp.m_pSection ); // When the method exits, pLock will go out of scope, be destructed, and release the lock 00528 if ( pLock.Lock( 50 ) ) // If we wait more than 1/20th of a second for access, Lock will return false so we can just give up 00529 { 00530 // Get a pointer to the main Shareaza window 00531 if ( CMainWnd* pMainWnd = (CMainWnd*)theApp.m_pSafeWnd ) 00532 { 00533 // Get pointers to the window manager, and null a pointer to a packet window 00534 CWindowManager* pWindows = &pMainWnd->m_pWindows; 00535 CPacketWnd* pWnd = NULL; 00536 00537 // Loop through all the windows, pointing pWnd at each one 00538 while ( pWnd = (CPacketWnd*)pWindows->Find( RUNTIME_CLASS(CPacketWnd), pWnd ) ) 00539 { 00540 // Give each window this packet to process, along with the related CNeighbour object, IP address, and travel direction 00541 pWnd->Process( pNeighbour, pUDP, bOutgoing, this ); 00542 } 00543 } 00544 } 00545 } 00546 00548 // CPacket RAZA signatures 00549 00550 // Takes the number of bytes in this packet to hash 00551 // Computs the SHA hash of those bytes 00552 // Writes the hash under the given pointer and returns true, or false on error 00553 BOOL CPacket::GetRazaHash(SHA1* pHash, DWORD nLength) const 00554 { 00555 // If the caller didn't specify a length, we'll hash all the bytes in the packet 00556 if ( nLength == 0xFFFFFFFF ) nLength = m_nLength; 00557 00558 // Make sure the caller didn't ask to hash more bytes than the packet contains 00559 if ( (DWORD)m_nLength < nLength ) return FALSE; 00560 00561 // Make a new local CSHA object to use to hash the data 00562 CSHA pSHA; 00563 pSHA.Add( m_pBuffer, nLength ); // Add the bytes of the packet to those it needs to hash 00564 pSHA.Finish(); // Tell it that's all we have 00565 pSHA.GetHash( pHash ); // Ask it to write the hash under the pHash pointer 00566 return TRUE; // Report success 00567 } 00568 00569 // Does nothing, and is not overriden by any inheritng class (do) 00570 void CPacket::RazaSign() 00571 { 00572 // Do nothing (do) 00573 } 00574 00575 // Does nothing, and is not overriden by any inheritng class (do) 00576 BOOL CPacket::RazaVerify() const 00577 { 00578 // Always return false (do) 00579 return FALSE; 00580 } 00581 00583 // CPacketPool construction 00584 00585 // Make a new packet pool 00586 CPacketPool::CPacketPool() 00587 { 00588 // Set member variables to null and 0 defaults 00589 m_pFree = NULL; // No pointer to a CPacket object 00590 m_nFree = 0; // Start the count at 0 (do) 00591 } 00592 00593 // Delete this packet pool 00594 CPacketPool::~CPacketPool() 00595 { 00596 // Free all the packets in this pool before the destructor frees this packet pool object itself 00597 Clear(); 00598 } 00599 00601 // CPacketPool clear 00602 00603 // Delete all the packet objects that this packet pool points to, and return the member variables to defaults 00604 void CPacketPool::Clear() 00605 { 00606 // Loop from the end of the pointer array back to the start 00607 for ( 00608 int nIndex = m_pPools.GetSize() - 1; // GetSize returns the number of pointers in the array, start nIndex on the last one 00609 nIndex >= 0; // If nIndex reaches 0, loop one more time, when it's -1, don't do the loop anymore 00610 nIndex-- ) // Move back one index in the pointer array 00611 { 00612 // Point pPool at the packet pool at that position in the array 00613 CPacket* pPool = (CPacket*)m_pPools.GetAt( nIndex ); 00614 00615 // Delete the packet pool, freeing the memory of the 256 packets in it 00616 FreePoolImpl( pPool ); // Calls up higher on the inheritance tree 00617 } 00618 00619 // Clear all the member variables of this packet pool object 00620 m_pPools.RemoveAll(); // Remove all the pointers from the MFC CPtrArray structure 00621 m_pFree = NULL; // There are no packets to point to anymore 00622 m_nFree = 0; // This packet pool has 0 packets now 00623 } 00624 00626 // CPacketPool new pool setup 00627 00628 // Create a new array of 256 packets, called a packet pool, and add it to this CPacketPool object's list of them 00629 void CPacketPool::NewPool() 00630 { 00631 // Allocate an array of 256 packets, this is a new packet pool 00632 CPacket* pPool = NULL; 00633 int nPitch = 0, nSize = 256; 00634 NewPoolImpl( // NewPoolImpl allocates an array of packets for this packet pool object 00635 nSize, // The number of packets the array will hold, we want 256 00636 pPool, // NewPoolImpl will save a pointer to the allocated array here 00637 nPitch ); // NewPoolImpl will save the size in bytes of each packet in the array here 00638 00639 // Add the new packet pool to m_pPools, this CPacketPool object's list of them 00640 m_pPools.Add( pPool ); 00641 00642 // Link the packets in the new pool so m_pFree points at the last one, they each point to the one before, and the first points to what m_pFree used to 00643 BYTE* pBytes = (BYTE*)pPool; // Start the pBytes pointer at the start of our new packet pool 00644 while ( nSize-- > 0 ) // Loop 256 times, once for each packet in the new pool 00645 { 00646 // Link this packet to the one before it 00647 pPool = (CPacket*)pBytes; // Point pPool at the new packet pool we just created and added to the list 00648 pBytes += nPitch; // Move pBytes to the next packet in the pool 00649 pPool->m_pNext = m_pFree; // Set the next pointer in the first packet in the pool 00650 m_pFree = pPool; // Point m_pFree at the next packet 00651 m_nFree++; // Record one more packet is linked into the list 00652 } 00653 }