414 lines
8.5 KiB
C++
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;
|
||
|
}
|