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