[PATCH] mf: Add stub scheme handler for local file urls.

Nikolay Sivov nsivov at codeweavers.com
Mon Apr 29 09:26:39 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/Makefile.in |   2 +
 dlls/mf/main.c      | 236 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/mf/mf.idl      |  26 +++++
 dlls/mf/mf.spec     |   8 +-
 4 files changed, 268 insertions(+), 4 deletions(-)
 create mode 100644 dlls/mf/mf.idl

diff --git a/dlls/mf/Makefile.in b/dlls/mf/Makefile.in
index f05364bca6..5e18ab454e 100644
--- a/dlls/mf/Makefile.in
+++ b/dlls/mf/Makefile.in
@@ -6,3 +6,5 @@ C_SRCS = \
 	main.c \
 	session.c \
 	topology.c
+
+IDL_SRCS = mf.idl
diff --git a/dlls/mf/main.c b/dlls/mf/main.c
index b3573d78af..1b00ea502e 100644
--- a/dlls/mf/main.c
+++ b/dlls/mf/main.c
@@ -25,11 +25,246 @@
 #include "windef.h"
 #include "winbase.h"
 #include "mfidl.h"
+#include "rpcproxy.h"
+
+#include "initguid.h"
+#include "mf.h"
 
 #include "wine/debug.h"
+#include "wine/heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
 
