CPacket CPacketPool 类 cpp文件

//
// Packet.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2005.
// This file is part of SHAREAZA (
www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

// CPacket represents a packet on a peer-to-peer network, and CPacketPool keeps lists of them
//
http://wiki.shareaza.com/static/Developers.Code.CPacket

// Copy in the contents of these files here before compiling
#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "Network.h"
#include "Packet.h"
#include "ZLib.h"
#include "SHA.h"
#include "Buffer.h"
#include "WndMain.h"
#include "WndPacket.h"

// If we are compiling in debug mode, replace the text "THIS_FILE" in the code with the name of this file
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// Buffers that hold 128 ASCII and 128 wide characters, used so MultiByteToWideChar can convert short text quickly

CHAR  CPacket::m_szSCHAR[PACKET_BUF_SCHAR + 1]; // 静态变量声明

WCHAR CPacket::m_szWCHAR[PACKET_BUF_WCHAR + 1];

//
// CPacket construction

// Takes a protocol id, like PROTOCOL_G1 for Gnutella
// Makes a new CPacket object to represent a packet

CPacket::CPacket(PROTOCOLID nProtocol)
{
 // Save the given protocol id in the object
 
 m_nProtocol  = nProtocol;

 // This packet isn't in a list yet, and isn't being used at all yet
 
 m_pNext      = NULL; // No packet next in a list
 
 m_nReference = 0;    // No one needs this packet yet, the reference count starts at 0

 // Start out memory pointers and lengths at null and 0
 
 m_pBuffer    = NULL; // This is just a pointer to allocated bytes, not a CBuffer object that would take care of itself
 
 m_nBuffer    = 0;
 
 m_nLength    = 0;
 
 m_nPosition  = 0;

 // Assume the bytes of the packet are in big endian order
 
 m_bBigEndian = TRUE;//默认packet是bigendian的
}

// Delete this CPacket object

//删除m_pBuffer所占用的空间,m_nReference必须为0才可以删除

CPacket::~CPacket()
{
 // Make sure the reference count is zero

 ASSERT( m_nReference == 0 ); // If it's not, then this packet is being deleted when something still needs it

 // If the packet points to some memory, delete it

 if ( m_pBuffer ) //byte *
 {
  delete [] m_pBuffer;
 }
}

//
// CPacket reset

// Clear and reset the values of this packet object to use it again, just like it came from the constructor

//注意这里没有释放buffer占用的内存,只是把各个长度变量清0了

void CPacket::Reset()
{
 // Make sure Reset is only called when nothing is referencing this packet object
 
 ASSERT( m_nReference == 0 );//m_nReference 为0才可以reset

 // Reset the member variables to null and 0 defaults
 
 m_pNext      = NULL;
 
 m_nLength    = 0;
 
 m_nPosition  = 0;
 
 m_bBigEndian = TRUE;
}

//
// CPacket position and seeking

// 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
// Moves the position this packet object remembers to that distance from the start or end

//设置m_nPosition为nPosition,如果nPosition位置有数据的话,nRelative指定了是从开始向后数nPosition个位置

//还是从末尾向前数nPosition个位置

void CPacket::Seek(DWORD nPosition, int nRelative)
{
 // Set the position forwards from the start
 
 if ( nRelative == seekStart ) //确保m_nPosition在有数据的区域
 {
  // Move the position in the object to the given position, making sure it's in the data
 
  m_nPosition = max( DWORD(0), min( m_nLength, nPosition ) );

 } // Set the position backwards from the end
 else
 {
  // Move the position in the object to m_nLength - nPosition from the start, which is nPosition from the end

  m_nPosition = max( DWORD(0), min( m_nLength, m_nLength - nPosition ) );
 }
}

// Takes a number of bytes

// Shortens the packet to that length

//如果nLength比m_nLength小,则设置m_nLength为参数nLength,同样修改m_nPositon的值

void CPacket::Shorten(DWORD nLength)
{
 // If the given length is within the data of the packet, shorten the packet and our position in it
 
 m_nLength = min( m_nLength, nLength );     // Record that there are only nLength bytes of packet data written in the buffer
 
 m_nPosition = min( m_nPosition, m_nLength ); // Make sure this doesn't move our position beyond the bytes of the packet
}

//
// CPacket strings

// Takes the number of bytes to look at from our position in the packet as ASCII text
// Reads those up to the next null terminator as text
// Returns a string

