/*========================================================================== * * 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 #pragma warning(pop) #include #include #include //=====================// // 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(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( &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(&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( &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(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( reinterpret_cast(&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(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(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(io_pPropertyInstance->lpData); enum { nMAX_GUID_STRING = 50 // more than enough characters for a symbolic representation of a GUID }; OLECHAR arr_wcGUID[nMAX_GUID_STRING]; StringFromGUID2(rguid, arr_wcGUID, nMAX_GUID_STRING); char arr_cGUID[nMAX_GUID_STRING]; WideCharToMultiByte(CP_ACP, 0, arr_wcGUID, -1, arr_cGUID, sizeof(arr_cGUID), NULL, NULL); strSummary += arr_cGUID; strcpy(io_pPropertyInstance->szPropertyText, strSummary.c_str()); } // FormatPropertyInstance_InstanceGUID namespace { std::string MapSetFlagsToLabels( LABELED_BIT i_arr_FlagsBitLabels[], int i_nNumOfFlags, DWORD i_dwFlags ) { std::string strString; int nBit = 0; bool bNotFirst = false; for ( DWORD dwBitMask = 1; dwBitMask != 0x80000000; dwBitMask <<= 1, ++nBit ) { if ( (i_dwFlags & dwBitMask) == dwBitMask ) { for ( int n = 0; n < i_nNumOfFlags; ++n ) { if ( i_arr_FlagsBitLabels[n].BitNumber == nBit) { if ( bNotFirst ) { strString += ", "; } bNotFirst = true; strString += i_arr_FlagsBitLabels[n].LabelOn; break; } } } } return strString; } // MapSetFlagsToLabels } // Anonymous namespace // DESCRIPTION: Custom description formatter for the Flags summary // // ARGUMENTS: io_pPropertyInstance - Data of the property's instance // // RETURNS: NOTHING // VOID WINAPIV FormatPropertyInstance_FlagsSummary( LPPROPERTYINST io_pPropertyInstance ) { std::string strSummary = "Flags: "; DWORD dwFlags = *reinterpret_cast(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(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(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(io_pPropertyInstance->lpPropertyInstEx->lpData); NAMETABLEENTRY_INSTDATA& rInstData = *reinterpret_cast(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(&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(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(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(&rMsgBody.dnConnectInfo + 1); DN_NAMETABLE_INFO& rNameTableInfo = *reinterpret_cast(&rApplicationDescInfo + 1); DN_NAMETABLE_ENTRY_INFO* pNameTableEntryInfo = reinterpret_cast(&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(&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(&i_pBase->dnConnectInfo + 1); AttachApplicationDescriptionProperties(i_hFrame, i_pBase, &rApplicationDescInfo); DN_NAMETABLE_INFO& rNameTableInfo = *reinterpret_cast(&rApplicationDescInfo + 1); DN_NAMETABLE_ENTRY_INFO* pNameTableEntryInfo = reinterpret_cast(&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(&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 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(pNameTableEntryInfo); // Process group entries if ( !queGroups.empty() ) { pNameTableEntryInfo = reinterpret_cast(&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(&rPlayerConnectInfo.dwDNETVersion) + 2, 0, 2, 0); // DPlay Version Month subfield AttachPropertyInstance(i_hFrame, g_arr_SessionProperties[SESSION_BUILDMONTH].hProperty, sizeof(BYTE), reinterpret_cast(&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(&i_pBase->dnAckNametableOp.dwNumEntries + 1); for ( size_t sztOp = 0; sztOp < i_pBase->dnAckNametableOp.dwNumEntries; ++sztOp, ++pOpInfo ) { AttachMessageProperties(pOpInfo->dwMsgId, i_hFrame, reinterpret_cast(reinterpret_cast(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(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(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