|
|
/***************************************************************************/ /** 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 <nmutil.h>
// #include <referenc.h>
#include <inodecnt.h>
#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 */
|