[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 = &reg_stream_mt,
     },
     {
-        wQTDName,
-        &CLSID_QTSplitter,
-        QTSplitter_create,
-        NULL,
-        &amfQTD,
-    }
+        .dwFlags = REG_PINFLAG_B_OUTPUT | REG_PINFLAG_B_ZERO,
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_audio_mt,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_OUTPUT | REG_PINFLAG_B_ZERO,
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_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 = &reg_video_mt,
+    },
+    {
+        .dwFlags = REG_PINFLAG_B_OUTPUT,
+        .nMediaTypes = 1,
+        .lpMediaType = &reg_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, &reg_qt_splitter);
+    IFilterMapper2_RegisterFilter(mapper, &CLSID_QTVDecoder, wQTVName, NULL, NULL, NULL, &reg_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