From c7b956f8fcf18c0b66271c22a8d82369bb0788f0 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 11 Jun 2019 15:40:01 +0300 Subject: [PATCH] mfplat: Add MFRegisterLocalByteStreamHandler(). Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- 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 c0866f799bf..f759b5cbd87 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -47,13 +47,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 { @@ -7153,21 +7162,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 = (lstrlenW(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; } /*********************************************************************** @@ -7201,12 +7214,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)) @@ -7300,6 +7309,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); @@ -7309,10 +7319,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); @@ -7323,3 +7333,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 2dfa92f2028..1ae0927f513 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 ab651c54f22..e63efc154be 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)