From: Jactry Zeng Subject: [PATCH v6 2/3] mfplat: Implement IMFByteStream::{GetLength,SetLength}. Message-Id: <85ea27bf-c42e-f734-01dd-48904e1f4899@codeweavers.com> Date: Tue, 12 Feb 2019 16:24:33 +0800 Signed-off-by: Jactry Zeng --- dlls/mfplat/main.c | 30 ++++- dlls/mfplat/tests/Makefile.in | 2 +- dlls/mfplat/tests/mfplat.c | 199 +++++++++++++++++++++++++++++++++- 3 files changed, 224 insertions(+), 7 deletions(-) diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index ff559e6667..43218d667a 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -851,6 +851,7 @@ typedef struct _mfbytestream mfattributes attributes; IMFByteStream IMFByteStream_iface; IStream *stream; + QWORD length; } mfbytestream; static inline mfbytestream *impl_from_IMFByteStream(IMFByteStream *iface) @@ -923,18 +924,22 @@ static HRESULT WINAPI mfbytestream_GetLength(IMFByteStream *iface, QWORD *length { mfbytestream *This = impl_from_IMFByteStream(iface); - FIXME("%p, %p\n", This, length); + TRACE("(%p)->(%p)\n", This, length); - return E_NOTIMPL; + *length = This->length; + + return S_OK; } 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) @@ -1137,6 +1142,8 @@ static const IMFAttributesVtbl mfbytestream_attributes_vtbl = HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream) { mfbytestream *object; + ULARGE_INTEGER stream_size; + HRESULT hres; TRACE("(%p, %p): stub\n", stream, bytestream); @@ -1148,6 +1155,13 @@ HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **byt object->IMFByteStream_iface.lpVtbl = &mfbytestream_vtbl; object->attributes.IMFAttributes_iface.lpVtbl = &mfbytestream_attributes_vtbl; object->stream = stream; + hres = IStream_Size(object->stream, &stream_size); + if(FAILED(hres)) + { + heap_free(object); + return hres; + } + object->length = stream_size.QuadPart; IStream_AddRef(object->stream); *bytestream = &object->IMFByteStream_iface; @@ -1163,6 +1177,7 @@ HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE open DWORD attributes = FILE_ATTRIBUTE_NORMAL; BOOL create = FALSE, reset = FALSE; IStream *stream = NULL; + ULARGE_INTEGER stream_size; HRESULT hres; TRACE("(%d, %d, %d, %s, %p)\n", accessmode, openmode, flags, debugstr_w(url), bytestream); @@ -1226,6 +1241,13 @@ HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE open object->IMFByteStream_iface.lpVtbl = &mfbytestream_vtbl; object->attributes.IMFAttributes_iface.lpVtbl = &mfbytestream_attributes_vtbl; object->stream = stream; + hres = IStream_Size(object->stream, &stream_size); + if (FAILED(hres)) + { + heap_free(object); + return hres; + } + object->length = stream_size.QuadPart; *bytestream = &object->IMFByteStream_iface; 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 3c39be6ea9..2c7c12c5f3 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,195 @@ 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) || broken(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_READWRITE, 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, 1000); + 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 || broken(length == 1000) /* xp */, "got wrong length: %s.\n", wine_dbgstr_longlong(length)); + todo_wine CHECK_BS_POS(bytestream, 0); + read = 0xdeadbeef; + 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 == 0 || broken(read == 1000) /* xp */, "got wrong read length: %d.\n", read); + memset(buffer, 0, sizeof(buffer)); + 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 || broken(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) || broken(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 +974,8 @@ START_TEST(mfplat) test_MFCreateMFByteStreamOnStream(); test_MFCreateMemoryBuffer(); test_source_resolver(); + test_bytestream_from_file(); + test_bytestream_from_stream(); CoUninitialize(); } -- 2.20.1