|
|
//
// dmprfdll.cpp
//
// Copyright (c) 1997-1999 Microsoft Corporation
//
// Note: Dll entry points as well as class factory implementations.
//
// READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// 4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
//
// We disable this because we use exceptions and do *not* specify -GX (USE_NATIVE_EH in
// sources).
//
// The one place we use exceptions is around construction of objects that call
// InitializeCriticalSection. We guarantee that it is safe to use in this case with
// the restriction given by not using -GX (automatic objects in the call chain between
// throw and handler are not destructed). Turning on -GX buys us nothing but +10% to code
// size because of the unwind code.
//
// Any other use of exceptions must follow these restrictions or -GX must be turned on.
//
// READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
#pragma warning(disable:4530)
#include <objbase.h>
#include <initguid.h>
#include <mmsystem.h>
#include <dsoundp.h>
#include "debug.h"
#define ASSERT assert
#include "debug.h"
#include "dmprfdll.h"
#include "dmperf.h"
#include "dmsegobj.h"
#include "song.h"
#include "seqtrack.h"
#include "sysextrk.h"
#include "tempotrk.h"
#include "tsigtrk.h"
#include "marktrk.h"
#include "wavtrack.h"
#include "segtrtrk.h"
#include "lyrictrk.h"
#include "ParamTrk.h"
#include "dmgraph.h"
#include "dmusicc.h"
#include "dmusici.h"
#include "dmusicf.h"
#include "..\shared\oledll.h"
#include "..\dmstyle\dmstylep.h"
#include "..\dmband\dmbndtrk.h"
#include "..\shared\dmstrm.h"
#include "..\shared\Validate.h"
#include "dmksctrl.h"
#include "dmscriptautguids.h"
#include "audpath.h"
#include "..\dswave\dswave.h"
#include "dsoundp.h" // For IDirectSoundPrivate
bool g_fInitCS = false; CRITICAL_SECTION g_CritSec;
//////////////////////////////////////////////////////////////////////
// Globals
// Dll's hModule
//
HMODULE g_hModule = NULL;
// Count of active components and class factory server locks
//
long g_cComponent = 0; long g_cLock = 0;
// Flags DMI_F_xxx from dmusicp.h
//
DWORD g_fFlags;
static char const g_szDoEmulation[] = "DoEmulation";
// CClassFactory::QueryInterface
//
HRESULT __stdcall CClassFactory::QueryInterface(const IID &iid, void **ppv) { if (iid == IID_IUnknown || iid == IID_IClassFactory) { *ppv = static_cast<IClassFactory*>(this); } else { *ppv = NULL; return E_NOINTERFACE; }
reinterpret_cast<IUnknown*>(*ppv)->AddRef(); return S_OK; }
CClassFactory::CClassFactory(DWORD dwClassType)
{ m_cRef = 1; m_dwClassType = dwClassType; InterlockedIncrement(&g_cLock); }
CClassFactory::~CClassFactory()
{ InterlockedDecrement(&g_cLock); }
// CClassFactory::AddRef
//
ULONG __stdcall CClassFactory::AddRef() { return InterlockedIncrement(&m_cRef); }
// CClassFactory::Release
//
ULONG __stdcall CClassFactory::Release() { if (!InterlockedDecrement(&m_cRef)) { delete this; return 0; }
return m_cRef; }
// CClassFactory::CreateInstance
//
//
HRESULT __stdcall CClassFactory::CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv) { HRESULT hr;
if (pUnknownOuter) { return CLASS_E_NOAGGREGATION; }
switch (m_dwClassType) { case CLASS_PERFORMANCE: { CPerformance *pInst;
try { pInst = new CPerformance; } catch( ... ) { hr = E_OUTOFMEMORY; break; }
if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_GRAPH: { CGraph *pInst = new CGraph; if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_SEGMENT: { CSegment *pInst = new CSegment; if (pInst == NULL) { hr = E_OUTOFMEMORY; break; } // The segment is initialized with a ref count of 0, so QI will set it to 1.
hr = pInst->QueryInterface(iid, ppv); } break; case CLASS_SONG: { CSong *pInst = new CSong; if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_AUDIOPATH: { CAudioPathConfig *pInst;
try { pInst = new CAudioPathConfig; } catch( ... ) { hr = E_OUTOFMEMORY; break; }
if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_SEQTRACK: { CSeqTrack *pInst;
try { pInst = new CSeqTrack; } catch( ... ) { hr = E_OUTOFMEMORY; break; }
if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_SYSEXTRACK: { CSysExTrack *pInst;
try { pInst = new CSysExTrack; } catch( ... ) { hr = E_OUTOFMEMORY; break; } if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_TEMPOTRACK: { CTempoTrack *pInst;
try { pInst = new CTempoTrack; } catch( ... ) { hr = E_OUTOFMEMORY; break; }
if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_TIMESIGTRACK: { CTimeSigTrack *pInst; try { pInst = new CTimeSigTrack; } catch( ... ) { hr = E_OUTOFMEMORY; break; }
if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_MARKERTRACK: { CMarkerTrack *pInst; try { pInst = new CMarkerTrack; } catch( ... ) { hr = E_OUTOFMEMORY; break; }
if (pInst == NULL) { hr = E_OUTOFMEMORY; break; } hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_WAVETRACK: { CWavTrack *pInst; try { pInst = new CWavTrack; } catch( ... ) { hr = E_OUTOFMEMORY; break; }
if (pInst == NULL) { hr = E_OUTOFMEMORY; break; } hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } break; case CLASS_TRIGGERTRACK: { try { hr = TrackHelpCreateInstance<CSegTriggerTrack>(pUnknownOuter, iid, ppv); } catch( ... ) { hr = E_OUTOFMEMORY; } } break; case CLASS_LYRICSTRACK: { try { hr = TrackHelpCreateInstance<CLyricsTrack>(pUnknownOuter, iid, ppv); } catch( ... ) { hr = E_OUTOFMEMORY; } } break; case CLASS_PARAMSTRACK: { try { hr = TrackHelpCreateInstance<CParamControlTrack>(pUnknownOuter, iid, ppv); } catch( ... ) { hr = E_OUTOFMEMORY; } } break; case CLASS_SEGSTATE: { CSegState *pInst = new CSegState; if (pInst == NULL) { hr = E_OUTOFMEMORY; break; }
hr = pInst->QueryInterface(iid, ppv); pInst->Release(); } } return hr; }
// CClassFactory::LockServer
//
HRESULT __stdcall CClassFactory::LockServer(BOOL bLock) { if (bLock) { InterlockedIncrement(&g_cLock); } else { InterlockedDecrement(&g_cLock); }
return S_OK; }
// Version information for our class
//
TCHAR g_szDMPerformanceFriendlyName[] = TEXT("DirectMusicPerformance"); TCHAR g_szDMPerformanceVerIndProgID[] = TEXT("Microsoft.DirectMusicPerformance"); TCHAR g_szDMPerformanceProgID[] = TEXT("Microsoft.DirectMusicPerformance.1");
TCHAR g_szDMSegmentFriendlyName[] = TEXT("DirectMusicSegment"); TCHAR g_szDMSegmentVerIndProgID[] = TEXT("Microsoft.DirectMusicSegment"); TCHAR g_szDMSegmentProgID[] = TEXT("Microsoft.DirectMusicSegment.1");
TCHAR g_szDMSegmentStateFriendlyName[] = TEXT("DirectMusicSegmentState"); TCHAR g_szDMSegmentStateVerIndProgID[] = TEXT("Microsoft.DirectMusicSegmentState"); TCHAR g_szDMSegmentStateProgID[] = TEXT("Microsoft.DirectMusicSegmentState.1");
TCHAR g_szSongFriendlyName[] = TEXT("DirectMusicSong"); TCHAR g_szSongVerIndProgID[] = TEXT("Microsoft.DirectMusicSong"); TCHAR g_szSongProgID[] = TEXT("Microsoft.DirectMusicSong.1");
TCHAR g_szAudioPathFriendlyName[] = TEXT("DirectMusicAudioPath"); TCHAR g_szAudioPathVerIndProgID[] = TEXT("Microsoft.DirectMusicAudioPath"); TCHAR g_szAudioPathProgID[] = TEXT("Microsoft.DirectMusicAudioPath.1");
TCHAR g_szDMGraphFriendlyName[] = TEXT("DirectMusicGraph"); TCHAR g_szDMGraphVerIndProgID[] = TEXT("Microsoft.DirectMusicGraph"); TCHAR g_szDMGraphProgID[] = TEXT("Microsoft.DirectMusicGraph.1");
TCHAR g_szDMSeqTrackFriendlyName[] = TEXT("DirectMusicSeqTrack"); TCHAR g_szDMSeqTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicSeqTrack"); TCHAR g_szDMSeqTrackProgID[] = TEXT("Microsoft.DirectMusicSeqTrack.1");
TCHAR g_szDMSysExTrackFriendlyName[] = TEXT("DirectMusicSysExTrack"); TCHAR g_szDMSysExTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicSysExTrack"); TCHAR g_szDMSysExTrackProgID[] = TEXT("Microsoft.DirectMusicSysExTrack.1");
TCHAR g_szDMTempoTrackFriendlyName[] = TEXT("DirectMusicTempoTrack"); TCHAR g_szDMTempoTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicTempoTrack"); TCHAR g_szDMTempoTrackProgID[] = TEXT("Microsoft.DirectMusicTempoTrack.1");
TCHAR g_szDMTimeSigTrackFriendlyName[] = TEXT("DirectMusicTimeSigTrack"); TCHAR g_szDMTimeSigTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicTimeSigTrack"); TCHAR g_szDMTimeSigTrackProgID[] = TEXT("Microsoft.DirectMusicTimeSigTrack.1");
TCHAR g_szMarkerTrackFriendlyName[] = TEXT("DirectMusicMarkerTrack"); TCHAR g_szMarkerTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicMarkerTrack"); TCHAR g_szMarkerTrackProgID[] = TEXT("Microsoft.DirectMusicMarkerTrack.1");
TCHAR g_szWaveTrackFriendlyName[] = TEXT("DirectMusicWaveTrack"); TCHAR g_szWaveTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicWaveTrack"); TCHAR g_szWaveTrackProgID[] = TEXT("Microsoft.DirectMusicWaveTrack.1");
TCHAR g_szSegTriggerTrackFriendlyName[] = TEXT("DirectMusicSegTriggerTrack"); TCHAR g_szSegTriggerTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicSegTriggerTrack"); TCHAR g_szSegTriggerTrackProgID[] = TEXT("Microsoft.DirectMusicSegTriggerTrack.1");
TCHAR g_szLyricsTrackFriendlyName[] = TEXT("DirectMusicLyricsTrack"); TCHAR g_szLyricsTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicLyricsTrack"); TCHAR g_szLyricsTrackProgID[] = TEXT("Microsoft.DirectMusicLyricsTrack.1");
TCHAR g_szParamControlTrackFriendlyName[] = TEXT("DirectMusicParamControlTrack"); TCHAR g_szParamControlTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicParamControlTrack"); TCHAR g_szParamControlTrackProgID[] = TEXT("Microsoft.DirectMusicParamControlTrack.1");
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Standard calls needed to be an inproc server
//////////////////////////////////////////////////////////////////////
// DllCanUnloadNow
STDAPI DllCanUnloadNow() { if (g_cComponent || g_cLock) { return S_FALSE; }
return S_OK; }
//////////////////////////////////////////////////////////////////////
// DllGetClassObject
STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void** ppv) { IUnknown* pIUnknown = NULL; DWORD dwTypeID = 0;
if(clsid == CLSID_DirectMusicPerformance) { dwTypeID = CLASS_PERFORMANCE; } else if(clsid == CLSID_DirectMusicSegment) { dwTypeID = CLASS_SEGMENT; } else if(clsid == CLSID_DirectMusicSong) { dwTypeID = CLASS_SONG; } else if(clsid == CLSID_DirectMusicAudioPathConfig) { dwTypeID = CLASS_AUDIOPATH; } else if(clsid == CLSID_DirectMusicSeqTrack) { dwTypeID = CLASS_SEQTRACK; } else if(clsid == CLSID_DirectMusicGraph) { dwTypeID = CLASS_GRAPH; } else if(clsid == CLSID_DirectMusicSysExTrack) { dwTypeID = CLASS_SYSEXTRACK; } else if(clsid == CLSID_DirectMusicTempoTrack) { dwTypeID = CLASS_TEMPOTRACK; } else if(clsid == CLSID_DirectMusicTimeSigTrack) { dwTypeID = CLASS_TIMESIGTRACK; } else if(clsid == CLSID_DirectMusicMarkerTrack) { dwTypeID = CLASS_MARKERTRACK; } else if(clsid == CLSID_DirectMusicWaveTrack) { dwTypeID = CLASS_WAVETRACK; } else if(clsid == CLSID_DirectMusicSegmentTriggerTrack) { dwTypeID = CLASS_TRIGGERTRACK; } else if(clsid == CLSID_DirectMusicLyricsTrack) { dwTypeID = CLASS_LYRICSTRACK; } else if(clsid == CLSID_DirectMusicParamControlTrack) { dwTypeID = CLASS_PARAMSTRACK; } else if(clsid == CLSID_DirectMusicSegmentState) { dwTypeID = CLASS_SEGSTATE; } else { return CLASS_E_CLASSNOTAVAILABLE; } pIUnknown = static_cast<IUnknown*> (new CClassFactory(dwTypeID)); if(pIUnknown) { HRESULT hr = pIUnknown->QueryInterface(iid, ppv); pIUnknown->Release(); return hr; } return E_OUTOFMEMORY; }
//////////////////////////////////////////////////////////////////////
// DllUnregisterServer
STDAPI DllUnregisterServer() { UnregisterServer(CLSID_DirectMusicPerformance, g_szDMPerformanceFriendlyName, g_szDMPerformanceVerIndProgID, g_szDMPerformanceProgID);
UnregisterServer(CLSID_DirectMusicSegment, g_szDMSegmentFriendlyName, g_szDMSegmentVerIndProgID, g_szDMSegmentProgID);
UnregisterServer(CLSID_DirectMusicSegmentState, g_szDMSegmentStateFriendlyName, g_szDMSegmentStateVerIndProgID, g_szDMSegmentStateProgID);
UnregisterServer(CLSID_DirectMusicSong, g_szSongFriendlyName, g_szSongVerIndProgID, g_szSongProgID);
UnregisterServer(CLSID_DirectMusicAudioPathConfig, g_szAudioPathFriendlyName, g_szAudioPathVerIndProgID, g_szAudioPathProgID); UnregisterServer(CLSID_DirectMusicGraph, g_szDMGraphFriendlyName, g_szDMGraphVerIndProgID, g_szDMGraphProgID);
UnregisterServer(CLSID_DirectMusicSeqTrack, g_szDMSeqTrackFriendlyName, g_szDMSeqTrackVerIndProgID, g_szDMSeqTrackProgID);
UnregisterServer(CLSID_DirectMusicSysExTrack, g_szDMSysExTrackFriendlyName, g_szDMSysExTrackVerIndProgID, g_szDMSysExTrackProgID);
UnregisterServer(CLSID_DirectMusicTempoTrack, g_szDMTempoTrackFriendlyName, g_szDMTempoTrackVerIndProgID, g_szDMTempoTrackProgID);
UnregisterServer(CLSID_DirectMusicTimeSigTrack, g_szDMTimeSigTrackFriendlyName, g_szDMTimeSigTrackVerIndProgID, g_szDMTimeSigTrackProgID);
UnregisterServer(CLSID_DirectMusicMarkerTrack, g_szMarkerTrackFriendlyName, g_szMarkerTrackVerIndProgID, g_szMarkerTrackProgID);
UnregisterServer(CLSID_DirectMusicWaveTrack, g_szWaveTrackFriendlyName, g_szWaveTrackVerIndProgID, g_szWaveTrackProgID);
UnregisterServer(CLSID_DirectMusicSegmentTriggerTrack, g_szSegTriggerTrackFriendlyName, g_szSegTriggerTrackVerIndProgID, g_szSegTriggerTrackProgID);
UnregisterServer(CLSID_DirectMusicLyricsTrack, g_szLyricsTrackFriendlyName, g_szLyricsTrackVerIndProgID, g_szLyricsTrackProgID);
UnregisterServer(CLSID_DirectMusicParamControlTrack, g_szParamControlTrackFriendlyName, g_szParamControlTrackVerIndProgID, g_szParamControlTrackProgID);
return S_OK; }
//////////////////////////////////////////////////////////////////////
// DllRegisterServer
STDAPI DllRegisterServer() { RegisterServer(g_hModule, CLSID_DirectMusicPerformance, g_szDMPerformanceFriendlyName, g_szDMPerformanceVerIndProgID, g_szDMPerformanceProgID);
RegisterServer(g_hModule, CLSID_DirectMusicSegment, g_szDMSegmentFriendlyName, g_szDMSegmentVerIndProgID, g_szDMSegmentProgID);
RegisterServer(g_hModule, CLSID_DirectMusicSegmentState, g_szDMSegmentStateFriendlyName, g_szDMSegmentStateVerIndProgID, g_szDMSegmentStateProgID);
RegisterServer(g_hModule, CLSID_DirectMusicSong, g_szSongFriendlyName, g_szSongVerIndProgID, g_szSongProgID);
RegisterServer(g_hModule, CLSID_DirectMusicAudioPathConfig, g_szAudioPathFriendlyName, g_szAudioPathVerIndProgID, g_szAudioPathProgID);
RegisterServer(g_hModule, CLSID_DirectMusicGraph, g_szDMGraphFriendlyName, g_szDMGraphVerIndProgID, g_szDMGraphProgID);
RegisterServer(g_hModule, CLSID_DirectMusicSeqTrack, g_szDMSeqTrackFriendlyName, g_szDMSeqTrackVerIndProgID, g_szDMSeqTrackProgID);
RegisterServer(g_hModule, CLSID_DirectMusicSysExTrack, g_szDMSysExTrackFriendlyName, g_szDMSysExTrackVerIndProgID, g_szDMSysExTrackProgID);
RegisterServer(g_hModule, CLSID_DirectMusicTempoTrack, g_szDMTempoTrackFriendlyName, g_szDMTempoTrackVerIndProgID, g_szDMTempoTrackProgID);
RegisterServer(g_hModule, CLSID_DirectMusicTimeSigTrack, g_szDMTimeSigTrackFriendlyName, g_szDMTimeSigTrackVerIndProgID, g_szDMTimeSigTrackProgID); RegisterServer(g_hModule, CLSID_DirectMusicMarkerTrack, g_szMarkerTrackFriendlyName, g_szMarkerTrackVerIndProgID, g_szMarkerTrackProgID); RegisterServer(g_hModule, CLSID_DirectMusicWaveTrack, g_szWaveTrackFriendlyName, g_szWaveTrackVerIndProgID, g_szWaveTrackProgID); RegisterServer(g_hModule, CLSID_DirectMusicSegmentTriggerTrack, g_szSegTriggerTrackFriendlyName, g_szSegTriggerTrackVerIndProgID, g_szSegTriggerTrackProgID); RegisterServer(g_hModule, CLSID_DirectMusicLyricsTrack, g_szLyricsTrackFriendlyName, g_szLyricsTrackVerIndProgID, g_szLyricsTrackProgID); RegisterServer(g_hModule, CLSID_DirectMusicParamControlTrack, g_szParamControlTrackFriendlyName, g_szParamControlTrackVerIndProgID, g_szParamControlTrackProgID); return S_OK; }
//////////////////////////////////////////////////////////////////////
// Standard Win32 DllMain
//////////////////////////////////////////////////////////////////////
// DllMain
#ifdef DBG
static char* aszReasons[] = { "DLL_PROCESS_DETACH", "DLL_PROCESS_ATTACH", "DLL_THREAD_ATTACH", "DLL_THREAD_DETACH" }; const DWORD nReasons = (sizeof(aszReasons) / sizeof(char*)); #endif
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, void *lpReserved) { static int nReferenceCount = 0;
#ifdef DBG
if (dwReason < nReasons) { TraceI(0, "DllMain: %s\n", (LPSTR)aszReasons[dwReason]); } else { TraceI(0, "DllMain: Unknown dwReason <%u>\n", dwReason); } #endif
switch(dwReason) { case DLL_PROCESS_ATTACH: if (++nReferenceCount == 1) { g_fInitCS = false; try { InitializeCriticalSection(&g_CritSec); InitializeCriticalSection(&WaveItem::st_WaveListCritSect); } catch( ... ) { TraceI(0, "InitializeCriticalSection failed.\n"); return FALSE; } g_fInitCS = true;
#ifdef DBG
DebugInit(); #endif
if (!DisableThreadLibraryCalls(hModule)) { TraceI(1, "DisableThreadLibraryCalls failed.\n"); }
g_hModule = hModule; } break;
case DLL_PROCESS_DETACH: if (--nReferenceCount == 0) { TraceI(-1, "Unloading g_cLock %d g_cComponent %d\n", g_cLock, g_cComponent); if (g_fInitCS) { DeleteCriticalSection(&g_CritSec); DeleteCriticalSection(&WaveItem::st_WaveListCritSect); }
// Assert if we still have some objects hanging around
assert(g_cComponent == 0); assert(g_cLock == 0); } break; } return TRUE; }
|