[PATCH v2 1/5] mfplat: Add MFCreateFile stub

Zebediah Figura z.figura12 at gmail.com
Mon Oct 29 20:12:50 CDT 2018


On 10/29/18 5:26 PM, Sven Baars wrote:
> Signed-off-by: Sven Baars <sven.wine at gmail.com>
> ---
> 
> This patch series stops Disgaea 5 from crashing. This is the first time I
> send any functional patches, so feel free to correct me.
> 
> v2: Use the right Release method and test for IUnknown
> 
>   dlls/mfplat/main.c            |  30 ++++++++++
>   dlls/mfplat/mfplat.spec       |   2 +-
>   dlls/mfplat/tests/Makefile.in |   2 +
>   dlls/mfplat/tests/mfplat.c    | 101 +++++++++++++++++++++++++++++++++-
>   dlls/mfplat/tests/resource.rc |  24 ++++++++
>   dlls/mfplat/tests/test.mp4    | Bin 0 -> 1554 bytes
>   include/mfapi.h               |   2 +
>   7 files changed, 159 insertions(+), 2 deletions(-)
>   create mode 100644 dlls/mfplat/tests/resource.rc
>   create mode 100644 dlls/mfplat/tests/test.mp4
> 
> diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
> index bd6b99f1fa..0bf4d07bbd 100644
> --- a/dlls/mfplat/main.c
> +++ b/dlls/mfplat/main.c
> @@ -452,6 +452,8 @@ typedef struct _mfbytestream
>   {
>       IMFByteStream IMFByteStream_iface;
>       LONG ref;
> +
> +    IMFAttributes *attributes;
>   } mfbytestream;
>   
>   static inline mfbytestream *impl_from_IMFByteStream(IMFByteStream *iface)
> @@ -470,6 +472,10 @@ static HRESULT WINAPI mfbytestream_QueryInterface(IMFByteStream *iface, REFIID r
>       {
>           *out = &This->IMFByteStream_iface;
>       }
> +    else if(IsEqualGUID(riid, &IID_IMFAttributes) && This->attributes)
> +    {
> +        *out = This->attributes;
> +    }
>       else
>       {
>           FIXME("(%s, %p)\n", debugstr_guid(riid), out);

Unfortunately this won't work, as then the IMFAttributes interface can't 
return an IMFByteStream when queried in re

> @@ -500,6 +506,8 @@ static ULONG  WINAPI mfbytestream_Release(IMFByteStream *iface)
>   
>       if (!ref)
>       {
> +        if (This->attributes)
> +            IMFAttributes_Release(This->attributes);
>           HeapFree(GetProcessHeap(), 0, This);
>       }
>   
> @@ -681,12 +689,34 @@ HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **byt
>   
>       object->ref = 1;
>       object->IMFByteStream_iface.lpVtbl = &mfbytesteam_vtbl;
> +    MFCreateAttributes(&object->attributes, 0);
> +
> +    *bytestream = &object->IMFByteStream_iface;
> +
> +    return S_OK;
> +}
> +
> +HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags,
> +                            LPCWSTR url, IMFByteStream **bytestream)
> +{
> +    mfbytestream *object;
> +
> +    FIXME("(%d, %d, %d, %s, %p): stub\n", accessmode, openmode, flags, debugstr_w(url), bytestream);
> +
> +    object = heap_alloc( sizeof(*object) );
> +    if(!object)
> +        return E_OUTOFMEMORY;
> +
> +    object->ref = 1;
> +    object->IMFByteStream_iface.lpVtbl = &mfbytesteam_vtbl;
> +    MFCreateAttributes(&object->attributes, 0);
>   
>       *bytestream = &object->IMFByteStream_iface;
>   
>       return S_OK;
>   }

I think it probably wouldn't be too difficult to implement this directly 
on top of MFCreateMFByteStreamOnStream, using SHCreateStreamOnFile(). 
Obviously the latter doesn't do anything yet, but the implementation 
seems pretty clear.

>   
> +

Stray newline.

