diff --git a/dlls/qcap/qcap.spec b/dlls/qcap/qcap.spec index b16365d0c9f..6bdfdf6e9eb 100644 --- a/dlls/qcap/qcap.spec +++ b/dlls/qcap/qcap.spec @@ -1,4 +1,4 @@ @ stdcall -private DllCanUnloadNow() -@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr) STRMBASE_DllGetClassObject @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c index fdfc2149062..422eee7f60e 100644 --- a/dlls/qcap/qcap_main.c +++ b/dlls/qcap/qcap_main.c @@ -44,7 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(qcap); static LONG objects_ref = 0; -static LONG server_locks = 0; static const WCHAR wAudioCaptFilter[] = {'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0}; @@ -181,157 +180,9 @@ HRESULT WINAPI DllCanUnloadNow(void) { TRACE("\n"); - if (objects_ref == 0 && server_locks == 0) + if (STRMBASE_DllCanUnloadNow() && objects_ref == 0) return S_OK; - return S_FALSE; -} - -/****************************************************************************** - * DLL ClassFactory - */ -typedef struct { - IClassFactory ITF_IClassFactory; - - LONG ref; - LPFNNewCOMObject pfnCreateInstance; -} IClassFactoryImpl; - -static HRESULT WINAPI -DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) -{ - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IClassFactory)) - { - IClassFactory_AddRef(iface); - *ppobj = This; - return S_OK; - } - - WARN("(%p)->(%s,%p), not found\n", This, debugstr_guid(riid), ppobj); - return E_NOINTERFACE; -} - -static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface) -{ - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface) -{ - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - - ULONG ref = InterlockedDecrement(&This->ref); - - if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); - - return ref; -} - -static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, - REFIID riid, LPVOID *ppobj) -{ - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - HRESULT hres = ERROR_SUCCESS; - LPUNKNOWN punk; - - TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj); - - if (!ppobj) - return E_POINTER; - - /* Enforce the normal OLE rules regarding interfaces and delegation */ - if (pOuter && !IsEqualGUID(riid, &IID_IUnknown)) - return E_NOINTERFACE; - - *ppobj = NULL; - punk = This->pfnCreateInstance(pOuter, &hres); - if (!punk) - { - /* No object created, update error if it isn't done already and return */ - if (SUCCEEDED(hres)) - hres = E_OUTOFMEMORY; - return hres; - } - - if (SUCCEEDED(hres)) - { - hres = IUnknown_QueryInterface(punk, riid, ppobj); - } - /* Releasing the object. If everything was successful, QueryInterface - should have incremented the refcount once more, otherwise this will - purge the object. */ - IUnknown_Release(punk); - return hres; -} - -static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) -{ - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - TRACE("(%p)->(%d)\n",This, dolock); - - if (dolock) - InterlockedIncrement(&server_locks); - else - InterlockedDecrement(&server_locks); - return S_OK; -} - -static const IClassFactoryVtbl DSCF_Vtbl = -{ - DSCF_QueryInterface, - DSCF_AddRef, - DSCF_Release, - DSCF_CreateInstance, - DSCF_LockServer -}; - -/*********************************************************************** - * DllGetClassObject (QCAP.@) - */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) -{ - const FactoryTemplate *pList = g_Templates; - IClassFactoryImpl *factory; - int i; - - TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); - - if (!ppv) - return E_POINTER; - - *ppv = NULL; - - if (!IsEqualGUID(&IID_IClassFactory, riid) && - !IsEqualGUID(&IID_IUnknown, riid)) - return E_NOINTERFACE; - - for (i = 0; i < g_cTemplates; i++, pList++) - { - if (IsEqualGUID(pList->m_ClsID, rclsid)) - break; - } - - if (i == g_cTemplates) - { - FIXME("%s: no class found.\n", debugstr_guid(rclsid)); - return CLASS_E_CLASSNOTAVAILABLE; - } - - factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl)); - if (!factory) - return E_OUTOFMEMORY; - - factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl; - factory->ref = 1; - - factory->pfnCreateInstance = pList->m_lpfnNew; - - *ppv = &(factory->ITF_IClassFactory); - return S_OK; + return S_FALSE; } DWORD ObjectRefCount(BOOL increment) diff --git a/dlls/strmbase/dllfunc.c b/dlls/strmbase/dllfunc.c index c24ec97e7bc..35e373fc9cf 100644 --- a/dlls/strmbase/dllfunc.c +++ b/dlls/strmbase/dllfunc.c @@ -46,6 +46,7 @@ extern const int g_cTemplates; extern const FactoryTemplate g_Templates[]; static HINSTANCE g_hInst = NULL; +static LONG server_locks = 0; /* * defines and constants @@ -233,3 +234,163 @@ BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) } return TRUE; } + +/****************************************************************************** + * DLL ClassFactory + */ +typedef struct { + IClassFactory ITF_IClassFactory; + + LONG ref; + LPFNNewCOMObject pfnCreateInstance; +} IClassFactoryImpl; + +static HRESULT WINAPI +DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef(iface); + *ppobj = This; + return S_OK; + } + + WARN("(%p)->(%s,%p), not found\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + ULONG ref = InterlockedDecrement(&This->ref); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, + REFIID riid, LPVOID *ppobj) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + HRESULT hres = ERROR_SUCCESS; + LPUNKNOWN punk; + + TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj); + + if (!ppobj) + return E_POINTER; + + /* Enforce the normal OLE rules regarding interfaces and delegation */ + if (pOuter && !IsEqualGUID(riid, &IID_IUnknown)) + return E_NOINTERFACE; + + *ppobj = NULL; + punk = This->pfnCreateInstance(pOuter, &hres); + if (!punk) + { + /* No object created, update error if it isn't done already and return */ + if (SUCCEEDED(hres)) + hres = E_OUTOFMEMORY; + return hres; + } + + if (SUCCEEDED(hres)) + { + hres = IUnknown_QueryInterface(punk, riid, ppobj); + } + /* Releasing the object. If everything was successful, QueryInterface + should have incremented the refcount once more, otherwise this will + purge the object. */ + IUnknown_Release(punk); + return hres; +} + +static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + TRACE("(%p)->(%d)\n",This, dolock); + + if (dolock) + InterlockedIncrement(&server_locks); + else + InterlockedDecrement(&server_locks); + return S_OK; +} + +static const IClassFactoryVtbl DSCF_Vtbl = +{ + DSCF_QueryInterface, + DSCF_AddRef, + DSCF_Release, + DSCF_CreateInstance, + DSCF_LockServer +}; + +/*********************************************************************** + * DllGetClassObject + */ +HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + const FactoryTemplate *pList = g_Templates; + IClassFactoryImpl *factory; + int i; + + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + + if (!ppv) + return E_POINTER; + + *ppv = NULL; + + if (!IsEqualGUID(&IID_IClassFactory, riid) && + !IsEqualGUID(&IID_IUnknown, riid)) + return E_NOINTERFACE; + + for (i = 0; i < g_cTemplates; i++, pList++) + { + if (IsEqualGUID(pList->m_ClsID, rclsid)) + break; + } + + if (i == g_cTemplates) + { + FIXME("%s: no class found.\n", debugstr_guid(rclsid)); + return CLASS_E_CLASSNOTAVAILABLE; + } + + factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl)); + if (!factory) + return E_OUTOFMEMORY; + + factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl; + factory->ref = 1; + + factory->pfnCreateInstance = pList->m_lpfnNew; + + *ppv = &(factory->ITF_IClassFactory); + return S_OK; +} + +/*********************************************************************** + * DllCanUnloadNow + */ +HRESULT WINAPI STRMBASE_DllCanUnloadNow(void) +{ + TRACE("\n"); + + if (server_locks == 0) + return S_OK; + return S_FALSE; +} diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 581643ef851..07913fec555 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -315,3 +315,5 @@ HRESULT WINAPI AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER const * pFil /* Dll Functions */ BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv); +HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv); +HRESULT WINAPI STRMBASE_DllCanUnloadNow(void);