[PATCH v6 rebase 2/3] mfplat: Implement IMFByteStream::{GetLength,SetLength}.

Jactry Zeng jzeng at codeweavers.com
Mon Feb 25 00:41:06 CST 2019


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 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 2df195218b..49eefce641 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -923,6 +923,7 @@ typedef struct _mfbytestream
     mfattributes attributes;
     IMFByteStream IMFByteStream_iface;
     IStream *stream;
+    QWORD length;
 } mfbytestream;
 
 static inline mfbytestream *impl_from_IMFByteStream(IMFByteStream *iface)
@@ -995,18 +996,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)
@@ -1209,6 +1214,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);
 
@@ -1220,6 +1227,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;
@@ -1235,6 +1249,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);
@@ -1298,6 +1313,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 0f039fe44f..76ac919f55 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"
 
@@ -56,6 +57,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__)
@@ -637,7 +641,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);
@@ -652,7 +656,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);
@@ -1108,6 +1112,195 @@ static void test_MFHeapAlloc(void)
     pMFHeapFree(res);
 }
 
+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);
@@ -1129,6 +1322,8 @@ START_TEST(mfplat)
     test_MFCopyImage();
     test_MFCreateCollection();
     test_MFHeapAlloc();
+    test_bytestream_from_file();
+    test_bytestream_from_stream();
 
     CoUninitialize();
 }
-- 
2.20.1





More information about the wine-devel mailing list