windows-nt/Source/XPSP1/NT/multimedia/directx/dplay/dvoice/dxvoice/trnotify.cpp
2020-09-26 16:20:57 +08:00

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;
}