Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

Packet.cpp

Go to the documentation of this file.
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 }

Generated on Thu Dec 15 10:39:45 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2