[PATCH v2 4/5] wineqtdecoder: Reimplement COM registration and vending locally.
Zebediah Figura
z.figura12 at gmail.com
Sun Mar 8 14:05:10 CDT 2020
From: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/wineqtdecoder/Makefile.in | 4 +-
dlls/wineqtdecoder/main.c | 292 ++++++++++++-------
dlls/wineqtdecoder/qtsplitter.c | 16 +-
dlls/wineqtdecoder/qtvdecoder.c | 20 +-
dlls/wineqtdecoder/wineqtdecoder_classes.idl | 37 +++
5 files changed, 234 insertions(+), 135 deletions(-)
create mode 100644 dlls/wineqtdecoder/wineqtdecoder_classes.idl
diff --git a/dlls/wineqtdecoder/Makefile.in b/dlls/wineqtdecoder/Makefile.in
index bdd387432e5..b7db9b7c243 100644
--- a/dlls/wineqtdecoder/Makefile.in
+++ b/dlls/wineqtdecoder/Makefile.in
@@ -4,7 +4,6 @@ EXTRALIBS = $(QUICKTIME_LIBS)
PARENTSRC = ../strmbase
C_SRCS = \
- dllfunc.c \
filter.c \
main.c \
mediatype.c \
@@ -20,3 +19,6 @@ C_SRCS = \
RC_SRCS = \
rsrc.rc
+
+IDL_SRCS = \
+ wineqtdecoder_classes.idl
diff --git a/dlls/wineqtdecoder/main.c b/dlls/wineqtdecoder/main.c
index ac9268d70f5..6e0dd8c46b5 100644
--- a/dlls/wineqtdecoder/main.c
+++ b/dlls/wineqtdecoder/main.c
@@ -2,6 +2,7 @@
* DirectShow filter for QuickTime Toolkit on Mac OS X
*
* Copyright (C) 2010 Aric Stewart, CodeWeavers
+ * 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
@@ -40,158 +41,223 @@
#include "wine/debug.h"
#include "wine/strmbase.h"
+#include "wineqtdecoder_classes.h"
+
#include "initguid.h"
-DEFINE_GUID(CLSID_QTVDecoder, 0x683DDACB, 0x4354, 0x490C, 0xA0,0x58, 0xE0,0x5A,0xD0,0xF2,0x05,0x37);
-DEFINE_GUID(CLSID_QTSplitter, 0xD0E70E49, 0x5927, 0x4894, 0xA3,0x86, 0x35,0x94,0x60,0xEE,0x87,0xC9);
DEFINE_GUID(WINESUBTYPE_QTSplitter, 0xFFFFFFFF, 0x5927, 0x4894, 0xA3,0x86, 0x35,0x94,0x60,0xEE,0x87,0xC9);
WINE_DEFAULT_DEBUG_CHANNEL(qtdecoder);
-extern IUnknown * CALLBACK QTVDecoder_create(IUnknown * pUnkOuter, HRESULT* phr);
-extern IUnknown * CALLBACK QTSplitter_create(IUnknown * pUnkOuter, HRESULT* phr);
+extern HRESULT video_decoder_create(IUnknown *outer, IUnknown **out);
+extern HRESULT qt_splitter_create(IUnknown *outer, IUnknown **out);
static const WCHAR wQTVName[] =
{'Q','T',' ','V','i','d','e','o',' ','D','e','c','o','d','e','r',0};
static const WCHAR wQTDName[] =
{'Q','T',' ','V','i','d','e','o',' ','D','e','m','u','x',0};
-static WCHAR wNull[] = {'\0'};
-
-static const AMOVIESETUP_MEDIATYPE amfMTvideo[] =
-{ { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL } };
-static const AMOVIESETUP_MEDIATYPE amfMTaudio[] =
-{ { &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL } };
-static const AMOVIESETUP_MEDIATYPE amfMTstream[] =
-{ { &MEDIATYPE_Stream, &WINESUBTYPE_QTSplitter},
- { &MEDIATYPE_Stream, &MEDIASUBTYPE_NULL } };
-
-static const AMOVIESETUP_PIN amfQTVPin[] =
-{ { wNull,
- FALSE, FALSE, FALSE, FALSE,
- &GUID_NULL,
- NULL,
- 1,
- amfMTvideo
- },
+
+static HINSTANCE wineqtdecoder_instance;
+
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
{
- wNull,
- FALSE, TRUE, FALSE, FALSE,
- &GUID_NULL,
- NULL,
- 1,
- amfMTvideo
- },
+ wineqtdecoder_instance = instance;
+ DisableThreadLibraryCalls(instance);
+ }
+ return TRUE;
+}
+
+struct class_factory
+{
+ IClassFactory IClassFactory_iface;
+ HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
};
-static const AMOVIESETUP_PIN amfQTDPin[] =
-{ { wNull,
- FALSE, FALSE, FALSE, FALSE,
- &GUID_NULL,
- NULL,
- 2,
- amfMTstream
- },
+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))
{
- wNull,
- FALSE, TRUE, TRUE, FALSE,
- &GUID_NULL,
- NULL,
- 1,
- amfMTvideo
- },
+ *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)))
{
- wNull,
- FALSE, TRUE, TRUE, FALSE,
- &GUID_NULL,
- NULL,
- 1,
- amfMTaudio
- },
-};
+ hr = IUnknown_QueryInterface(unk, iid, out);
+ IUnknown_Release(unk);
+ }
+ return hr;
+}
-static const AMOVIESETUP_FILTER amfQTV =
-{ &CLSID_QTVDecoder,
- wQTVName,
- MERIT_NORMAL-1,
- 2,
- amfQTVPin
-};
+static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock)
+{
+ TRACE("iface %p, lock %d.\n", iface, lock);
+ return S_OK;
+}
-static const AMOVIESETUP_FILTER amfQTD =
-{ &CLSID_QTSplitter,
- wQTDName,
- MERIT_NORMAL-1,
- 3,
- amfQTDPin
+static const IClassFactoryVtbl class_factory_vtbl =
+{
+ class_factory_QueryInterface,
+ class_factory_AddRef,
+ class_factory_Release,
+ class_factory_CreateInstance,
+ class_factory_LockServer,
};
-FactoryTemplate const g_Templates[] = {
+static struct class_factory qt_splitter_cf = {{&class_factory_vtbl}, qt_splitter_create};
+static struct class_factory video_decoder_cf = {{&class_factory_vtbl}, video_decoder_create};
+
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
+{
+ struct class_factory *factory;
+ HRESULT hr;
+
+ TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out);
+
+ if (IsEqualGUID(clsid, &CLSID_QTSplitter))
+ factory = &qt_splitter_cf;
+ else if (IsEqualGUID(clsid, &CLSID_QTVDecoder))
+ factory = &video_decoder_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_audio_mt = {&MEDIATYPE_Audio, &GUID_NULL};
+static const REGPINTYPES reg_stream_mt = {&MEDIATYPE_Stream, &GUID_NULL};
+static const REGPINTYPES reg_video_mt = {&MEDIATYPE_Video, &GUID_NULL};
+
+static const REGFILTERPINS2 reg_qt_splitter_pins[3] =
+{
{
- wQTVName,
- &CLSID_QTVDecoder,
- QTVDecoder_create,
- NULL,
- &amfQTV,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_stream_mt,
},
{
- wQTDName,
- &CLSID_QTSplitter,
- QTSplitter_create,
- NULL,
- &amfQTD,
- }
+ .dwFlags = REG_PINFLAG_B_OUTPUT | REG_PINFLAG_B_ZERO,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_audio_mt,
+ },
+ {
+ .dwFlags = REG_PINFLAG_B_OUTPUT | REG_PINFLAG_B_ZERO,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_video_mt,
+ },
};
-int g_cTemplates = ARRAY_SIZE(g_Templates);
-static HINSTANCE hInst = NULL;
+static const REGFILTER2 reg_qt_splitter =
+{
+ .dwVersion = 2,
+ .dwMerit = MERIT_NORMAL - 1,
+ .u.s2.cPins2 = 3,
+ .u.s2.rgPins2 = reg_qt_splitter_pins,
+};
-/***********************************************************************
- * Dll EntryPoint (wineqtdecoder.@)
- */
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+static const REGFILTERPINS2 reg_qt_splitter_pins[2] =
{
- hInst = hInstDLL;
- return STRMBASE_DllMain(hInstDLL,fdwReason,lpv);
-}
+ {
+ .nMediaTypes = 1,
+ .lpMediaType = ®_video_mt,
+ },
+ {
+ .dwFlags = REG_PINFLAG_B_OUTPUT,
+ .nMediaTypes = 1,
+ .lpMediaType = ®_video_mt,
+ },
+};
-/***********************************************************************
- * DllGetClassObject
- */
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+static const REGFILTER2 reg_video_decoder =
{
- return STRMBASE_DllGetClassObject( rclsid, riid, ppv );
-}
+ .dwVersion = 2,
+ .dwMerit = MERIT_NORMAL - 1,
+ .u.s2.cPins2 = 2,
+ .u.s2.rgPins2 = reg_video_decoder_pins,
+};
-/***********************************************************************
- * DllRegisterServer (wineqtdecoder.@)
- */
HRESULT WINAPI DllRegisterServer(void)
{
+ IFilterMapper2 *mapper;
HRESULT hr;
- TRACE("()\n");
- hr = AMovieDllRegisterServer2(TRUE);
- if (SUCCEEDED(hr))
- hr = __wine_register_resources(hInst);
- return hr;
+
+ TRACE(".\n");
+
+ if (FAILED(hr = __wine_register_resources(wineqtdecoder_instance)))
+ return hr;
+
+ if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IFilterMapper2, (void **)&mapper)))
+ return hr;
+
+ IFilterMapper2_RegisterFilter(mapper, &CLSID_QTSplitter, wQTDName, NULL, NULL, NULL, ®_qt_splitter);
+ IFilterMapper2_RegisterFilter(mapper, &CLSID_QTVDecoder, wQTVName, NULL, NULL, NULL, ®_video_decoder);
+
+ IFilterMapper2_Release(mapper);
+ return S_OK;
}
-/***********************************************************************
- * DllUnregisterServer (wineqtdecoder.@)
- */
HRESULT WINAPI DllUnregisterServer(void)
{
+ IFilterMapper2 *mapper;
HRESULT hr;
- TRACE("\n");
- hr = AMovieDllRegisterServer2(FALSE);
- if (SUCCEEDED(hr))
- hr = __wine_unregister_resources(hInst);
- return hr;
+
+ TRACE(".\n");
+
+ if (FAILED(hr = __wine_unregister_resources(wineqtdecoder_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_QTSplitter);
+ IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_QTVDecoder);
+
+ IFilterMapper2_Release(mapper);
+ return S_OK;
}
-/***********************************************************************
- * DllCanUnloadNow (wineqtdecoder.@)
- */
HRESULT WINAPI DllCanUnloadNow(void)
{
- TRACE("\n");
- return STRMBASE_DllCanUnloadNow();
+ TRACE(".\n");
+ return S_FALSE;
}
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 1421e0bf53c..69736208097 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -124,6 +124,7 @@
#include "wine/strmbase.h"
#include "qtprivate.h"
+#include "wineqtdecoder_classes.h"
WINE_DEFAULT_DEBUG_CHANNEL(qtsplitter);
extern CLSID CLSID_QTSplitter;
@@ -402,7 +403,7 @@ static const struct strmbase_sink_ops sink_ops =
.sink_disconnect = qt_splitter_sink_disconnect,
};
-IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr)
+HRESULT qt_splitter_create(IUnknown *outer, IUnknown **out)
{
QTSplitter *This;
static const WCHAR wcsInputPinName[] = {'I','n','p','u','t',' ','P','i','n',0};
@@ -411,12 +412,8 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr)
RegisterWineDataHandler();
- This = CoTaskMemAlloc(sizeof(*This));
- if (!This)
- {
- *phr = E_OUTOFMEMORY;
- return NULL;
- }
+ if (!(This = CoTaskMemAlloc(sizeof(*This))))
+ return E_OUTOFMEMORY;
ZeroMemory(This,sizeof(*This));
strmbase_filter_init(&This->filter, outer, &CLSID_QTSplitter, &filter_ops);
@@ -430,8 +427,9 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr)
This->aSession = NULL;
This->runEvent = CreateEventW(NULL, 0, 0, NULL);
- *phr = S_OK;
- return &This->filter.IUnknown_inner;
+ TRACE("Created QT splitter %p.\n", This);
+ *out = &This->filter.IUnknown_inner;
+ return S_OK;
}
static OSErr QT_Create_Extract_Session(QTSplitter *filter)
diff --git a/dlls/wineqtdecoder/qtvdecoder.c b/dlls/wineqtdecoder/qtvdecoder.c
index 4be654e5a10..5417124782c 100644
--- a/dlls/wineqtdecoder/qtvdecoder.c
+++ b/dlls/wineqtdecoder/qtvdecoder.c
@@ -126,6 +126,7 @@
#include "wine/strmbase.h"
#include "qtprivate.h"
+#include "wineqtdecoder_classes.h"
extern CLSID CLSID_QTVDecoder;
@@ -505,22 +506,17 @@ static const TransformFilterFuncTable QTVDecoder_FuncsTable = {
.pfnBreakConnect = QTVDecoder_BreakConnect,
};
-IUnknown * CALLBACK QTVDecoder_create(IUnknown *outer, HRESULT* phr)
+HRESULT video_decoder_create(IUnknown *outer, IUnknown **out)
{
+ QTVDecoderImpl *object;
HRESULT hr;
- QTVDecoderImpl * This;
-
- *phr = S_OK;
hr = strmbase_transform_create(sizeof(QTVDecoderImpl), outer, &CLSID_QTVDecoder,
- &QTVDecoder_FuncsTable, (IBaseFilter **)&This);
-
+ &QTVDecoder_FuncsTable, (IBaseFilter **)&object);
if (FAILED(hr))
- {
- *phr = hr;
- return NULL;
- }
+ return hr;
- *phr = hr;
- return &This->tf.filter.IUnknown_inner;
+ TRACE("Created video decoder %p.\n", object);
+ *out = &object->tf.filter.IUnknown_inner;
+ return S_OK;
}
diff --git a/dlls/wineqtdecoder/wineqtdecoder_classes.idl b/dlls/wineqtdecoder/wineqtdecoder_classes.idl
new file mode 100644
index 00000000000..49badcc6d72
--- /dev/null
+++ b/dlls/wineqtdecoder/wineqtdecoder_classes.idl
@@ -0,0 +1,37 @@
+/*
+ * COM classes for wineqtdecoder
+ *
+ * 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 header
+#pragma makedep ident
+#pragma makedep register
+
+[
+ helpstring("Wine QuickTime splitter"),
+ threading(both),
+ uuid(d0e70e49-5927-4894-a386-359460ee87c9)
+]
+coclass QTSplitter {}
+
+[
+ helpstring("Wine QuickTime video decoder"),
+ threading(both),
+ uuid(683ddacb-4354-490c-a058-e05ad0f20537)
+]
+coclass QTVDecoder {}
--
2.25.1
More information about the wine-devel
mailing list