Signed-off-by: Nikolay Sivov <nsivov(a)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