//从m_pBuffer + m_nPosition位置读取数据,转化为utf8编码,返回结果CString

CString CPacket::ReadString(DWORD nMaximum)
{
 // We'll convert the ASCII text in the packet into wide characters, and return them in this string
 
 CString strString;

 // If maximum would have us read beyond the end of the packet, make it smaller to read to the end of the packet
 
 //nMaximum最大只能是m_nLength - m_nPosition,也就是剩余的空间那么多

 nMaximum = min( nMaximum, m_nLength - m_nPosition );
 
 if ( ! nMaximum )
 {
  return strString; // If that would have us read nothing, return the new blank string
 }

 // Setup pointers to look at bytes in the packet
 
 LPCSTR pszInput = (LPCSTR)m_pBuffer + m_nPosition; // Point pszInput at our position inside the buffer
 
 LPCSTR pszScan  = pszInput;                        // Start out pszScan at the same spot, it will find the next null terminator

 // Loop for each byte in the packet at and beyond our position in it, searching for a null terminator
   
 DWORD nLength = 0; // When this loop is done, nLength will be the number of ASCII bytes we moved over before finding the null terminator
 
 //计算出pszScan中的ascii字节的数目,下面要用到

 for ( ; nLength < nMaximum ; nLength++ )
 {
  // Move the position pointer in this CPacket object to the next byte
  
  m_nPosition++;

  // If pszScan points to a 0 byte, exit the loop, otherwise move the pointer forward and keep going
  
  if ( ! *pszScan++ )
  {
   break;
  }
 }

 // Find out how many wide characters the ASCII bytes will become when converted
 
 //算出需要多大的空间来存放pszInput的数据

 int nWide = MultiByteToWideChar(
  CP_ACP,   // Use the code page for ASCII
  0,        // No character type options
  pszInput, // Pointer to ASCII text in the packet
  nLength,  // Number of bytes to read there, the number of bytes before we found the null terminator
  NULL,     // No output buffer, we just want to know how many wide characters one would need to hold
  0 );

 // Convert the ASCII bytes into wide characters

 //转化为utf8编码,保存到strString中
 
 MultiByteToWideChar(
  CP_ACP,                       // Use the UTF8 code page
  0,                            // No character type options
  pszInput,                     // Pointer to ASCII text
  nLength,                      // Number of bytes to read there, the number of bytes before we found the null terminator
  strString.GetBuffer( nWide ), // Get access to the string's buffer, telling it we will write in nWide wide characters
  nWide );                      // Tell MultiByteToWideChar it can write nWide characters in the buffer

 // Close the string and return it
 
 strString.ReleaseBuffer( nWide );
 
 return strString;
}

// Takes text, and true to also write a null terminator
// Converts the text into ASCII bytes using the ASCII code page, and writes them into the end of the packet

//使用ASCII码表将参数pszString转化为multibytes,也就是ascii字符

void CPacket::WriteString(LPCTSTR pszString, BOOL bNull)
{
 // Find out how many ASCII bytes the wide characters will become when converted
 
 //计算出转化为multibytes后所需空间

 int nByte = WideCharToMultiByte(
  CP_ACP,    // Use the ASCII code page
  0,         // No special flags
  pszString, // Wide characters to convert
  -1,        // The wide character text is null terminated, and the null terminator will be converted into a wide null terminator
  NULL,      // No buffer given, we just want to know how big one would need to be
  0,         // No buffer size given
  NULL,      // No special options for unmappable characters
  NULL );

 // If our buffer of 128 ASCII characters is big enough, use it, otherwise allocate a new bigger buffer
 
 //如果小于127字节,则保存到 m_szSCHAR中,否则创建新的内存空间

 LPSTR pszByte = nByte <= PACKET_BUF_SCHAR ? m_szSCHAR : new CHAR[ nByte ];

 // Convert the wide characters into bytes of ASCII text

 //将参数pszString写入到pszBytes中
 
 WideCharToMultiByte(
  CP_ACP,    // Use the ASCII code page
  0,         // No special flags
  pszString, // Wide characters to convert
  -1,        // The wide character text is null terminated
  pszByte,   // Have WideCharToMultiByte write the ASCII bytes in our static or just allocated buffer
  nByte,     // This is how much space it has
  NULL,      // No special options for unmappable characters
  NULL );

 // Write the ASCII text into the end of the packet

 //写入到buffer中,如果bNull为真,则在最后写入/0,否则不写
 
 Write( pszByte, nByte - ( bNull ? 0 : 1 ) ); // If bNull is true, also write the null terminator which got converted

 // If we needed a bigger buffer and allocated one, we have to remember to delete it
 
 if ( pszByte != m_szSCHAR ) // 如果是新分配的内存,则释放之
 {
  delete [] pszByte;
 }

}

