[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