Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
373
Src/Plugins/Input/in_dshow/base/dllentry.cpp
Normal file
373
Src/Plugins/Input/in_dshow/base/dllentry.cpp
Normal file
|
@ -0,0 +1,373 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// File: DlleEntry.cpp
|
||||
//
|
||||
// Desc: DirectShow base classes - implements classes used to support dll
|
||||
// entry points for COM objects.
|
||||
//
|
||||
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <streams.h>
|
||||
#include <initguid.h>
|
||||
#include "combase.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef UNICODE
|
||||
#ifndef _UNICODE
|
||||
#define _UNICODE
|
||||
#endif // _UNICODE
|
||||
#endif // UNICODE
|
||||
|
||||
#include <tchar.h>
|
||||
#endif // DEBUG
|
||||
#include <strsafe.h>
|
||||
|
||||
|
||||
//extern int g_cTemplates;
|
||||
//extern CFactoryTemplate g_Templates[];
|
||||
|
||||
HINSTANCE g_hInst;
|
||||
DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
|
||||
OSVERSIONINFO g_osInfo;
|
||||
|
||||
//
|
||||
// an instance of this is created by the DLLGetClassObject entrypoint
|
||||
// it uses the CFactoryTemplate object it is given to support the
|
||||
// IClassFactory interface
|
||||
|
||||
class CClassFactory : public IClassFactory, public CBaseObject
|
||||
{
|
||||
|
||||
private:
|
||||
const CFactoryTemplate *const m_pTemplate;
|
||||
|
||||
ULONG m_cRef;
|
||||
|
||||
static int m_cLocked;
|
||||
public:
|
||||
CClassFactory(const CFactoryTemplate *);
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(REFIID riid, __deref_out void ** ppv);
|
||||
STDMETHODIMP_(ULONG)AddRef();
|
||||
STDMETHODIMP_(ULONG)Release();
|
||||
|
||||
// IClassFactory
|
||||
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, __deref_out void **pv);
|
||||
STDMETHODIMP LockServer(BOOL fLock);
|
||||
|
||||
// allow DLLGetClassObject to know about global server lock status
|
||||
static BOOL IsLocked() {
|
||||
return (m_cLocked > 0);
|
||||
};
|
||||
};
|
||||
|
||||
// process-wide dll locked state
|
||||
int CClassFactory::m_cLocked = 0;
|
||||
|
||||
CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate)
|
||||
: CBaseObject(NAME("Class Factory"))
|
||||
, m_cRef(0)
|
||||
, m_pTemplate(pTemplate)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP
|
||||
CClassFactory::QueryInterface(REFIID riid,__deref_out void **ppv)
|
||||
{
|
||||
CheckPointer(ppv,E_POINTER)
|
||||
ValidateReadWritePtr(ppv,sizeof(PVOID));
|
||||
*ppv = NULL;
|
||||
|
||||
// any interface on this object is the object pointer.
|
||||
if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) {
|
||||
*ppv = (LPVOID) this;
|
||||
// AddRef returned interface pointer
|
||||
((LPUNKNOWN) *ppv)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
return ResultFromScode(E_NOINTERFACE);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP_(ULONG)
|
||||
CClassFactory::AddRef()
|
||||
{
|
||||
return ++m_cRef;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG)
|
||||
CClassFactory::Release()
|
||||
{
|
||||
LONG lRef = InterlockedDecrement((volatile LONG *)&m_cRef);
|
||||
if (lRef == 0) {
|
||||
delete this;
|
||||
return 0;
|
||||
} else {
|
||||
return lRef;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CClassFactory::CreateInstance(
|
||||
LPUNKNOWN pUnkOuter,
|
||||
REFIID riid,
|
||||
__deref_out void **pv)
|
||||
{
|
||||
CheckPointer(pv,E_POINTER)
|
||||
ValidateReadWritePtr(pv,sizeof(void *));
|
||||
*pv = NULL;
|
||||
|
||||
/* Enforce the normal OLE rules regarding interfaces and delegation */
|
||||
|
||||
if (pUnkOuter != NULL) {
|
||||
if (IsEqualIID(riid,IID_IUnknown) == FALSE) {
|
||||
*pv = NULL;
|
||||
return ResultFromScode(E_NOINTERFACE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the new object through the derived class's create function */
|
||||
|
||||
HRESULT hr = NOERROR;
|
||||
CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr);
|
||||
|
||||
if (pObj == NULL) {
|
||||
*pv = NULL;
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* Delete the object if we got a construction error */
|
||||
|
||||
if (FAILED(hr)) {
|
||||
delete pObj;
|
||||
*pv = NULL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* Get a reference counted interface on the object */
|
||||
|
||||
/* We wrap the non-delegating QI with NDAddRef & NDRelease. */
|
||||
/* This protects any outer object from being prematurely */
|
||||
/* released by an inner object that may have to be created */
|
||||
/* in order to supply the requested interface. */
|
||||
pObj->NonDelegatingAddRef();
|
||||
hr = pObj->NonDelegatingQueryInterface(riid, pv);
|
||||
pObj->NonDelegatingRelease();
|
||||
/* Note that if NonDelegatingQueryInterface fails, it will */
|
||||
/* not increment the ref count, so the NonDelegatingRelease */
|
||||
/* will drop the ref back to zero and the object will "self-*/
|
||||
/* destruct". Hence we don't need additional tidy-up code */
|
||||
/* to cope with NonDelegatingQueryInterface failing. */
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
ASSERT(*pv);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP
|
||||
CClassFactory::LockServer(BOOL fLock)
|
||||
{
|
||||
if (fLock) {
|
||||
m_cLocked++;
|
||||
} else {
|
||||
m_cLocked--;
|
||||
}
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
// --- COM entrypoints -----------------------------------------
|
||||
|
||||
//called by COM to get the class factory object for a given class
|
||||
/*
|
||||
__control_entrypoint(DllExport) STDAPI
|
||||
DllGetClassObject(
|
||||
__in REFCLSID rClsID,
|
||||
__in REFIID riid,
|
||||
__deref_out void **pv)
|
||||
{
|
||||
*pv = NULL;
|
||||
if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// traverse the array of templates looking for one with this
|
||||
// class id
|
||||
for (int i = 0; i < g_cTemplates; i++) {
|
||||
const CFactoryTemplate * pT = &g_Templates[i];
|
||||
if (pT->IsClassID(rClsID)) {
|
||||
|
||||
// found a template - make a class factory based on this
|
||||
// template
|
||||
|
||||
*pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT);
|
||||
if (*pv == NULL) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
((LPUNKNOWN)*pv)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
}
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
// Call any initialization routines
|
||||
//
|
||||
/*
|
||||
void
|
||||
DllInitClasses(BOOL bLoading)
|
||||
{
|
||||
int i;
|
||||
|
||||
// traverse the array of templates calling the init routine
|
||||
// if they have one
|
||||
for (i = 0; i < g_cTemplates; i++) {
|
||||
const CFactoryTemplate * pT = &g_Templates[i];
|
||||
if (pT->m_lpfnInit != NULL) {
|
||||
(*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
// called by COM to determine if this dll can be unloaded
|
||||
// return ok unless there are outstanding objects or a lock requested
|
||||
// by IClassFactory::LockServer
|
||||
//
|
||||
// CClassFactory has a static function that can tell us about the locks,
|
||||
// and CCOMObject has a static function that can tell us about the active
|
||||
// object count
|
||||
STDAPI
|
||||
DllCanUnloadNow()
|
||||
{
|
||||
DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"),
|
||||
CClassFactory::IsLocked(),
|
||||
CBaseObject::ObjectsActive()));
|
||||
|
||||
if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) {
|
||||
return S_FALSE;
|
||||
} else {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- standard WIN32 entrypoints --------------------------------------
|
||||
/*
|
||||
|
||||
extern "C" void __cdecl __security_init_cookie(void);
|
||||
extern "C" BOOL WINAPI _DllEntryPoint(HINSTANCE, ULONG, __inout_opt LPVOID);
|
||||
#pragma comment(linker, "/merge:.CRT=.rdata")
|
||||
|
||||
extern "C"
|
||||
DECLSPEC_NOINLINE
|
||||
BOOL
|
||||
WINAPI
|
||||
DllEntryPoint(
|
||||
HINSTANCE hInstance,
|
||||
ULONG ulReason,
|
||||
__inout_opt LPVOID pv
|
||||
)
|
||||
{
|
||||
if ( ulReason == DLL_PROCESS_ATTACH ) {
|
||||
// Must happen before any other code is executed. Thankfully - it's re-entrant
|
||||
__security_init_cookie();
|
||||
}
|
||||
return _DllEntryPoint(hInstance, ulReason, pv);
|
||||
}
|
||||
|
||||
|
||||
DECLSPEC_NOINLINE
|
||||
BOOL
|
||||
WINAPI
|
||||
_DllEntryPoint(
|
||||
HINSTANCE hInstance,
|
||||
ULONG ulReason,
|
||||
__inout_opt LPVOID pv
|
||||
)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
extern bool g_fDbgInDllEntryPoint;
|
||||
g_fDbgInDllEntryPoint = true;
|
||||
#endif
|
||||
|
||||
switch (ulReason)
|
||||
{
|
||||
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstance);
|
||||
DbgInitialise(hInstance);
|
||||
|
||||
{
|
||||
// The platform identifier is used to work out whether
|
||||
// full unicode support is available or not. Hence the
|
||||
// default will be the lowest common denominator - i.e. N/A
|
||||
g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
|
||||
|
||||
g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo);
|
||||
if (GetVersionEx(&g_osInfo)) {
|
||||
g_amPlatform = g_osInfo.dwPlatformId;
|
||||
} else {
|
||||
DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95")));
|
||||
}
|
||||
}
|
||||
|
||||
g_hInst = hInstance;
|
||||
DllInitClasses(TRUE);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
DllInitClasses(FALSE);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (CBaseObject::ObjectsActive()) {
|
||||
DbgSetModuleLevel(LOG_MEMORY, 2);
|
||||
TCHAR szInfo[512];
|
||||
extern TCHAR m_ModuleName[]; // Cut down module name
|
||||
|
||||
TCHAR FullName[_MAX_PATH]; // Load the full path and module name
|
||||
TCHAR *pName; // Searches from the end for a backslash
|
||||
|
||||
GetModuleFileName(NULL,FullName,_MAX_PATH);
|
||||
pName = _tcsrchr(FullName,'\\');
|
||||
if (pName == NULL) {
|
||||
pName = FullName;
|
||||
} else {
|
||||
pName++;
|
||||
}
|
||||
|
||||
(void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("Executable: %s Pid %x Tid %x. "),
|
||||
pName, GetCurrentProcessId(), GetCurrentThreadId());
|
||||
|
||||
(void)StringCchPrintf(szInfo+lstrlen(szInfo), NUMELMS(szInfo) - lstrlen(szInfo), TEXT("Module %s, %d objects left active!"),
|
||||
m_ModuleName, CBaseObject::ObjectsActive());
|
||||
DbgAssert(szInfo, TEXT(__FILE__),__LINE__);
|
||||
|
||||
// If running remotely wait for the Assert to be acknowledged
|
||||
// before dumping out the object register
|
||||
DbgDumpObjectRegister();
|
||||
}
|
||||
DbgTerminate();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
g_fDbgInDllEntryPoint = false;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue