218 lines
7.2 KiB
C++
218 lines
7.2 KiB
C++
/*==========================================================================
|
|
*
|
|
* 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;
|
|
}
|