strmbase: Implement STRMBASE_DllGetClassObject and STRMBASE_DllCanUnloadNow.
diff --git a/dlls/strmbase/dllfunc.c b/dlls/strmbase/dllfunc.c
index c24ec97..35e373f 100644
--- a/dlls/strmbase/dllfunc.c
+++ b/dlls/strmbase/dllfunc.c
@@ -46,6 +46,7 @@
 extern const FactoryTemplate g_Templates[];
 
 static HINSTANCE g_hInst = NULL;
+static LONG server_locks = 0;
 
 /*
  * defines and constants
@@ -233,3 +234,163 @@
     }
     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;
+}