// Takes text
// Determines how many bytes of ASCII text it would turn into when converted
// Returns the number, 5 for "hello", that does not include a null terminator

//返回将参数LPCTSTR pszString转化为multibytes ascii编码 字符串后的长度

int CPacket::GetStringLen(LPCTSTR pszString) const
{
 // If the text is blank, the length is 0
 
 if ( *pszString == 0 )
 {
  return 0;
 }

 // Find the number of characters in the text下面WideCharToMultiByte要用到
 
 int nLength = _tcslen( pszString ); // Same as lstrlen, doesn't include null terminator

 // Find out how many ASCII bytes the text would convert into, and return that number
 
 nLength = WideCharToMultiByte( CP_ACP, 0, pszString, nLength, NULL, 0, NULL, NULL );
 
 return nLength;
}

//
// CPacket UTF-8 strings

// Takes the number of bytes to look at from our position in the packet as ASCII text
// Converts those up to the next null terminator into wide characters using the UTF8 code page
// Returns the string of converted Unicode wide characters

//将m_pBuffer + m_nPosition位置开始的数据转化为utf8编码的CString unicode widechar

CString CPacket::ReadStringUTF8(DWORD nMaximum)
{
 // We'll convert the ASCII text in the packet into wide characters using the UTF8 code page, and return them in this string
 
 CString strString;

 // If maximum would have us read beyond the end of the packet, make it smaller to read to the end of the packet
 
 nMaximum = min( nMaximum, m_nLength - m_nPosition );
 
 if ( ! nMaximum )
 {
  return strString; // If that would have us read nothing, return the new blank string
 }

 // Setup pointers to look at bytes in the packet

 LPCSTR pszInput = (LPCSTR)m_pBuffer + m_nPosition; // Point pszInput at our position inside the buffer
 
 LPCSTR pszScan = pszInput;                        // Start out pszScan at the same spot, it will find the next null terminator

 // Loop for each byte in the packet at and beyond our position in it, searching for a null terminator
  
 DWORD nLength = 0; // When this loop is done, nLength will be the number of ASCII bytes we moved over before finding the null terminator
 
 for ( ; nLength < nMaximum ; nLength++ )
 {
  // Move the position pointer in this CPacket object to the next byte
  
  m_nPosition++;

  // If pszScan points to a 0 byte, exit the loop, otherwise move the pointer forward and keep going
  
  if ( ! *pszScan++ )
  {
   break;
  }
 }

 // Find out how many wide characters the ASCII bytes will become when converted
 
 int nWide = MultiByteToWideChar(
  CP_UTF8,  // Use the UTF8 code page
  0,        // No character type options
  pszInput, // Pointer to ASCII text in the packet
  nLength,  // Number of bytes to read there, the number of bytes before we found the null terminator
  NULL,     // No output buffer, we just want to know how many wide characters one would need to hold
  0 );

 // Convert the ASCII bytes into wide characters
 
 MultiByteToWideChar(
  CP_UTF8,                      // Use the UTF8 code page
  0,                            // No character type options
  pszInput,                     // Pointer to ASCII text
  nLength,                      // Number of bytes to read there, the number of bytes before we found the null terminator
  strString.GetBuffer( nWide ), // Get access to the string's buffer, telling it we will write in nWide wide characters
  nWide );                      // Tell MultiByteToWideChar it can write nWide characters in the buffer

 // Close the string and return it
 
 strString.ReleaseBuffer( nWide );
 
 return strString;
}

// Takes Unicode text, and true to also write a null terminator into the packet
// Converts it into ASCII bytes using the UTF8 code page, and writes them into the end of the packet

//将参数utf8编码的pszString转化为ascii编码的字符串,写入到buffer中

