[PATCH v2 2/5] qcap: Reimplement COM registration and vending locally.
Zebediah Figura
z.figura12 at gmail.com
Sun Mar 8 14:05:08 CDT 2020
From: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
v2: Fix copy-paste error, thanks Chip.
dlls/qcap/Makefile.in | 4 +-
dlls/qcap/audiorecord.c | 24 ++-
dlls/qcap/avico.c | 25 ++-
dlls/qcap/avimux.c | 17 +-
dlls/qcap/capturegraph.c | 40 ++---
dlls/qcap/qcap_classes.idl | 71 ++++++++
dlls/qcap/qcap_main.c | 321 +++++++++++++++++++++++--------------
dlls/qcap/qcap_main.h | 19 +--
dlls/qcap/smartteefilter.c | 16 +-
dlls/qcap/vfwcapture.c | 11 +-
10 files changed, 341 insertions(+), 207 deletions(-)
create mode 100644 dlls/qcap/qcap_classes.idl
diff --git a/dlls/qcap/Makefile.in b/dlls/qcap/Makefile.in
index d10075aea08..981a0dc3f39 100644
--- a/dlls/qcap/Makefile.in
+++ b/dlls/qcap/Makefile.in
@@ -8,7 +8,6 @@ C_SRCS = \
avico.c \
avimux.c \
capturegraph.c \
- dllfunc.c \
filter.c \
mediatype.c \
pin.c \
@@ -18,3 +17,6 @@ C_SRCS = \
vfwcapture.c
RC_SRCS = version.rc
+
+IDL_SRCS = \
+ qcap_classes.idl
diff --git a/dlls/qcap/audiorecord.c b/dlls/qcap/audiorecord.c
index 3c15734e894..48be64b63f5 100644
--- a/dlls/qcap/audiorecord.c
+++ b/dlls/qcap/audiorecord.c
@@ -154,22 +154,18 @@ static const IPersistPropertyBagVtbl PersistPropertyBagVtbl =
PPB_Save
};
-IUnknown* WINAPI QCAP_createAudioCaptureFilter(IUnknown *outer, HRESULT *phr)
+HRESULT audio_record_create(IUnknown *outer, IUnknown **out)
{
- AudioRecord *This = NULL;
+ AudioRecord *object;
- FIXME("(%p, %p): the entire CLSID_AudioRecord implementation is just stubs\n", outer, phr);
+ if (!(object = CoTaskMemAlloc(sizeof(*object))))
+ return E_OUTOFMEMORY;
+ memset(object, 0, sizeof(*object));
- This = CoTaskMemAlloc(sizeof(*This));
- if (This == NULL) {
- *phr = E_OUTOFMEMORY;
- return NULL;
- }
- memset(This, 0, sizeof(*This));
- This->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
-
- strmbase_filter_init(&This->filter, outer, &CLSID_AudioRecord, &filter_ops);
+ object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
+ strmbase_filter_init(&object->filter, outer, &CLSID_AudioRecord, &filter_ops);
- *phr = S_OK;
- return &This->filter.IUnknown_inner;
+ TRACE("Created audio recorder %p.\n", object);
+ *out = &object->filter.IUnknown_inner;
+ return S_OK;
}
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index 53b8526f449..fc5826b16fe 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -480,25 +480,22 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = AVICompressorOut_DecideAllocator,
};
-IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
+HRESULT avi_compressor_create(IUnknown *outer, IUnknown **out)
{
static const WCHAR source_name[] = {'O','u','t',0};
static const WCHAR sink_name[] = {'I','n',0};
- AVICompressor *compressor;
+ AVICompressor *object;
- compressor = heap_alloc_zero(sizeof(*compressor));
- if(!compressor) {
- *phr = E_NOINTERFACE;
- return NULL;
- }
-
- strmbase_filter_init(&compressor->filter, outer, &CLSID_AVICo, &filter_ops);
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
- compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
+ strmbase_filter_init(&object->filter, outer, &CLSID_AVICo, &filter_ops);
+ object->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
- strmbase_sink_init(&compressor->sink, &compressor->filter, sink_name, &sink_ops, NULL);
- strmbase_source_init(&compressor->source, &compressor->filter, source_name, &source_ops);
+ strmbase_sink_init(&object->sink, &object->filter, sink_name, &sink_ops, NULL);
+ strmbase_source_init(&object->source, &object->filter, source_name, &source_ops);
- *phr = S_OK;
- return &compressor->filter.IUnknown_inner;
+ TRACE("Created AVI compressor %p.\n", object);
+ *out = &object->filter.IUnknown_inner;
+ return S_OK;
}
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index 91a0b17f8e1..f1e703bfb60 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1835,7 +1835,7 @@ static HRESULT create_input_pin(AviMux *avimux)
return S_OK;
}
-IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
+HRESULT avi_mux_create(IUnknown *outer, IUnknown **out)
{
static const WCHAR output_name[] = {'A','V','I',' ','O','u','t',0};
@@ -1843,11 +1843,8 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
PIN_INFO info;
HRESULT hr;
- avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux));
- if(!avimux) {
- *phr = E_OUTOFMEMORY;
- return NULL;
- }
+ if (!(avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux))))
+ return E_OUTOFMEMORY;
strmbase_filter_init(&avimux->filter, outer, &CLSID_AviDest, &filter_ops);
avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl;
@@ -1870,13 +1867,13 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
strmbase_source_cleanup(&avimux->source);
strmbase_filter_cleanup(&avimux->filter);
HeapFree(GetProcessHeap(), 0, avimux);
- *phr = hr;
- return NULL;
+ return hr;
}
avimux->interleave = 10000000;
+ TRACE("Created AVI mux %p.\n", avimux);
ObjectRefCount(TRUE);
- *phr = S_OK;
- return &avimux->filter.IUnknown_inner;
+ *out = &avimux->filter.IUnknown_inner;
+ return S_OK;
}
diff --git a/dlls/qcap/capturegraph.c b/dlls/qcap/capturegraph.c
index 894d4f61e9c..33b0ecfaa11 100644
--- a/dlls/qcap/capturegraph.c
+++ b/dlls/qcap/capturegraph.c
@@ -74,33 +74,27 @@ static inline CaptureGraphImpl *impl_from_ICaptureGraphBuilder2(ICaptureGraphBui
}
-IUnknown * CALLBACK QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter,
- HRESULT *phr)
+HRESULT capture_graph_create(IUnknown *outer, IUnknown **out)
{
- CaptureGraphImpl * pCapture = NULL;
+ CaptureGraphImpl *object;
- TRACE("(%p, %p)\n", pUnkOuter, phr);
+ if (outer)
+ return CLASS_E_NOAGGREGATION;
- *phr = CLASS_E_NOAGGREGATION;
- if (pUnkOuter)
- {
- return NULL;
- }
- *phr = E_OUTOFMEMORY;
+ if (!(object = CoTaskMemAlloc(sizeof(*object))))
+ return E_OUTOFMEMORY;
- pCapture = CoTaskMemAlloc(sizeof(CaptureGraphImpl));
- if (pCapture)
- {
- pCapture->ICaptureGraphBuilder2_iface.lpVtbl = &builder2_Vtbl;
- pCapture->ICaptureGraphBuilder_iface.lpVtbl = &builder_Vtbl;
- pCapture->ref = 1;
- pCapture->mygraph = NULL;
- InitializeCriticalSection(&pCapture->csFilter);
- pCapture->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CaptureGraphImpl.csFilter");
- *phr = S_OK;
- ObjectRefCount(TRUE);
- }
- return (IUnknown *)&pCapture->ICaptureGraphBuilder_iface;
+ object->ICaptureGraphBuilder2_iface.lpVtbl = &builder2_Vtbl;
+ object->ICaptureGraphBuilder_iface.lpVtbl = &builder_Vtbl;
+ object->ref = 1;
+ object->mygraph = NULL;
+ InitializeCriticalSection(&object->csFilter);
+ object->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CaptureGraphImpl.csFilter");
+
+ TRACE("Created capture graph builder %p.\n", object);
+ ObjectRefCount(TRUE);
+ *out = (IUnknown *)&object->ICaptureGraphBuilder_iface;
+ return S_OK;
}
static HRESULT WINAPI
diff --git a/dlls/qcap/qcap_classes.idl b/dlls/qcap/qcap_classes.idl
new file mode 100644
index 00000000000..ac1ec9a21b9
--- /dev/null
+++ b/dlls/qcap/qcap_classes.idl
@@ -0,0 +1,71 @@
+/*
+ * COM classes for qcap
+ *
+ * Copyright 2019 Zebediah Figura
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#pragma makedep register
+
+[
+ helpstring("Audio Capture Filter"),
+ threading(both),
+ uuid(e30629d2-27e5-11ce-875d-00608cb78066)
+]
+coclass AudioRecord {}
+
+[
+ helpstring("Audio Capture Filter"),
+ threading(both),
+ uuid(d76e2820-1563-11cf-ac98-00aa004c0fa9)
+]
+coclass AVICo {}
+
+[
+ helpstring("AVI mux"),
+ threading(both),
+ uuid(e2510970-f137-11ce-8b67-00aa00a3f1a6)
+]
+coclass AviDest {}
+
+[
+ helpstring("Capture Graph Builder"),
+ threading(both),
+ uuid(bf87b6e0-8c27-11d0-b3f0-00aa003761c5)
+]
+coclass CaptureGraphBuilder {}
+
+[
+ helpstring("Capture Graph Builder 2"),
+ threading(both),
+ uuid(bf87b6e1-8c27-11d0-b3f0-00aa003761c5)
+]
+coclass CaptureGraphBuilder2 {}
+
+[
+ helpstring("Smart Tee Filter"),
+ threading(both),
+ uuid(cc58e280-8aa1-11d1-b3f1-00aa003761c5)
+]
+coclass SmartTee {}
+
+[
+ helpstring("VFW Capture Filter"),
+ threading(both),
+ uuid(1b544c22-fd0b-11ce-8c63-00aa0044b51e)
+]
+coclass VfwCapture {}
+
diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c
index c5b4931c907..05b07ecd873 100644
--- a/dlls/qcap/qcap_main.c
+++ b/dlls/qcap/qcap_main.c
@@ -1,8 +1,9 @@
/*
- * Qcap implementation, dllentry points
+ * DirectShow capture
*
* Copyright (C) 2003 Dominik Strasser
* Copyright (C) 2005 Rolf Kalbermatter
+ * Copyright (C) 2019 Zebediah Figura
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,7 +26,8 @@
#include <stdarg.h>
#define COBJMACROS
-
+#define NONAMELESSSTRUCT
+#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
@@ -33,6 +35,7 @@
#include "objbase.h"
#include "uuids.h"
#include "strmif.h"
+#include "rpcproxy.h"
#include "qcap_main.h"
@@ -41,132 +44,207 @@
WINE_DEFAULT_DEBUG_CHANNEL(qcap);
+static HINSTANCE qcap_instance;
+
static LONG objects_ref = 0;
-static const WCHAR wAudioCaptureFilter[] =
-{'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
-static const WCHAR wAVICompressor[] =
-{'A','V','I',' ','C','o','m','p','r','e','s','s','o','r',0};
-static const WCHAR wVFWCaptFilter[] =
-{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',0};
-static const WCHAR wVFWCaptFilterProp[] =
-{'V','F','W',' ','C','a','p','t','u','r','e',' ','F','i','l','t','e','r',' ',
- 'P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
-static const WCHAR wAVIMux[] =
-{'A','V','I',' ','m','u','x',0};
-static const WCHAR wAVIMuxPropPage[] =
-{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e',0};
-static const WCHAR wAVIMuxPropPage1[] =
-{'A','V','I',' ','m','u','x',' ','P','r','o','p','e','r','t','y',' ','P','a','g','e','1',0};
-static const WCHAR wFileWriter[] =
-{'F','i','l','e',' ','W','r','i','t','e','r',0};
-static const WCHAR wCaptGraphBuilder[] =
-{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r',0};
-static const WCHAR wCaptGraphBuilder2[] =
-{'C','a','p','t','u','r','e',' ','G','r','a','p','h',' ','B','u','i','l','d','e','r','2',0};
-static const WCHAR wInfPinTeeFilter[] =
-{'I','n','f','i','n','i','t','e',' ','P','i','n',' ','T','e','e',' ','F','i',
- 'l','t','e','r',0};
-static const WCHAR wSmartTeeFilter[] =
-{'S','m','a','r','t',' ','T','e','e',' ','F','i','l','t','e','r',0};
-static const WCHAR wAudioInMixerProp[] =
-{'A','u','d','i','o','I','n','p','u','t','M','i','x','e','r',' ','P','r','o',
- 'p','e','r','t','y',' ','P','a','g','e',0};
-
-FactoryTemplate const g_Templates[] = {
+struct class_factory
+{
+ IClassFactory IClassFactory_iface;
+ HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
+};
+
+static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
+{
+ return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
+}
+
+static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
+{
+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+ if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
+ {
+ *out = iface;
+ IClassFactory_AddRef(iface);
+ return S_OK;
+ }
+
+ *out = NULL;
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI class_factory_Release(IClassFactory *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out)
+{
+ struct class_factory *factory = impl_from_IClassFactory(iface);
+ IUnknown *unk;
+ HRESULT hr;
+
+ TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
+
+ if (outer && !IsEqualGUID(iid, &IID_IUnknown))
+ return E_NOINTERFACE;
+
+ *out = NULL;
+ if (SUCCEEDED(hr = factory->create_instance(outer, &unk)))
{
- wAudioCaptureFilter,
- &CLSID_AudioRecord,
- QCAP_createAudioCaptureFilter,
- NULL
- },{
- wAVICompressor,
- &CLSID_AVICo,
- QCAP_createAVICompressor,
- NULL
- },{
- wVFWCaptFilter,
- &CLSID_VfwCapture,
- QCAP_createVFWCaptureFilter,
- NULL
- },{
- wVFWCaptFilterProp,
- &CLSID_CaptureProperties,
- NULL, /* FIXME: Implement QCAP_createVFWCaptureFilterPropertyPage */
- NULL
- },{
- wAVIMux,
- &CLSID_AviDest,
- QCAP_createAVIMux,
- NULL
- },{
- wAVIMuxPropPage,
- &CLSID_AviMuxProptyPage,
- NULL, /* FIXME: Implement QCAP_createAVIMuxPropertyPage */
- NULL
- },{
- wAVIMuxPropPage1,
- &CLSID_AviMuxProptyPage1,
- NULL, /* FIXME: Implement QCAP_createAVIMuxPropertyPage1 */
- NULL
- },{
- wFileWriter,
- &CLSID_FileWriter,
- NULL, /* FIXME: Implement QCAP_createFileWriter */
- NULL
- },{
- wCaptGraphBuilder,
- &CLSID_CaptureGraphBuilder,
- QCAP_createCaptureGraphBuilder2,
- NULL
- },{
- wCaptGraphBuilder2,
- &CLSID_CaptureGraphBuilder2,
- QCAP_createCaptureGraphBuilder2,
- NULL
- },{
- wInfPinTeeFilter,
- &CLSID_InfTee,
- NULL, /* FIXME: Implement QCAP_createInfinitePinTeeFilter */
- NULL
- },{
- wSmartTeeFilter,
- &CLSID_SmartTee,
- QCAP_createSmartTeeFilter,
- NULL
- },{
- wAudioInMixerProp,
- &CLSID_AudioInputMixerProperties,
- NULL, /* FIXME: Implement QCAP_createAudioInputMixerPropertyPage */
- NULL
+ hr = IUnknown_QueryInterface(unk, iid, out);
+ IUnknown_Release(unk);
}
+ return hr;
+}
+
+static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock)
+{
+ TRACE("iface %p, lock %d.\n", iface, lock);
+
+ if (lock)
+ InterlockedIncrement(&objects_ref);
+ else
+ InterlockedDecrement(&objects_ref);
+ return S_OK;
+}
+
+static const IClassFactoryVtbl class_factory_vtbl =
+{
+ class_factory_QueryInterface,
+ class_factory_AddRef,
+ class_factory_Release,
+ class_factory_CreateInstance,
+ class_factory_LockServer,
};
-const int g_cTemplates = ARRAY_SIZE(g_Templates);
+static struct class_factory audio_record_cf = {{&class_factory_vtbl}, audio_record_create};
+static struct class_factory avi_compressor_cf = {{&class_factory_vtbl}, avi_compressor_create};
+static struct class_factory avi_mux_cf = {{&class_factory_vtbl}, avi_mux_create};
+static struct class_factory capture_graph_cf = {{&class_factory_vtbl}, capture_graph_create};
+static struct class_factory smart_tee_cf = {{&class_factory_vtbl}, smart_tee_create};
+static struct class_factory vfw_capture_cf = {{&class_factory_vtbl}, vfw_capture_create};
-/***********************************************************************
- * Dll EntryPoint (QCAP.@)
- */
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
- return STRMBASE_DllMain(hInstDLL,fdwReason,lpv);
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ qcap_instance = instance;
+ DisableThreadLibraryCalls(instance);
+ }
+ return TRUE;
}
-/***********************************************************************
- * DllGetClassObject
- */
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
{
- return STRMBASE_DllGetClassObject( rclsid, riid, ppv );
+ struct class_factory *factory;
+
+ TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out);
+
+ if (IsEqualGUID(clsid, &CLSID_AudioRecord))
+ factory = &audio_record_cf;
+ else if (IsEqualGUID(clsid, &CLSID_AVICo))
+ factory = &avi_compressor_cf;
+ else if (IsEqualGUID(clsid, &CLSID_AviDest))
+ factory = &avi_mux_cf;
+ else if (IsEqualGUID(clsid, &CLSID_CaptureGraphBuilder))
+ factory = &capture_graph_cf;
+ else if (IsEqualGUID(clsid, &CLSID_CaptureGraphBuilder2))
+ factory = &capture_graph_cf;
+ else if (IsEqualGUID(clsid, &CLSID_SmartTee))
+ factory = &smart_tee_cf;
+ else if (IsEqualGUID(clsid, &CLSID_VfwCapture))
+ factory = &vfw_capture_cf;
+ else
+ {
+ FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid));
+ return CLASS_E_CLASSNOTAVAILABLE;
+ }
+
+ return IClassFactory_QueryInterface(&factory->IClassFactory_iface, iid, out);
}
+static const REGPINTYPES reg_avi_mux_sink_mt = {&MEDIATYPE_Stream, &MEDIASUBTYPE_Avi};
+
+static const REGFILTERPINS2 reg_avi_mux_pins[1] =
+{
+ {
+ .cInstances = 1,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_avi_mux_sink_mt,
+ },
+};
+
+static const REGFILTER2 reg_avi_mux =
+{
+ .dwVersion = 2,
+ .dwMerit = MERIT_DO_NOT_USE,
+ .u.s2.cPins2 = 1,
+ .u.s2.rgPins2 = reg_avi_mux_pins,
+};
+
+static const REGPINTYPES reg_video_mt = {&MEDIATYPE_Video, &GUID_NULL};
+
+static const REGFILTERPINS2 reg_smart_tee_pins[3] =
+{
+ {
+ .cInstances = 1,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_video_mt,
+ },
+ {
+ .dwFlags = REG_PINFLAG_B_OUTPUT,
+ .cInstances = 1,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_video_mt,
+ },
+ {
+ .dwFlags = REG_PINFLAG_B_OUTPUT,
+ .cInstances = 1,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_video_mt,
+ },
+};
+
+static const REGFILTER2 reg_smart_tee =
+{
+ .dwVersion = 2,
+ .dwMerit = MERIT_DO_NOT_USE,
+ .u.s2.cPins2 = 3,
+ .u.s2.rgPins2 = reg_smart_tee_pins,
+};
+
/***********************************************************************
* DllRegisterServer (QCAP.@)
*/
HRESULT WINAPI DllRegisterServer(void)
{
- TRACE("()\n");
- return AMovieDllRegisterServer2(TRUE);
+ static const WCHAR avi_muxW[] = {'A','V','I',' ','M','u','x',0};
+ static const WCHAR smart_teeW[] = {'S','m','a','r','t',' ','T','e','e',0};
+ IFilterMapper2 *mapper;
+ HRESULT hr;
+
+ if (FAILED(hr = __wine_register_resources( qcap_instance )))
+ return hr;
+
+ if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IFilterMapper2, (void **)&mapper)))
+ return hr;
+
+ IFilterMapper2_RegisterFilter(mapper, &CLSID_AviDest, avi_muxW,
+ NULL, NULL, NULL, ®_avi_mux);
+ IFilterMapper2_RegisterFilter(mapper, &CLSID_SmartTee, smart_teeW,
+ NULL, NULL, NULL, ®_smart_tee);
+
+ IFilterMapper2_Release(mapper);
+ return S_OK;
}
/***********************************************************************
@@ -174,8 +252,21 @@ HRESULT WINAPI DllRegisterServer(void)
*/
HRESULT WINAPI DllUnregisterServer(void)
{
- TRACE("\n");
- return AMovieDllRegisterServer2(FALSE);
+ IFilterMapper2 *mapper;
+ HRESULT hr;
+
+ if (FAILED(hr = __wine_unregister_resources( qcap_instance )))
+ return hr;
+
+ if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IFilterMapper2, (void **)&mapper)))
+ return hr;
+
+ IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_AviDest);
+ IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_SmartTee);
+
+ IFilterMapper2_Release(mapper);
+ return S_OK;
}
/***********************************************************************
@@ -183,11 +274,9 @@ HRESULT WINAPI DllUnregisterServer(void)
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
- TRACE("\n");
+ TRACE(".\n");
- if (STRMBASE_DllCanUnloadNow() == S_OK && objects_ref == 0)
- return S_OK;
- return S_FALSE;
+ return objects_ref ? S_FALSE : S_OK;
}
DWORD ObjectRefCount(BOOL increment)
diff --git a/dlls/qcap/qcap_main.h b/dlls/qcap/qcap_main.h
index ab02dbb9ab5..58c7a26f9e1 100644
--- a/dlls/qcap/qcap_main.h
+++ b/dlls/qcap/qcap_main.h
@@ -25,18 +25,11 @@
extern DWORD ObjectRefCount(BOOL increment) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAudioCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAVICompressor(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createVFWCaptureFilterPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAVICompressor(IUnknown*,HRESULT*) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAVIMuxPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAVIMuxPropertyPage1(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createFileWriter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createInfinitePinTeeFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createSmartTeeFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
-extern IUnknown * WINAPI QCAP_createAudioInputMixerPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN;
+HRESULT audio_record_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT avi_compressor_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT avi_mux_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT capture_graph_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT smart_tee_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
+HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
#endif /* _QCAP_MAIN_H_DEFINED */
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index 5339cb5134f..46ec09ca7e4 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -321,7 +321,7 @@ static const struct strmbase_source_ops preview_ops =
.pfnDecideAllocator = SmartTeeFilterPreview_DecideAllocator,
};
-IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
+HRESULT smart_tee_create(IUnknown *outer, IUnknown **out)
{
static const WCHAR captureW[] = {'C','a','p','t','u','r','e',0};
static const WCHAR previewW[] = {'P','r','e','v','i','e','w',0};
@@ -330,10 +330,7 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
HRESULT hr;
if (!(object = CoTaskMemAlloc(sizeof(*object))))
- {
- *phr = E_OUTOFMEMORY;
- return NULL;
- }
+ return E_OUTOFMEMORY;
memset(object, 0, sizeof(*object));
strmbase_filter_init(&object->filter, outer, &CLSID_SmartTee, &filter_ops);
@@ -342,14 +339,15 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
&IID_IMemAllocator, (void **)&object->sink.pAllocator);
if (FAILED(hr))
{
- *phr = hr;
strmbase_filter_cleanup(&object->filter);
- return NULL;
+ CoTaskMemFree(object);
+ return hr;
}
strmbase_source_init(&object->capture, &object->filter, captureW, &capture_ops);
strmbase_source_init(&object->preview, &object->filter, previewW, &preview_ops);
- *phr = S_OK;
- return &object->filter.IUnknown_inner;
+ TRACE("Created smart tee %p.\n", object);
+ *out = &object->filter.IUnknown_inner;
+ return S_OK;
}
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c
index 6cd4a84d2e1..d2acf9eda43 100644
--- a/dlls/qcap/vfwcapture.c
+++ b/dlls/qcap/vfwcapture.c
@@ -559,16 +559,13 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
};
-IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
+HRESULT vfw_capture_create(IUnknown *outer, IUnknown **out)
{
static const WCHAR source_name[] = {'O','u','t','p','u','t',0};
VfwCapture *object;
if (!(object = CoTaskMemAlloc(sizeof(*object))))
- {
- *phr = E_OUTOFMEMORY;
- return NULL;
- }
+ return E_OUTOFMEMORY;
strmbase_filter_init(&object->filter, outer, &CLSID_VfwCapture, &filter_ops);
@@ -583,6 +580,6 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
TRACE("Created VFW capture filter %p.\n", object);
ObjectRefCount(TRUE);
- *phr = S_OK;
- return &object->filter.IUnknown_inner;
+ *out = &object->filter.IUnknown_inner;
+ return S_OK;
}
--
2.25.1
More information about the wine-devel
mailing list