windows-nt/Source/XPSP1/NT/multimedia/directx/dplay/tools/parsers/sessionparser.cpp
2020-09-26 16:20:57 +08:00

3189 lines
116 KiB
C++

/*==========================================================================
*
* Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
*
* File: SessionParser.cpp
* Content: DirectPlay Service Provider Parser
*@@BEGIN_MSINTERNAL
* History:
* Date By Reason
* ==== == ======
* 08/08/00 micmil Created
* 08/11/00 rodtoll Bug #42171 -- Build break
* 01/26/01 minara Removed unused structures
*@@END_MSINTERNAL
*
***************************************************************************/
//==================//
// Standard headers //
//==================//
#pragma warning(push)
#pragma warning(disable : 4786) // The identifier string exceeded the maximum allowable length and was truncated
#include <queue>
#pragma warning(pop)
#include <string>
#include <winsock2.h>
#include <wsipx.h>
//=====================//
// Proprietary headers //
//=====================//
// Prototypes
#include "SessionParser.hpp"
// Session protocol headers
#include "DPlay8.h"
#include "Message.h" // DN_INTERNAL_MESSAGE_XXX definitions
//#include "AppDesc.h" // DPN_APPLICATION_DESC_INFO definition
////////////////////////////////////////////////////////////////////////////////////
// TODO: SHOULD BE MOVED TO DPLAY CORE'S HEADER FILE
////////////////////////////////////////////////////////////////////////////////////
#define NAMETABLE_ENTRY_FLAG_LOCAL 0x0001
#define NAMETABLE_ENTRY_FLAG_HOST 0x0002
#define NAMETABLE_ENTRY_FLAG_ALL_PLAYERS_GROUP 0x0004
#define NAMETABLE_ENTRY_FLAG_GROUP 0x0010
#define NAMETABLE_ENTRY_FLAG_GROUP_MULTICAST 0x0020
#define NAMETABLE_ENTRY_FLAG_GROUP_AUTODESTRUCT 0x0040
#define NAMETABLE_ENTRY_FLAG_PEER 0x0100
#define NAMETABLE_ENTRY_FLAG_CLIENT 0x0200
#define NAMETABLE_ENTRY_FLAG_SERVER 0x0400
#define NAMETABLE_ENTRY_FLAG_AVAILABLE 0x1000
#define NAMETABLE_ENTRY_FLAG_CONNECTING 0x2000
#define NAMETABLE_ENTRY_FLAG_DISCONNECTING 0x4000
enum
{
NAMETABLE_ENTRY_FLAG_ANY_GROUP = NAMETABLE_ENTRY_FLAG_ALL_PLAYERS_GROUP | NAMETABLE_ENTRY_FLAG_GROUP |
NAMETABLE_ENTRY_FLAG_GROUP_MULTICAST | NAMETABLE_ENTRY_FLAG_GROUP_AUTODESTRUCT
};
typedef struct _DN_NAMETABLE_INFO
{
DPNID dpnid;
DWORD dwVersion;
DWORD dwVersionNotUsed;
DWORD dwEntryCount;
DWORD dwMembershipCount;
} DN_NAMETABLE_INFO;
typedef struct _DN_NAMETABLE_ENTRY_INFO
{
DPNID dpnid;
DPNID dpnidOwner;
DWORD dwFlags;
DWORD dwVersion;
DWORD dwVersionNotUsed;
DWORD dwDNETVersion;
DWORD dwNameOffset;
DWORD dwNameSize;
DWORD dwDataOffset;
DWORD dwDataSize;
DWORD dwURLOffset;
DWORD dwURLSize;
} DN_NAMETABLE_ENTRY_INFO;
typedef struct _DN_NAMETABLE_MEMBERSHIP_INFO
{
DPNID dpnidPlayer;
DPNID dpnidGroup;
DWORD dwVersion;
DWORD dwVersionNotUsed;
} DN_NAMETABLE_MEMBERSHIP_INFO, *PDN_NAMETABLE_MEMBERSHIP_INFO;
struct DN_INTERNAL_MESSAGE_ALL
{
union
{
DN_INTERNAL_MESSAGE_CONNECT_INFO dnConnectInfo;
DN_INTERNAL_MESSAGE_CONNECT_FAILED dnConnectFailed;
DN_INTERNAL_MESSAGE_PLAYER_CONNECT_INFO dnPlayerConnectInfo;
DN_INTERNAL_MESSAGE_REQUEST_FAILED dnRequestFailed;
DN_INTERNAL_MESSAGE_SEND_PLAYER_DPNID dnSendPlayerID;
DN_INTERNAL_MESSAGE_INSTRUCT_CONNECT dnInstructConnect;
DN_INTERNAL_MESSAGE_INSTRUCTED_CONNECT_FAILED dnInstructedConnectFailed;
DN_INTERNAL_MESSAGE_DESTROY_PLAYER dnDestroyPlayer;
DN_INTERNAL_MESSAGE_CREATE_GROUP dnCreateGroup;
DN_INTERNAL_MESSAGE_DESTROY_GROUP dnDestroyGroup;
DN_INTERNAL_MESSAGE_ADD_PLAYER_TO_GROUP dnAddPlayerToGroup;
DN_INTERNAL_MESSAGE_DELETE_PLAYER_FROM_GROUP dnDeletePlayerFromGroup;
DN_INTERNAL_MESSAGE_UPDATE_INFO dnUpdateInfo;
DN_INTERNAL_MESSAGE_HOST_MIGRATE dnHostMigrate;
DN_INTERNAL_MESSAGE_NAMETABLE_VERSION dnNametableVersion;
DN_INTERNAL_MESSAGE_RESYNC_VERSION dnResyncVersion;
DN_INTERNAL_MESSAGE_REQ_NAMETABLE_OP dnReqNametableOp;
DN_INTERNAL_MESSAGE_ACK_NAMETABLE_OP dnAckNametableOp;
DN_INTERNAL_MESSAGE_REQ_PROCESS_COMPLETION dnReqProcessCompletion;
DN_INTERNAL_MESSAGE_PROCESS_COMPLETION dnProcessCompletion;
DN_INTERNAL_MESSAGE_TERMINATE_SESSION dnTerminateSession;
DN_INTERNAL_MESSAGE_INTEGRITY_CHECK dnIntegrityCheck;
DN_INTERNAL_MESSAGE_INTEGRITY_CHECK_RESPONSE dnIntegrityCheckResponse;
DPN_APPLICATION_DESC_INFO dnUpdateAppDescInfo;
DN_NAMETABLE_ENTRY_INFO dnAddPlayer;
struct
{
DN_INTERNAL_MESSAGE_REQ_PROCESS_COMPLETION dnReqProcessCompletionHeader;
union
{
DN_INTERNAL_MESSAGE_REQ_CREATE_GROUP dnReqCreateGroup;
DN_INTERNAL_MESSAGE_REQ_DESTROY_GROUP dnReqDestroyGroup;
DN_INTERNAL_MESSAGE_REQ_ADD_PLAYER_TO_GROUP dnReqAddPlayerToGroup;
DN_INTERNAL_MESSAGE_REQ_DELETE_PLAYER_FROM_GROUP dnReqDeletePlayerFromGroup;
DN_INTERNAL_MESSAGE_REQ_UPDATE_INFO dnReqUpdateInfo;
DN_INTERNAL_MESSAGE_REQ_INTEGRITY_CHECK dnReqIntegrityCheck;
};
};
BYTE bOffsetBase; // used as a base for fields' offsets
};
};
struct DN_INTERNAL_MESSAGE_FULLMSG
{
DWORD dwMsgType;
DN_INTERNAL_MESSAGE_ALL MsgBody;
};
////////////////////////////////////////////////////////////////////////////////////
namespace
{
HPROTOCOL g_hSessionProtocol;
ULPBYTE g_upbyPastEndOfFrame;
//====================//
// Message Type field //---------------------------------------------------------------------------------------------
//====================//
LABELED_DWORD g_arr_MessageTypeDWordLabels[] =
{ { DN_MSG_INTERNAL_PLAYER_CONNECT_INFO, "Player connection information" },
{ DN_MSG_INTERNAL_SEND_CONNECT_INFO, "Session information" },
{ DN_MSG_INTERNAL_ACK_CONNECT_INFO, "Session information has been acknowledged" },
{ DN_MSG_INTERNAL_SEND_PLAYER_DNID, "Player ID" },
{ DN_MSG_INTERNAL_CONNECT_FAILED, "Connection failed" },
{ DN_MSG_INTERNAL_INSTRUCT_CONNECT, "Instruction to connect" },
{ DN_MSG_INTERNAL_INSTRUCTED_CONNECT_FAILED, "Instruction to connect failed" },
{ DN_MSG_INTERNAL_NAMETABLE_VERSION, "Nametable version" },
{ DN_MSG_INTERNAL_RESYNC_VERSION, "Resync the version" },
{ DN_MSG_INTERNAL_REQ_NAMETABLE_OP, "Reqesting a nametable" },
{ DN_MSG_INTERNAL_ACK_NAMETABLE_OP, "Nametable acknowledgement" },
{ DN_MSG_INTERNAL_HOST_MIGRATE, "Host migration in process" },
{ DN_MSG_INTERNAL_HOST_MIGRATE_COMPLETE, "Host migration has been completed" },
{ DN_MSG_INTERNAL_UPDATE_APPLICATION_DESC, "Update application description" },
{ DN_MSG_INTERNAL_ADD_PLAYER, "Add a player" },
{ DN_MSG_INTERNAL_DESTROY_PLAYER, "Destroy a player" },
{ DN_MSG_INTERNAL_REQ_CREATE_GROUP, "Requesting a group creation" },
{ DN_MSG_INTERNAL_REQ_ADD_PLAYER_TO_GROUP, "Requesting a player addition to the group" },
{ DN_MSG_INTERNAL_REQ_DELETE_PLAYER_FROM_GROUP, "Requesting a player deletion from the group" },
{ DN_MSG_INTERNAL_REQ_DESTROY_GROUP, "Requesting a group destruction " },
{ DN_MSG_INTERNAL_REQ_UPDATE_INFO, "Requesting information update" },
{ DN_MSG_INTERNAL_CREATE_GROUP, "Creating a group" },
{ DN_MSG_INTERNAL_DESTROY_GROUP, "Destroying a group" },
{ DN_MSG_INTERNAL_ADD_PLAYER_TO_GROUP, "Adding a player to the group" },
{ DN_MSG_INTERNAL_DELETE_PLAYER_FROM_GROUP, "Deleting a player from the group" },
{ DN_MSG_INTERNAL_UPDATE_INFO, "Information update" },
{ DN_MSG_INTERNAL_BUFFER_IN_USE, "Buffer is in use" },
{ DN_MSG_INTERNAL_REQUEST_FAILED, "Request has failed" },
{ DN_MSG_INTERNAL_TERMINATE_SESSION, "Terminating session" },
{ DN_MSG_INTERNAL_REQ_PROCESS_COMPLETION, "Initiating reliably handled message transmission" },
{ DN_MSG_INTERNAL_PROCESS_COMPLETION, "Message has been handled by the message handler" },
{ DN_MSG_INTERNAL_REQ_INTEGRITY_CHECK, "Requesting a host to check whether another peer is still in the session" },
{ DN_MSG_INTERNAL_INTEGRITY_CHECK, "Querying a peer whether it's still in the session" },
{ DN_MSG_INTERNAL_INTEGRITY_CHECK_RESPONSE, "Acknowledgement of being still in the session" } };
SET g_LabeledMessageTypeDWordSet = { sizeof(g_arr_MessageTypeDWordLabels) / sizeof(LABELED_DWORD), g_arr_MessageTypeDWordLabels };
//===================//
// Result Code field //----------------------------------------------------------------------------------------------
//===================//
LABELED_DWORD g_arr_ResultCodeDWordLabels[] = { { DPN_OK, "Success" },
{ DPNSUCCESS_EQUAL, "Success (equal)" },
{ DPNSUCCESS_NOTEQUAL, "Success (not equal)" },
{ DPNERR_ABORTED, "Aborted" },
{ DPNERR_ADDRESSING, "Addressing" },
{ DPNERR_ALREADYCLOSING, "Already closing" },
{ DPNERR_ALREADYCONNECTED, "Already connected" },
{ DPNERR_ALREADYDISCONNECTING, "Already disconnecting" },
{ DPNERR_ALREADYINITIALIZED, "Already initialized" },
{ DPNERR_BUFFERTOOSMALL, "Buffer is too small" },
{ DPNERR_CANNOTCANCEL, "Could not cancel" },
{ DPNERR_CANTCREATEGROUP, "Could not create a group" },
{ DPNERR_CANTCREATEPLAYER, "Could not create a player" },
{ DPNERR_CANTLAUNCHAPPLICATION, "Could not launch an application" },
{ DPNERR_CONNECTING, "Connecting" },
{ DPNERR_CONNECTIONLOST, "Connection has been lost" },
{ DPNERR_CONVERSION, "Conversion" },
{ DPNERR_DOESNOTEXIST, "Does not exist" },
{ DPNERR_DUPLICATECOMMAND, "Duplicate command" },
{ DPNERR_ENDPOINTNOTRECEIVING, "Endpoint is not receiving" },
{ DPNERR_ENUMQUERYTOOLARGE, "Enumeration query is too large" },
{ DPNERR_ENUMRESPONSETOOLARGE, "Enumeration response is too large" },
{ DPNERR_EXCEPTION, "Exception was thrown" },
{ DPNERR_GENERIC, "Generic error" },
{ DPNERR_GROUPNOTEMPTY, "Group is not empty" },
{ DPNERR_HOSTING, "Hosting" },
{ DPNERR_HOSTREJECTEDCONNECTION, "Host has rejected the connection" },
{ DPNERR_HOSTTERMINATEDSESSION, "Host terminated the session" },
{ DPNERR_INCOMPLETEADDRESS, "Incomplete address" },
{ DPNERR_INVALIDADDRESSFORMAT, "Invalid address format" },
{ DPNERR_INVALIDAPPLICATION, "Invalid application" },
{ DPNERR_INVALIDCOMMAND, "Invalid command" },
{ DPNERR_INVALIDENDPOINT, "Invalid endpoint" },
{ DPNERR_INVALIDFLAGS, "Invalid flags" },
{ DPNERR_INVALIDGROUP, "Invalid group" },
{ DPNERR_INVALIDHANDLE, "Invalid handle" },
{ DPNERR_INVALIDINSTANCE, "Invalid instance" },
{ DPNERR_INVALIDINTERFACE, "Invalid interface" },
{ DPNERR_INVALIDDEVICEADDRESS, "Invalid device address" },
{ DPNERR_INVALIDOBJECT, "Invalid object" },
{ DPNERR_INVALIDPARAM, "Invalid parameter" },
{ DPNERR_INVALIDPASSWORD, "Invalid password" },
{ DPNERR_INVALIDPLAYER, "Invalid player" },
{ DPNERR_INVALIDPOINTER, "Invalid pointer" },
{ DPNERR_INVALIDPRIORITY, "Invalid priority" },
{ DPNERR_INVALIDHOSTADDRESS, "Invalid host address" },
{ DPNERR_INVALIDSTRING, "Invalid string" },
{ DPNERR_INVALIDURL, "Invalid URL" },
{ DPNERR_INVALIDVERSION, "Invalid version" },
{ DPNERR_NOCAPS, "No CAPs" },
{ DPNERR_NOCONNECTION, "No connection" },
{ DPNERR_NOHOSTPLAYER, "No host player is present" },
{ DPNERR_NOINTERFACE, "No interface" },
{ DPNERR_NOMOREADDRESSCOMPONENTS, "No more address components" },
{ DPNERR_NORESPONSE, "No response" },
{ DPNERR_NOTALLOWED, "Not allowed" },
{ DPNERR_NOTHOST, "Not a host" },
{ DPNERR_NOTREADY, "Not ready" },
{ DPNERR_OUTOFMEMORY, "Out of memory" },
{ DPNERR_PENDING, "Pending" },
{ DPNERR_PLAYERLOST, "Player has been lost" },
{ DPNERR_PLAYERNOTREACHABLE, "Player is not reachable" },
{ DPNERR_SENDTOOLARGE, "Sent data is too large" },
{ DPNERR_SESSIONFULL, "Session is full" },
{ DPNERR_TABLEFULL, "Table is full" },
{ DPNERR_TIMEDOUT, "Timed out" },
{ DPNERR_UNINITIALIZED, "Uninitialized" },
{ DPNERR_UNSUPPORTED, "Unsupported" },
{ DPNERR_USERCANCEL, "User has canceled" } };
SET g_LabeledResultCodeDWordSet = { sizeof(g_arr_ResultCodeDWordLabels) / sizeof(LABELED_DWORD), g_arr_ResultCodeDWordLabels };
//====================//
// Player Flags field //---------------------------------------------------------------------------------------------
//====================//
LABELED_BIT g_arr_FlagsBitLabels[] = { { 0, "Not local", "Local" }, // NAMETABLE_ENTRY_FLAG_LOCAL
{ 1, "Not a host", "Host" }, // NAMETABLE_ENTRY_FLAG_HOST
{ 2, "Not an All Players group", "All Players group" }, // NAMETABLE_ENTRY_FLAG_ALL_PLAYERS_GROUP
{ 4, "Not a group", "Group" }, // NAMETABLE_ENTRY_FLAG_GROUP
{ 5, "Not a Multicast group", "Multicast group" }, // NAMETABLE_ENTRY_FLAG_GROUP_MULTICAST
{ 6, "Not an Autodestruct group", "Autodestruct group" }, // NAMETABLE_ENTRY_FLAG_GROUP_AUTODESTRUCT
{ 8, "Not a peer", "Peer" }, // NAMETABLE_ENTRY_FLAG_PEER
{ 9, "Not a client", "Client" }, // NAMETABLE_ENTRY_FLAG_CLIENT
{ 10, "Not a server", "Server" }, // NAMETABLE_ENTRY_FLAG_SERVER
{ 12, "Not available", "Available" }, // NAMETABLE_ENTRY_FLAG_AVAILABLE
{ 13, "Not connecting", "Connecting" }, // NAMETABLE_ENTRY_FLAG_CONNECTING
{ 14, "Not disconnecting", "Disconnecting" } }; // NAMETABLE_ENTRY_FLAG_DISCONNECTING
SET g_LabeledFlagsBitSet = { sizeof(g_arr_FlagsBitLabels) / sizeof(LABELED_BIT), g_arr_FlagsBitLabels };
//===================//
// Info Flags field //---------------------------------------------------------------------------------------------
//===================//
LABELED_BIT g_arr_InfoFlagsBitLabels[] = { { 0, "No name is included", "Name is included" }, // DPNINFO_NAME
{ 1, "No data is included", "Data is included" } }; // DPNINFO_DATA
SET g_LabeledInfoFlagsBitSet = { sizeof(g_arr_InfoFlagsBitLabels) / sizeof(LABELED_BIT), g_arr_InfoFlagsBitLabels };
//====================//
// Group Flags field //---------------------------------------------------------------------------------------------
//====================//
LABELED_BIT g_arr_GroupFlagsBitLabels[] = { { 0, "Not an autodestruct group", "An autodestruct group" }, // DPNGROUP_AUTODESTRUCT
{ 5, "Not a multicast group", "A multicast group" } }; // DPNGROUP_MULTICAST
SET g_LabeledGroupFlagsBitSet = { sizeof(g_arr_GroupFlagsBitLabels) / sizeof(LABELED_BIT), g_arr_GroupFlagsBitLabels };
//===========================//
// Maximum Number of Players //--------------------------------------------------------------------------------------------
//===========================//
LABELED_DWORD g_arr_MaxNumOfPlayersDWordLabels[] = { { 0, "Unlimited" } };
SET g_LabeledMaxNumOfPlayersDWordSet = { sizeof(g_arr_MaxNumOfPlayersDWordLabels) / sizeof(LABELED_DWORD), g_arr_MaxNumOfPlayersDWordLabels };
//=================================//
// Player Destruction Reason field //---------------------------------------------------------------------------------------------
//=================================//
LABELED_DWORD g_arr_PlayerDestructionReasonDWordLabels[] = { { DPNDESTROYPLAYERREASON_NORMAL, "Player self-destructed" },
{ DPNDESTROYPLAYERREASON_CONNECTIONLOST, "Connection lost" },
{ DPNDESTROYPLAYERREASON_SESSIONTERMINATED, "Session has been terminated" },
{ DPNDESTROYPLAYERREASON_HOSTDESTROYEDPLAYER, "Host destroyed the player" } };
SET g_LabeledPlayerDestructionReasonDWordSet = { sizeof(g_arr_PlayerDestructionReasonDWordLabels) / sizeof(LABELED_DWORD), g_arr_PlayerDestructionReasonDWordLabels };
////////////////////////////////
// Custom Property Formatters //=====================================================================================
////////////////////////////////
// DESCRIPTION: Custom description formatter for the Session packet summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_SessionSummary( LPPROPERTYINST io_pPropertyInstance )
{
std::string strSummary;
char arr_cBuffer[10];
// Check what Session frame we are dealing with
DN_INTERNAL_MESSAGE_FULLMSG& rBase = *reinterpret_cast<DN_INTERNAL_MESSAGE_FULLMSG*>(io_pPropertyInstance->lpData);
// Message title
switch ( rBase.dwMsgType )
{
case DN_MSG_INTERNAL_PLAYER_CONNECT_INFO:
{
if ( rBase.MsgBody.dnPlayerConnectInfo.dwNameSize )
{
strSummary = "Player ";
enum { nMAX_PLAYER_NAME = 64 };
char arr_cPlayerName[nMAX_PLAYER_NAME];
WideCharToMultiByte(CP_ACP, 0,
reinterpret_cast<WCHAR*>( &rBase.MsgBody.bOffsetBase + rBase.MsgBody.dnPlayerConnectInfo.dwNameOffset ),
rBase.MsgBody.dnPlayerConnectInfo.dwNameSize, arr_cPlayerName, sizeof(arr_cPlayerName), NULL, NULL);
strSummary += arr_cPlayerName;
}
else
{
strSummary = "Unnamed player";
}
strSummary += " is attempting to connect to the session";
break;
}
case DN_MSG_INTERNAL_SEND_CONNECT_INFO:
{
DPN_APPLICATION_DESC_INFO& rApplicationDescInfo = *reinterpret_cast<DPN_APPLICATION_DESC_INFO*>(&rBase.MsgBody.dnConnectInfo + 1);
if ( rApplicationDescInfo.dwSessionNameSize )
{
strSummary = "Session ";
enum { nMAX_SESSION_NAME = 64 };
char arr_cSessionName[nMAX_SESSION_NAME];
WideCharToMultiByte(CP_ACP, 0,
reinterpret_cast<WCHAR*>( &rBase.MsgBody.bOffsetBase + rApplicationDescInfo.dwSessionNameOffset ),
rApplicationDescInfo.dwSessionNameSize, arr_cSessionName, sizeof(arr_cSessionName), NULL, NULL);
strSummary += arr_cSessionName;
}
else
{
strSummary = "Unnamed session";
}
strSummary += " is sending its information";
break;
}
case DN_MSG_INTERNAL_SEND_PLAYER_DNID:
{
strSummary = "Player ID is 0x";
strSummary += _itoa(rBase.MsgBody.dnSendPlayerID.dpnid, arr_cBuffer, 16);
break;
}
case DN_MSG_INTERNAL_REQ_PROCESS_COMPLETION:
{
strSummary = "Initiating reliably handled message transmission (SyncID=0x";
strSummary += _itoa(rBase.MsgBody.dnReqProcessCompletion.hCompletionOp, arr_cBuffer, 16);
strSummary += ")";
break;
}
case DN_MSG_INTERNAL_PROCESS_COMPLETION:
{
strSummary = "Message has been handled by the message handler (SyncID=0x";
strSummary += _itoa(rBase.MsgBody.dnProcessCompletion.hCompletionOp, arr_cBuffer, 16);
strSummary += ")";
break;
}
case DN_MSG_INTERNAL_DESTROY_PLAYER:
{
strSummary += "Player 0x";
strSummary += _itoa(rBase.MsgBody.dnDestroyPlayer.dpnidLeaving, arr_cBuffer, 16);
strSummary += " is leaving the session";
break;
}
case DN_MSG_INTERNAL_DELETE_PLAYER_FROM_GROUP:
{
strSummary = "Player 0x";
strSummary += _itoa(rBase.MsgBody.dnDeletePlayerFromGroup.dpnidRequesting, arr_cBuffer, 16);
strSummary += " is requesting to delete player 0x";
strSummary += _itoa(rBase.MsgBody.dnDeletePlayerFromGroup.dpnidPlayer, arr_cBuffer, 16);
strSummary += " from group 0x";
strSummary += _itoa(rBase.MsgBody.dnDeletePlayerFromGroup.dpnidGroup, arr_cBuffer, 16);
break;
}
case DN_MSG_INTERNAL_NAMETABLE_VERSION:
{
strSummary += "Nametable version is ";
strSummary += _itoa(rBase.MsgBody.dnNametableVersion.dwVersion, arr_cBuffer, 10);
break;
}
default:
{
for ( int n = 0; n < sizeof(g_arr_MessageTypeDWordLabels)/sizeof(LABELED_DWORD); ++n )
{
if ( g_arr_MessageTypeDWordLabels[n].Value == rBase.dwMsgType )
{
strSummary = g_arr_MessageTypeDWordLabels[n].Label;
break;
}
}
break;
}
}
// Message highlights
switch ( rBase.dwMsgType )
{
case DN_MSG_INTERNAL_HOST_MIGRATE:
{
strSummary += " (0x";
strSummary += _itoa(rBase.MsgBody.dnHostMigrate.dpnidOldHost, arr_cBuffer, 16);
strSummary += " => 0x";
strSummary += _itoa(rBase.MsgBody.dnHostMigrate.dpnidNewHost, arr_cBuffer, 16);
strSummary += ")";
break;
}
}
strcpy(io_pPropertyInstance->szPropertyText, strSummary.c_str());
} // FormatPropertyInstance_SessionSummary
// DESCRIPTION: Custom description formatter for the Application Description summary
//
// ARGUMENTS: io_pProperyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_AppDescSummary( LPPROPERTYINST io_pProperyInstance )
{
std::string strSummary;
char arr_cBuffer[10];
DPN_APPLICATION_DESC_INFO& rApplicationDescInfo = *reinterpret_cast<DPN_APPLICATION_DESC_INFO*>(io_pProperyInstance->lpData);
if ( rApplicationDescInfo.dwSessionNameSize )
{
strSummary = "Session ";
enum { nMAX_SESSION_NAME = 64 };
char arr_cSessionName[nMAX_SESSION_NAME];
// TODO: Once NetMon supports passage of pointer types via PROPERTYINSTEX,
// TODO: remove the less generic reference to size of DN_INTERNAL_MESSAGE_CONNECT_INFO
WideCharToMultiByte(CP_ACP, 0,
reinterpret_cast<WCHAR*>( reinterpret_cast<char*>(&rApplicationDescInfo) -
sizeof(DN_INTERNAL_MESSAGE_CONNECT_INFO) +
rApplicationDescInfo.dwSessionNameOffset ),
rApplicationDescInfo.dwSessionNameSize, arr_cSessionName, sizeof(arr_cSessionName), NULL, NULL);
strSummary += arr_cSessionName;
}
else
{
strSummary = "Unnamed session";
}
strSummary += " is hosting ";
strSummary += _itoa(rApplicationDescInfo.dwCurrentPlayers, arr_cBuffer, 10);
strSummary += " out of ";
strSummary += ( rApplicationDescInfo.dwMaxPlayers == 0 ? "unlimited number of" : _itoa(rApplicationDescInfo.dwMaxPlayers, arr_cBuffer, 10) );
strSummary += " players";
strcpy(io_pProperyInstance->szPropertyText, strSummary.c_str());
} // FormatPropertyInstance_AppDescSummary
// DESCRIPTION: Custom description formatter for the Name Table's summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_NameTableSummary( LPPROPERTYINST io_pPropertyInstance )
{
DN_NAMETABLE_INFO& rNameTableInfo = *reinterpret_cast<DN_NAMETABLE_INFO*>(io_pPropertyInstance->lpData);
sprintf(io_pPropertyInstance->szPropertyText, "NameTable (ver=%d)", rNameTableInfo.dwVersion);
} // FormatPropertyInstance_NameTableSummary
// DESCRIPTION: Custom description formatter for the Application GUID field
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_ApplicationGUID( LPPROPERTYINST io_pPropertyInstance )
{
std::string strSummary = "Application GUID = ";
REFGUID rguid = *reinterpret_cast<GUID*>(io_pPropertyInstance->lpData);
enum
{
nMAX_GUID_STRING = 50 // more than enough characters for a symbolic representation of a GUID
};
OLECHAR arr_wcGUID[nMAX_GUID_STRING];
StringFromGUID2(rguid, arr_wcGUID, nMAX_GUID_STRING);
char arr_cGUID[nMAX_GUID_STRING];
WideCharToMultiByte(CP_ACP, 0, arr_wcGUID, -1, arr_cGUID, sizeof(arr_cGUID), NULL, NULL);
strSummary += arr_cGUID;
strcpy(io_pPropertyInstance->szPropertyText, strSummary.c_str());
} // FormatPropertyInstance_ApplicationGUID
// DESCRIPTION: Custom description formatter for the Instance GUID field
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_InstanceGUID( LPPROPERTYINST io_pPropertyInstance )
{
std::string strSummary = "Instance GUID = ";
REFGUID rguid = *reinterpret_cast<GUID*>(io_pPropertyInstance->lpData);
enum
{
nMAX_GUID_STRING = 50 // more than enough characters for a symbolic representation of a GUID
};
OLECHAR arr_wcGUID[nMAX_GUID_STRING];
StringFromGUID2(rguid, arr_wcGUID, nMAX_GUID_STRING);
char arr_cGUID[nMAX_GUID_STRING];
WideCharToMultiByte(CP_ACP, 0, arr_wcGUID, -1, arr_cGUID, sizeof(arr_cGUID), NULL, NULL);
strSummary += arr_cGUID;
strcpy(io_pPropertyInstance->szPropertyText, strSummary.c_str());
} // FormatPropertyInstance_InstanceGUID
namespace
{
std::string MapSetFlagsToLabels( LABELED_BIT i_arr_FlagsBitLabels[], int i_nNumOfFlags, DWORD i_dwFlags )
{
std::string strString;
int nBit = 0;
bool bNotFirst = false;
for ( DWORD dwBitMask = 1; dwBitMask != 0x80000000; dwBitMask <<= 1, ++nBit )
{
if ( (i_dwFlags & dwBitMask) == dwBitMask )
{
for ( int n = 0; n < i_nNumOfFlags; ++n )
{
if ( i_arr_FlagsBitLabels[n].BitNumber == nBit)
{
if ( bNotFirst )
{
strString += ", ";
}
bNotFirst = true;
strString += i_arr_FlagsBitLabels[n].LabelOn;
break;
}
}
}
}
return strString;
} // MapSetFlagsToLabels
} // Anonymous namespace
// DESCRIPTION: Custom description formatter for the Flags summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_FlagsSummary( LPPROPERTYINST io_pPropertyInstance )
{
std::string strSummary = "Flags: ";
DWORD dwFlags = *reinterpret_cast<DWORD*>(io_pPropertyInstance->lpData);
if ( dwFlags == 0 )
{
strSummary += "Must be zero";
}
else
{
strSummary += MapSetFlagsToLabels(g_arr_FlagsBitLabels, sizeof(g_arr_FlagsBitLabels)/sizeof(LABELED_BIT), dwFlags);
}
strcpy(io_pPropertyInstance->szPropertyText, strSummary.c_str());
} // FormatPropertyInstance_FlagsSummary
// DESCRIPTION: Custom description formatter for the Information Flags summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_InfoFlagsSummary( LPPROPERTYINST io_pPropertyInstance )
{
std::string strSummary = "Information Flags: ";
DWORD dwInfoFlags = *reinterpret_cast<DWORD*>(io_pPropertyInstance->lpData);
if ( dwInfoFlags == 0 )
{
strSummary += "Must be zero";
}
else
{
strSummary += MapSetFlagsToLabels(g_arr_InfoFlagsBitLabels, sizeof(g_arr_InfoFlagsBitLabels)/sizeof(LABELED_BIT), dwInfoFlags);
}
strcpy(io_pPropertyInstance->szPropertyText, strSummary.c_str());
} // FormatPropertyInstance_InfoFlagsSummary
// DESCRIPTION: Custom description formatter for the Group Flags summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_GroupFlagsSummary( LPPROPERTYINST io_pPropertyInstance )
{
std::string strSummary = "Group Flags: ";
DWORD dwGroupFlags = *reinterpret_cast<DWORD*>(io_pPropertyInstance->lpData);
if ( dwGroupFlags == 0 )
{
strSummary += "Must be zero";
}
else
{
strSummary += MapSetFlagsToLabels(g_arr_GroupFlagsBitLabels, sizeof(g_arr_GroupFlagsBitLabels)/sizeof(LABELED_BIT), dwGroupFlags);
}
strcpy(io_pPropertyInstance->szPropertyText, strSummary.c_str());
} // FormatPropertyInstance_GroupFlagsSummary
// DESCRIPTION: Custom description formatter for the Version summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_VersionSummary( LPPROPERTYINST io_pPropertyInstance )
{
sprintf(io_pPropertyInstance->szPropertyText, "Version: 0x%08X", *((DWORD*)(io_pPropertyInstance->lpByte)));
} // FormatPropertyInstance_VersionSummary
// DESCRIPTION: Custom description formatter for the Player ID property
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_PlayerID( LPPROPERTYINST io_pPropertyInstance )
{
sprintf(io_pPropertyInstance->szPropertyText, "Player ID = 0x%X", *io_pPropertyInstance->lpDword);
} // FormatPropertyInstance_PlayerID
// DESCRIPTION: Custom description formatter for the Old Host ID property
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_OldHostID( LPPROPERTYINST io_pPropertyInstance )
{
sprintf(io_pPropertyInstance->szPropertyText, "Old Host ID = 0x%X", *io_pPropertyInstance->lpDword);
} // FormatPropertyInstance_OldHostID
// DESCRIPTION: Custom description formatter for the New Host ID property
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_NewHostID( LPPROPERTYINST io_pPropertyInstance )
{
sprintf(io_pPropertyInstance->szPropertyText, "New Host ID = 0x%X", *io_pPropertyInstance->lpDword);
} // FormatPropertyInstance_NewHostID
// DESCRIPTION: Custom description formatter for the Group ID property
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_GroupID( LPPROPERTYINST io_pPropertyInstance )
{
sprintf(io_pPropertyInstance->szPropertyText, "Group ID = 0x%X", *io_pPropertyInstance->lpDword);
} // FormatPropertyInstance_GroupID
struct NAMETABLEENTRY_INSTDATA
{
DN_INTERNAL_MESSAGE_ALL* pBase;
DWORD dwEntry; // if -1, then not printed
};
// DESCRIPTION: Custom description formatter for the NameTable Entry summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_NameTableEntrySummary( LPPROPERTYINST io_pPropertyInstance )
{
DN_NAMETABLE_ENTRY_INFO& rNameTableEntry = *reinterpret_cast<DN_NAMETABLE_ENTRY_INFO*>(io_pPropertyInstance->lpPropertyInstEx->lpData);
NAMETABLEENTRY_INSTDATA& rInstData = *reinterpret_cast<NAMETABLEENTRY_INSTDATA*>(io_pPropertyInstance->lpPropertyInstEx->Byte);
enum { nMAX_PLAYER_NAME = 64 };
char arr_cPlayerName[nMAX_PLAYER_NAME];
if ( rNameTableEntry.dwNameSize )
{
// Convert the UNICODE name into its ANSI equivalent
WideCharToMultiByte(CP_ACP, 0, reinterpret_cast<WCHAR*>(&rInstData.pBase->bOffsetBase + rNameTableEntry.dwNameOffset),
rNameTableEntry.dwNameSize, arr_cPlayerName, sizeof(arr_cPlayerName), NULL, NULL);
}
else
{
strcpy(arr_cPlayerName, "No name");
}
if ( rInstData.dwEntry == -1 )
{
sprintf(io_pPropertyInstance->szPropertyText, "%s (ID=0x%X) (%s)", arr_cPlayerName, rNameTableEntry.dpnid,
MapSetFlagsToLabels(g_arr_FlagsBitLabels, sizeof(g_arr_FlagsBitLabels)/sizeof(LABELED_BIT), rNameTableEntry.dwFlags).c_str());
}
else
{
sprintf(io_pPropertyInstance->szPropertyText, "%d. %s (ID=0x%X) (%s)", rInstData.dwEntry, arr_cPlayerName, rNameTableEntry.dpnid,
MapSetFlagsToLabels(g_arr_FlagsBitLabels, sizeof(g_arr_FlagsBitLabels)/sizeof(LABELED_BIT), rNameTableEntry.dwFlags).c_str());
}
} // FormatPropertyInstance_NameTableEntrySummary
// DESCRIPTION: Custom description formatter for the NameTable Entry summary
//
// ARGUMENTS: io_pPropertyInstance - Data of the property's instance
//
// RETURNS: NOTHING
//
VOID WINAPIV FormatPropertyInstance_NameTableMembershipSummary( LPPROPERTYINST io_pPropertyInstance )
{
DN_NAMETABLE_MEMBERSHIP_INFO& rNameTableMembershipInfo = *reinterpret_cast<DN_NAMETABLE_MEMBERSHIP_INFO*>(io_pPropertyInstance->lpPropertyInstEx->lpData);
sprintf(io_pPropertyInstance->szPropertyText, "%d. Player 0x%X is in group 0x%X (ver=%d)", io_pPropertyInstance->lpPropertyInstEx->Dword[0],
rNameTableMembershipInfo.dpnidPlayer, rNameTableMembershipInfo.dpnidGroup, rNameTableMembershipInfo.dwVersion);
} // FormatPropertyInstance_NameTableMembershipSummary
//==================//
// Properties table //-----------------------------------------------------------------------------------------------
//==================//
PROPERTYINFO g_arr_SessionProperties[] =
{
// Session packet summary property (SESSION_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"DPlay Session packet", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
512, // description's maximum length
FormatPropertyInstance_SessionSummary // generic formatter
},
// Message Type property (SESSION_UNPARSABLEFRAGMENT)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"This is a non-initial part of the fragmented Transport layer message and can not be parsed", // label
"Unparsable fragment summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Message Type property (SESSION_INCOMPLETEMESSAGE)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"The rest of the data needed to parse this message has been sent in a separate fragment and can not be parsed", // label
"Incomplete message summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Message Type property (SESSION_INCOMPLETEFIELD)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"The rest of the data needed to parse this field is in a separate fragment. Field value may look corrupted!", // label
"Incomplete field summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
150, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Message Type property (SESSION_MESSAGETYPE)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Message Type", // label
"Message Type field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_LABELED_SET, // data type qualifier.
&g_LabeledMessageTypeDWordSet, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Player's ID property (SESSION_PLAYERID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Player ID", // label
"Player ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance_PlayerID // generic formatter
},
// Result Code property (SESSION_RESULTCODE)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Result Code", // label
"Result Code field", // status-bar comment
PROP_TYPE_DWORD, // data type (HRESULT)
PROP_QUAL_LABELED_SET, // data type qualifier.
&g_LabeledResultCodeDWordSet, // labeled byte set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// DPlay Version property (SESSION_DPLAYVERSION)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"DPlay's version", // label
"DPlay's version field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance_VersionSummary // generic formatter
},
// Build Day property (SESSION_BUILDDAY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Build's Day", // label
"Build's Day field", // status-bar comment
PROP_TYPE_BYTE, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Build Month property (SESSION_BUILDMONTH)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Build's Month", // label
"Build's Month field", // status-bar comment
PROP_TYPE_BYTE, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Build Year property (SESSION_BUILDYEAR)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Build's Year (starting from 2000)", // label
"Build's Year field", // status-bar comment
PROP_TYPE_BYTE, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Flags summary property (SESSION_FLAGS_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"Flags summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
512, // description's maximum length
FormatPropertyInstance_FlagsSummary // generic formatter
},
// Flags property (SESSION_FLAGS)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Flags", // label
"Flags field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_FLAGS, // data type qualifier.
&g_LabeledFlagsBitSet, // labeled bit set
2048, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Flags summary property (SESSION_INFOFLAGS_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"Information Flags summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
512, // description's maximum length
FormatPropertyInstance_InfoFlagsSummary // generic formatter
},
// Flags property (SESSION_INFOFLAGS)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Information Flags", // label
"Information Flags field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_FLAGS, // data type qualifier.
&g_LabeledInfoFlagsBitSet, // labeled bit set
2048, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Flags summary property (SESSION_GROUPFLAGS_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"Group Flags summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
512, // description's maximum length
FormatPropertyInstance_GroupFlagsSummary // generic formatter
},
// Flags property (SESSION_GROUPFLAGS)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Group Flags", // label
"Group Flags field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_FLAGS, // data type qualifier.
&g_LabeledGroupFlagsBitSet, // labeled bit set
2048, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Offset property (SESSION_FIELDOFFSET)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Offset", // label
"Offset field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Size property (SESSION_FIELDSIZE)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Size", // label
"Size field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Session Name property (SESSION_SESSIONNAME)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Session Name", // label
"Session Name field", // status-bar comment
PROP_TYPE_STRING, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Session Name summary property (SESSION_NOSESSIONNAME_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Session Name", // label
"No Session Name summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Player Name property (SESSION_PLAYERNAME)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Player name", // label
"Player name field", // status-bar comment
PROP_TYPE_STRING, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Player Name summary property (SESSION_NOPLAYERNAME_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Player Name", // label
"No Player Name summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Data property (SESSION_DATA)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Data", // label
"Data field", // status-bar comment
PROP_TYPE_VOID, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Data summary property (SESSION_NODATA_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Data", // label
"No Data summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Data property (SESSION_REPLY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Reply", // label
"Reply field", // status-bar comment
PROP_TYPE_STRING, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Data summary property (SESSION_NOREPLY_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Reply", // label
"No Reply summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Password property (SESSION_PASSWORD)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Password", // label
"Password field", // status-bar comment
PROP_TYPE_STRING, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Password summary property (SESSION_NOPASSWORD_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Password", // label
"No Password summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Connection Data property (SESSION_CONNECTIONDATA)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Connection Data", // label
"Connection Data field", // status-bar comment
PROP_TYPE_VOID, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Connection Data summary property (SESSION_NOCONNECTIONDATA_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Connection Data", // label
"No Connection Data summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// URL property (SESSION_URL)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"URL", // label
"URL field", // status-bar comment
PROP_TYPE_STRING, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
512, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No URL summary property (SESSION_NOURL_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No URL", // label
"No URL summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Application GUID property (SESSION_APPGUID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Application GUID", // label
"Application GUID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance_ApplicationGUID // generic formatter
},
// Instance GUID property (SESSION_INSTGUID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Instance GUID", // label
"Instance GUID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance_InstanceGUID // generic formatter
},
// Application Description summary property (SESSION_APPDESCINFO_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"Application Description summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance_AppDescSummary // generic formatter
},
// Application Description's Size property (SESSION_APPDESCINFOSIZE)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Application Description's Size", // label
"Application Description's Size field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Maximum Number of Players property (SESSION_MAXPLAYERS)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Maximum Number of Players", // label
"Maximum Number of Players field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_LABELED_SET, // data type qualifier.
&g_LabeledMaxNumOfPlayersDWordSet, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Current Number of Players property (SESSION_CURRENTPLAYERS)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Current Number of Players", // label
"Current Number of Players field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Reserved Data property (SESSION_RESERVEDDATA)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Reserved Data", // label
"Reserved Data", // status-bar comment
PROP_TYPE_VOID, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Reserved Data summary property (SESSION_NORESERVEDDATA_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Reserved Data", // label
"No Reserved Data summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Application Reserved Data property (SESSION_APPRESERVEDDATA)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Application Reserved Data", // label
"Application Reserved Data", // status-bar comment
PROP_TYPE_VOID, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// No Application Reserved Data summary property (SESSION_NOAPPRESERVEDDATA_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"No Application Reserved Data", // label
"No Application Reserved Data summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// NameTable's summary property (SESSION_NAMETABLEINFO_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"NameTable's summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance_NameTableSummary // generic formatter
},
// Version property (SESSION_VERSION)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Version", // label
"Version field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// RESERVED property (SESSION_RESERVED)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"RESERVED", // label
"RESERVED field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Number of Entries in the NameTable property (SESSION_NUMBEROFENTRIES)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Number of Entries", // label
"Number of Entries field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Number of Memberships in the NameTable property (SESSION_NUMBEROFMEMBERSHIPS)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Number of Memberships", // label
"Number of Memberships field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// NameTable Entry summary property (SESSION_PLAYERS_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Players", // label
"NameTable player entries summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// NameTable Entry summary property (SESSION_GROUPS_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Groups", // label
"NameTable group entries summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// NameTable Entry summary property (SESSION_NAMETABLEENTRY_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"NameTable Entry summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
256, // description's maximum length
FormatPropertyInstance_NameTableEntrySummary // generic formatter
},
// Owner's ID property (SESSION_OWNERID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Owner ID", // label
"Owner ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// NameTable Memberships summary property (SESSION_NAMETABLEMEMBERSHIPS_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Memberships", // label
"Memberships summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance // generic formatter
},
// NameTable Membership Entry summary property (SESSION_NAMETABLEMEMBERSHIPENTRY_SUMMARY)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"", // label
"Membership Entry summary", // status-bar comment
PROP_TYPE_SUMMARY, // data type
PROP_QUAL_NONE, // data type qualifier
NULL, // labeled bit set
128, // description's maximum length
FormatPropertyInstance_NameTableMembershipSummary // generic formatter
},
// Group's ID property (SESSION_GROUPID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Group ID", // label
"Group ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance_GroupID // generic formatter
},
// Old Host ID property (SESSION_OLDHOSTID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Old Host ID", // label
"Old Host ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance_OldHostID // generic formatter
},
// New Host ID property (SESSION_NEWHOSTID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"New Host ID", // label
"New Host ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance_NewHostID // generic formatter
},
// New Host ID property (SESSION_SYNCID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Synchronization ID", // label
"Synchronization ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Player's ID property (SESSION_REQUESTINGPLAYERID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Requesting Player ID", // label
"Requesting Player ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Player Destruction Reason property (SESSION_PLAYERDESTRUCTIONREASON)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Reason", // label
"Reason field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_LABELED_SET, // data type qualifier.
&g_LabeledPlayerDestructionReasonDWordSet, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Target Peer's ID property (SESSION_TARGETPEERID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Target Peer ID", // label
"Target Peer ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
},
// Requesting Peer's ID property (SESSION_REQUESTINGPEERID)
{
0, // handle placeholder (MBZ)
0, // reserved (MBZ)
"Requesting Peer ID", // label
"Requesting Peer ID field", // status-bar comment
PROP_TYPE_DWORD, // data type
PROP_QUAL_NONE, // data type qualifier.
NULL, // labeled bit set
64, // description's maximum length
FormatPropertyInstance // generic formatter
}
};
enum
{
nNUM_OF_Session_PROPS = sizeof(g_arr_SessionProperties) / sizeof(PROPERTYINFO)
};
// Properties' indices
enum
{
SESSION_SUMMARY = 0,
SESSION_UNPARSABLEFRAGMENT,
SESSION_INCOMPLETEMESSAGE,
SESSION_INCOMPLETEFIELD,
SESSION_MESSAGETYPE,
SESSION_PLAYERID,
SESSION_RESULTCODE,
SESSION_DPLAYVERSION,
SESSION_BUILDDAY,
SESSION_BUILDMONTH,
SESSION_BUILDYEAR,
SESSION_FLAGS_SUMMARY,
SESSION_FLAGS,
SESSION_INFOFLAGS_SUMMARY,
SESSION_INFOFLAGS,
SESSION_GROUPFLAGS_SUMMARY,
SESSION_GROUPFLAGS,
SESSION_FIELDOFFSET,
SESSION_FIELDSIZE,
SESSION_SESSIONNAME,
SESSION_NOSESSIONNAME_SUMMARY,
SESSION_PLAYERNAME,
SESSION_NOPLAYERNAME_SUMMARY,
SESSION_DATA,
SESSION_NODATA_SUMMARY,
SESSION_REPLY,
SESSION_NOREPLY_SUMMARY,
SESSION_PASSWORD,
SESSION_NOPASSWORD_SUMMARY,
SESSION_CONNECTIONDATA,
SESSION_NOCONNECTIONDATA_SUMMARY,
SESSION_URL,
SESSION_NOURL_SUMMARY,
SESSION_APPGUID,
SESSION_INSTGUID,
SESSION_APPDESCINFO_SUMMARY,
SESSION_APPDESCINFOSIZE,
SESSION_MAXPLAYERS,
SESSION_CURRENTPLAYERS,
SESSION_RESERVEDDATA,
SESSION_NORESERVEDDATA_SUMMARY,
SESSION_APPRESERVEDDATA,
SESSION_NOAPPRESERVEDDATA_SUMMARY,
SESSION_NAMETABLEINFO_SUMMARY,
SESSION_VERSION,
SESSION_RESERVED,
SESSION_NUMBEROFENTRIES,
SESSION_NUMBEROFMEMBERSHIPS,
SESSION_PLAYERS_SUMMARY,
SESSION_GROUPS_SUMMARY,
SESSION_NAMETABLEENTRY_SUMMARY,
SESSION_OWNERID,
SESSION_NAMETABLEMEMBERSHIPS_SUMMARY,
SESSION_NAMETABLEMEMBERSHIPENTRY_SUMMARY,
SESSION_GROUPID,
SESSION_OLDHOSTID,
SESSION_NEWHOSTID,
SESSION_SYNCID,
SESSION_REQUESTINGPLAYERID,
SESSION_PLAYERDESTRUCTIONREASON,
SESSION_TARGETPEERID,
SESSION_REQUESTINGPEERID
};
} // anonymous namespace
// DESCRIPTION: Creates and fills-in a properties database for the protocol.
// Network Monitor uses this database to determine which properties the protocol supports.
//
// ARGUMENTS: i_hSessionProtocol - The handle of the protocol provided by the Network Monitor.
//
// RETURNS: NOTHING
//
DPLAYPARSER_API VOID BHAPI SessionRegister( HPROTOCOL i_hSessionProtocol )
{
// TODO: PROCESS THE RETURN VALUE
CreatePropertyDatabase(i_hSessionProtocol, nNUM_OF_Session_PROPS);
// Add the properties to the database
for( int nProp=0; nProp < nNUM_OF_Session_PROPS; ++nProp )
{
// TODO: PROCESS THE RETURN VALUE
AddProperty(i_hSessionProtocol, &g_arr_SessionProperties[nProp]);
}
} // SessionRegister
// DESCRIPTION: Frees the resources used to create the protocol property database.
//
// ARGUMENTS: i_hSessionProtocol - The handle of the protocol provided by the Network Monitor.
//
// RETURNS: NOTHING
//
DPLAYPARSER_API VOID WINAPI SessionDeregister( HPROTOCOL i_hProtocol )
{
// TODO: PROCESS THE RETURN VALUE
DestroyPropertyDatabase(i_hProtocol);
} // SessionDeregister
namespace
{
// DESCRIPTION: Parses the Session frame to find its size (in bytes) NOT including the user data
//
// ARGUMENTS: i_pbSessionFrame - Pointer to the start of the unclaimed data. Typically, the unclaimed data is located
// in the middle of a frame because a previous parser has claimed data before this parser.
//
// RETURNS: Size of the Sessionecified Session frame (in bytes)
//
int SessionHeaderSize( LPBYTE i_pbSessionFrame )
{
DN_INTERNAL_MESSAGE_FULLMSG& rSessionFrame = *reinterpret_cast<DN_INTERNAL_MESSAGE_FULLMSG*>(i_pbSessionFrame);
DN_INTERNAL_MESSAGE_ALL& rMsgBody = rSessionFrame.MsgBody;
int nHeaderSize = sizeof(rSessionFrame.dwMsgType);
switch ( rSessionFrame.dwMsgType )
{
case DN_MSG_INTERNAL_PLAYER_CONNECT_INFO:
{
nHeaderSize += sizeof(rMsgBody.dnPlayerConnectInfo) + rMsgBody.dnPlayerConnectInfo.dwNameSize + rMsgBody.dnPlayerConnectInfo.dwDataSize +
rMsgBody.dnPlayerConnectInfo.dwPasswordSize + rMsgBody.dnPlayerConnectInfo.dwConnectDataSize + rMsgBody.dnPlayerConnectInfo.dwURLSize;
break;
}
case DN_MSG_INTERNAL_SEND_CONNECT_INFO:
{
DPN_APPLICATION_DESC_INFO& rApplicationDescInfo = *reinterpret_cast<DPN_APPLICATION_DESC_INFO*>(&rMsgBody.dnConnectInfo + 1);
DN_NAMETABLE_INFO& rNameTableInfo = *reinterpret_cast<DN_NAMETABLE_INFO*>(&rApplicationDescInfo + 1);
DN_NAMETABLE_ENTRY_INFO* pNameTableEntryInfo = reinterpret_cast<DN_NAMETABLE_ENTRY_INFO*>(&rNameTableInfo + 1);
nHeaderSize += sizeof(DN_INTERNAL_MESSAGE_CONNECT_INFO) + rApplicationDescInfo.dwSize + sizeof(DN_NAMETABLE_INFO) +
rNameTableInfo.dwEntryCount * sizeof(DN_NAMETABLE_ENTRY_INFO) +
rNameTableInfo.dwMembershipCount * sizeof(DN_NAMETABLE_MEMBERSHIP_INFO);
for ( size_t sztEntry = 1; sztEntry <= rNameTableInfo.dwEntryCount; ++sztEntry, ++pNameTableEntryInfo )
{
nHeaderSize += pNameTableEntryInfo->dwNameSize + pNameTableEntryInfo->dwDataSize + pNameTableEntryInfo->dwURLSize;
}
break;
}
case DN_MSG_INTERNAL_ACK_CONNECT_INFO:
{
// No fields
break;
}
case DN_MSG_INTERNAL_SEND_PLAYER_DNID:
{
nHeaderSize += sizeof(rMsgBody.dnSendPlayerID);
break;
}
case DN_MSG_INTERNAL_CONNECT_FAILED:
{
nHeaderSize += sizeof(rMsgBody.dnConnectFailed);
break;
}
case DN_MSG_INTERNAL_INSTRUCT_CONNECT:
{
nHeaderSize += sizeof(rMsgBody.dnInstructConnect);
break;
}
case DN_MSG_INTERNAL_INSTRUCTED_CONNECT_FAILED:
{
nHeaderSize += sizeof(rMsgBody.dnInstructedConnectFailed);
break;
}
case DN_MSG_INTERNAL_NAMETABLE_VERSION:
{
nHeaderSize += sizeof(rMsgBody.dnNametableVersion);
break;
}
case DN_MSG_INTERNAL_RESYNC_VERSION:
{
nHeaderSize += sizeof(rMsgBody.dnResyncVersion);
break;
}
case DN_MSG_INTERNAL_REQ_NAMETABLE_OP:
{
nHeaderSize += sizeof(rMsgBody.dnReqNametableOp);
break;
}
case DN_MSG_INTERNAL_ACK_NAMETABLE_OP:
{
nHeaderSize += sizeof(rMsgBody.dnAckNametableOp);
const DN_NAMETABLE_OP_INFO* pOpInfo = reinterpret_cast<DN_NAMETABLE_OP_INFO*>(&rMsgBody.dnAckNametableOp.dwNumEntries + 1);
for ( size_t sztOp = 0; sztOp < rMsgBody.dnAckNametableOp.dwNumEntries; ++sztOp, ++pOpInfo )
{
nHeaderSize += sizeof(*pOpInfo) + pOpInfo->dwOpSize;
}
break;
}
case DN_MSG_INTERNAL_HOST_MIGRATE:
{
nHeaderSize += sizeof(rMsgBody.dnHostMigrate);
break;
}
case DN_MSG_INTERNAL_HOST_MIGRATE_COMPLETE:
{
// No fields
break;
}
case DN_MSG_INTERNAL_UPDATE_APPLICATION_DESC:
{
nHeaderSize += rMsgBody.dnUpdateAppDescInfo.dwSize;
break;
}
case DN_MSG_INTERNAL_ADD_PLAYER:
{
nHeaderSize += sizeof(rMsgBody.dnAddPlayer) + rMsgBody.dnAddPlayer.dwDataSize +
rMsgBody.dnAddPlayer.dwNameSize + rMsgBody.dnAddPlayer.dwURLSize;
break;
}
case DN_MSG_INTERNAL_DESTROY_PLAYER:
{
nHeaderSize += sizeof(rMsgBody.dnDestroyPlayer);
break;
}
case DN_MSG_INTERNAL_REQ_CREATE_GROUP:
{
nHeaderSize += sizeof(rMsgBody.dnReqProcessCompletionHeader) + sizeof(rMsgBody.dnReqCreateGroup) +
rMsgBody.dnReqCreateGroup.dwNameSize + rMsgBody.dnReqCreateGroup.dwDataSize;
break;
}
case DN_MSG_INTERNAL_REQ_ADD_PLAYER_TO_GROUP:
case DN_MSG_INTERNAL_REQ_DELETE_PLAYER_FROM_GROUP: // same structure as in AddPlayerToGroup
{
nHeaderSize += sizeof(rMsgBody.dnReqProcessCompletionHeader) + sizeof(rMsgBody.dnAddPlayerToGroup);
break;
}
case DN_MSG_INTERNAL_REQ_DESTROY_GROUP:
{
nHeaderSize += sizeof(rMsgBody.dnReqProcessCompletionHeader) + sizeof(rMsgBody.dnReqDestroyGroup);
break;
}
case DN_MSG_INTERNAL_REQ_UPDATE_INFO:
{
nHeaderSize += sizeof(rMsgBody.dnReqProcessCompletionHeader) + sizeof(rMsgBody.dnReqUpdateInfo) +
rMsgBody.dnReqUpdateInfo.dwNameSize + rMsgBody.dnReqUpdateInfo.dwDataSize;
break;
}
case DN_MSG_INTERNAL_CREATE_GROUP:
{
nHeaderSize += sizeof(rMsgBody.dnCreateGroup);
break;
}
case DN_MSG_INTERNAL_DESTROY_GROUP:
{
nHeaderSize += sizeof(rMsgBody.dnDestroyGroup);
break;
}
case DN_MSG_INTERNAL_ADD_PLAYER_TO_GROUP:
case DN_MSG_INTERNAL_DELETE_PLAYER_FROM_GROUP: // same structure as AddPlayerToGroup
{
nHeaderSize += sizeof(rMsgBody.dnAddPlayerToGroup);
break;
}
case DN_MSG_INTERNAL_UPDATE_INFO:
{
nHeaderSize += sizeof(rMsgBody.dnUpdateInfo) + rMsgBody.dnUpdateInfo.dwNameSize + rMsgBody.dnUpdateInfo.dwDataSize;
break;
}
case DN_MSG_INTERNAL_BUFFER_IN_USE:
{
// No fields
break;
}
case DN_MSG_INTERNAL_REQUEST_FAILED:
{
nHeaderSize += sizeof(rMsgBody.dnRequestFailed);
break;
}
case DN_MSG_INTERNAL_TERMINATE_SESSION:
{
nHeaderSize += sizeof(rMsgBody.dnTerminateSession) + rMsgBody.dnTerminateSession.dwTerminateDataSize;
break;
}
case DN_MSG_INTERNAL_REQ_PROCESS_COMPLETION:
{
nHeaderSize += sizeof(rMsgBody.dnReqProcessCompletion);
break;
}
case DN_MSG_INTERNAL_PROCESS_COMPLETION :
{
nHeaderSize += sizeof(rMsgBody.dnProcessCompletion);
break;
}
case DN_MSG_INTERNAL_REQ_INTEGRITY_CHECK:
{
nHeaderSize += sizeof(rMsgBody.dnReqProcessCompletionHeader) + sizeof(rMsgBody.dnReqIntegrityCheck);
break;
}
case DN_MSG_INTERNAL_INTEGRITY_CHECK:
{
nHeaderSize += sizeof(rMsgBody.dnIntegrityCheck);
break;
}
case DN_MSG_INTERNAL_INTEGRITY_CHECK_RESPONSE:
{
nHeaderSize += sizeof(rMsgBody.dnIntegrityCheckResponse);
break;
}
default:
{
return -1; // TODO: DPF(0, "Unknown Session frame!");
}
}
return nHeaderSize;
} // SessionHeaderSize
} // Anonymous namespace
// DESCRIPTION: Indicates whether a piece of data is recognized as the protocol that the parser detects.
//
// ARGUMENTS: i_hFrame - The handle to the frame that contains the data.
// i_pbMacFrame - The pointer to the first byte of the frame; the pointer provides a way to view
// the data that the other parsers recognize.
// i_pbSessionFrame - Pointer to the start of the unclaimed data. Typically, the unclaimed data is located
// in the middle of a frame because a previous parser has claimed data before this parser.
// i_dwMacType - MAC value of the first protocol in a frame. Typically, the i_dwMacType value is used
// when the parser must identify the first protocol in the frame. Can be one of the following:
// MAC_TYPE_ETHERNET = 802.3, MAC_TYPE_TOKENRING = 802.5, MAC_TYPE_FDDI ANSI = X3T9.5.
// i_dwBytesLeft - The remaining number of bytes from a location in the frame to the end of the frame.
// i_hPrevProtocol - Handle of the previous protocol.
// i_dwPrevProtOffset - Offset of the previous protocol (from the beginning of the frame).
// o_pdwProtocolStatus - Protocol status indicator. Must be one of the following: PROTOCOL_STATUS_RECOGNIZED,
// PROTOCOL_STATUS_NOT_RECOGNIZED, PROTOCOL_STATUS_CLAIMED, PROTOCOL_STATUS_NEXT_PROTOCOL.
// o_phNextProtocol - Placeholder for the handle of the next protocol. This parameter is set when the parser identifies
// the protocol that follows its own protocol.
// io_pdwptrInstData - On input, a pointer to the instance data from the previous protocol.
// On output, a pointer to the instance data for the current protocol.
//
// RETURNS: If the function is successful, the return value is a pointer to the first byte after the recognized parser data.
// If the parser claims all the remaining data, the return value is NULL. If the function is unsuccessful, the return
// value is the initial value of the i_pbSessionFrame parameter.
//
DPLAYPARSER_API LPBYTE BHAPI SessionRecognizeFrame( HFRAME i_hFrame,
ULPBYTE i_upbMacFrame,
ULPBYTE i_upbySessionFrame,
DWORD i_dwMacType,
DWORD i_dwBytesLeft,
HPROTOCOL i_hPrevProtocol,
DWORD i_dwPrevProtOffset,
LPDWORD o_pdwProtocolStatus,
LPHPROTOCOL o_phNextProtocol,
PDWORD_PTR io_pdwptrInstData )
{
// Validate the amount of unclaimed data
enum
{
// TODO: CHANGE TO PROPER MIN SIZE
nMIN_SessionHeaderSize = sizeof(DWORD),
nNUMBER_OF_MSG_TYPES = sizeof(g_arr_MessageTypeDWordLabels) / sizeof(LABELED_DWORD)
};
for ( int nTypeIndex = 0; nTypeIndex < nNUMBER_OF_MSG_TYPES; ++nTypeIndex )
{
if ( g_arr_MessageTypeDWordLabels[nTypeIndex].Value == *i_upbySessionFrame )
{
break;
}
}
// Validate the packet as DPlay Session type
if ( ((i_dwBytesLeft >= nMIN_SessionHeaderSize) && (nTypeIndex < nNUMBER_OF_MSG_TYPES)) || (*io_pdwptrInstData == 0) )
{
// Claim the remaining data
*o_pdwProtocolStatus = PROTOCOL_STATUS_CLAIMED;
return ( g_upbyPastEndOfFrame = i_upbySessionFrame + SessionHeaderSize(i_upbySessionFrame) );
}
// Assume the unclaimed data is not recognizable
*o_pdwProtocolStatus = PROTOCOL_STATUS_NOT_RECOGNIZED;
return i_upbySessionFrame;
} // SessionRecognizeFrame
namespace
{
// DESCRIPTION:
//
// ARGUMENTS: i_hFrame - Handle of the frame that is being parsed.
// i_nProperty -
// i_pSessionFrame -
// i_pdwOffset -
// i_pdwSize -
// i_dwFlags -
// i_nLevel -
//
// RETURNS: NOTHING
//
void AttachValueOffsetSizeProperties( HFRAME i_hFrame, int i_nProperty, DN_INTERNAL_MESSAGE_ALL* i_pBase,
DWORD* i_pdwOffset, DWORD* i_pdwSize, DWORD i_dwFlags, int i_nLevel )
{
if ( *i_pdwSize )
{
// Value field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[i_nProperty].hProperty,
*i_pdwSize, &i_pBase->bOffsetBase + *i_pdwOffset, 0, i_nLevel, i_dwFlags);
// If the field's value is outside the frame, let the user know it will show up incomplete or corrupted
if ( &i_pBase->bOffsetBase + *i_pdwOffset + *i_pdwSize >= g_upbyPastEndOfFrame )
{
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INCOMPLETEFIELD].hProperty,
*i_pdwSize, &i_pBase->bOffsetBase + *i_pdwOffset, 0, i_nLevel+1, 0);
}
// Value's Offset field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FIELDOFFSET].hProperty,
sizeof(*i_pdwOffset), i_pdwOffset, 0, i_nLevel + 1, 0);
// Value's Size field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FIELDSIZE].hProperty,
sizeof(*i_pdwSize), i_pdwSize, 0, i_nLevel + 1, 0);
}
else
{
// No field summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[i_nProperty + 1].hProperty,
sizeof(*i_pdwOffset) + sizeof(*i_pdwSize), i_pdwOffset, 0, i_nLevel, 0);
}
}// AttachValueOffsetSizeProperties
// DESCRIPTION: Attaches the properties to the nametable entry
//
// ARGUMENTS: i_hFrame - Handle of the frame that is being parsed
// i_pNameTableEntryInfo - Pointer to the beginning of nametable's entry
// i_dwEntry - Ordinal number of the entry (if -1, then not printed)
// i_pSessionFrame - Pointer to the beginning of the protocol data in a frame.
//
// RETURNS: NOTHING
//
void AttachNameTableEntry(HFRAME i_hFrame, DN_NAMETABLE_ENTRY_INFO* i_pNameTableEntryInfo, DWORD i_dwEntry,
DN_INTERNAL_MESSAGE_ALL* i_pBase )
{
NAMETABLEENTRY_INSTDATA rInstData = { i_pBase, i_dwEntry };
// NameTable entry summary
AttachPropertyInstanceEx(i_hFrame, g_arr_SessionProperties[SESSION_NAMETABLEENTRY_SUMMARY].hProperty,
sizeof(*i_pNameTableEntryInfo), i_pNameTableEntryInfo,
sizeof(rInstData), &rInstData, 0, 3, 0);
if ( i_pNameTableEntryInfo->dwFlags & NAMETABLE_ENTRY_FLAG_ANY_GROUP )
{
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pNameTableEntryInfo->dpnid), &i_pNameTableEntryInfo->dpnid, 0, 4, 0);
}
else
{
// Group ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPID].hProperty,
sizeof(i_pNameTableEntryInfo->dpnid), &i_pNameTableEntryInfo->dpnid, 0, 4, 0);
}
// Owner ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_OWNERID].hProperty,
sizeof(i_pNameTableEntryInfo->dpnidOwner), &i_pNameTableEntryInfo->dpnidOwner, 0, 4, 0);
// Flags summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FLAGS_SUMMARY].hProperty,
sizeof(i_pNameTableEntryInfo->dwFlags), &i_pNameTableEntryInfo->dwFlags, 0, 4, 0);
// Flags field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FLAGS].hProperty,
sizeof(i_pNameTableEntryInfo->dwFlags), &i_pNameTableEntryInfo->dwFlags, 0, 5, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(i_pNameTableEntryInfo->dwVersion), &i_pNameTableEntryInfo->dwVersion, 0, 4, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(i_pNameTableEntryInfo->dwVersionNotUsed), &i_pNameTableEntryInfo->dwVersionNotUsed, 0, 4, 0);
// DPlay Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_DPLAYVERSION].hProperty,
sizeof(i_pNameTableEntryInfo->dwDNETVersion), &i_pNameTableEntryInfo->dwDNETVersion, 0, 4, 0);
// Player Name field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_PLAYERNAME, i_pBase,
&i_pNameTableEntryInfo->dwNameOffset, &i_pNameTableEntryInfo->dwNameSize, IFLAG_UNICODE, 4);
// Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_DATA, i_pBase,
&i_pNameTableEntryInfo->dwDataOffset, &i_pNameTableEntryInfo->dwDataSize, NULL, 4);
// URL field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_URL, i_pBase,
&i_pNameTableEntryInfo->dwURLOffset, &i_pNameTableEntryInfo->dwURLSize, NULL, 4);
} // AttachNameTableEntry
// DESCRIPTION: Attaches the properties to the Application Description structure
//
// ARGUMENTS: i_hFrame - Handle of the frame that is being parsed.
// i_pbSessionFrame - Pointer to the beginning of the protocol data in a frame.
// i_pApplicationDescInfo - Pointer to the beginning of the application description.
//
// RETURNS: NOTHING
//
void AttachApplicationDescriptionProperties( HFRAME i_hFrame, DN_INTERNAL_MESSAGE_ALL* i_pBase,
DPN_APPLICATION_DESC_INFO* i_pApplicationDescInfo )
{
// Application Description summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_APPDESCINFO_SUMMARY].hProperty,
sizeof(*i_pApplicationDescInfo), i_pApplicationDescInfo, 0, 1, 0);
// Application Description's Size field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_APPDESCINFOSIZE].hProperty,
sizeof(i_pApplicationDescInfo->dwSize), &i_pApplicationDescInfo->dwSize, 0, 2, 0);
// Flags summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FLAGS_SUMMARY].hProperty,
sizeof(i_pApplicationDescInfo->dwFlags), &i_pApplicationDescInfo->dwFlags, 0, 2, 0);
// Flags field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FLAGS].hProperty,
sizeof(i_pApplicationDescInfo->dwFlags), &i_pApplicationDescInfo->dwFlags, 0, 3, 0);
// Maximum Number of Players field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_MAXPLAYERS].hProperty,
sizeof(i_pApplicationDescInfo->dwMaxPlayers), &i_pApplicationDescInfo->dwMaxPlayers, 0, 2, 0);
// Current Number of Players field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_CURRENTPLAYERS].hProperty,
sizeof(i_pApplicationDescInfo->dwCurrentPlayers), &i_pApplicationDescInfo->dwCurrentPlayers, 0, 2, 0);
// Session Name field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_SESSIONNAME, i_pBase,
&i_pApplicationDescInfo->dwSessionNameOffset, &i_pApplicationDescInfo->dwSessionNameSize, IFLAG_UNICODE, 2);
// Password field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_PASSWORD, i_pBase,
&i_pApplicationDescInfo->dwPasswordOffset, &i_pApplicationDescInfo->dwPasswordSize, IFLAG_UNICODE, 2);
// Reserved Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_RESERVEDDATA, i_pBase,
&i_pApplicationDescInfo->dwReservedDataOffset, &i_pApplicationDescInfo->dwReservedDataSize, NULL, 2);
// Application Reserved Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_APPRESERVEDDATA, i_pBase,
&i_pApplicationDescInfo->dwApplicationReservedDataOffset, &i_pApplicationDescInfo->dwApplicationReservedDataSize, NULL, 2);
// Instance GUID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INSTGUID].hProperty,
sizeof(i_pApplicationDescInfo->guidInstance), &i_pApplicationDescInfo->guidInstance, 0, 2, 0);
// Application GUID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_APPGUID].hProperty,
sizeof(i_pApplicationDescInfo->guidApplication), &i_pApplicationDescInfo->guidApplication, 0, 2, 0);
} // AttachApplicationDescriptionProperties
// DESCRIPTION: Attaches the properties to the Session Information packet
//
// ARGUMENTS: i_hFrame - Handle of the frame that is being parsed.
// i_pbSessionFrame - Pointer to the beginning of the protocol data in a frame.
//
// RETURNS: NOTHING
//
void AttachSessionInformationProperties( HFRAME i_hFrame, DN_INTERNAL_MESSAGE_ALL* i_pBase )
{
// Reply field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_REPLY, i_pBase,
&i_pBase->dnConnectInfo.dwReplyOffset, &i_pBase->dnConnectInfo.dwReplySize, NULL, 1);
DPN_APPLICATION_DESC_INFO& rApplicationDescInfo = *reinterpret_cast<DPN_APPLICATION_DESC_INFO*>(&i_pBase->dnConnectInfo + 1);
AttachApplicationDescriptionProperties(i_hFrame, i_pBase, &rApplicationDescInfo);
DN_NAMETABLE_INFO& rNameTableInfo = *reinterpret_cast<DN_NAMETABLE_INFO*>(&rApplicationDescInfo + 1);
DN_NAMETABLE_ENTRY_INFO* pNameTableEntryInfo = reinterpret_cast<DN_NAMETABLE_ENTRY_INFO*>(&rNameTableInfo + 1);
// Calculating the size of the nametable
size_t sztNameTableSize = sizeof(DN_NAMETABLE_INFO) +
rNameTableInfo.dwEntryCount * sizeof(DN_NAMETABLE_ENTRY_INFO) +
rNameTableInfo.dwMembershipCount * sizeof(DN_NAMETABLE_MEMBERSHIP_INFO);
//
for ( size_t sztEntry = 1; sztEntry <= rNameTableInfo.dwEntryCount; ++sztEntry, ++pNameTableEntryInfo )
{
sztNameTableSize += pNameTableEntryInfo->dwNameSize + pNameTableEntryInfo->dwDataSize + pNameTableEntryInfo->dwURLSize;
}
// Nametable's summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_NAMETABLEINFO_SUMMARY].hProperty,
sztNameTableSize, &rNameTableInfo, 0, 1, 0);
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(rNameTableInfo.dpnid), &rNameTableInfo.dpnid, 0, 2, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(rNameTableInfo.dwVersion), &rNameTableInfo.dwVersion, 0, 2, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(rNameTableInfo.dwVersionNotUsed), &rNameTableInfo.dwVersionNotUsed, 0, 2, 0);
// Number of NameTable Entries field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_NUMBEROFENTRIES].hProperty,
sizeof(rNameTableInfo.dwEntryCount), &rNameTableInfo.dwEntryCount, 0, 2, 0);
// Number of NameTable Memberships field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_NUMBEROFMEMBERSHIPS].hProperty,
sizeof(rNameTableInfo.dwMembershipCount), &rNameTableInfo.dwMembershipCount, 0, 2, 0);
pNameTableEntryInfo = reinterpret_cast<DN_NAMETABLE_ENTRY_INFO*>(&rNameTableInfo + 1);
// NameTable Player entries summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERS_SUMMARY].hProperty,
rNameTableInfo.dwEntryCount * sizeof(*pNameTableEntryInfo), pNameTableEntryInfo, 0, 2, 0);
std::queue<DN_NAMETABLE_ENTRY_INFO*> queGroups;
// Process player entries
int nPlayerEntry = 1;
for ( sztEntry = 1; sztEntry <= rNameTableInfo.dwEntryCount; ++sztEntry, ++pNameTableEntryInfo )
{
// If the entry contains group information, enqueue it for later processing
if ( pNameTableEntryInfo->dwFlags & NAMETABLE_ENTRY_FLAG_ANY_GROUP )
{
queGroups.push(pNameTableEntryInfo);
}
else
{
AttachNameTableEntry(i_hFrame, pNameTableEntryInfo, nPlayerEntry, i_pBase);
++nPlayerEntry;
}
}
DN_NAMETABLE_MEMBERSHIP_INFO* pNameTableMembershipInfo = reinterpret_cast<DN_NAMETABLE_MEMBERSHIP_INFO*>(pNameTableEntryInfo);
// Process group entries
if ( !queGroups.empty() )
{
pNameTableEntryInfo = reinterpret_cast<DN_NAMETABLE_ENTRY_INFO*>(&rNameTableInfo + 1);
// NameTable Group entries summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPS_SUMMARY].hProperty,
rNameTableInfo.dwEntryCount * sizeof(*pNameTableEntryInfo), pNameTableEntryInfo, 0, 2, 0);
for ( nPlayerEntry = 1; !queGroups.empty(); queGroups.pop(), ++nPlayerEntry )
{
AttachNameTableEntry(i_hFrame, queGroups.front(), nPlayerEntry, i_pBase);
}
}
// NameTable's Memberships summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_NAMETABLEMEMBERSHIPS_SUMMARY].hProperty,
rNameTableInfo.dwMembershipCount * sizeof(*pNameTableMembershipInfo), pNameTableMembershipInfo, 0, 2, 0);
for ( sztEntry = 1; sztEntry <= rNameTableInfo.dwMembershipCount; ++sztEntry, ++pNameTableMembershipInfo )
{
// NameTable's Membership Entry summary
AttachPropertyInstanceEx(i_hFrame, g_arr_SessionProperties[SESSION_NAMETABLEMEMBERSHIPENTRY_SUMMARY].hProperty,
sizeof(*pNameTableMembershipInfo), pNameTableMembershipInfo,
sizeof(sztEntry), &sztEntry, 0, 3, 0);
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(pNameTableMembershipInfo->dpnidPlayer), &pNameTableMembershipInfo->dpnidPlayer, 0, 4, 0);
// Group ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPID].hProperty,
sizeof(pNameTableMembershipInfo->dpnidGroup), &pNameTableMembershipInfo->dpnidGroup, 0, 4, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(pNameTableMembershipInfo->dwVersion), &pNameTableMembershipInfo->dwVersion, 0, 4, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(pNameTableMembershipInfo->dwVersionNotUsed), &pNameTableMembershipInfo->dwVersionNotUsed, 0, 4, 0);
}
} // AttachSessionInformationProperties
// DESCRIPTION: Attaches the properties to the Session Information packet
//
// ARGUMENTS: i_hFrame - Handle of the frame that is being parsed.
// i_pPlayerConnectionInfo - Pointer to the connecting player's information.
//
// RETURNS: NOTHING
//
void AttachPlayerInformationProperties( HFRAME i_hFrame, DN_INTERNAL_MESSAGE_ALL* i_pBase )
{
// Synonym declaration (to make code more readable)
DN_INTERNAL_MESSAGE_PLAYER_CONNECT_INFO& rPlayerConnectInfo = i_pBase->dnPlayerConnectInfo;
// Flags summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FLAGS_SUMMARY].hProperty,
sizeof(rPlayerConnectInfo.dwFlags), &rPlayerConnectInfo.dwFlags, 0, 1, 0);
// Flags field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_FLAGS].hProperty,
sizeof(rPlayerConnectInfo.dwFlags), &rPlayerConnectInfo.dwFlags, 0, 2, 0);
// DPlay Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_DPLAYVERSION].hProperty,
sizeof(rPlayerConnectInfo.dwDNETVersion), &rPlayerConnectInfo.dwDNETVersion, 0, 1, 0);
// DPlay Version Day subfield
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_BUILDDAY].hProperty,
sizeof(BYTE), reinterpret_cast<LPBYTE>(&rPlayerConnectInfo.dwDNETVersion) + 2, 0, 2, 0);
// DPlay Version Month subfield
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_BUILDMONTH].hProperty,
sizeof(BYTE), reinterpret_cast<LPBYTE>(&rPlayerConnectInfo.dwDNETVersion) + 1, 0, 2, 0);
// DPlay Version Year subfield
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_BUILDYEAR].hProperty,
sizeof(BYTE), &rPlayerConnectInfo.dwDNETVersion, 0, 2, 0);
// Player Name field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_PLAYERNAME, i_pBase,
&rPlayerConnectInfo.dwNameOffset, &rPlayerConnectInfo.dwNameSize, IFLAG_UNICODE, 1);
// Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_DATA, i_pBase,
&rPlayerConnectInfo.dwDataOffset, &rPlayerConnectInfo.dwDataSize, NULL, 1);
// Password field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_PASSWORD, i_pBase,
&rPlayerConnectInfo.dwPasswordOffset, &rPlayerConnectInfo.dwPasswordSize, IFLAG_UNICODE, 1);
// Connection Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_CONNECTIONDATA, i_pBase,
&rPlayerConnectInfo.dwConnectDataOffset, &rPlayerConnectInfo.dwConnectDataSize, NULL, 1);
// URL field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_URL, i_pBase,
&rPlayerConnectInfo.dwURLOffset, &rPlayerConnectInfo.dwURLSize, NULL, 1);
// Instance GUID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INSTGUID].hProperty,
sizeof(rPlayerConnectInfo.guidInstance), &rPlayerConnectInfo.guidInstance, 0, 1, 0);
// Application GUID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_APPGUID].hProperty,
sizeof(rPlayerConnectInfo.guidApplication), &rPlayerConnectInfo.guidApplication, 0, 1, 0);
} // AttachPlayerInformationProperties
// DESCRIPTION: Attaches the properties to a Session message packet or delegates to appropriate function
//
// ARGUMENTS: i_dwMsgType - Message ID
// i_hFrame - Handle of the frame that is being parsed.
// i_pSessionFrame - Pointer to the start of the recognized data.
//
// RETURNS: NOTHING
//
void AttachMessageProperties( const DWORD i_dwMsgType, const HFRAME i_hFrame, DN_INTERNAL_MESSAGE_ALL *const i_pBase )
{
switch ( i_dwMsgType )
{
case DN_MSG_INTERNAL_PLAYER_CONNECT_INFO:
{
AttachPlayerInformationProperties(i_hFrame, i_pBase);
break;
}
case DN_MSG_INTERNAL_SEND_CONNECT_INFO:
{
AttachSessionInformationProperties(i_hFrame, i_pBase);
break;
}
case DN_MSG_INTERNAL_ACK_CONNECT_INFO:
{
// No fields
break;
}
case DN_MSG_INTERNAL_SEND_PLAYER_DNID:
{
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnSendPlayerID.dpnid), &i_pBase->dnSendPlayerID.dpnid, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_INSTRUCT_CONNECT:
{
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnInstructConnect.dpnid), &i_pBase->dnInstructConnect.dpnid, 0, 1, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(i_pBase->dnInstructConnect.dwVersion), &i_pBase->dnInstructConnect.dwVersion, 0, 1, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(i_pBase->dnInstructConnect.dwVersionNotUsed), &i_pBase->dnInstructConnect.dwVersionNotUsed, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_CONNECT_FAILED:
{
// Result Code field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESULTCODE].hProperty,
sizeof(i_pBase->dnConnectFailed.hResultCode), &i_pBase->dnConnectFailed.hResultCode, 0, 1, 0);
// Reply field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_REPLY, i_pBase,
&i_pBase->dnConnectFailed.dwReplyOffset, &i_pBase->dnConnectFailed.dwReplySize, NULL, 1);
break;
}
case DN_MSG_INTERNAL_INSTRUCTED_CONNECT_FAILED:
{
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnInstructedConnectFailed.dpnid), &i_pBase->dnInstructedConnectFailed.dpnid, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_ACK_NAMETABLE_OP:
{
// Number of Entries field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_NUMBEROFENTRIES].hProperty,
sizeof(i_pBase->dnAckNametableOp.dwNumEntries), &i_pBase->dnAckNametableOp.dwNumEntries, 0, 1, 0);
const DN_NAMETABLE_OP_INFO* pOpInfo = reinterpret_cast<DN_NAMETABLE_OP_INFO*>(&i_pBase->dnAckNametableOp.dwNumEntries + 1);
for ( size_t sztOp = 0; sztOp < i_pBase->dnAckNametableOp.dwNumEntries; ++sztOp, ++pOpInfo )
{
AttachMessageProperties(pOpInfo->dwMsgId, i_hFrame, reinterpret_cast<DN_INTERNAL_MESSAGE_ALL*>(reinterpret_cast<BYTE*>(i_pBase) + pOpInfo->dwOpOffset));
}
break;
}
case DN_MSG_INTERNAL_HOST_MIGRATE:
{
// Old Host ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_OLDHOSTID].hProperty,
sizeof(i_pBase->dnHostMigrate.dpnidOldHost), &i_pBase->dnHostMigrate.dpnidOldHost, 0, 1, 0);
// New Host ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_NEWHOSTID].hProperty,
sizeof(i_pBase->dnHostMigrate.dpnidNewHost), &i_pBase->dnHostMigrate.dpnidNewHost, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_NAMETABLE_VERSION:
case DN_MSG_INTERNAL_REQ_NAMETABLE_OP: // same structure as in NameTableVersion
case DN_MSG_INTERNAL_RESYNC_VERSION: // same structure as in NameTableVersion
{
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(i_pBase->dnNametableVersion.dwVersion), &i_pBase->dnNametableVersion.dwVersion, 0, 1, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(i_pBase->dnNametableVersion.dwVersionNotUsed), &i_pBase->dnNametableVersion.dwVersionNotUsed, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_HOST_MIGRATE_COMPLETE:
{
// No fields
break;
}
case DN_MSG_INTERNAL_UPDATE_APPLICATION_DESC:
{
AttachApplicationDescriptionProperties(i_hFrame, i_pBase, &i_pBase->dnUpdateAppDescInfo);
break;
}
case DN_MSG_INTERNAL_ADD_PLAYER:
{
AttachNameTableEntry(i_hFrame, &i_pBase->dnAddPlayer, -1, i_pBase);
break;
}
case DN_MSG_INTERNAL_DESTROY_PLAYER:
{
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnDestroyPlayer.dpnidLeaving), &i_pBase->dnDestroyPlayer.dpnidLeaving, 0, 1, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(i_pBase->dnDestroyPlayer.dwVersion), &i_pBase->dnDestroyPlayer.dwVersion, 0, 1, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(i_pBase->dnDestroyPlayer.dwVersionNotUsed), &i_pBase->dnDestroyPlayer.dwVersionNotUsed, 0, 1, 0);
// Player Destruction Reason field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERDESTRUCTIONREASON].hProperty,
sizeof(i_pBase->dnDestroyPlayer.dwDestroyReason), &i_pBase->dnDestroyPlayer.dwDestroyReason, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_REQ_CREATE_GROUP:
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnReqProcessCompletionHeader.hCompletionOp), &i_pBase->dnReqProcessCompletionHeader.hCompletionOp, 0, 1, 0);
// Group flags summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPFLAGS_SUMMARY].hProperty,
sizeof(i_pBase->dnReqCreateGroup.dwGroupFlags), &i_pBase->dnReqCreateGroup.dwGroupFlags, 0, 1, 0);
// Group field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPFLAGS].hProperty,
sizeof(i_pBase->dnReqCreateGroup.dwGroupFlags), &i_pBase->dnReqCreateGroup.dwGroupFlags, 0, 2, 0);
// Info flags summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INFOFLAGS_SUMMARY].hProperty,
sizeof(i_pBase->dnReqCreateGroup.dwInfoFlags), &i_pBase->dnReqCreateGroup.dwInfoFlags, 0, 1, 0);
// Info flags field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INFOFLAGS].hProperty,
sizeof(i_pBase->dnReqCreateGroup.dwInfoFlags), &i_pBase->dnReqCreateGroup.dwInfoFlags, 0, 2, 0);
// Player Name field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_PLAYERNAME, i_pBase,
&i_pBase->dnReqCreateGroup.dwNameOffset, &i_pBase->dnReqCreateGroup.dwNameSize, IFLAG_UNICODE, 1);
// Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_DATA, i_pBase,
&i_pBase->dnReqCreateGroup.dwDataOffset, &i_pBase->dnReqCreateGroup.dwDataSize, NULL, 1);
break;
}
case DN_MSG_INTERNAL_REQ_ADD_PLAYER_TO_GROUP:
case DN_MSG_INTERNAL_REQ_DELETE_PLAYER_FROM_GROUP: // same structure as in AddPlayerToGroup
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnReqProcessCompletionHeader.hCompletionOp), &i_pBase->dnReqProcessCompletionHeader.hCompletionOp, 0, 1, 0);
// Group ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPID].hProperty,
sizeof(i_pBase->dnReqAddPlayerToGroup.dpnidGroup), &i_pBase->dnReqAddPlayerToGroup.dpnidGroup, 0, 1, 0);
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnReqAddPlayerToGroup.dpnidPlayer), &i_pBase->dnReqAddPlayerToGroup.dpnidPlayer, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_REQ_DESTROY_GROUP:
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnReqProcessCompletionHeader.hCompletionOp), &i_pBase->dnReqProcessCompletionHeader.hCompletionOp, 0, 1, 0);
// Group ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPID].hProperty,
sizeof(i_pBase->dnReqDestroyGroup.dpnidGroup), &i_pBase->dnReqDestroyGroup.dpnidGroup, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_REQ_UPDATE_INFO:
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnReqProcessCompletionHeader.hCompletionOp), &i_pBase->dnReqProcessCompletionHeader.hCompletionOp, 0, 1, 0);
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnReqUpdateInfo.dpnid), &i_pBase->dnReqUpdateInfo.dpnid, 0, 1, 0);
// Info flags summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INFOFLAGS_SUMMARY].hProperty,
sizeof(i_pBase->dnReqUpdateInfo.dwInfoFlags), &i_pBase->dnReqUpdateInfo.dwInfoFlags, 0, 1, 0);
// Info flags field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INFOFLAGS].hProperty,
sizeof(i_pBase->dnReqUpdateInfo.dwInfoFlags), &i_pBase->dnReqUpdateInfo.dwInfoFlags, 0, 2, 0);
// Player Name field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_PLAYERNAME, i_pBase,
&i_pBase->dnReqUpdateInfo.dwNameOffset, &i_pBase->dnReqUpdateInfo.dwNameSize, IFLAG_UNICODE, 1);
// Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_DATA, i_pBase,
&i_pBase->dnReqUpdateInfo.dwDataOffset, &i_pBase->dnReqUpdateInfo.dwDataSize, NULL, 1);
break;
}
case DN_MSG_INTERNAL_CREATE_GROUP:
{
// Requesting Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_REQUESTINGPLAYERID].hProperty,
sizeof(i_pBase->dnCreateGroup.dpnidRequesting), &i_pBase->dnCreateGroup.dpnidRequesting, 0, 1, 0);
// Synchronization ID
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnCreateGroup.hCompletionOp), &i_pBase->dnCreateGroup.hCompletionOp, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_DESTROY_GROUP:
{
// Group ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPID].hProperty,
sizeof(i_pBase->dnDestroyGroup.dpnidGroup), &i_pBase->dnDestroyGroup.dpnidGroup, 0, 1, 0);
// Requesting Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_REQUESTINGPLAYERID].hProperty,
sizeof(i_pBase->dnDestroyGroup.dpnidRequesting), &i_pBase->dnDestroyGroup.dpnidRequesting, 0, 1, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(i_pBase->dnDestroyGroup.dwVersion), &i_pBase->dnDestroyGroup.dwVersion, 0, 1, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(i_pBase->dnDestroyGroup.dwVersionNotUsed), &i_pBase->dnDestroyGroup.dwVersionNotUsed, 0, 1, 0);
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnDestroyGroup.hCompletionOp), &i_pBase->dnDestroyGroup.hCompletionOp, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_ADD_PLAYER_TO_GROUP:
case DN_MSG_INTERNAL_DELETE_PLAYER_FROM_GROUP: // same structure as AddPlayerToGroup
{
// Group ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_GROUPID].hProperty,
sizeof(i_pBase->dnAddPlayerToGroup.dpnidGroup), &i_pBase->dnAddPlayerToGroup.dpnidGroup, 0, 1, 0);
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnAddPlayerToGroup.dpnidPlayer), &i_pBase->dnAddPlayerToGroup.dpnidPlayer, 0, 1, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(i_pBase->dnAddPlayerToGroup.dwVersion), &i_pBase->dnAddPlayerToGroup.dwVersion, 0, 1, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(i_pBase->dnAddPlayerToGroup.dwVersionNotUsed), &i_pBase->dnAddPlayerToGroup.dwVersionNotUsed, 0, 1, 0);
// Requesting Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_REQUESTINGPLAYERID].hProperty,
sizeof(i_pBase->dnAddPlayerToGroup.dpnidRequesting), &i_pBase->dnAddPlayerToGroup.dpnidRequesting, 0, 1, 0);
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnAddPlayerToGroup.hCompletionOp), &i_pBase->dnAddPlayerToGroup.hCompletionOp, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_UPDATE_INFO:
{
// Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_PLAYERID].hProperty,
sizeof(i_pBase->dnUpdateInfo.dpnid), &i_pBase->dnUpdateInfo.dpnid, 0, 1, 0);
// Version field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_VERSION].hProperty,
sizeof(i_pBase->dnUpdateInfo.dwVersion), &i_pBase->dnUpdateInfo.dwVersion, 0, 1, 0);
// RESERVED field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESERVED].hProperty,
sizeof(i_pBase->dnUpdateInfo.dwVersionNotUsed), &i_pBase->dnUpdateInfo.dwVersionNotUsed, 0, 1, 0);
// Flags summary
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INFOFLAGS_SUMMARY].hProperty,
sizeof(i_pBase->dnUpdateInfo.dwInfoFlags), &i_pBase->dnUpdateInfo.dwInfoFlags, 0, 1, 0);
// Flags field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INFOFLAGS].hProperty,
sizeof(i_pBase->dnUpdateInfo.dwInfoFlags), &i_pBase->dnUpdateInfo.dwInfoFlags, 0, 2, 0);
// Player Name field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_PLAYERNAME, i_pBase,
&i_pBase->dnUpdateInfo.dwNameOffset, &i_pBase->dnUpdateInfo.dwNameSize, IFLAG_UNICODE, 1);
// Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_DATA, i_pBase,
&i_pBase->dnUpdateInfo.dwDataOffset, &i_pBase->dnUpdateInfo.dwDataSize, NULL, 1);
// Requesting Player ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_REQUESTINGPLAYERID].hProperty,
sizeof(i_pBase->dnUpdateInfo.dpnidRequesting), &i_pBase->dnUpdateInfo.dpnidRequesting, 0, 1, 0);
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnUpdateInfo.hCompletionOp), &i_pBase->dnUpdateInfo.hCompletionOp, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_BUFFER_IN_USE:
{
// No fields
break;
}
case DN_MSG_INTERNAL_REQUEST_FAILED:
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnRequestFailed.hCompletionOp), &i_pBase->dnRequestFailed.hCompletionOp, 0, 1, 0);
// Result Code field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_RESULTCODE].hProperty,
sizeof(i_pBase->dnRequestFailed.hResultCode), &i_pBase->dnRequestFailed.hResultCode, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_TERMINATE_SESSION:
{
// Data field
AttachValueOffsetSizeProperties(i_hFrame, SESSION_DATA, i_pBase,
&i_pBase->dnTerminateSession.dwTerminateDataOffset, &i_pBase->dnTerminateSession.dwTerminateDataSize, NULL, 1);
break;
}
case DN_MSG_INTERNAL_REQ_PROCESS_COMPLETION:
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnReqProcessCompletion.hCompletionOp), &i_pBase->dnReqProcessCompletion.hCompletionOp, 0, 1, 0);
// TODO: AttachPropertyInstance(REST OF THE FRAME IS USER DATA)
break;
}
case DN_MSG_INTERNAL_PROCESS_COMPLETION :
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnProcessCompletion.hCompletionOp), &i_pBase->dnProcessCompletion.hCompletionOp, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_REQ_INTEGRITY_CHECK:
{
// Synchronization ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SYNCID].hProperty,
sizeof(i_pBase->dnReqProcessCompletionHeader.hCompletionOp), &i_pBase->dnReqProcessCompletionHeader.hCompletionOp, 0, 1, 0);
// Target Peer ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_TARGETPEERID].hProperty,
sizeof(i_pBase->dnReqIntegrityCheck.dpnidTarget), &i_pBase->dnReqIntegrityCheck.dpnidTarget, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_INTEGRITY_CHECK:
{
// Requesting Peer ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_TARGETPEERID].hProperty,
sizeof(i_pBase->dnIntegrityCheck.dpnidRequesting), &i_pBase->dnIntegrityCheck.dpnidRequesting, 0, 1, 0);
break;
}
case DN_MSG_INTERNAL_INTEGRITY_CHECK_RESPONSE:
{
// Requesting Peer ID field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_TARGETPEERID].hProperty,
sizeof(i_pBase->dnIntegrityCheckResponse.dpnidRequesting), &i_pBase->dnIntegrityCheckResponse.dpnidRequesting, 0, 1, 0);
break;
}
default:
{
break; // TODO: DPF(0, "Unknown Session frame!");
}
}
} // AttachMessageProperties
} // Anonymous namespace
// DESCRIPTION: Maps the properties that exist in a piece of recognized data to Sessionecific locations.
//
// ARGUMENTS: i_hFrame - Handle of the frame that is being parsed.
// i_pbMacFram - Pointer to the first byte in the frame.
// i_pbSessionFrame - Pointer to the start of the recognized data.
// i_dwMacType - MAC value of the first protocol in a frame. Typically, the i_dwMacType value is used
// when the parser must identify the first protocol in the frame. Can be one of the following:
// MAC_TYPE_ETHERNET = 802.3, MAC_TYPE_TOKENRING = 802.5, MAC_TYPE_FDDI ANSI = X3T9.5.
// i_dwBytesLeft - The remaining number of bytes in a frame (starting from the beginning of the recognized data).
// i_hPrevProtocol - Handle of the previous protocol.
// i_dwPrevProtOffset - Offset of the previous protocol (starting from the beginning of the frame).
// i_dwptrInstData - Pointer to the instance data that the previous protocol provides.
//
// RETURNS: Must return NULL
//
DPLAYPARSER_API LPBYTE BHAPI SessionAttachProperties( HFRAME i_hFrame,
ULPBYTE i_upbMacFrame,
ULPBYTE i_upbySessionFrame,
DWORD i_dwMacType,
DWORD i_dwBytesLeft,
HPROTOCOL i_hPrevProtocol,
DWORD i_dwPrevProtOffset,
DWORD_PTR i_dwptrInstData )
{
//===================//
// Attach Properties //
//===================//
if ( i_dwptrInstData == 0 )
{
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_UNPARSABLEFRAGMENT].hProperty,
i_dwBytesLeft, i_upbySessionFrame, 0, 0, 0);
return NULL;
}
// Summary line
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_SUMMARY].hProperty,
SessionHeaderSize(i_upbySessionFrame), i_upbySessionFrame, 0, 0, 0);
// Check what Session frame we are dealing with
DN_INTERNAL_MESSAGE_FULLMSG& rSessionFrame = *reinterpret_cast<DN_INTERNAL_MESSAGE_FULLMSG*>(i_upbySessionFrame);
// Message type field
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_MESSAGETYPE].hProperty,
sizeof(rSessionFrame.dwMsgType), &rSessionFrame.dwMsgType, 0, 1, 0);
__try
{
// Attach the properties appropriate to the message type
AttachMessageProperties(rSessionFrame.dwMsgType, i_hFrame, &rSessionFrame.MsgBody);
}
__except ( GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH )
{
AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_INCOMPLETEMESSAGE].hProperty,
i_dwBytesLeft, i_upbySessionFrame, 0, 1, 0);
}
return NULL;
} // SessionAttachProperties
// DESCRIPTION: Formats the data that is diSessionlayed in the details pane of the Network Monitor UI.
//
// ARGUMENTS: i_hFrame - Handle of the frame that is being parsed.
// i_pbMacFrame - Pointer to the first byte of a frame.
// i_pbSessionFrame - Pointer to the beginning of the protocol data in a frame.
// i_dwPropertyInsts - Number of PROPERTYINST structures provided by lpPropInst.
// i_pPropInst - Pointer to an array of PROPERTYINST structures.
//
// RETURNS: If the function is successful, the return value is a pointer to the first byte after the recognized data in a frame,
// or NULL if the recognized data is the last piece of data in a frame. If the function is unsuccessful, the return value
// is the initial value of i_pbSessionFrame.
//
DPLAYPARSER_API DWORD BHAPI SessionFormatProperties( HFRAME i_hFrame,
ULPBYTE i_upbMacFrame,
ULPBYTE i_upbySessionFrame,
DWORD i_dwPropertyInsts,
LPPROPERTYINST i_pPropInst )
{
// Loop through the property instances...
while( i_dwPropertyInsts-- > 0)
{
// ...and call the formatter for each
reinterpret_cast<FORMAT>(i_pPropInst->lpPropertyInfo->InstanceData)(i_pPropInst);
++i_pPropInst;
}
// TODO: MAKE SURE THIS SHOULD NOT BE TRUE
return NMERR_SUCCESS;
} // SessionFormatProperties
// DESCRIPTION: Notifies Network Monitor that DNET protocol parser exists.
//
// ARGUMENTS: NONE
//
// RETURNS: TRUE - success, FALSE - failure
//
bool CreateSessionProtocol( void )
{
// The entry points to the export functions that Network Monitor uses to operate the parser
ENTRYPOINTS SessionEntryPoints =
{
// SessionParser Entry Points
SessionRegister,
SessionDeregister,
SessionRecognizeFrame,
SessionAttachProperties,
SessionFormatProperties
};
// The first active instance of this parser needs to register with the kernel
g_hSessionProtocol = CreateProtocol("DPLAYSESSION", &SessionEntryPoints, ENTRYPOINTS_SIZE);
return (g_hSessionProtocol ? TRUE : FALSE);
} // CreateSessionProtocol
// DESCRIPTION: Removes the DNET protocol parser from the Network Monitor's database of parsers
//
// ARGUMENTS: NONE
//
// RETURNS: NOTHING
//
void DestroySessionProtocol( void )
{
DestroyProtocol(g_hSessionProtocol);
} // DestroySessionProtocol