void CPacket::WriteStringUTF8(LPCTSTR pszString, BOOL bNull)
{
 // Find out how many bytes of ASCII text the wide characters will become when converted with the UTF8 code page
 
 int nByte = WideCharToMultiByte(
  CP_UTF8,   // Use the UTF8 code page
  0,         // No special performance and mapping flags
  pszString, // Wide characters to convert
  -1,        // The given text in null terminated, and we want the text and the null terminator converted
  NULL,      // No buffer given, we just want to know how many bytes the converted ASCII text will take up
  0,
  NULL,      // No special options for unmappable characters
  NULL );

 // If our buffer of 128 ASCII characters is big enough, use it, otherwise allocate a new bigger buffer
 
 LPSTR pszByte = nByte <= PACKET_BUF_SCHAR ? m_szSCHAR : new CHAR[ nByte ];

 // Convert the wide characters into bytes of ASCII text
 
 WideCharToMultiByte(
  CP_UTF8,   // Use the UTF8 code page
  0,         // No special performance and mapping flags
  pszString, // Wide characters to convert
  -1,        // The given text in null terminated, and we want the text and the null terminator converted
  pszByte,   // Have WideCharToMultiByte write the ASCII bytes in our static or just allocated buffer
  nByte,     // This is how much space it has
  NULL,      // No special options for unmappable characters
  NULL );

 // Write the ASCII text into the end of the packet
 
 Write( pszByte, nByte - ( bNull ? 0 : 1 ) ); // If bNull is true, also write the null terminator which got converted

 // If we needed a bigger buffer and allocated one, we have to remember to delete it
 
 if ( pszByte != m_szSCHAR )
 {
  delete [] pszByte;
 }
}

// Takes text
// Determines how many bytes of ASCII text it would turn into when converted with the UTF8 code page
// Returns the number, which does not include a null terminator

//计算出如果将字符串pszString转化为utf8编码后需要多少个字节

int CPacket::GetStringLenUTF8(LPCTSTR pszString) const
{
 // If the text is blank, the length is 0

 if ( *pszString == 0 )
 {
  return 0;
 }

 // Find the number of characters in the text

 int nLength = _tcslen( pszString ); // Same as lstrlen, doesn't include null terminator

 // Find out how many ASCII bytes the text would convert into using the UTF8 code page, and return that number
 
 nLength = WideCharToMultiByte( CP_UTF8, 0, pszString, nLength, NULL, 0, NULL, NULL );

 return nLength;
}

//
// CPacket ZLIB

// 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
// Uses zlib to decompress the next nLength bytes of data from our current position in the packet
// Returns a pointer to the decompressed memory that CZLib allocated

//将当前buffer中的压缩过的数据解压缩,返回结果unsigned char *

LPBYTE CPacket::ReadZLib(DWORD nLength, DWORD* pnOutput, DWORD nSuggest)
{
 // The packet has m_nLength bytes, and we are at m_nPosition in it, make sure nLength can fit in the part afterwards
 
 if ( m_nLength - m_nPosition < nLength ) // 从m_nPosition开始nLength长度的数据解压缩
 {
  return NULL;
 }

 // Decompress the data 解压缩数据,pnOutput保存了解压缩后的长度

 *pnOutput = 0;    // CZLib will write the size of the memory block it's returning here
 
 LPBYTE pOutput = CZLib::Decompress( // Use zlib, return a pointer to memory CZLib allocated
  m_pBuffer + m_nPosition,        // The compressed data starts here
  nLength,                        // And is this long
  (DWORD*)pnOutput,               // CZLib::Decompress will write the size of the memory it returns a pointer to here
  nSuggest );                     // Tell zlib how big we expect the data to be when decompressed

 // Move the position in the packet past the memory we just decompressed

 m_nPosition += nLength;// 指向压缩数据后面的数据

 // Return a pointer to the memory that CZLib allocated

 return pOutput;
}

// Takes a pointer to memory, and the number of bytes we can read there
// Compresses that data, and writes it into the packet

//将参数pData压缩,结果写入到当前buffer中

void CPacket::WriteZLib(LPCVOID pData, DWORD nLength)
{
 // Compress the given data

 DWORD nOutput = 0;               // CZLib will write the size of the memory it returns here
 
 BYTE* pOutput = CZLib::Compress( // Compress the data, getting a pointer to the memory CZLib allocated
  pData,                       // Compress the data at pData
  (DWORD)nLength,              // Where there are nLength bytes
  &nOutput );                  // CZLib will write the size of the memory it returns in nOutput

 // Write the compressed bytes into the packet

 Write( pOutput, nOutput );

 // Remember to delete the memory the CZLib allocated and returned

 delete [] pOutput;
}

