mfplat: Implement MFCreatePathFromURL().

This commit is contained in:
Nikolay Sivov 2023-05-08 14:38:43 +02:00 committed by Alexandre Julliard
parent d26e0b880c
commit 32cec5e628
3 changed files with 154 additions and 1 deletions

View file

@ -9464,3 +9464,28 @@ LONGLONG WINAPI MFllMulDiv(LONGLONG val, LONGLONG num, LONGLONG denom, LONGLONG
return sign ? -(LONGLONG)ret : ret;
#undef LLOVERFLOW
}
/***********************************************************************
* MFCreatePathFromURL (mfplat.@)
*/
HRESULT WINAPI MFCreatePathFromURL(const WCHAR *url, WCHAR **ret_path)
{
WCHAR path[MAX_PATH];
DWORD length;
HRESULT hr;
TRACE("%s, %p.\n", debugstr_w(url), ret_path);
if (!url || !ret_path)
return E_POINTER;
length = ARRAY_SIZE(path);
if (FAILED(hr = PathCreateFromUrlW(url, path, &length, 0)))
return hr;
if (!(*ret_path = CoTaskMemAlloc((length + 1) * sizeof(*path))))
return E_OUTOFMEMORY;
memcpy(*ret_path, path, (length + 1) * sizeof(*path));
return S_OK;
}

View file

@ -62,7 +62,7 @@
@ stub MFCreateMediaTypeFromRepresentation
@ stdcall MFCreateMemoryBuffer(long ptr)
@ stub MFCreateMemoryStream
@ stub MFCreatePathFromURL
@ stdcall MFCreatePathFromURL(wstr ptr)
@ stdcall MFCreatePresentationDescriptor(long ptr ptr)
@ stdcall MFCreateSample(ptr)
@ stub MFCreateSocket

View file

