123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- //------------------------------------------------------------------------------
- // 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;
- }
- */
|