//
// CPacket pointer access

// Takes the number of bytes to write, nLength, and where we want to write them, nOffset
// Increases the size of the buffer and makes a gap to hold that many bytes there
// Returns a pointer to the gap where the caller can insert the new data

//返回可写入的位置,m_pBuffer + nOffset,将原来的数据后移nLength个位置

BYTE* CPacket::WriteGetPointer(DWORD nLength, DWORD nOffset)
{
 // If the caller didn't specify an nOffset, the method's default is -1, make nOffset the end of the packet
 
 if ( nOffset == 0xFFFFFFFF )// 没有指定noffset,默认是全部的长度m_nLength
 {
  nOffset = m_nLength;
 }

 // If adding nLength would go beyond the buffer, we need to make it bigger

 if ( m_nLength + nLength > m_nBuffer ) // 原来buffer的长度不够了,增大这个长度
 {
  // Increase the size of the buffer by the needed length, or 128 bytes, whichever is bigger
  
  m_nBuffer += max( nLength, DWORD(PACKET_GROW) ); // Packet grow is 128 bytes
  
  LPBYTE pNew = new BYTE[ m_nBuffer ];             // Allocate a new buffer of that size
  
  CopyMemory( pNew, m_pBuffer, m_nLength );        // Copy all the memory of the old buffer into the new bigger one
  
  if ( m_pBuffer )
  {
   delete [] m_pBuffer;            // Free the old buffer
  }
  
  m_pBuffer = pNew;                                // Point this packet object at its new, bigger buffer
 }

 // If the offset isn't at the very end of the buffer

 if ( nOffset != m_nLength ) // 指定了长度,则首先将m_pBuffer + nOffset位置的数据移动到m_pBuffer + nOffset + nLength位置
 {
  // Shift the fragment beyond the offset into the buffer further to make a gap m_nLength big to hold the new data
  
  MoveMemory(
   m_pBuffer + nOffset + nLength, // Destination is beyond the offset and the length of what we're going to insert
   m_pBuffer + nOffset,           // Source is at the offset
   m_nLength - nOffset );         // Size is the number of bytes written in the buffer beyond the offset
 }

 // Record there are going to be nLength more bytes stored in the buffer

 m_nLength += nLength;

 // Return a pointer to where the caller can write the nLength bytes

 return m_pBuffer + nOffset;
}

//
// CPacket string conversion

// Ask this packet what type it is
// Returns text

LPCTSTR CPacket::GetType() const // Saying const indicates this method doesn't change the values of any member variables
{
 // This is just a CPacket, not a G1Packet which would have a type
 
 return NULL; // Return blank
}

// Express all the bytes of the packet as base 16 digits separated by spaces, like "08 C0 12 AF"
// Returns a string

//将原来的内容m_pBuffer的所有内容转化为16进制形式返回,例如0X12 0X34转化为:“12 34”

CString CPacket::ToHex() const
{
 // Setup the alphabet to use when endoing each byte in two hexadecimal characters, 0-9 and A-F
 
 LPCTSTR pszHex = _T("0123456789ABCDEF");

 // Make a string and open it to write the characters in it directly, for speed

 CString strDump; // 结果数据空间,长度变为3倍,例如变为数字0XFF变为“空格FF”

 LPTSTR pszDump = strDump.GetBuffer( m_nLength * 3 ); // Each byte will become 3 characters

 // Loop i down each byte in the packet

 for ( DWORD i = 0 ; i < m_nLength ; i++ )
 {
  // Copy the byte at i into an integer called nChar

  int nChar = m_pBuffer[i];

  // If this isn't the very start, write a space into the text

  if ( i ) // 第一个数字没有空格,后面的都有空格,类似于:12 34 46 48 98
  {
   *pszDump++ = ' '; // Write a space at pszDump, then move the pszDump pointer forward to the next character
  }

  // Express the byte as two characters in the text, "00" through "FF"
  
  *pszDump++ = pszHex[ nChar >> 4 ];
  
  *pszDump++ = pszHex[ nChar & 0x0F ];
 }

 // Write a null terminator beyond the characters we wrote, close direct memory access to the string, and return it
 
 *pszDump = 0;//最后了,写入/0
 
 strDump.ReleaseBuffer();

 return strDump;
}