>   static HRESULT WINAPI MFPluginControl_QueryInterface(IMFPluginControl *iface, REFIID riid, void **ppv)
>   {
>       if(IsEqualGUID(riid, &IID_IUnknown)) {
> diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
> index 3e42d2fd70..4533eeb71c 100644
> --- a/dlls/mfplat/mfplat.spec
> +++ b/dlls/mfplat/mfplat.spec
> @@ -43,7 +43,7 @@
>   @ stub MFCreateAudioMediaType
>   @ stub MFCreateCollection
>   @ stdcall MFCreateEventQueue(ptr)
> -@ stub MFCreateFile
> +@ stdcall MFCreateFile(long long long wstr ptr)
>   @ stub MFCreateLegacyMediaBufferOnMFMediaBuffer
>   @ stdcall MFCreateMFByteStreamOnStream(ptr ptr)
>   @ stub MFCreateMFVideoFormatFromMFMediaType
> diff --git a/dlls/mfplat/tests/Makefile.in b/dlls/mfplat/tests/Makefile.in
> index a5553a5af3..07cf328ad2 100644
> --- a/dlls/mfplat/tests/Makefile.in
> +++ b/dlls/mfplat/tests/Makefile.in
> @@ -3,3 +3,5 @@ IMPORTS   = ole32 mfplat
>   
>   C_SRCS = \
>   	mfplat.c
> +
> +RC_SRCS = resource.rc
> diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
> index 17cdc46579..2c7dfda767 100644
> --- a/dlls/mfplat/tests/mfplat.c
> +++ b/dlls/mfplat/tests/mfplat.c
> @@ -49,6 +49,36 @@ 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 WCHAR mp4file[] = {'t','e','s','t','.','m','p','4',0};
> +
> +static WCHAR *load_resource(const WCHAR *name)
> +{
> +    static WCHAR pathW[MAX_PATH];
> +    DWORD written;
> +    HANDLE file;
> +    HRSRC res;
> +    void *ptr;
> +
> +    GetTempPathW(ARRAY_SIZE(pathW), pathW);
> +    lstrcatW(pathW, name);
> +
> +    file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
> +                       NULL, CREATE_ALWAYS, 0, 0);
> +    ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
> +       wine_dbgstr_w(pathW), GetLastError());
> +
> +    res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
> +    ok(res != 0, "couldn't find resource\n");
> +    ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
> +    WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
> +               &written, NULL);
> +    ok(written == SizeofResource(GetModuleHandleA(NULL), res),
> +       "couldn't write resource\n" );
> +    CloseHandle(file);
> +
> +    return pathW;
> +}
> +
>   static BOOL check_clsid(CLSID *clsids, UINT32 count)
>   {
>       int i;
> @@ -170,6 +200,9 @@ static void test_source_resolver(void)
>   {
>       IMFSourceResolver *resolver, *resolver2;
>       HRESULT hr;
> +    WCHAR *filename;
> +
> +    static const WCHAR file_type[] = {'v','i','d','e','o','/','m','p','4',0};
>   
>       if (!pMFCreateSourceResolver)
>       {
> @@ -177,6 +210,12 @@ static void test_source_resolver(void)
>           return;
>       }
>   
> +    hr = MFStartup(MAKELONG( MF_API_VERSION, 0xdead ), MFSTARTUP_FULL);
> +    ok(hr == MF_E_BAD_STARTUP_VERSION, "got 0x%08x\n", hr);
> +
> +    hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
> +    ok(hr == S_OK, "got 0x%08x\n", hr);
> +

These tests should be submitted in a separate patch.

>       hr = pMFCreateSourceResolver(NULL);
>       ok(hr == E_POINTER, "got %#x\n", hr);
>   
> @@ -259,6 +298,8 @@ static void test_MFCreateMFByteStreamOnStream(void)
>   {
>       IMFByteStream *bytestream;
>       IStream *stream;
> +    IMFAttributes *attributes = NULL;
> +    IUnknown *unknown;
>       HRESULT hr;
>   
>       if(!pMFCreateMFByteStreamOnStream)
> @@ -270,13 +311,70 @@ static void test_MFCreateMFByteStreamOnStream(void)
>       hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
>       ok(hr == S_OK, "got 0x%08x\n", hr);
>   
> -    hr = pMFCreateMFByteStreamOnStream(stream, &bytestream );
> +    hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
>       ok(hr == S_OK, "got 0x%08x\n", hr);
>   
> +    hr = IUnknown_QueryInterface(bytestream, &IID_IMFAttributes,
> +                                 (void **)&attributes);
> +    ok(hr == S_OK ||
> +       /* w7pro64 */
> +       broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
> +
> +    if (hr == S_OK)
> +    {
> +        ok(attributes != NULL, "got NULL\n");
> +        IMFAttributes_Release(attributes);
> +    }
> +
> +    hr = IUnknown_QueryInterface(bytestream, &IID_IUnknown,
> +                                 (void **)&unknown);
> +    ok(hr == S_OK, "got 0x%08x\n", hr);
> +    ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
> +    IUnknown_Release(unknown);
> +

Possibly these should be in a separate patch as well, i.e. I'd submit 
one patch to add IMFAttributes to IMFByteStream, and one to implement 
MFCreateFile().

>       IStream_Release(stream);
>       IMFByteStream_Release(bytestream);
>   }
>   
> +static void test_MFCreateFile(void)
> +{
> +    IMFByteStream *bytestream;
> +    IMFAttributes *attributes = NULL;
> +    IUnknown *unknown;
> +    HRESULT hr;
> +    WCHAR *filename;
> +
> +    filename = load_resource(mp4file);
> +
> +    hr = MFStartup(MAKELONG( MF_API_VERSION, 0xdead ), MFSTARTUP_FULL);
> +    ok(hr == MF_E_BAD_STARTUP_VERSION, "got 0x%08x\n", hr);
> +

This test is redundant and not really relevant here.

> +    hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
> +    ok(hr == S_OK, "got 0x%08x\n", hr);
> +
> +    hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
> +                      MF_FILEFLAGS_NONE, filename, &bytestream);
> +    ok(hr == S_OK, "got 0x%08x\n", hr);
> +
> +    hr = IUnknown_QueryInterface(bytestream, &IID_IMFAttributes,
> +                                 (void **)&attributes);
> +    ok(hr == S_OK, "got 0x%08x\n", hr);
> +    ok(attributes != NULL, "got NULL\n");
> +    IMFAttributes_Release(attributes);
> +
> +    hr = IUnknown_QueryInterface(bytestream, &IID_IUnknown,
> +                                 (void **)&unknown);
> +    ok(hr == S_OK, "got 0x%08x\n", hr);
> +    ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
> +    IUnknown_Release(unknown);
> +
> +    IMFByteStream_Release(bytestream);
> +
> +    MFShutdown();
> +
> +    DeleteFileW(filename);
> +}
> +
>   static void test_MFCreateMemoryBuffer(void)
>   {
>       IMFMediaBuffer *buffer;
> @@ -390,6 +488,7 @@ START_TEST(mfplat)
>       test_MFCreateMediaType();
>       test_MFCreateAttributes();
>       test_MFSample();
> +    test_MFCreateFile();
>       test_MFCreateMFByteStreamOnStream();
>       test_MFCreateMemoryBuffer();
>   
> diff --git a/dlls/mfplat/tests/resource.rc b/dlls/mfplat/tests/resource.rc
> new file mode 100644
> index 0000000000..e9bf920c31
> --- /dev/null
> +++ b/dlls/mfplat/tests/resource.rc
> @@ -0,0 +1,24 @@
> +/*
> + * Resources for mfplat test suite.
> + *
> + * Copyright 2018 Sven Baars
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
> + */
> +
> +#include "windef.h"
> +
> +/* @makedep: test.mp4 */
> +test.mp4 RCDATA test.mp4
> diff --git a/dlls/mfplat/tests/test.mp4 b/dlls/mfplat/tests/test.mp4
> new file mode 100644
> index 0000000000000000000000000000000000000000..a5bbca6bbf7692eab047050b79b8ccc83516e6b4
> GIT binary patch
> literal 1554
> zcmZuxeN0nV6u<3bttg}g3M<<3v4A5C7=;cYskS&=aH+Gw(TQ=|2k#+BpKbac6$q26
> zgvfMZE^O--6L1NclR1flh8QLw4%rM5#eGC{R2Jv(j|s9(8MANazOwnmo#gk<x#yhw
> zyZ4 at R-$e*%%DGx+CF@`ik|L}DS&UP!LkKM^chNNX_cIj9Atd<{DdnJiN*lZEK&*TH
> zLUnilE|&Pi#`t<(V2JeCh0xUFbE~$JpP!3QD)e^to at B05Kdu~jt~KuYz}1=h$wy;^
> z-(P&iYuL#r*6qMlmYD;w&8gboiuVmim)E`@VY(w}d_`I2ihOP3>WzsJPV$oN<)LWX
> zeE-6+iWMz`xA<B45szMa^nqwQ5w>wzrc-v;{3ns3&Hgygab at co_v%sWh^~kxZdgv1
> zG$e27=y&X0FwfM)&vJ1wQfF>hX5`>p!|hca@<xwAt#6-gnD>;lG>BPmWrt3nUp`73
> z+Yr|+TbnzS=UsV1v;C6gviW|rw)-!S-=bHn;0v1+QGDC}Ia|1D&?ob%jF`h$Wc#Ew
> zV;vf3`obS*$vM<kEDwCQ`|#nw>4L6xr#4wnKY06wGT*}wdIn7LW=}zVn#?n%4mVMz
> zS*QG<-xMcs%$)a1n<6jX{=IjfF~joa!xMeyYRwY|Cr0Vm>*3w%uu#*`=0;_WapAn$
> zU<`El at AbuA79AjpWMkq|c1;#tZJ#~+J(2cx>Nm%BvdmP*5AP|wGW~$TESZLVhn6a1
> ztO^C+GL%><v}DW7eXsQJ-HUG|I!ZcwqEv0#Ya at m<t5KG7N5rlo$2IYtr*eGsbj8h0
> z?c at jJ8?GH6PW~!_$shUIcJraKf^47ff8>qKKRQs;^7r5rKP{`hCoZsRD*LTIOV>}^
> zv}Z#0Dsy%(f4!(s5zT+wRX-W1@{bU&DxT$gcYNB95Wz4GhZ`=WopD!CphZIb3Y&Tt
> zN#HB;J~@EE6G4Pb;@qcgDO~ywITu+4q3v9iuqGi&TV#WEm&%fL{&(FFn1q2)5>0U|
> zXbo*=;Rh207#4X2E~$c{DoKbWFx1ksXMtOViZ2NB(km#tOR(VMuB70{eJoZOI||7?
> zl%2*olCw<Zo^mi$Zbl##Z##(!#x#_R#yMDUJgnMfPYBwQI+iQ7gFVc0?7t1cIX-wf
> zaHFt at IfI@MICdeJ7+9Xp2>Ks?)jSUa8_iO<Oo;G!Jey%!2<ZHT2<$>SD4dRa20SkU
> zV;68rdYYqx<dOt*;hjTh6eXe7GH{(SlkT#Yax=1Y8M;ip4CY9n)kw{9LK`q0-qUjY
> z7J{U}>4bH`mH}`KUjy7ccnDD_0CJHA at _=3toU_OwXamIR7Gqf9{35_wfE7@%h&<3n
> zKs;bQARC}!xiSZ6ESNJ5P+CoKB<O7nEod-NqPX>NU0kHoiM#Wkq*n&-SMq0^0~2cD
> TJ;x-N6hTeOp(eUDP!ruh^$B~#
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/include/mfapi.h b/include/mfapi.h
> index bc832bf95f..0230a08471 100644
> --- a/include/mfapi.h
> +++ b/include/mfapi.h
> @@ -67,6 +67,8 @@ HRESULT WINAPI MFCancelWorkItem(MFWORKITEM_KEY key);
>   HRESULT WINAPI MFCopyImage(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride, DWORD width, DWORD lines);
>   HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size);
>   HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue);
> +HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags,
> +                            LPCWSTR url, IMFByteStream **bytestream);
>   HRESULT WINAPI MFCreateMediaType(IMFMediaType **type);
>   HRESULT WINAPI MFCreateSample(IMFSample **sample);
>   HRESULT WINAPI MFCreateMemoryBuffer(DWORD max_length, IMFMediaBuffer **buffer);
> 



More information about the wine-devel mailing list