Signed-off-by: Jactry Zeng <jzeng(a)codeweavers.com>
---
dlls/mfplat/main.c | 19 +++-
dlls/mfplat/tests/Makefile.in | 2 +-
dlls/mfplat/tests/mfplat.c | 194 +++++++++++++++++++++++++++++++++-
3 files changed, 208 insertions(+), 7 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 8aab65c28d..4f42fc0939 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -922,19 +922,30 @@ static HRESULT WINAPI mfbytestream_GetCapabilities(IMFByteStream *iface, DWORD *
static HRESULT WINAPI mfbytestream_GetLength(IMFByteStream *iface, QWORD *length)
{
mfbytestream *This = impl_from_IMFByteStream(iface);
+ HRESULT hr;
+ STATSTG statstg;
- FIXME("%p, %p\n", This, length);
+ TRACE("(%p)->(%p)\n", This, length);
- return E_NOTIMPL;
+ memset(&statstg, 0, sizeof(statstg));
+
+ hr = IStream_Stat(This->stream, &statstg, STATFLAG_NONAME);
+
+ if (SUCCEEDED(hr))
+ *length = statstg.cbSize.QuadPart;
+
+ return hr;
}
static HRESULT WINAPI mfbytestream_SetLength(IMFByteStream *iface, QWORD length)
{
mfbytestream *This = impl_from_IMFByteStream(iface);
+ ULARGE_INTEGER size;
- FIXME("%p, %s\n", This, wine_dbgstr_longlong(length));
+ TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(length));
- return E_NOTIMPL;
+ size.QuadPart = length;
+ return IStream_SetSize(This->stream, size);
}
static HRESULT WINAPI mfbytestream_GetCurrentPosition(IMFByteStream *iface, QWORD *position)
diff --git a/dlls/mfplat/tests/Makefile.in b/dlls/mfplat/tests/Makefile.in
index 07cf328ad2..f7f09aa33e 100644
--- a/dlls/mfplat/tests/Makefile.in
+++ b/dlls/mfplat/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = mfplat.dll
-IMPORTS = ole32 mfplat
+IMPORTS = ole32 mfplat shlwapi
C_SRCS = \
mfplat.c
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index a4f11da36e..dabc5f7301 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -33,6 +33,7 @@
#include "mfidl.h"
#include "mferror.h"
#include "mfreadwrite.h"
+#include "shlwapi.h"
#include "wine/test.h"
@@ -52,6 +53,9 @@ DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,
DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
+static const byte asf_header[] = {0x30,0x26,0xb2,0x75,0x8e,0x66,0xcf,0x11,
+ 0xa6,0xd9,0x00,0xaa,0x00,0x62,0xce,0x6c};
+
static const WCHAR mp4file[] = {'t','e','s','t','.','m','p','4',0};
#define CHECK_REF(obj,ref) _check_ref((IUnknown*)obj, ref, __LINE__)
@@ -638,7 +642,7 @@ static void test_MFCreateFile(void)
hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_APPEND_IF_EXIST,
MF_FILEFLAGS_ALLOW_WRITE_SHARING, filename, &bytestream);
ok(hr == S_OK, "MFCreateFile failed: 0x%08x.\n", hr);
- todo_wine CHECK_BS_LEN(bytestream, file_size);
+ CHECK_BS_LEN(bytestream, file_size);
todo_wine CHECK_BS_POS(bytestream, 0);
IMFByteStream_Release(bytestream);
CHECK_FILE_SIZE(filename, file_size);
@@ -653,7 +657,7 @@ static void test_MFCreateFile(void)
hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_RESET_IF_EXIST,
MF_FILEFLAGS_NONE, filename, &bytestream);
ok(hr == S_OK, "MFCreateFile failed: 0x%08x.\n", hr);
- todo_wine CHECK_BS_LEN(bytestream, 0);
+ CHECK_BS_LEN(bytestream, 0);
todo_wine CHECK_BS_POS(bytestream, 0);
IMFByteStream_Release(bytestream);
CHECK_FILE_SIZE(filename, 0);
@@ -766,6 +770,190 @@ static void test_MFSample(void)
IMFSample_Release(sample);
}
+static void test_bytestream_from_file(void)
+{
+ IMFByteStream *bytestream;
+ HRESULT hr;
+ HANDLE file;
+ static WCHAR asffile[] = {'t','e','s','t','.','a','s','f',0};
+ byte buffer[1024] = {0};
+ byte test_data[] = {0x1,0x2,0x3,0x4};
+ ULONG written, read;
+ QWORD length;
+
+ file = CreateFileW(asffile, GENERIC_READ|GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, 0, 0);
+ ok(file != INVALID_HANDLE_VALUE, "File creation failed: 0x%08x.\n", GetLastError());
+ WriteFile(file, asf_header, sizeof(asf_header), &written, NULL);
+ CloseHandle(file);
+
+ hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
+ ok(hr == S_OK, "MFStartup failed: 0x%08x.\n", hr);
+
+ hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
+ MF_FILEFLAGS_NONE, asffile, &bytestream);
+ ok(hr == S_OK, "MFCreateFile failed: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ read = 0;
+ hr = IMFByteStream_Read(bytestream, buffer, sizeof(buffer), &read);
+ todo_wine ok(hr == S_OK, "IMFByteStream_Read failed: 0x%08x.\n", hr);
+ todo_wine ok(read == sizeof(asf_header), "got wrong read length: %d.\n", read);
+ todo_wine ok(!memcmp(buffer, asf_header, sizeof(asf_header)), "got wrong content.\n");
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+ memset(buffer, 0, sizeof(buffer));
+ hr = IMFByteStream_Write(bytestream, asf_header, sizeof(asf_header), &written);
+ todo_wine ok(hr == E_ACCESSDENIED, "IMFByteStream_Write should fail: 0x%08x.\n", hr);
+ hr = IMFByteStream_SetLength(bytestream, 200);
+ ok(hr == E_FAIL, "IMFByteStream_SetLength should fail: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ IMFByteStream_Release(bytestream);
+
+ hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
+ MF_FILEFLAGS_NONE, asffile, &bytestream);
+ ok(hr == S_OK, "MFCreateFile failed: 0x%08x.\n", hr);
+ hr = IMFByteStream_Read(bytestream, buffer, sizeof(buffer), &read);
+ todo_wine ok(hr == E_ACCESSDENIED, "IMFByteStream_Read should fail: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ written = 0xdeadbeef;
+ hr = IMFByteStream_Write(bytestream, asf_header, sizeof(asf_header), &written);
+ todo_wine ok(hr == S_OK, "IMFByteStream_Write failed: 0x%08x.\n", hr);
+ todo_wine ok(written == sizeof(asf_header), "got wrong written length: %d.\n", written);
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+
+ hr = IMFByteStream_SetLength(bytestream, sizeof(asf_header) + 2);
+ ok(hr == S_OK, "IMFByteStream_SetLength failed: 0x%08x.\n", hr);
+ length = 0xdeadbeef;
+ hr = IMFByteStream_GetLength(bytestream, &length);
+ ok(hr == S_OK, "IMFByteStream_GetLength failed: 0x%08x.\n", hr);
+ ok(length == sizeof(asf_header) || length == (sizeof(asf_header) + 2) /* xp */,
+ "got wrong length: %s.\n", wine_dbgstr_longlong(length));
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+ IMFByteStream_Release(bytestream);
+ file = CreateFileW(asffile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+ ReadFile(file, buffer, sizeof(buffer), &read, NULL);
+ ok(read == sizeof(asf_header) + 2, "got wrong read length: %d.\n", read);
+ ok(!memcmp(buffer, asf_header, sizeof(asf_header)), "got wrong content.\n");
+ memset(buffer, 0, sizeof(buffer));
+ CloseHandle(file);
+
+ hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_APPEND_IF_EXIST,
+ MF_FILEFLAGS_NONE, asffile, &bytestream);
+ ok(hr == S_OK, "MFCreateFile failed: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ CHECK_BS_LEN(bytestream, sizeof(asf_header) + 2);
+ written = 0xdeadbeef;
+ hr = IMFByteStream_Write(bytestream, test_data, sizeof(test_data), &written);
+ todo_wine ok(hr == S_OK, "IMFByteStream_Write failed: 0x%08x.\n", hr);
+ todo_wine ok(written == sizeof(test_data), "got wrong written length: %d.\n", written);
+ CHECK_BS_LEN(bytestream, sizeof(asf_header) + 2);
+ todo_wine CHECK_BS_POS(bytestream, sizeof(test_data));
+ IMFByteStream_Release(bytestream);
+
+ hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_RESET_IF_EXIST,
+ MF_FILEFLAGS_NONE, asffile, &bytestream);
+ ok(hr == S_OK, "MFCreateFile failed: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ CHECK_BS_LEN(bytestream, 0);
+ hr = IMFByteStream_SetLength(bytestream, 2000);
+ ok(hr == S_OK, "IMFByteStream_SetLength failed: 0x%08x.\n", hr);
+ length = 0xdeadbeef;
+ hr = IMFByteStream_GetLength(bytestream, &length);
+ ok(hr == S_OK, "IMFByteStream_GetLength failed: 0x%08x.\n", hr);
+ ok(length == 0 || length == 2000 /* xp */, "got wrong length: %s.\n", wine_dbgstr_longlong(length));
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ IMFByteStream_Release(bytestream);
+
+ MFShutdown();
+ DeleteFileW(asffile);
+}
+
+static void test_bytestream_from_stream(void)
+{
+ IMFByteStream *bytestream;
+ IStream *stream;
+ HRESULT hr;
+ HANDLE file;
+ static WCHAR asffile[] = {'t','e','s','t','.','a','s','f',0};
+ byte buffer[1024] = {0};
+ ULONG written, read;
+ QWORD length;
+
+ if(!pMFCreateMFByteStreamOnStream)
+ {
+ win_skip("MFCreateMFByteStreamOnStream() not found\n");
+ return;
+ }
+
+ file = CreateFileW(asffile, GENERIC_READ|GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, 0, 0);
+ ok(file != INVALID_HANDLE_VALUE, "File creation failed: 0x%08x.\n", GetLastError());
+ WriteFile(file, asf_header, sizeof(asf_header), &written, NULL);
+ CloseHandle(file);
+
+ hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
+ ok(hr == S_OK, "MFStartup failed: 0x%08x.\n", hr);
+
+ hr = SHCreateStreamOnFileW(asffile, STGM_READ|STGM_FAILIFTHERE|STGM_SHARE_DENY_WRITE, &stream);
+ ok(hr == S_OK, "SHCreateStreamOnFileEx failed: 0x%08x.\n", hr);
+ hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
+ ok(hr == S_OK, "MFCreateMFByteStreamOnStream failed: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ hr = IMFByteStream_Read(bytestream, buffer, sizeof(buffer), &read);
+ todo_wine ok(hr == S_FALSE, "IMFByteStream_Read returned: 0x%08x.\n", hr);
+ todo_wine ok(read == sizeof(asf_header), "got wrong read length: %d.\n", read);
+ todo_wine ok(!memcmp(buffer, asf_header, sizeof(asf_header)), "got wrong content.\n");
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+ memset(buffer, 0, sizeof(buffer));
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ hr = IMFByteStream_SetLength(bytestream, 200);
+ ok(hr == E_FAIL || hr == S_OK, "IMFByteStream_SetLength should fail: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ IMFByteStream_Release(bytestream);
+ IStream_Release(stream);
+
+ hr = SHCreateStreamOnFileW(asffile, STGM_WRITE|STGM_FAILIFTHERE|STGM_SHARE_DENY_WRITE, &stream);
+ ok(hr == S_OK, "SHCreateStreamOnFileEx failed: 0x%08x.\n", hr);
+ hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
+ ok(hr == S_OK, "MFCreateMFByteStreamOnStream failed: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ hr = IMFByteStream_Read(bytestream, buffer, sizeof(buffer), &read);
+ todo_wine ok(hr == S_FALSE, "IMFByteStream_Read should fail: 0x%08x.\n", hr);
+ todo_wine CHECK_BS_POS(bytestream, 0);
+ written = 0xdeadbeef;
+ hr = IMFByteStream_Write(bytestream, asf_header, sizeof(asf_header), &written);
+ todo_wine ok(hr == S_OK, "IMFByteStream_Write failed: 0x%08x.\n", hr);
+ todo_wine ok(written == sizeof(asf_header), "got wrong written length: %d.\n", written);
+ CHECK_BS_LEN(bytestream, sizeof(asf_header));
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+
+ hr = IMFByteStream_SetLength(bytestream, sizeof(asf_header) + 2);
+ ok(hr == S_OK, "IMFByteStream_SetLength failed: 0x%08x.\n", hr);
+ length = 0xdeadbeef;
+ hr = IMFByteStream_GetLength(bytestream, &length);
+ ok(hr == S_OK, "IMFByteStream_GetLength failed: 0x%08x.\n", hr);
+ ok(length == sizeof(asf_header) || length == (sizeof(asf_header) + 2) /* xp */,
+ "got wrong length: %s.\n", wine_dbgstr_longlong(length));
+ todo_wine CHECK_BS_POS(bytestream, sizeof(asf_header));
+ IMFByteStream_Release(bytestream);
+ IStream_Release(stream);
+ file = CreateFileW(asffile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+ ReadFile(file, buffer, sizeof(buffer), &read, NULL);
+ ok(read == sizeof(asf_header) + 2, "got wrong read length: %d.\n", read);
+ ok(!memcmp(buffer, asf_header, sizeof(asf_header)), "got wrong content.\n");
+ memset(buffer, 0, sizeof(buffer));
+ CloseHandle(file);
+
+ MFShutdown();
+ DeleteFileW(asffile);
+}
+
START_TEST(mfplat)
{
CoInitialize(NULL);
@@ -781,6 +969,8 @@ START_TEST(mfplat)
test_MFCreateMFByteStreamOnStream();
test_MFCreateMemoryBuffer();
test_source_resolver();
+ test_bytestream_from_file();
+ test_bytestream_from_stream();
CoUninitialize();
}
--
2.20.1