// Read the bytes of the packet as though they are ASCII characters, placing periods for those that aren't
// Returns a string like "abc..fgh.i"

//将m_pBuffer的所有内容转化为ascii,如果是小于32的字符则显示为.

CString CPacket::ToASCII() const
{
 // Make a string and get direct access to its memory buffer

 CString strDump;

 LPTSTR pszDump = strDump.GetBuffer( m_nLength + 1 ); // We'll write a character for each byte, and 1 more for the null terminator

 // Loop i down each byte in the packet

 for ( DWORD i = 0 ; i < m_nLength ; i++ )
 {
  // Copy the byte at i into an integer called nChar

  int nChar = m_pBuffer[i];

  // If the byte is 32 or greater, read it as an ASCII character and copy that character into the string
  
  *pszDump++ = ( nChar >= 32 ? nChar : '.' ); // If it's 0-31, copy in a period instead
 }

 // Write a null terminator beyond the characters we wrote, close direct memory access to the string, and return it
 
 *pszDump = 0;

 strDump.ReleaseBuffer();

 return strDump;
}

//
// CPacket debugging

// Classes that inherit from CPacket override this with their own Debug methods that record debugging information
// Takes text that describes what happened

//Debug用,显示当前buffer的真实内容

void CPacket::Debug(LPCTSTR pszReason) const
{
// Only include these lines in the program if it is being compiled in debug mode

#ifdef _DEBUG

 theApp.Message( MSG_DEBUG, pszReason );

 CString strOutput;

 // Loop the index i down each byte in the packet buffer
 for ( DWORD i = 0 ; i < m_nLength ; i++ )
 {
  // Read the byte there as an int called nChar

  int nChar = m_pBuffer[i];

  // Encode it as two base 16 characters followed by an ASCII character, like "00(.) " or "41(A) "
  // avoid % in order to avoid trouble with format functions

  CString strTmp;

  strTmp.Format( _T("%.2X(%c) "), nChar, ( nChar >= 32 && nChar != '%' ? nChar : '.' ) );

  strOutput += strTmp;
 }

 theApp.Message( MSG_DEBUG, LPCTSTR( strOutput ) );

// Go back to including all the lines in the program

#endif

}

//
// CPacket smart dumping

// Takes a CNeighbour object, an IP address without a port number, and true if we are sending the packet, false if we received it
// Gives this packet and related objects to each window in the tab bar for them to process it

//调用所有CPacketWnd类的窗口都处理包含当前对象的,参数为参数列表的消息,调用Process方法

void CPacket::SmartDump(CNeighbour* pNeighbour,
      IN_ADDR* pUDP, BOOL bOutgoing) const
{
 // Get exclusive access to the program's critical section while this method runs
 
 CSingleLock pLock( &theApp.m_pSection ); // When the method exits, pLock will go out of scope, be destructed, and release the lock
 
 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
 {
  // Get a pointer to the main Shareaza window 找到主Shareaza窗口

  if ( CMainWnd* pMainWnd = (CMainWnd*)theApp.m_pSafeWnd )
  {
   // Get pointers to the window manager, and null a pointer to a packet window

   CWindowManager* pWindows = &pMainWnd->m_pWindows;

   CPacketWnd*     pWnd     = NULL;

   // Loop through all the windows, pointing pWnd at each one 遍历搜索和调用Process

   while ( pWnd = (CPacketWnd*)pWindows->Find( RUNTIME_CLASS(CPacketWnd), pWnd ) )
   {
    // Give each window this packet to process, along with the related CNeighbour object, IP address, and travel direction
    
    pWnd->Process( pNeighbour, pUDP, bOutgoing, this );
   }
  }
 }
}

//
// CPacket RAZA signatures

// Takes the number of bytes in this packet to hash
// Computs the SHA hash of those bytes
// Writes the hash under the given pointer and returns true, or false on error

//获得当前packet对应的sha1 hash

