mfplat: Add MFRegisterLocalByteStreamHandler().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-06-11 15:40:01 +03:00 committed by Alexandre Julliard
parent f8a04c7f2e
commit c7b956f8fc
3 changed files with 77 additions and 14 deletions

View File

@ -47,13 +47,22 @@ static LONG platform_lock;
struct local_handler
{
struct list entry;
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;
}

View File

@ -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)

View File

@ -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)