Signed-off-by: Nikolay Sivov nsivov@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