|
|
/*==========================================================================
* * 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 const 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
|