BOOL CPacket::GetRazaHash(SHA1* pHash, DWORD nLength) const
{
 // If the caller didn't specify a length, we'll hash all the bytes in the packet

 if ( nLength == 0xFFFFFFFF ) // 用户没有指定nLength,默认为m_nLength
 {
  nLength = m_nLength;
 }

 // Make sure the caller didn't ask to hash more bytes than the packet contains

 if ( (DWORD)m_nLength < nLength ) // nLength只能比m_nLength要小
 {
  return FALSE;
 }

 // Make a new local CSHA object to use to hash the data

 //将m_pBuffer的hash结果写入参数pHash中

 CSHA pSHA;

 pSHA.Add( m_pBuffer, nLength ); // Add the bytes of the packet to those it needs to hash
 
 pSHA.Finish();                  // Tell it that's all we have
 
 pSHA.GetHash( pHash );          // Ask it to write the hash under the pHash pointer
 
 return TRUE;                    // Report success
}

// Does nothing, and is not overriden by any inheritng class (do)
void CPacket::RazaSign()
{
 // Do nothing (do)
}

// Does nothing, and is not overriden by any inheritng class (do)
BOOL CPacket::RazaVerify() const
{
 // Always return false (do)

 return FALSE;
}

//
// CPacketPool construction

// Make a new packet pool

CPacketPool::CPacketPool()
{
 // Set member variables to null and 0 defaults

 m_pFree = NULL; // No pointer to a CPacket object

 m_nFree = 0;    // Start the count at 0 (do)
}

// Delete this packet pool

CPacketPool::~CPacketPool()
{
 // Free all the packets in this pool before the destructor frees this packet pool object itself
 
 Clear();
}

//
// CPacketPool clear

// Delete all the packet objects that this packet pool points to, and return the member variables to defaults

//释放m_pPools的所有空间

void CPacketPool::Clear()
{
 //删除m_pPools数组中所有的CPacket pPool,调用FreePoolImpl来释放内存

 // Loop from the end of the pointer array back to the start
 
 for (
  int nIndex = m_pPools.GetSize() - 1; // GetSize returns the number of pointers in the array, start nIndex on the last one
  nIndex >= 0;                         // If nIndex reaches 0, loop one more time, when it's -1, don't do the loop anymore
  nIndex-- )                           // Move back one index in the pointer array
 {
  
  // Point pPool at the packet pool at that position in the array
  
  CPacket* pPool = (CPacket*)m_pPools.GetAt( nIndex );

  // Delete the packet pool, freeing the memory of the 256 packets in it
  
  FreePoolImpl( pPool ); // Calls up higher on the inheritance tree
 }

 // Clear all the member variables of this packet pool object,清空m_pPools
 
 m_pPools.RemoveAll(); // Remove all the pointers from the MFC CPtrArray structure
 
 m_pFree = NULL;       // There are no packets to point to anymore
 
 m_nFree = 0;          // This packet pool has 0 packets now
}

//
// CPacketPool new pool setup

// Create a new array of 256 packets, called a packet pool, and add it to this CPacketPool object's list of them

//加入一个CPacket* Pool到m_pPools中

void CPacketPool::NewPool()
{
 // Allocate an array of 256 packets, this is a new packet pool

 CPacket* pPool = NULL;

 int nPitch = 0, nSize = 256;

 //分配一个256个packet的array,结果保存在pPool中

 NewPoolImpl(  // NewPoolImpl allocates an array of packets for this packet pool object
  nSize,    // The number of packets the array will hold, we want 256
  pPool,    // NewPoolImpl will save a pointer to the allocated array here
  nPitch ); // NewPoolImpl will save the size in bytes of each packet in the array here

 // Add the new packet pool to m_pPools, this CPacketPool object's list of them
 
 //将新的pPool加入到m_pPools的最后

 m_pPools.Add( pPool );

 // 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
 
 //将参数pPool的所有CPacket加入到m_pFree链表的开始位置

 BYTE* pBytes = (BYTE*)pPool; // Start the pBytes pointer at the start of our new packet pool
 
 while ( nSize-- > 0 )        // Loop 256 times, once for each packet in the new pool
 {
  // Link this packet to the one before it
  
  pPool = (CPacket*)pBytes; // Point pPool at the new packet pool we just created and added to the list
  
  pBytes += nPitch;         // Move pBytes to the next packet in the pool
  
  pPool->m_pNext = m_pFree; // Set the next pointer in the first packet in the pool
  
  m_pFree = pPool;          // Point m_pFree at the next packet
  
  m_nFree++;                // Record one more packet is linked into the list
 }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值