[PATCH 1/5] mfplat: Add MFRegisterLocalByteStreamHandler().

Nikolay Sivov nsivov at codeweavers.com
Tue Jun 11 07:40:01 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/main.c         | 75 +++++++++++++++++++++++++++++++-------
 dlls/mfplat/mfplat.spec    |  1 +
 dlls/mfplat/tests/mfplat.c | 15 ++++++++
 3 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 4082f9e2ac..b0db0db922 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -48,13 +48,22 @@ static LONG platform_lock;
 struct local_handler
 {
     struct list entry;
-    WCHAR *scheme;
+    union
+    {
+        WCHAR *scheme;
+        struct
+        {
+            WCHAR *extension;
+            WCHAR *mime;
+        } bytestream;
+    } u;
     IMFActivate *activate;
 };
 
 static CRITICAL_SECTION local_handlers_section = { NULL, -1, 0, 0, 0, 0 };
 
 static struct list local_scheme_handlers = LIST_INIT(local_scheme_handlers);
+static struct list local_bytestream_handlers = LIST_INIT(local_bytestream_handlers);
 
 struct system_clock
 {
@@ -7154,21 +7163,25 @@ static const IMFAsyncCallbackVtbl async_create_file_callback_vtbl =
     async_create_file_callback_Invoke,
 };
 
-static WCHAR *heap_strdupW(const WCHAR *str)
+static HRESULT heap_strdupW(const WCHAR *str, WCHAR **dest)
 {
-    WCHAR *ret = NULL;
+    HRESULT hr = S_OK;
 
     if (str)
     {
         unsigned int size;
 
         size = (strlenW(str) + 1) * sizeof(WCHAR);
-        ret = heap_alloc(size);
-        if (ret)
-            memcpy(ret, str, size);
+        *dest = heap_alloc(size);
+        if (*dest)
+            memcpy(*dest, str, size);
+        else
+            hr = E_OUTOFMEMORY;
     }
+    else
+        *dest = NULL;
 
-    return ret;
+    return hr;
 }
 
 /***********************************************************************
@@ -7202,12 +7215,8 @@ HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMOD
     async->access_mode = access_mode;
     async->open_mode = open_mode;
     async->flags = flags;
-    async->path = heap_strdupW(path);
-    if (!async->path)
-    {
-        hr = E_OUTOFMEMORY;
+    if (FAILED(hr = heap_strdupW(path, &async->path)))
         goto failed;
-    }
 
     hr = MFCreateAsyncResult(NULL, &async->IMFAsyncCallback_iface, (IUnknown *)caller, &item);
     if (FAILED(hr))
@@ -7301,6 +7310,7 @@ HRESULT WINAPI MFCancelCreateFile(IUnknown *cancel_cookie)
 HRESULT WINAPI MFRegisterLocalSchemeHandler(const WCHAR *scheme, IMFActivate *activate)
 {
     struct local_handler *handler;
+    HRESULT hr;
 
     TRACE("%s, %p.\n", debugstr_w(scheme), activate);
 
@@ -7310,10 +7320,10 @@ HRESULT WINAPI MFRegisterLocalSchemeHandler(const WCHAR *scheme, IMFActivate *ac
     if (!(handler = heap_alloc(sizeof(*handler))))
         return E_OUTOFMEMORY;
 
-    if (!(handler->scheme = heap_strdupW(scheme)))
+    if (FAILED(hr = heap_strdupW(scheme, &handler->u.scheme)))
     {
         heap_free(handler);
-        return E_OUTOFMEMORY;
+        return hr;
     }
     handler->activate = activate;
     IMFActivate_AddRef(handler->activate);
@@ -7324,3 +7334,40 @@ HRESULT WINAPI MFRegisterLocalSchemeHandler(const WCHAR *scheme, IMFActivate *ac
 
     return S_OK;
 }
+
+/***********************************************************************
+ *      MFRegisterLocalByteStreamHandler (mfplat.@)
+ */
+HRESULT WINAPI MFRegisterLocalByteStreamHandler(const WCHAR *extension, const WCHAR *mime, IMFActivate *activate)
+{
+    struct local_handler *handler;
+    HRESULT hr;
+
+    TRACE("%s, %s, %p.\n", debugstr_w(extension), debugstr_w(mime), activate);
+
+    if ((!extension && !mime) || !activate)
+        return E_INVALIDARG;
+
+    if (!(handler = heap_alloc_zero(sizeof(*handler))))
+        return E_OUTOFMEMORY;
+
+    hr = heap_strdupW(extension, &handler->u.bytestream.extension);
+    if (SUCCEEDED(hr))
+        hr = heap_strdupW(mime, &handler->u.bytestream.mime);
+
+    if (FAILED(hr))
+        goto failed;
+
+    EnterCriticalSection(&local_handlers_section);
+    list_add_head(&local_bytestream_handlers, &handler->entry);
+    LeaveCriticalSection(&local_handlers_section);
+
+    return hr;
+
+failed:
+    heap_free(handler->u.bytestream.extension);
+    heap_free(handler->u.bytestream.mime);
+    heap_free(handler);
+
+    return hr;
+}
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index 2dfa92f202..1ae0927f51 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -128,6 +128,7 @@
 @ stdcall MFPutWorkItemEx(long ptr)
 @ stdcall MFPutWorkItemEx2(long long ptr)
 @ stub MFRecordError
+@ stdcall MFRegisterLocalByteStreamHandler(wstr wstr ptr)
 @ stdcall MFRegisterLocalSchemeHandler(wstr ptr)
 @ stdcall MFRemovePeriodicCallback(long)
 @ stdcall MFScheduleWorkItem(ptr ptr int64 ptr)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index ab651c54f2..e63efc154b 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -3591,6 +3591,21 @@ static void test_local_handlers(void)
 
     hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
     ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
+
+    hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
+    ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
+
+    hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
+    ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
+
+    hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
+    ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
 }
 
 START_TEST(mfplat)
-- 
2.20.1




More information about the wine-devel mailing list