|
|
/*==========================================================================
* * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. * * File: trnotify.cpp * Content: Implementation of the IDirectXVoiceNotify interface * * History: * Date By Reason * ==== == ====== * 07/26/99 rodtoll Created * 08/03/99 rodtoll Updated with new parameters for Initialize * Updated for new initialization order * 08/05/99 rodtoll Added hook for host migration * 08/05/99 rodtoll Added new receive parameter * 08/10/99 rodtoll Initial host migration * 08/31/99 rodtoll Updated to use new debug libs * 09/14/99 rodtoll Updated to reflect new parameters for Initialize call * 09/20/99 rodtoll Updated to check for out of memory errors * 09/28/99 rodtoll Added release on server interface created by host migration * 10/05/99 rodtoll Additional comments * 10/19/99 rodtoll Fix: Bug #113904 - Shutdown issues * - Added reference count for notify interface, allows * determination if stopsession should be called from release * - Fixed host migration break caused by Fix. * 10/25/99 rodtoll Fix: Bug #114098 - Release/Addref failure from multiple threads * 12/16/99 rodtoll Fix: Bug #122629 - Updated for new host migration * 04/07/2000 rodtoll Updated to match changes in DP <--> DPV interface * 07/22/20000 rodtoll Bug #40296, 38858 - Crashes due to shutdown race condition * Now ensures that all threads from transport have left and that * all notificatinos have been processed before shutdown is complete. * 01/04/2001 rodtoll WinBug #94200 - Remove stray comments * ***************************************************************************/
#include "dxvoicepch.h"
extern HRESULT DVC_Create(LPDIRECTVOICECLIENTOBJECT *piDVC); extern HRESULT DVS_Create(LPDIRECTVOICESERVEROBJECT *piDVS);
#undef DPF_MODNAME
#define DPF_MODNAME "DV_HostMigrate"
//
// DV_HostMigrate
//
// Called by DV_NotifyEvent to handle host migration
//
void DV_HostMigrate( LPDIRECTVOICEOBJECT lpdv, DVID dvidNewHost ) { LPDIRECTVOICECLIENTOBJECT lpdvcClientObject = NULL; LPDIRECTVOICESERVEROBJECT lpdvsServerObject = NULL; DVSESSIONDESC dvSessionDesc; HRESULT hr = DP_OK;
DPFX(DPFPREP, DVF_INFOLEVEL, "DV_HostMigrate: Notified of a host migration. New Host = 0x%x", dvidNewHost ); // We're the new host! Create and setup a server object for the session host
// When other clients receive the host migrate message this object will
// be contacted with join messages.
//
// If this case is active, we should be a client, afterall why would we host migrate
// to ourselves.
//
if( dvidNewHost == lpdv->lpDVTransport->GetLocalID() ) { lpdvcClientObject = (LPDIRECTVOICECLIENTOBJECT) lpdv;
DPFX(DPFPREP, DVF_INFOLEVEL, "DV_HostMigrate: We're the new host -- Congrats!" ); // Create a new server object
DVS_Create( &lpdvsServerObject );
// FYI: Casts to a DXTransport, which should be safe unless we implement a different transport
// If you implement different transport object interface then a QI type system will be needed
//
CDirectVoiceDirectXTransport *transport = (CDirectVoiceDirectXTransport *) lpdv->lpDVTransport;
// Initialize the server object
hr = DV_Initialize( lpdvsServerObject, transport->GetTransportInterface(), NULL, NULL, NULL, 0 );
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "DV_Initialize on new host object failed. hr=0x%x", hr ); return; }
dvSessionDesc.dwSize = sizeof( DVSESSIONDESC ); hr = lpdvcClientObject->lpDVClientEngine->GetSessionDesc( &dvSessionDesc );
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "GetSessionInfo failed. hr=0x%x", hr ); lpdvsServerObject->lIntRefCnt = 1;
DVS_Release( lpdvsServerObject );
return; }
DPFX(DPFPREP, DVF_INFOLEVEL, "DV_HostMigrate: Starting new object" ); lpdvsServerObject->lpDVServerEngine->HostMigrateStart(&dvSessionDesc);
DPFX(DPFPREP, DVF_INFOLEVEL, "DV_HostMigrate: WStartup Complete" ); }
DPFX(DPFPREP, DVF_INFOLEVEL, "DV_HostMigrate: Informing local engine of new host" ); lpdv->lpDVEngine->MigrateHost( dvidNewHost, (LPDIRECTPLAYVOICESERVER) lpdvsServerObject );
// Ok. We need an extra reference to this object to prevent
// the code which detects it needs to call StopSession for
// people who don't call StopSession before calling Release.
/*
// Release this function's reference on the object
if( lpdvsServerObject != NULL ) { DVS_Release( lpdvsServerObject ); }*/ }
#undef DPF_MODNAME
#define DPF_MODNAME "DV_NotifyEvent"
STDMETHODIMP DV_NotifyEvent( LPDIRECTVOICENOTIFYOBJECT lpDVN, DWORD dwNotifyType, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
switch( dwNotifyType ) { case DVEVENT_MIGRATEHOST: lpDVN->lpDV->lpDVEngine->MigrateHost( 0, NULL ); break; case DVEVENT_STARTSESSION: lpDVN->lpDV->lpDVEngine->StartTransportSession(); break; case DVEVENT_STOPSESSION: lpDVN->lpDV->lpDVEngine->StopTransportSession(); break; case DVEVENT_ADDPLAYER: lpDVN->lpDV->lpDVEngine->AddPlayer( (DVID) dwParam1 ); break; case DVEVENT_REMOVEPLAYER: lpDVN->lpDV->lpDVEngine->RemovePlayer( (DVID) dwParam1 ); break; case DVEVENT_CREATEGROUP: lpDVN->lpDV->lpDVEngine->CreateGroup( (DVID) dwParam1 ); break; case DVEVENT_DELETEGROUP: lpDVN->lpDV->lpDVEngine->DeleteGroup( (DVID) dwParam1 ); break; case DVEVENT_ADDPLAYERTOGROUP: lpDVN->lpDV->lpDVEngine->AddPlayerToGroup( (DVID) dwParam1, (DVID) dwParam2 ); break; case DVEVENT_REMOVEPLAYERFROMGROUP: lpDVN->lpDV->lpDVEngine->RemovePlayerFromGroup( (DVID) dwParam1, (DVID) dwParam2 ); break; case DVEVENT_SENDCOMPLETE: lpDVN->lpDV->lpDVEngine->SendComplete( (PDVEVENTMSG_SENDCOMPLETE) dwParam1 ); break; }
return DV_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "DV_ReceiveSpeechMessage"
STDMETHODIMP DV_ReceiveSpeechMessage( LPDIRECTVOICENOTIFYOBJECT lpDVN, DVID dvidSource, DVID dvidTo, LPVOID lpMessage, DWORD dwSize ) { lpDVN->lpDV->lpDVEngine->ReceiveSpeechMessage( dvidSource, lpMessage, dwSize );
return DV_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "DV_Notify_Initialize"
STDMETHODIMP DV_Notify_Initialize( LPDIRECTVOICENOTIFYOBJECT lpDVN ) { return lpDVN->lpDV->lpDVTransport->Initialize(); }
#undef DPF_MODNAME
#define DPF_MODNAME "DV_Notify_AddRef"
STDMETHODIMP DV_Notify_AddRef(LPDIRECTVOICENOTIFYOBJECT lpDVN ) { lpDVN->lpDV->lpDVTransport->AddRef(); return 0; }
#undef DPF_MODNAME
#define DPF_MODNAME "DVC_Notify_Release"
STDAPI DVC_Notify_Release(LPDIRECTVOICENOTIFYOBJECT lpDVN ) { lpDVN->lpDV->lpDVTransport->Release(); return 0; }
#undef DPF_MODNAME
#define DPF_MODNAME "DVC_Notify_QueryInterface"
STDMETHODIMP DVC_Notify_QueryInterface(LPDIRECTVOICENOTIFYOBJECT lpDVN, REFIID riid, LPVOID * ppvObj ) { return DVC_QueryInterface( (LPDIRECTVOICECLIENTOBJECT) lpDVN->lpDV, riid, ppvObj ); }
#undef DPF_MODNAME
#define DPF_MODNAME "DVS_Notify_QueryInterface"
STDMETHODIMP DVS_Notify_QueryInterface(LPDIRECTVOICENOTIFYOBJECT lpDVN, REFIID riid, LPVOID * ppvObj ) { return DVS_QueryInterface( (LPDIRECTVOICESERVEROBJECT) lpDVN->lpDV, riid, ppvObj ); }
#undef DPF_MODNAME
#define DPF_MODNAME "DVS_Notify_Release"
STDAPI DVS_Notify_Release(LPDIRECTVOICENOTIFYOBJECT lpDVN ) { lpDVN->lpDV->lpDVTransport->Release(); return 0; }
|