You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
6.3 KiB
285 lines
6.3 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1999 - 1999 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: vnametbl.h
|
|
* Content: Voice Name Table Routines
|
|
*
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 03/26/00 rodtoll Created
|
|
* 06/02/00 rodtoll Updated so host migration algorithm returns ID as well as order ID
|
|
* 06/21/2000 rodtoll Fixed bug in error handling (not yet encountered -- but good to fix).
|
|
* 07/01/2000 rodtoll Bug #38280 - DVMSGID_DELETEVOICEPLAYER messages are being sent in non-peer to peer sessions
|
|
* Nametable will now only unravel with messages if session is peer to peer.
|
|
* 07/09/2000 rodtoll Added signature bytes
|
|
* 08/28/2000 masonb Voice Merge: Changed classhash.h to classhashvc.h
|
|
* 04/09/2001 rodtoll WINBUG #364126 - DPVoice : Memory leak when Initializing 2 Voice Servers with same DPlay transport
|
|
* 02/28/2002 rodtoll WINBUG #549943 - SECURITY: DPVOICE: Possible corruption of voice server state
|
|
* - Addition of single operation return and delete operation to allow for protection against second
|
|
* spoofed delete player message from crashing the server.
|
|
*
|
|
***************************************************************************/
|
|
|
|
#ifndef __NAMETABLE_H
|
|
#define __NAMETABLE_H
|
|
|
|
#undef DPF_SUBCOMP
|
|
#define DPF_SUBCOMP DN_SUBCOMP_VOICE
|
|
|
|
|
|
#define VSIG_VOICENAMETABLE 'BTNV'
|
|
#define VSIG_VOICENAMETABLE_FREE 'BTN_'
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "ClassHash_Hash"
|
|
inline DWORD_PTR ClassHash_Hash( const DVID &dvidKey, UINT_PTR HashBitCount )
|
|
{
|
|
DWORD_PTR hashResult;
|
|
|
|
hashResult = dvidKey;
|
|
|
|
// Clear upper bits
|
|
hashResult <<= ((sizeof(DWORD_PTR)*8)-HashBitCount);
|
|
|
|
// Restore value
|
|
hashResult >>= ((sizeof(DWORD_PTR)*8)-HashBitCount);
|
|
|
|
return hashResult;
|
|
}
|
|
|
|
#define VOICE_NAMETABLE_START_BITDEPTH 6
|
|
#define VOICE_NAMETABLE_GROW_BITDEPTH 2
|
|
|
|
volatile class CVoiceNameTable
|
|
{
|
|
public:
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::CVoiceNameTable"
|
|
CVoiceNameTable( )
|
|
{
|
|
m_dwSignature = VSIG_VOICENAMETABLE;
|
|
m_fInitialized = FALSE;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::~CVoiceNameTable"
|
|
~CVoiceNameTable()
|
|
{
|
|
DeInitialize(FALSE, NULL, NULL);
|
|
|
|
m_dwSignature = VSIG_VOICENAMETABLE_FREE;
|
|
}
|
|
|
|
HRESULT DeInitialize(BOOL fUnRavel, PVOID pvContext, LPDVMESSAGEHANDLER pvMessageHandler);
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::Initialize"
|
|
inline HRESULT Initialize()
|
|
{
|
|
BOOL fResult;
|
|
|
|
if (!DNInitializeCriticalSection( &m_csTableLock ))
|
|
{
|
|
return DVERR_OUTOFMEMORY;
|
|
}
|
|
|
|
fResult = m_nameTable.Initialize( VOICE_NAMETABLE_START_BITDEPTH, VOICE_NAMETABLE_GROW_BITDEPTH );
|
|
|
|
if( !fResult )
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to initialize hash table" );
|
|
DNDeleteCriticalSection( &m_csTableLock );
|
|
return DVERR_GENERIC;
|
|
}
|
|
|
|
m_fInitialized = TRUE;
|
|
|
|
return DV_OK;
|
|
};
|
|
|
|
DWORD GetLowestHostOrderID(DVID *pdvidHost);
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::IsEntry"
|
|
BOOL IsEntry( const DVID dvidID )
|
|
{
|
|
BOOL fResult;
|
|
|
|
CVoicePlayer *pEntry;
|
|
|
|
Lock();
|
|
|
|
fResult = m_nameTable.Find( dvidID, &pEntry );
|
|
|
|
UnLock();
|
|
|
|
return fResult;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::GetEntry"
|
|
inline HRESULT GetEntry( const DVID dvidID, CVoicePlayer **ppEntry, BOOL fAddReference )
|
|
{
|
|
BOOL fFound;
|
|
|
|
Lock();
|
|
|
|
fFound = m_nameTable.Find( dvidID, ppEntry );
|
|
|
|
if( !fFound )
|
|
{
|
|
*ppEntry = NULL;
|
|
UnLock();
|
|
return DVERR_INVALIDPLAYER;
|
|
}
|
|
|
|
DNASSERT( *ppEntry != NULL );
|
|
|
|
if( fAddReference )
|
|
{
|
|
(*ppEntry)->AddRef();
|
|
}
|
|
|
|
UnLock();
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::AddEntry"
|
|
inline HRESULT AddEntry( const DVID dvidID, CVoicePlayer *pEntry )
|
|
{
|
|
BOOL fFound;
|
|
CVoicePlayer *pTmpEntry;
|
|
|
|
Lock();
|
|
|
|
fFound = m_nameTable.Find( dvidID, &pTmpEntry );
|
|
|
|
if( fFound )
|
|
{
|
|
UnLock();
|
|
return DVERR_GENERIC;
|
|
}
|
|
|
|
pEntry->AddRef();
|
|
|
|
fFound = m_nameTable.Insert( dvidID, pEntry );
|
|
|
|
if( !fFound )
|
|
{
|
|
pEntry->Release();
|
|
UnLock();
|
|
return DVERR_GENERIC;
|
|
}
|
|
|
|
UnLock();
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::DeleteAndReturnEntry"
|
|
//
|
|
// This function removes and returns a record from the nametable, if one exists.
|
|
// The player object returned will have the nametable's reference on the player
|
|
// so the calling function MUST call release on the object to see it destroyed.
|
|
//
|
|
// After this function returns the player will no longer be available.
|
|
//
|
|
inline HRESULT DeleteAndReturnEntry( const DVID dvidID, CVoicePlayer **pTarget )
|
|
{
|
|
BOOL fFound;
|
|
CVoicePlayer *pTmpEntry;
|
|
|
|
Lock();
|
|
|
|
fFound = m_nameTable.Find( dvidID, &pTmpEntry );
|
|
|
|
if( !fFound )
|
|
{
|
|
UnLock();
|
|
return DVERR_GENERIC;
|
|
}
|
|
|
|
if( pTmpEntry == NULL )
|
|
{
|
|
DNASSERT( FALSE );
|
|
UnLock();
|
|
return DVERR_GENERIC;
|
|
}
|
|
|
|
m_nameTable.Remove( dvidID );
|
|
|
|
// Returning the object from the table, no release
|
|
// called therefore giving the reference to the caller.
|
|
*pTarget = pTmpEntry;
|
|
|
|
UnLock();
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::DeleteEntry"
|
|
inline HRESULT DeleteEntry( const DVID dvidID )
|
|
{
|
|
BOOL fFound;
|
|
CVoicePlayer *pTmpEntry;
|
|
|
|
Lock();
|
|
|
|
fFound = m_nameTable.Find( dvidID, &pTmpEntry );
|
|
|
|
if( !fFound )
|
|
{
|
|
UnLock();
|
|
return DVERR_GENERIC;
|
|
}
|
|
|
|
m_nameTable.Remove( dvidID );
|
|
|
|
DNASSERT( pTmpEntry != NULL );
|
|
|
|
// Regardless of if it was found..
|
|
// Drop the reference count
|
|
pTmpEntry->Release();
|
|
|
|
if( !fFound )
|
|
{
|
|
UnLock();
|
|
return DVERR_GENERIC;
|
|
}
|
|
|
|
UnLock();
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::Lock"
|
|
inline void Lock()
|
|
{
|
|
DNEnterCriticalSection( &m_csTableLock );
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CVoiceNameTable::UnLock"
|
|
inline void UnLock()
|
|
{
|
|
DNLeaveCriticalSection( &m_csTableLock );
|
|
}
|
|
|
|
protected:
|
|
|
|
DWORD m_dwSignature;
|
|
CClassHash<CVoicePlayer,DVID> m_nameTable;
|
|
DNCRITICAL_SECTION m_csTableLock;
|
|
BOOL m_fInitialized;
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
|
|
#endif
|