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.
364 lines
9.4 KiB
364 lines
9.4 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1999, 2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: dllmain.cpp
|
|
* Content: This file contains all of the DLL exports except for DllGetClass / DllCanUnload
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 07/05/00 rodtoll Created
|
|
* 08/23/2000 rodtoll DllCanUnloadNow always returning TRUE!
|
|
* 08/28/2000 masonb Voice Merge: Removed OSAL_* and dvosal.h
|
|
* 10/05/2000 rodtoll Bug #46541 - DPVOICE: A/V linking to dpvoice.lib could cause application to fail init and crash
|
|
* 01/11/2001 rmt MANBUG #48487 - DPLAY: Crashes if CoCreate() isn't called.
|
|
* 03/14/2001 rmt WINBUG #342420 - Restore COM emulation layer to operation.
|
|
* 02/28/2002 rodtoll WINBUG #550124 - SECURITY: DPVOICE: Shared memory region with NULL DACL
|
|
* - Remove performance statistics dumping to shared memory
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dxvoicepch.h"
|
|
|
|
|
|
DNCRITICAL_SECTION g_csObjectInitGuard;
|
|
LONG lInitCount = 0;
|
|
|
|
// # of objects active in the system
|
|
volatile LONG g_lNumObjects = 0;
|
|
LONG g_lNumLocks = 0;
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "RegisterDefaultSettings"
|
|
//
|
|
// RegisterDefaultSettings
|
|
//
|
|
// This function registers the default settings for this module.
|
|
//
|
|
// For DPVOICE.DLL this is making sure the compression provider sub-key is created.
|
|
//
|
|
HRESULT RegisterDefaultSettings()
|
|
{
|
|
CRegistry creg;
|
|
|
|
if( !creg.Open( HKEY_LOCAL_MACHINE, DPVOICE_REGISTRY_BASE DPVOICE_REGISTRY_CP, FALSE, TRUE ) )
|
|
{
|
|
return DVERR_GENERIC;
|
|
}
|
|
else
|
|
{
|
|
return DV_OK;
|
|
}
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "UnRegisterDefaultSettings"
|
|
//
|
|
// UnRegisterDefaultSettings
|
|
//
|
|
// This function registers the default settings for this module.
|
|
//
|
|
// For DPVOICE.DLL this is making sure the compression provider sub-key is created.
|
|
//
|
|
HRESULT UnRegisterDefaultSettings()
|
|
{
|
|
CRegistry creg;
|
|
|
|
if( !creg.Open( HKEY_LOCAL_MACHINE, DPVOICE_REGISTRY_BASE, FALSE, TRUE ) )
|
|
{
|
|
DPFERR( "Cannot remove compression provider, does not exist" );
|
|
}
|
|
else
|
|
{
|
|
if( !creg.DeleteSubKey( &(DPVOICE_REGISTRY_CP)[1] ) )
|
|
{
|
|
DPFERR( "Cannot remove cp sub-key, could have elements" );
|
|
}
|
|
}
|
|
|
|
return DV_OK;
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DllRegisterServer"
|
|
HRESULT WINAPI DllRegisterServer()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fFailed = FALSE;
|
|
|
|
#if !defined(DBG) || !defined( DIRECTX_REDIST )
|
|
#define DPVOICE_FILENAME_DPVOICE L"dpvoice.dll"
|
|
#else
|
|
// For redist debug builds we append a 'd' to the name to allow both debug and retail to be installed on the system
|
|
#define DPVOICE_FILENAME_DPVOICE L"dpvoiced.dll"
|
|
#endif // !defined(DBG) || !defined( DIRECTX_REDIST )
|
|
|
|
if( !CRegistry::Register( L"DirectPlayVoice.Compat.1", L"DirectPlayVoice Object",
|
|
DPVOICE_FILENAME_DPVOICE, &CLSID_DIRECTPLAYVOICE, L"DirectPlayVoice.Compat") )
|
|
{
|
|
DPFERR( "Could not register compat object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( !CRegistry::Register( L"DirectPlayVoice.Server.1", L"DirectPlayVoice Server Object",
|
|
DPVOICE_FILENAME_DPVOICE, &CLSID_DirectPlayVoiceServer, L"DirectPlayVoice.Server") )
|
|
{
|
|
DPFERR( "Could not register server object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( !CRegistry::Register( L"DirectPlayVoice.Client.1", L"DirectPlayVoice Client Object",
|
|
DPVOICE_FILENAME_DPVOICE, &CLSID_DirectPlayVoiceClient,
|
|
L"DirectPlayVoice.Client") )
|
|
{
|
|
|
|
DPFERR( "Could not register client object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( !CRegistry::Register( L"DirectPlayVoice.Test.1", L"DirectPlayVoice Test Object",
|
|
DPVOICE_FILENAME_DPVOICE, &CLSID_DirectPlayVoiceTest,
|
|
L"DirectPlayVoice.Test") )
|
|
{
|
|
DPFERR( "Could not register test object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( FAILED( hr = RegisterDefaultSettings() ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not register default settings hr = 0x%x", hr );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( fFailed )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DllUnregisterServer"
|
|
STDAPI DllUnregisterServer()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fFailed = FALSE;
|
|
|
|
if( !CRegistry::UnRegister(&CLSID_DirectPlayVoiceServer) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister server object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( !CRegistry::UnRegister(&CLSID_DIRECTPLAYVOICE) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister compat object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( !CRegistry::UnRegister(&CLSID_DirectPlayVoiceClient) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister client object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( !CRegistry::UnRegister(&CLSID_DirectPlayVoiceTest) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister test object" );
|
|
fFailed = TRUE;
|
|
}
|
|
|
|
if( FAILED( hr = UnRegisterDefaultSettings() ) )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to remove default settings hr=0x%x", hr );
|
|
}
|
|
|
|
if( fFailed )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DirectPlayVoiceCreate"
|
|
HRESULT WINAPI DirectPlayVoiceCreate( const GUID * pcIID, void **ppvInterface, IUnknown *pUnknown)
|
|
{
|
|
GUID clsid;
|
|
|
|
if( pcIID == NULL ||
|
|
!DNVALID_READPTR( pcIID, sizeof( GUID ) ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Invalid pointer specified for interface GUID" );
|
|
return DVERR_INVALIDPOINTER;
|
|
}
|
|
|
|
if( *pcIID != IID_IDirectPlayVoiceClient &&
|
|
*pcIID != IID_IDirectPlayVoiceServer &&
|
|
*pcIID != IID_IDirectPlayVoiceTest )
|
|
{
|
|
DPFX(DPFPREP, 0, "Interface ID is not recognized" );
|
|
return DVERR_INVALIDPARAM;
|
|
}
|
|
|
|
if( ppvInterface == NULL || !DNVALID_WRITEPTR( ppvInterface, sizeof( void * ) ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Invalid pointer specified to receive interface" );
|
|
return DVERR_INVALIDPOINTER;
|
|
}
|
|
|
|
if( pUnknown != NULL )
|
|
{
|
|
DPFX(DPFPREP, 0, "Aggregation is not supported by this object yet" );
|
|
return DVERR_INVALIDPARAM;
|
|
}
|
|
|
|
if( *pcIID == IID_IDirectPlayVoiceClient )
|
|
{
|
|
clsid = CLSID_DirectPlayVoiceClient;
|
|
}
|
|
else if( *pcIID == IID_IDirectPlayVoiceServer )
|
|
{
|
|
clsid = CLSID_DirectPlayVoiceServer;
|
|
}
|
|
else if( *pcIID == IID_IDirectPlayVoiceTest )
|
|
{
|
|
clsid = CLSID_DirectPlayVoiceTest;
|
|
}
|
|
else
|
|
{
|
|
DPFERR( "Invalid IID specified" );
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
return COM_CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, *pcIID, ppvInterface, TRUE );
|
|
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DllMain"
|
|
BOOL WINAPI DllMain(
|
|
HINSTANCE hDllInst,
|
|
DWORD fdwReason,
|
|
LPVOID lpvReserved)
|
|
{
|
|
if( fdwReason == DLL_PROCESS_ATTACH )
|
|
{
|
|
if( !lInitCount )
|
|
{
|
|
#ifndef WIN95
|
|
SHFusionInitializeFromModule(hDllInst);
|
|
#endif
|
|
if (!DNOSIndirectionInit(0))
|
|
{
|
|
return FALSE;
|
|
}
|
|
if (!DNInitializeCriticalSection(&g_csObjectInitGuard))
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to create CS" );
|
|
DNOSIndirectionDeinit();
|
|
return FALSE;
|
|
}
|
|
if (FAILED(COM_Init()))
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to Init COM layer" );
|
|
DNDeleteCriticalSection(&g_csObjectInitGuard);
|
|
DNOSIndirectionDeinit();
|
|
return FALSE;
|
|
}
|
|
|
|
if (!DSERRTRACK_Init())
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to Init DS error tracking" );
|
|
COM_Free();
|
|
DNDeleteCriticalSection(&g_csObjectInitGuard);
|
|
DNOSIndirectionDeinit();
|
|
return FALSE;
|
|
}
|
|
|
|
#if defined(DEBUG) || defined(DBG)
|
|
Instrument_Core_Init();
|
|
#endif
|
|
InterlockedIncrement( &lInitCount );
|
|
}
|
|
}
|
|
else if( fdwReason == DLL_PROCESS_DETACH )
|
|
{
|
|
InterlockedDecrement( &lInitCount );
|
|
|
|
if( lInitCount == 0 )
|
|
{
|
|
DSERRTRACK_UnInit();
|
|
DPFX(DPFPREP, DVF_INFOLEVEL, ">>>>>>>>>>>>>>>> DPF UNINITED <<<<<<<<<<<<<<<" );
|
|
COM_Free();
|
|
|
|
DNDeleteCriticalSection(&g_csObjectInitGuard);
|
|
|
|
// This must be called after all DNDeleteCriticalSection calls are done
|
|
DNOSIndirectionDeinit();
|
|
|
|
// Check to ensure we're not being unloaded with objects active
|
|
|
|
if( g_lNumObjects != 0 || g_lNumLocks != 0 )
|
|
{
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "=========================================================================" );
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "DPVOICE.DLL is unloading with %i objects and %i locks still open. This is an ERROR. ", g_lNumObjects, g_lNumLocks );
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "You must release all DirectPlayVoice objects before exiting your process." );
|
|
DPFX(DPFPREP, DVF_ERRORLEVEL, "=========================================================================" );
|
|
DNASSERT( FALSE );
|
|
}
|
|
|
|
#ifndef WIN95
|
|
SHFusionUninitialize();
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LONG DecrementObjectCount()
|
|
{
|
|
LONG lNewValue;
|
|
|
|
DNEnterCriticalSection( &g_csObjectInitGuard );
|
|
|
|
g_lNumObjects--;
|
|
lNewValue = g_lNumObjects;
|
|
|
|
if( g_lNumObjects == 0 )
|
|
{
|
|
CDirectVoiceEngine::Shutdown();
|
|
}
|
|
|
|
DNLeaveCriticalSection( &g_csObjectInitGuard );
|
|
|
|
return lNewValue;
|
|
}
|
|
|
|
LONG IncrementObjectCount()
|
|
{
|
|
LONG lNewValue;
|
|
|
|
DNEnterCriticalSection( &g_csObjectInitGuard );
|
|
|
|
g_lNumObjects++;
|
|
lNewValue = g_lNumObjects;
|
|
|
|
if( g_lNumObjects == 1 )
|
|
{
|
|
CDirectVoiceEngine::Startup(DPVOICE_REGISTRY_BASE);
|
|
}
|
|
|
|
DNLeaveCriticalSection( &g_csObjectInitGuard );
|
|
|
|
return lNewValue;
|
|
}
|