diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index f38ca7b99e0..33080d0b278 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -1150,6 +1150,77 @@ HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **byt return S_OK; } +HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags, + LPCWSTR url, IMFByteStream **bytestream) +{ + mfbytestream *object; + DWORD fileaccessmode = 0; + DWORD filesharemode = FILE_SHARE_READ; + DWORD filecreation_disposition = 0; + DWORD fileattributes = 0; + HANDLE file; + + FIXME("(%d, %d, %d, %s, %p): stub\n", accessmode, openmode, flags, debugstr_w(url), bytestream); + + switch (accessmode) + { + case MF_ACCESSMODE_READ: + fileaccessmode = GENERIC_READ; + break; + case MF_ACCESSMODE_WRITE: + fileaccessmode = GENERIC_WRITE; + break; + case MF_ACCESSMODE_READWRITE: + fileaccessmode = GENERIC_READ | GENERIC_WRITE; + break; + } + + switch (openmode) + { + case MF_OPENMODE_FAIL_IF_NOT_EXIST: + filecreation_disposition = OPEN_EXISTING; + break; + case MF_OPENMODE_FAIL_IF_EXIST: + filecreation_disposition = CREATE_NEW; + break; + case MF_OPENMODE_RESET_IF_EXIST: + filecreation_disposition = TRUNCATE_EXISTING; + break; + case MF_OPENMODE_APPEND_IF_EXIST: + filecreation_disposition = OPEN_ALWAYS; + fileaccessmode |= FILE_APPEND_DATA; + break; + case MF_OPENMODE_DELETE_IF_EXIST: + filecreation_disposition = CREATE_ALWAYS; + break; + } + + if (flags & MF_FILEFLAGS_NOBUFFERING) + fileattributes |= FILE_FLAG_NO_BUFFERING; + + /* Open HANDLE to file */ + file = CreateFileW(url, fileaccessmode, filesharemode, NULL, + filecreation_disposition, fileattributes, 0); + + if(file == INVALID_HANDLE_VALUE) + return HRESULT_FROM_WIN32(GetLastError()); + + /* Close the file again, since we don't do anything with it yet */ + CloseHandle(file); + + object = heap_alloc( sizeof(*object) ); + if(!object) + return E_OUTOFMEMORY; + + init_attribute_object(&object->attributes, 0); + object->IMFByteStream_iface.lpVtbl = &mfbytestream_vtbl; + object->attributes.IMFAttributes_iface.lpVtbl = &mfbytestream_attributes_vtbl; + + *bytestream = &object->IMFByteStream_iface; + + return S_OK; +} + 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 3e42d2fd703..4533eeb71cf 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 a5553a5af31..07cf328ad28 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 4605e20f321..61cfbbfe897 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; @@ -326,6 +356,95 @@ static void test_MFCreateMFByteStreamOnStream(void) IStream_Release(stream); } +static void test_MFCreateFile(void) +{ + IMFByteStream *bytestream; + IMFByteStream *bytestream2; + IMFAttributes *attributes = NULL; + HRESULT hr; + WCHAR *filename; + + static const WCHAR newfilename[] = {'n','e','w','.','m','p','4',0}; + + filename = load_resource(mp4file); + + 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 = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_NONE, filename, &bytestream2); + ok(hr == S_OK, "got 0x%08x\n", hr); + IMFByteStream_Release(bytestream2); + + hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_NONE, filename, &bytestream2); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "got 0x%08x\n", hr); + if (hr == S_OK) IMFByteStream_Release(bytestream2); + + hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_NONE, filename, &bytestream2); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "got 0x%08x\n", hr); + if (hr == S_OK) IMFByteStream_Release(bytestream2); + + IMFByteStream_Release(bytestream); + + hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_NONE, newfilename, &bytestream); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr); + + hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST, + MF_FILEFLAGS_NONE, filename, &bytestream); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "got 0x%08x\n", hr); + + hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST, + MF_FILEFLAGS_NONE, newfilename, &bytestream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_NONE, newfilename, &bytestream2); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "got 0x%08x\n", hr); + if (hr == S_OK) IMFByteStream_Release(bytestream2); + + hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_NONE, newfilename, &bytestream2); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "got 0x%08x\n", hr); + if (hr == S_OK) IMFByteStream_Release(bytestream2); + + hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream2); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "got 0x%08x\n", hr); + if (hr == S_OK) IMFByteStream_Release(bytestream2); + + IMFByteStream_Release(bytestream); + + hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */ + hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream2); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "got 0x%08x\n", hr); + if (hr == S_OK) IMFByteStream_Release(bytestream2); + + IMFByteStream_Release(bytestream); + + MFShutdown(); + + DeleteFileW(filename); + DeleteFileW(newfilename); +} + static void test_MFCreateMemoryBuffer(void) { IMFMediaBuffer *buffer; @@ -439,6 +558,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 00000000000..e9bf920c319 --- /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 00000000000..a5bbca6bbf7 Binary files /dev/null and b/dlls/mfplat/tests/test.mp4 differ diff --git a/include/mfapi.h b/include/mfapi.h index bc832bf95f4..0230a084717 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);