@ -397,6 +397,7 @@ static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD
IMFMediaBuffer **buffer);
static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
DWORD min_alignment, IMFMediaBuffer **buffer);
static HRESULT (WINAPI *pMFCreatePathFromURL)(const WCHAR *url, WCHAR **path);
static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
@ -1277,6 +1278,7 @@ static void init_functions(void)
X(MFCreateSourceResolver);
X(MFCreateMediaBufferFromMediaType);
X(MFCreateMFByteStreamOnStream);
X(MFCreatePathFromURL);
X(MFCreateTrackedSample);
X(MFCreateTransformActivate);
X(MFCreateVideoMediaTypeFromSubtype);
@ -9123,6 +9125,131 @@ static void test_MFInitMediaTypeFromAMMediaType(void)
IMFMediaType_Release(media_type);
}
static void test_MFCreatePathFromURL(void)
{
static const struct
{
const WCHAR *url;
const WCHAR *path;
HRESULT hr;
}
tests[] =
{
/* 0 leading slash */
{ L"file:c:/foo/bar", L"c:\\foo\\bar" },
{ L"file:c|/foo/bar", L"c:\\foo\\bar" },
{ L"file:cx|/foo/bar", L"cx|\\foo\\bar" },
{ L"file:c:foo/bar", L"c:foo\\bar" },
{ L"file:c|foo/bar", L"c:foo\\bar" },
{ L"file:c:/foo%20ba%2fr", L"c:\\foo ba/r" },
{ L"file:foo%20ba%2fr", L"foo ba/r" },
{ L"file:foo/bar/", L"foo\\bar\\" },
/* 1 leading (back)slash */
{ L"file:/c:/foo/bar", L"c:\\foo\\bar" },
{ L"file:\\c:/foo/bar", L"c:\\foo\\bar" },
{ L"file:/c|/foo/bar", L"c:\\foo\\bar" },
{ L"file:/cx|/foo/bar", L"\\cx|\\foo\\bar" },
{ L"file:/c:foo/bar", L"c:foo\\bar" },
{ L"file:/c|foo/bar", L"c:foo\\bar" },
{ L"file:/c:/foo%20ba%2fr", L"c:\\foo ba/r" },
{ L"file:/foo%20ba%2fr", L"\\foo ba/r" },
{ L"file:/foo/bar/", L"\\foo\\bar\\" },
/* 2 leading (back)slashes */
{ L"file://c:/foo/bar", L"c:\\foo\\bar" },
{ L"file://c:/d:/foo/bar", L"c:\\d:\\foo\\bar" },
{ L"file://c|/d|/foo/bar", L"c:\\d|\\foo\\bar" },
{ L"file://cx|/foo/bar", L"\\\\cx|\\foo\\bar" },
{ L"file://c:foo/bar", L"c:foo\\bar" },
{ L"file://c|foo/bar", L"c:foo\\bar" },
{ L"file://c:/foo%20ba%2fr", L"c:\\foo%20ba%2fr" },
{ L"file://c%3a/foo/../bar", L"\\\\c:\\foo\\..\\bar" },
{ L"file://c%7c/foo/../bar", L"\\\\c|\\foo\\..\\bar" },
{ L"file://foo%20ba%2fr", L"\\\\foo ba/r" },
{ L"file://localhost/c:/foo/bar", L"c:\\foo\\bar" },
{ L"file://localhost/c:/foo%20ba%5Cr", L"c:\\foo ba\\r" },
{ L"file://LocalHost/c:/foo/bar", L"c:\\foo\\bar" },
{ L"file:\\\\localhost\\c:\\foo\\bar", L"c:\\foo\\bar" },
{ L"file://incomplete", L"\\\\incomplete" },
/* 3 leading (back)slashes (omitting hostname) */
{ L"file:///c:/foo/bar", L"c:\\foo\\bar" },
{ L"File:///c:/foo/bar", L"c:\\foo\\bar" },
{ L"file:///c:/foo%20ba%2fr", L"c:\\foo ba/r" },
{ L"file:///foo%20ba%2fr", L"\\foo ba/r" },
{ L"file:///foo/bar/", L"\\foo\\bar\\" },
{ L"file:///localhost/c:/foo/bar", L"\\localhost\\c:\\foo\\bar" },
/* 4 leading (back)slashes */
{ L"file:////c:/foo/bar", L"c:\\foo\\bar" },
{ L"file:////c:/foo%20ba%2fr", L"c:\\foo%20ba%2fr" },
{ L"file:////foo%20ba%2fr", L"\\\\foo%20ba%2fr" },
/* 5 and more leading (back)slashes */
{ L"file://///c:/foo/bar", L"\\\\c:\\foo\\bar" },
{ L"file://///c:/foo%20ba%2fr", L"\\\\c:\\foo ba/r" },
{ L"file://///foo%20ba%2fr", L"\\\\foo ba/r" },
{ L"file://////c:/foo/bar", L"\\\\c:\\foo\\bar" },
/* Leading (back)slashes cannot be escaped */
{ L"file:%2f%2flocalhost%2fc:/foo/bar", L"//localhost/c:\\foo\\bar" },
{ L"file:%5C%5Clocalhost%5Cc:/foo/bar", L"\\\\localhost\\c:\\foo\\bar" },
/* Hostname handling */
{ L"file://l%6fcalhost/c:/foo/bar", L"\\\\localhostc:\\foo\\bar" },
{ L"file://localhost:80/c:/foo/bar", L"\\\\localhost:80c:\\foo\\bar" },
{ L"file://host/c:/foo/bar", L"\\\\hostc:\\foo\\bar" },
{ L"file://host//c:/foo/bar", L"\\\\host\\\\c:\\foo\\bar" },
{ L"file://host/\\c:/foo/bar", L"\\\\host\\\\c:\\foo\\bar" },
{ L"file://host/c:foo/bar", L"\\\\hostc:foo\\bar" },
{ L"file://host/foo/bar", L"\\\\host\\foo\\bar" },
{ L"file:\\\\host\\c:\\foo\\bar", L"\\\\hostc:\\foo\\bar" },
{ L"file:\\\\host\\ca\\foo\\bar", L"\\\\host\\ca\\foo\\bar" },
{ L"file:\\\\host\\c|\\foo\\bar", L"\\\\hostc|\\foo\\bar" },
{ L"file:\\%5Chost\\c:\\foo\\bar", L"\\\\host\\c:\\foo\\bar" },
{ L"file:\\\\host\\cx:\\foo\\bar", L"\\\\host\\cx:\\foo\\bar" },
{ L"file:///host/c:/foo/bar", L"\\host\\c:\\foo\\bar" },
/* Not file URLs */
{ L"c:\\foo\\bar", NULL, E_INVALIDARG },
{ L"foo/bar", NULL, E_INVALIDARG },
{ L"http://foo/bar", NULL, E_INVALIDARG },
};
unsigned int i;
WCHAR *path;
HRESULT hr;
if (!pMFCreatePathFromURL)
{
win_skip("MFCreatePathFromURL() is not available.\n");
return;
}
hr = pMFCreatePathFromURL(NULL, NULL);
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
path = (void *)0xdeadbeef;
hr = pMFCreatePathFromURL(NULL, &path);
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
ok(path == (void *)0xdeadbeef, "Unexpected pointer %p.\n", path);
hr = pMFCreatePathFromURL(L"file://foo", NULL);
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
hr = pMFCreatePathFromURL(tests[i].url, &path);
ok(hr == tests[i].hr, "Unexpected hr %#lx, expected %#lx.\n", hr, tests[i].hr);
if (SUCCEEDED(hr))
{
ok(!wcscmp(path, tests[i].path), "Unexpected path %s, expected %s.\n",
debugstr_w(path), debugstr_w(tests[i].path));
CoTaskMemFree(path);
}
}
}
START_TEST(mfplat)
{
char **argv;
@ -9206,6 +9333,7 @@ START_TEST(mfplat)
test_MFCreateVideoMediaTypeFromVideoInfoHeader();
test_MFInitMediaTypeFromVideoInfoHeader();
test_MFInitMediaTypeFromAMMediaType();
test_MFCreatePathFromURL();
CoUninitialize();
}