/***************************************************************************/ /** Microsoft Windows **/ /** Copyright(c) Microsoft Corp., 1995-1996 **/ /***************************************************************************/ /**************************************************************************** events.hpp Nov. 95 LenS Event handler infrastructure. CSequentialEventList assumes that all activity occurs on a single thread. It is the responsibility of the users to do the sychronization and thread context switches for this to happen. ****************************************************************************/ #ifndef EVENTS_INC #define EVENTS_INC // #include // #include #include #include "ernccons.h" #include "cuserdta.hpp" class DCRNCConference; class CLogicalConnection; #define QUERY_IND_WORK_OWNER ((LPVOID) 1) class CWorkItem { friend class CSequentialWorkList; public: CWorkItem(LPVOID pOwner) : m_pOwner(pOwner) { } virtual CWorkItem::~CWorkItem(void) = 0; virtual void DoWork(void) = 0; BOOL IsOwnedBy(LPVOID pOwner) { return (pOwner == m_pOwner);}; protected: LPVOID m_pOwner; }; // Invited by a remote node. class CInviteIndWork : public CWorkItem { public: CInviteIndWork(PCONFERENCE pConference, LPCWSTR wszCallerID, PT120PRODUCTVERSION pRequestorVersion, GCCUserData **_ppUserData, UINT _nUserData, CLogicalConnection * _pConEntry); ~CInviteIndWork(void); void DoWork(void); LPWSTR GetCallerID(void) {return m_pwszCallerID;}; private: PCONFERENCE m_pConf; LPWSTR m_pwszCallerID; T120PRODUCTVERSION m_RequestorVersion; PT120PRODUCTVERSION m_pRequestorVersion; PUSERDATAINFO m_pUserDataList; UINT m_nUserData; BOOL m_fSecure; }; // joined by a remote node class CJoinIndWork : public CWorkItem { public: CJoinIndWork(GCCResponseTag Tag, PCONFERENCE pConference, LPCWSTR wszCallerID, CLogicalConnection *pConEntry, PT120PRODUCTVERSION pRequestorVersion, UINT _nUserData, GCCUserData **_ppUserData, HRESULT *pRetCode); ~CJoinIndWork(void); BOOL AddUserData(UINT nUserData, GCCUserData ** ppUserData); void DoWork(void); HRESULT Respond(GCCResult Result); PCONFERENCE GetConference(void) { return m_pConf; }; LPWSTR GetCallerID(void) { return m_pwszCallerID; }; CLogicalConnection *GetConEntry(void) { return m_pConEntry; }; private: GCCResponseTag m_nResponseTag; PCONFERENCE m_pConf; LPWSTR m_pwszCallerID; CLogicalConnection *m_pConEntry; T120PRODUCTVERSION m_RequestorVersion; PT120PRODUCTVERSION m_pRequestorVersion; PUSERDATAINFO m_pUserDataList; GCCUserData **m_ppUserData; UINT m_nUserData; }; class CQueryRemoteWork : public CWorkItem { public: CQueryRemoteWork(LPVOID pContext, GCCAsymmetryType, LPCSTR pcszNodeAddr, BOOL fSecure, HRESULT *); ~CQueryRemoteWork(void); void DoWork(void); void HandleQueryConfirmation(QueryConfirmMessage * pQueryMessage); void SyncQueryRemoteResult(void); void AsyncQueryRemoteResult(void); int GenerateRand(void); void SetHr(HRESULT hr) { m_hr = hr; } BOOL IsInUnknownQueryRequest(void) { return m_fInUnknownQueryRequest; } ConnectionHandle GetConnectionHandle(void) { return m_hGCCConnHandle; } void GetAsymIndicator ( GCCAsymmetryIndicator *pIndicator ) { pIndicator->asymmetry_type = m_LocalAsymIndicator.asymmetry_type; pIndicator->random_number = m_LocalAsymIndicator.random_number; } private: ConnectionHandle m_hGCCConnHandle; GCCAsymmetryType m_eAsymType; LPSTR m_pszAddress; LPWSTR *m_apConfNames; HRESULT m_hr; BOOL m_fRemoteIsMCU; PT120PRODUCTVERSION m_pVersion; T120PRODUCTVERSION m_Version; GCCAsymmetryIndicator m_LocalAsymIndicator; BOOL m_fInUnknownQueryRequest; int m_nRandSeed; BOOL m_fSecure; LPWSTR *m_apConfDescriptors; }; // The CSequentialWorkList class is used to process a series // of asynchronous requests one at a time. // The user subclasses CWorkItem and puts the CWorkItem object into // the list by calling CSequentialWorkList::Add(). // When it is its turn to be processed (i.e. there are no pending requests), // CWorkItem::Handle() is called. When the asynchonous work is done, // the user calls CSequentialWorkList::Remove which takes the CWorkItem // object out of the list, destroys it and calls CWorkItem::Handle() for // the next CWorkItem in the list (if any). class CSequentialWorkList : public CList { DEFINE_CLIST(CSequentialWorkList, CWorkItem*) public: ~CSequentialWorkList(void) { // Don't want to destroy an event list with pending events. // Codework: build I/O rundown into a generic event list, // and subclass. ASSERT(IsEmpty()); } void AddWorkItem(CWorkItem * pWorkItem); void RemoveWorkItem(CWorkItem * pWorkItem); void PurgeListEntriesByOwner(DCRNCConference *pOwner); void DeleteList(void); }; #define DEFINE_SEQ_WORK_LIST(_NewClass_,_PtrItemType_) \ public: \ _NewClass_(UINT cMaxItems = CLIST_DEFAULT_MAX_ITEMS) : CSequentialWorkList(cMaxItems) { ASSERT(sizeof(_PtrItemType_) == sizeof(CWorkItem*)); } \ _NewClass_(_NewClass_ *pSrc) : CSequentialWorkList((CSequentialWorkList *) pSrc) { ASSERT(sizeof(_PtrItemType_) == sizeof(CWorkItem*)); } \ _NewClass_(_NewClass_ &Src) : CSequentialWorkList((CSequentialWorkList *) &Src) { ASSERT(sizeof(_PtrItemType_) == sizeof(CWorkItem*)); } \ BOOL Append(_PtrItemType_ pData) { return CSequentialWorkList::Append((CWorkItem*) pData); } \ BOOL Prepend(_PtrItemType_ pData) { return CSequentialWorkList::Prepend((CWorkItem*) pData); } \ BOOL Remove(_PtrItemType_ pData) { return CSequentialWorkList::Remove((CWorkItem*) pData); } \ BOOL Find(_PtrItemType_ pData) { return CSequentialWorkList::Find((CWorkItem*) pData); } \ _PtrItemType_ Get(void) { return (_PtrItemType_) CSequentialWorkList::Get(); } \ _PtrItemType_ PeekHead(void) { return (_PtrItemType_) CSequentialWorkList::PeekHead(); } \ _PtrItemType_ Iterate(void) { return (_PtrItemType_) CSequentialWorkList::Iterate(); } class CInviteIndWorkList : public CSequentialWorkList { DEFINE_SEQ_WORK_LIST(CInviteIndWorkList, CInviteIndWork*) public: void AddWorkItem(CInviteIndWork * pWorkItem) { CSequentialWorkList::AddWorkItem(pWorkItem); } void RemoveWorkItem(CInviteIndWork * pWorkItem) { CSequentialWorkList::RemoveWorkItem(pWorkItem); } }; class CJoinIndWorkList : public CSequentialWorkList { DEFINE_SEQ_WORK_LIST(CJoinIndWorkList, CJoinIndWork*) public: void AddWorkItem(CJoinIndWork * pWorkItem) { CSequentialWorkList::AddWorkItem(pWorkItem); } void RemoveWorkItem(CJoinIndWork * pWorkItem) { CSequentialWorkList::RemoveWorkItem(pWorkItem); } }; class CQueryRemoteWorkList : public CSequentialWorkList { DEFINE_SEQ_WORK_LIST(CQueryRemoteWorkList, CQueryRemoteWork*) public: void AddWorkItem(CQueryRemoteWork * pWorkItem) { CSequentialWorkList::AddWorkItem(pWorkItem); } void RemoveWorkItem(CQueryRemoteWork * pWorkItem) { CSequentialWorkList::RemoveWorkItem(pWorkItem); } HRESULT Cancel ( LPVOID pCallerContext ); }; extern CQueryRemoteWorkList *g_pQueryRemoteList; #endif /* ndef EVENTS_INC */