+static HINSTANCE mf_instance;
+
+struct class_factory
+{
+    IClassFactory IClassFactory_iface;
+    HRESULT (*create_instance)(REFIID riid, void **obj);
+};
+
+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 riid, void **obj)
+{
+    TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+    if (IsEqualGUID(riid, &IID_IClassFactory) ||
+            IsEqualGUID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IClassFactory_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("%s is not supported.\n", debugstr_guid(riid));
+    *obj = NULL;
+    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 riid, void **obj)
+{
+    struct class_factory *factory = impl_from_IClassFactory(iface);
+
+    TRACE("%p, %p, %s, %p.\n", iface, outer, debugstr_guid(riid), obj);
+
+    if (outer)
+    {
+        *obj = NULL;
+        return CLASS_E_NOAGGREGATION;
+    }
+
+    return factory->create_instance(riid, obj);
+}
+
+static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL dolock)
+{
+    FIXME("%d.\n", dolock);
+
+    return S_OK;
+}
+
+static const IClassFactoryVtbl class_factory_vtbl =
+{
+    class_factory_QueryInterface,
+    class_factory_AddRef,
+    class_factory_Release,
+    class_factory_CreateInstance,
+    class_factory_LockServer,
+};
+
+struct file_scheme_handler
+{
+    IMFSchemeHandler IMFSchemeHandler_iface;
+    LONG refcount;
+};
+
+static struct file_scheme_handler *impl_from_IMFSchemeHandler(IMFSchemeHandler *iface)
+{
+    return CONTAINING_RECORD(iface, struct file_scheme_handler, IMFSchemeHandler_iface);
+}
+
+static HRESULT WINAPI file_scheme_handler_QueryInterface(IMFSchemeHandler *iface, REFIID riid, void **obj)
+{
+    TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+    if (IsEqualIID(riid, &IID_IMFSchemeHandler) ||
+            IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IMFSchemeHandler_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("Unsupported %s.\n", debugstr_guid(riid));
+    *obj = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI file_scheme_handler_AddRef(IMFSchemeHandler *iface)
+{
+    struct file_scheme_handler *handler = impl_from_IMFSchemeHandler(iface);
+    ULONG refcount = InterlockedIncrement(&handler->refcount);
+
+    TRACE("%p, refcount %u.\n", handler, refcount);
+
+    return refcount;
+}
+
+static ULONG WINAPI file_scheme_handler_Release(IMFSchemeHandler *iface)
+{
+    struct file_scheme_handler *handler = impl_from_IMFSchemeHandler(iface);
+    ULONG refcount = InterlockedDecrement(&handler->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    if (!refcount)
+        heap_free(handler);
+
+    return refcount;
+}
+
+static HRESULT WINAPI file_scheme_handler_BeginCreateObject(IMFSchemeHandler *iface, const WCHAR *url, DWORD flags,
+        IPropertyStore *props, IUnknown **cancel_cookie, IMFAsyncCallback *callback, IUnknown *state)
+{
+    FIXME("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI file_scheme_handler_EndCreateObject(IMFSchemeHandler *iface, IMFAsyncResult *result,
+        MF_OBJECT_TYPE *obj_type, IUnknown **object)
+{
+    FIXME("%p, %p, %p, %p.\n", iface, result, obj_type, object);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI file_scheme_handler_CancelObjectCreation(IMFSchemeHandler *iface, IUnknown *cancel_cookie)
+{
+    FIXME("%p, %p.\n", iface, cancel_cookie);
+
+    return E_NOTIMPL;
+}
+
+static const IMFSchemeHandlerVtbl file_scheme_handler_vtbl =
+{
+    file_scheme_handler_QueryInterface,
+    file_scheme_handler_AddRef,
+    file_scheme_handler_Release,
+    file_scheme_handler_BeginCreateObject,
+    file_scheme_handler_EndCreateObject,
+    file_scheme_handler_CancelObjectCreation,
+};
+
+static HRESULT file_scheme_handler_construct(REFIID riid, void **obj)
+{
+    struct file_scheme_handler *handler;
+    HRESULT hr;
+
+    TRACE("%s, %p.\n", debugstr_guid(riid), obj);
+
+    handler = heap_alloc(sizeof(*handler));
+    if (!handler)
+        return E_OUTOFMEMORY;
+
+    handler->IMFSchemeHandler_iface.lpVtbl = &file_scheme_handler_vtbl;
+    handler->refcount = 1;
+
+    hr = IMFSchemeHandler_QueryInterface(&handler->IMFSchemeHandler_iface, riid, obj);
+    IMFSchemeHandler_Release(&handler->IMFSchemeHandler_iface);
+
+    return hr;
+}
+
+static struct class_factory file_scheme_handler_factory = { { &class_factory_vtbl }, file_scheme_handler_construct };
+
+static const struct class_object
+{
+    const GUID *clsid;
+    IClassFactory *factory;
+}
+class_objects[] =
+{
+    { &CLSID_FileSchemeHandler, &file_scheme_handler_factory.IClassFactory_iface },
+};
+
+/*******************************************************************************
+ *      DllGetClassObject (mf.@)
+ */
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **obj)
+{
+    unsigned int i;
+
+    TRACE("%s, %s, %p.\n", debugstr_guid(rclsid), debugstr_guid(riid), obj);
+
+    for (i = 0; i < ARRAY_SIZE(class_objects); ++i)
+    {
+        if (IsEqualGUID(class_objects[i].clsid, rclsid))
+            return IClassFactory_QueryInterface(class_objects[i].factory, riid, obj);
+    }
+
+    WARN("%s: class not found.\n", debugstr_guid(rclsid));
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+/******************************************************************
+ *              DllCanUnloadNow (mf.@)
+ */
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+    return S_FALSE;
+}
+
+/***********************************************************************
+ *          DllRegisterServer (mf.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+    return __wine_register_resources( mf_instance );
+}
+
+/***********************************************************************
+ *          DllUnregisterServer (mf.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    return __wine_unregister_resources( mf_instance );
+}
+
 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
 {
     switch (reason)
@@ -37,6 +272,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
         case DLL_WINE_PREATTACH:
             return FALSE;    /* prefer native version */
         case DLL_PROCESS_ATTACH:
+            mf_instance = instance;
             DisableThreadLibraryCalls(instance);
             break;
     }
diff --git a/dlls/mf/mf.idl b/dlls/mf/mf.idl
new file mode 100644
index 0000000000..824c246d30
--- /dev/null
+++ b/dlls/mf/mf.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 Nikolay Sivov for CodeWeavers
+ *
+ * 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 register
+
+[
+    helpstring("File scheme handler"),
+    threading(both),
+    uuid(477ec299-1421-4bdd-971f-7ccb933f21ad)
+]
+coclass FileSchemeHandler { }
diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec
index 2d02ef8fec..dd3d6d0688 100644
--- a/dlls/mf/mf.spec
+++ b/dlls/mf/mf.spec
@@ -2,10 +2,10 @@
 @ stub ConvertPropVariant
 @ stub CopyPropertyStore
 @ stub CreateNamedPropertyStore
-@ stub DllCanUnloadNow
-@ stub DllGetClassObject
-@ stub DllRegisterServer
-@ stub DllUnregisterServer
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
 @ stub ExtractPropVariant
 @ stub MFCreate3GPMediaSink
 @ stub MFCreateASFByteStreamPlugin
-- 
2.20.1




More information about the wine-devel mailing list