//****************************************************************************
// Module: NMCHAT.EXE
// File: CCONF.CPP
// Content:
//
//
// Copyright (c) Microsoft Corporation 1997
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//****************************************************************************
#include "precomp.h"
// Global Varaiables
INmManager * g_pMgr = NULL; // The Conference Manager
CMgrNotify * g_pMgrNotify = NULL; // Notifications for the Manager
INmConference * g_pConference = NULL; // The Current Conference
CConfNotify * g_pConferenceNotify =NULL; // Notifications for the Conference
// Local Application Guid : {D29A8C50-774F-11d0-8B1D-00A0C91BC90E}
const GUID g_guidApp =
{ 0xd29a8c51, 0x774f, 0x11d0, { 0x8b, 0x1d, 0x0, 0xa0, 0xc9, 0x1b, 0xc9, 0xe} };
// NetMeeting 2.0 chat guid: {340F3A60-7067-11D0-A041-444553540000}
const GUID g_guidNM2Chat =
{ 0x340f3a60, 0x7067, 0x11d0, { 0xa0, 0x41, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 } };
//****************************************************************************
//
// CLASS CMgrNotify
//
//****************************************************************************
//****************************************************************************
//
// Constructor
//
//****************************************************************************
CMgrNotify::CMgrNotify() : RefCount(), CNotify()
{
}
//****************************************************************************
//
// Destructor
//
//****************************************************************************
CMgrNotify::~CMgrNotify()
{
}
//****************************************************************************
//
// Methods from IUnknown
//
//****************************************************************************
ULONG STDMETHODCALLTYPE CMgrNotify::AddRef(void)
{
return RefCount::AddRef();
}
ULONG STDMETHODCALLTYPE CMgrNotify::Release(void)
{
return RefCount::Release();
}
HRESULT STDMETHODCALLTYPE CMgrNotify::QueryInterface(REFIID riid, PVOID *ppvObject)
{
HRESULT hr = S_OK;
if (riid == IID_IUnknown)
{
*ppvObject = (IUnknown *)this;
}
else if (riid == IID_INmManagerNotify)
{
*ppvObject = (INmManagerNotify *)this;
}
else
{
hr = E_NOINTERFACE;
*ppvObject = NULL;
}
if (S_OK == hr)
{
AddRef();
}
return hr;
}
//****************************************************************************
//
// HRESULT InitConfMgr(void)
//
//****************************************************************************
HRESULT InitConfMgr(void)
{
HRESULT hr;
LPCLASSFACTORY pcf;
// Notify the system we want to use the conferencing services
// by creating a conference manager object
hr = CoGetClassObject(CLSID_NmManager,
CLSCTX_INPROC,
NULL,
IID_IClassFactory,
(void**)&pcf);
if (SUCCEEDED(hr))
{
// Get the conference manager object
hr = pcf->CreateInstance(NULL, IID_INmManager, (void**)&g_pMgr);
if (SUCCEEDED(hr))
{
// Connect to the conference manager object
g_pMgrNotify = new CMgrNotify();
if (NULL != g_pMgrNotify)
{
hr = g_pMgrNotify->Connect(g_pMgr);
if (SUCCEEDED(hr))
{
ULONG uchCaps = NMCH_ALL;
ULONG uOptions = 0;
hr = g_pMgr->Initialize(&uOptions, &uchCaps);
}
}
}
pcf->Release();
}
return hr;
}
//****************************************************************************
//
// VOID FreeConfMgr(void)
//
//****************************************************************************
VOID FreeConfMgr(void)
{
// Release conference manager notify
if (NULL != g_pMgrNotify)
{
g_pMgrNotify->Disconnect();
g_pMgrNotify->Release();
g_pMgrNotify = NULL;
}
// Release conference manager
if (NULL != g_pMgr)
{
g_pMgr->Release();
g_pMgr = NULL;
}
}
//****************************************************************************
//
// VOID FreeConference(void)
//
//****************************************************************************
VOID FreeConference(void)
{
if (NULL != g_pConferenceNotify)
{
g_pConferenceNotify->Disconnect();
g_pConferenceNotify->Release();
g_pConferenceNotify = NULL;
}
if (NULL != g_pConference)
{
g_pConference->Release();
g_pConference = NULL;
}
}
//****************************************************************************
//
// Methods from ICNotify
//
//****************************************************************************
HRESULT STDMETHODCALLTYPE CMgrNotify::Connect(IUnknown *pUnk)
{
return CNotify::Connect(pUnk, IID_INmManagerNotify, (IUnknown *)this);
}
HRESULT STDMETHODCALLTYPE CMgrNotify::Disconnect(void)
{
return CNotify::Disconnect();
}
//****************************************************************************
//
// Methods from INmManagerNotify
//
//****************************************************************************
HRESULT STDMETHODCALLTYPE CMgrNotify::NmUI(CONFN confn)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE CMgrNotify::CallCreated(INmCall *pCall)
{
return S_OK;
}
// As soon as a conference is available, create the data channel
HRESULT STDMETHODCALLTYPE CMgrNotify::ConferenceCreated(INmConference *pConference)
{
ASSERT(NULL == g_pConference);
ASSERT(NULL == g_pChannelData);
HookConference(pConference);
return S_OK;
}
//****************************************************************************
//
// HRESULT HookConference(INmConference * pConference)
//
//****************************************************************************
HRESULT HookConference(INmConference * pConference)
{
HRESULT hr;
ASSERT(NULL != pConference);
ASSERT(NULL == g_pConference);
g_pConference = pConference;
pConference->AddRef();
// Connect to the conference object
ASSERT(NULL == g_pConferenceNotify)
g_pConferenceNotify = new CConfNotify();
if (NULL == g_pConferenceNotify)
{
hr = E_OUTOFMEMORY;
}
else
{
hr = g_pConferenceNotify->Connect(pConference);
if (FAILED(hr))
{
g_pConferenceNotify->Release();
g_pConferenceNotify = NULL;
}
}
return hr;
}
//****************************************************************************
//
// CLASS CConfNotify
//
//****************************************************************************
//****************************************************************************
//
// Constructor
//
//****************************************************************************
CConfNotify::CConfNotify() : RefCount(), CNotify()
{
}
//****************************************************************************
//
// Destructor
//
//****************************************************************************
CConfNotify::~CConfNotify()
{
}
//****************************************************************************
//
// Methods from IUnknown
//
//****************************************************************************
ULONG STDMETHODCALLTYPE CConfNotify::AddRef(void)
{
return RefCount::AddRef();
}
ULONG STDMETHODCALLTYPE CConfNotify::Release(void)
{
return RefCount::Release();
}
HRESULT STDMETHODCALLTYPE CConfNotify::QueryInterface(REFIID riid, PVOID *ppvObject)
{
HRESULT hr = S_OK;
if (riid == IID_IUnknown)
{
*ppvObject = (IUnknown *)this;
}
else if (riid == IID_INmConferenceNotify)
{
*ppvObject = (INmConferenceNotify *)this;
}
else
{
hr = E_NOINTERFACE;
*ppvObject = NULL;
}
if (S_OK == hr)
{
AddRef();
}
return hr;
}
//****************************************************************************
//
// Methods from ICNotify
//
//****************************************************************************
HRESULT STDMETHODCALLTYPE CConfNotify::Connect(IUnknown *pUnk)
{
return CNotify::Connect(pUnk, IID_INmConferenceNotify, (IUnknown *)this);
}
HRESULT STDMETHODCALLTYPE CConfNotify::Disconnect(void)
{
return CNotify::Disconnect();
}
//****************************************************************************
//
// Methods from IConfNotify
//
//****************************************************************************
HRESULT STDMETHODCALLTYPE CConfNotify::NmUI(CONFN uNotify)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE CConfNotify::StateChanged(NM_CONFERENCE_STATE uState)
{
if (NULL == g_pConference)
return S_OK; // weird
switch (uState)
{
case NM_CONFERENCE_ACTIVE:
{
HRESULT hr;
INmChannelData * pChannelData;
#ifdef NM2_CHAT_PROTOCOL
hr = g_pConference->CreateDataChannel(&pChannelData, g_guidNM2Chat);
#else
hr = g_pConference->CreateDataChannel(&pChannelData, g_guidApp);
#endif /* NM2_CHAT_PROTOCOL */
if (S_OK == hr)
{
hr = HookData(pChannelData); // Real hook is g_pChannelData
}
DisplaySysMsg((S_OK == hr) ? TEXT("Chat Started") : TEXT("Chat failed to start!"), NULL);
break;
}
case NM_CONFERENCE_INITIALIZING:
break; // can't do anything just yet
case NM_CONFERENCE_WAITING:
FreeDataChannel();
DisplaySysMsg(TEXT("Waiting in Host Mode"), NULL);
break;
case NM_CONFERENCE_IDLE:
FreeDataChannel();
FreeConference();
DisplaySysMsg(TEXT("No conference"), NULL);
break;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CConfNotify::MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE CConfNotify::ChannelChanged(NM_CHANNEL_NOTIFY uNotify, INmChannel *pChannel)
{
return S_OK;
}