// Message.h : Declaration of the cMessage #ifndef __MESSAGE_H_ #define __MESSAGE_H_ #include #include "resource.h" // main symbols ///////////////////////////////////////////////////////////////////////////// // cMessage class ATL_NO_VTABLE cMessage : public CComObjectRootEx, public IDispatchImpl< IMessage, &IID_IMessage, &LIBID_DecalPlugins > { public: class cMessageElement; class cField { public: cMessageElement *m_pSchema; void *m_pvData; int m_nOwns; CComPtr< IDispatch > m_pDisp; }; typedef std::deque< cField > cFieldList; class cLoadContext { cMessage *m_pMessage; DWORD m_dwOffset; cLoadContext *m_pParent; public: cLoadContext( cMessage *pMessage ) : m_pMessage( pMessage ), m_dwOffset( 0 ), m_pParent( NULL ) { } cLoadContext( cLoadContext *pParent ) : m_pMessage( pParent->m_pMessage ), m_dwOffset( m_pMessage->m_fields.size() ), m_pParent( pParent ) { } cFieldList::iterator lookupField( cMessageElement *pElement ); DWORD addField( cMessageElement *pElement, void *pvData ) { cField f; f.m_pSchema = pElement; f.m_pvData = pvData; f.m_nOwns = 1; m_pMessage->m_fields.push_back( f ); return m_pMessage->m_fields.size(); } void groupField( DWORD dwIndex ) { m_pMessage->m_fields[ dwIndex - 1 ].m_nOwns += m_pMessage->m_fields.size() - dwIndex; } cMessage *getMessage() { return m_pMessage; } }; class cMessageElement { public: _bstr_t m_strName; virtual ~cMessageElement() { } // Decodes from the current point and returns // the pointer advanced by a certain number of offsets virtual bool load( cLoadContext &context ) = 0; virtual void getValue( cMessage *pMsg, cFieldList::iterator i, LPVARIANT pDest ) = 0; virtual long getNumber( cFieldList::iterator i ) { // Default implementation fails _ASSERTE( FALSE ); return 0; } }; typedef std::vector< std::auto_ptr< cMessageElement > > cElementList; class cMessageSchema { public: cElementList m_members; void loadSchema( DWORD dwSchema ); bool parseChildren( cElementList &list, MSXML::IXMLDOMElementPtr &pElement ); }; typedef std::map< DWORD, std::auto_ptr< cMessageSchema > > cMessageSchemaMap; static MSXML::IXMLDOMDocumentPtr * g_pXML; static cMessageSchemaMap g_schema; static void init(); static void term(); cMessage(); cFieldList m_fields; long m_nType; cMessageSchema *m_pSchema; cElementList::iterator m_icracked; cFieldList::iterator getFieldFromElement( cMessageElement *pElement ); BYTE *m_pStartCrack, *m_pEndCrack, *m_pEndData; void crackMessage( BYTE *pBody, DWORD dwSize ); void crackAll(); bool crackMember( cFieldList::iterator i ); BEGIN_COM_MAP(cMessage) COM_INTERFACE_ENTRY(IMessage) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() // IMessage public: STDMETHOD(get_Count)(/*[out, retval]*/ long *pVal); STDMETHOD(get_MemberName)(long nIndex, /*[out, retval]*/ BSTR *pVal); STDMETHOD(get_Member)(VARIANT vIndex, /*[out, retval]*/ VARIANT *pVal); STDMETHOD(get_Data)(/*[out, retval]*/ VARIANT *pVal); STDMETHOD(get_Type)(/*[out, retval]*/ long *pVal); }; #endif //__MESSAGE_H_