windows-nt/Source/XPSP1/NT/multimedia/directx/dmusic/dmloader/dll.cpp
2020-09-26 16:20:57 +08:00

414 lines
8.5 KiB
C++

// Copyright (c) 1998-1999 Microsoft Corporation
// loader dll.cpp
//
// Dll entry points and CLoaderFactory, CContainerFactory implementation
//
// 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 "debug.h"
#include "oledll.h"
#include "debug.h"
#include "dmusicc.h"
#include "dmusici.h"
#include "loader.h"
#include "container.h"
#ifndef UNDER_CE
#include <regstr.h>
#endif
// Globals
//
// Version information for our class
//
TCHAR g_szFriendlyName[] = TEXT("DirectMusicLoader");
TCHAR g_szVerIndProgID[] = TEXT("Microsoft.DirectMusicLoader");
TCHAR g_szProgID[] = TEXT("Microsoft.DirectMusicLoader.1");
TCHAR g_szContFriendlyName[] = TEXT("DirectMusicContainer");
TCHAR g_szContVerIndProgID[] = TEXT("Microsoft.DirectMusicContainer");
TCHAR g_szContProgID[] = TEXT("Microsoft.DirectMusicContainer.1");
// Dll's hModule
//
HMODULE g_hModule = NULL;
#ifndef UNDER_CE
// Track whether running on Unicode machine.
BOOL g_fIsUnicode = FALSE;
#endif
// Count of active components and class factory server locks
//
long g_cComponent = 0;
long g_cLock = 0;
// CLoaderFactory::QueryInterface
//
HRESULT __stdcall
CLoaderFactory::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;
}
CLoaderFactory::CLoaderFactory()
{
m_cRef = 1;
InterlockedIncrement(&g_cLock);
}
CLoaderFactory::~CLoaderFactory()
{
InterlockedDecrement(&g_cLock);
}
// CLoaderFactory::AddRef
//
ULONG __stdcall
CLoaderFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
// CLoaderFactory::Release
//
ULONG __stdcall
CLoaderFactory::Release()
{
if (!InterlockedDecrement(&m_cRef)) {
delete this;
return 0;
}
return m_cRef;
}
// CLoaderFactory::CreateInstance
//
//
HRESULT __stdcall
CLoaderFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv)
{
HRESULT hr;
if (pUnknownOuter) {
return CLASS_E_NOAGGREGATION;
}
CLoader *pLoader;
try
{
pLoader = new CLoader;
}
catch( ... )
{
return E_OUTOFMEMORY;
}
if (pLoader == NULL) {
return E_OUTOFMEMORY;
}
// Do initialiazation
//
hr = pLoader->Init();
if (!SUCCEEDED(hr)) {
delete pLoader;
return hr;
}
hr = pLoader->QueryInterface(iid, ppv);
pLoader->Release();
return hr;
}
// CLoaderFactory::LockServer
//
HRESULT __stdcall
CLoaderFactory::LockServer(BOOL bLock)
{
if (bLock) {
InterlockedIncrement(&g_cLock);
} else {
InterlockedDecrement(&g_cLock);
}
return S_OK;
}
// CContainerFactory::QueryInterface
//
HRESULT __stdcall
CContainerFactory::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;
}
CContainerFactory::CContainerFactory()
{
m_cRef = 1;
InterlockedIncrement(&g_cLock);
}
CContainerFactory::~CContainerFactory()
{
InterlockedDecrement(&g_cLock);
}
// CContainerFactory::AddRef
//
ULONG __stdcall
CContainerFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
// CContainerFactory::Release
//
ULONG __stdcall
CContainerFactory::Release()
{
if (!InterlockedDecrement(&m_cRef)) {
delete this;
return 0;
}
return m_cRef;
}
// CContainerFactory::CreateInstance
//
//
HRESULT __stdcall
CContainerFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv)
{
HRESULT hr;
if (pUnknownOuter) {
return CLASS_E_NOAGGREGATION;
}
CContainer *pContainer;
try
{
pContainer = new CContainer;
}
catch( ... )
{
return E_OUTOFMEMORY;
}
if (pContainer == NULL) {
return E_OUTOFMEMORY;
}
hr = pContainer->QueryInterface(iid, ppv);
pContainer->Release();
return hr;
}
// CContainerFactory::LockServer
//
HRESULT __stdcall
CContainerFactory::LockServer(BOOL bLock)
{
if (bLock) {
InterlockedIncrement(&g_cLock);
} else {
InterlockedDecrement(&g_cLock);
}
return S_OK;
}
// Standard calls needed to be an inproc server
//
STDAPI DllCanUnloadNow()
{
if (g_cComponent || g_cLock) {
return S_FALSE;
}
return S_OK;
}
STDAPI DllGetClassObject(const CLSID& clsid,
const IID& iid,
void** ppv)
{
IUnknown* pIUnknown = NULL;
if(clsid == CLSID_DirectMusicLoader)
{
pIUnknown = static_cast<IUnknown*> (new CLoaderFactory);
if(!pIUnknown)
{
return E_OUTOFMEMORY;
}
}
else if(clsid == CLSID_DirectMusicContainer)
{
pIUnknown = static_cast<IUnknown*> (new CContainerFactory);
if(!pIUnknown)
{
return E_OUTOFMEMORY;
}
}
else
{
return CLASS_E_CLASSNOTAVAILABLE;
}
HRESULT hr = pIUnknown->QueryInterface(iid, ppv);
pIUnknown->Release();
return hr;
}
STDAPI DllUnregisterServer()
{
UnregisterServer(CLSID_DirectMusicLoader,
g_szFriendlyName,
g_szVerIndProgID,
g_szProgID);
UnregisterServer(CLSID_DirectMusicContainer,
g_szContFriendlyName,
g_szContVerIndProgID,
g_szContProgID);
return S_OK;
}
STDAPI DllRegisterServer()
{
RegisterServer(g_hModule,
CLSID_DirectMusicLoader,
g_szFriendlyName,
g_szVerIndProgID,
g_szProgID);
RegisterServer(g_hModule,
CLSID_DirectMusicContainer,
g_szContFriendlyName,
g_szContVerIndProgID,
g_szContProgID);
return S_OK;
}
extern void DebugInit();
// Standard Win32 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)
{
DebugTrace(0, "DllMain: %s\n", (LPSTR)aszReasons[dwReason]);
}
else
{
DebugTrace(0, "DllMain: Unknown dwReason <%u>\n", dwReason);
}
#endif
if (dwReason == DLL_PROCESS_ATTACH) {
if (++nReferenceCount == 1)
{
g_hModule = (HMODULE)hModule;
#ifndef UNDER_CE
OSVERSIONINFO osvi;
DisableThreadLibraryCalls(hModule);
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
g_fIsUnicode =
(osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS);
#endif
#ifdef DBG
DebugInit();
#endif
}
}
#ifdef DBG
else if(dwReason == DLL_PROCESS_DETACH) {
if (--nReferenceCount == 0)
{
TraceI(-1, "Unloading DMLoader : g_cLock = %d, g_cComponent = %d", g_cLock, g_cComponent);
// Assert if we still have some objects hanging around
assert(g_cComponent == 0);
assert(g_cLock == 0);
}
}
#endif
return TRUE;
}