From 63db2d2e922b2b796f4d37202579a4f1220e236b Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 16 Mar 2014 16:06:28 +0400 Subject: [PATCH] scrrun: Implement CreateTextFile(). --- dlls/scrrun/filesystem.c | 51 +++++++++++++++++++---- dlls/scrrun/tests/filesystem.c | 74 ++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 8 deletions(-) diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index d87ba303b01..1d47d730eb5 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -109,6 +109,7 @@ struct textstream { LONG ref; IOMode mode; + HANDLE file; }; enum iotype { @@ -245,7 +246,10 @@ static ULONG WINAPI textstream_Release(ITextStream *iface) TRACE("(%p)->(%d)\n", This, ref); if (!ref) + { + CloseHandle(This->file); heap_free(This); + } return ref; } @@ -435,9 +439,26 @@ static const ITextStreamVtbl textstreamvtbl = { textstream_Close }; -static HRESULT create_textstream(IOMode mode, ITextStream **ret) +static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMode mode, ITextStream **ret) { struct textstream *stream; + DWORD access = 0; + + /* map access mode */ + switch (mode) + { + case ForReading: + access = GENERIC_READ; + break; + case ForWriting: + access = GENERIC_WRITE; + break; + case ForAppending: + access = FILE_APPEND_DATA; + break; + default: + return E_INVALIDARG; + } stream = heap_alloc(sizeof(struct textstream)); if (!stream) return E_OUTOFMEMORY; @@ -446,6 +467,14 @@ static HRESULT create_textstream(IOMode mode, ITextStream **ret) stream->ref = 1; stream->mode = mode; + stream->file = CreateFileW(filename, access, 0, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL); + if (stream->file == INVALID_HANDLE_VALUE) + { + HRESULT hr = create_error(GetLastError()); + heap_free(stream); + return hr; + } + *ret = &stream->ITextStream_iface; return S_OK; } @@ -3257,21 +3286,27 @@ static HRESULT WINAPI filesys_CreateFolder(IFileSystem3 *iface, BSTR path, return create_folder(path, folder); } -static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR FileName, - VARIANT_BOOL Overwrite, VARIANT_BOOL Unicode, - ITextStream **ppts) +static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR filename, + VARIANT_BOOL overwrite, VARIANT_BOOL unicode, + ITextStream **stream) { - FIXME("%p %s %d %d %p\n", iface, debugstr_w(FileName), Overwrite, Unicode, ppts); + DWORD disposition; - return E_NOTIMPL; + TRACE("%p %s %d %d %p\n", iface, debugstr_w(filename), overwrite, unicode, stream); + + disposition = overwrite == VARIANT_TRUE ? CREATE_ALWAYS : CREATE_NEW; + return create_textstream(filename, disposition, ForWriting, stream); } static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename, IOMode mode, VARIANT_BOOL create, Tristate format, ITextStream **stream) { - FIXME("(%p)->(%s %d %d %d %p)\n", iface, debugstr_w(filename), mode, create, format, stream); - return create_textstream(mode, stream); + DWORD disposition; + + TRACE("(%p)->(%s %d %d %d %p)\n", iface, debugstr_w(filename), mode, create, format, stream); + disposition = create == VARIANT_TRUE ? OPEN_ALWAYS : OPEN_EXISTING; + return create_textstream(filename, disposition, mode, stream); } static HRESULT WINAPI filesys_GetStandardStream(IFileSystem3 *iface, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index c62b2bca535..3e8d4bbd8fc 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -167,6 +167,28 @@ static void test_textstream(void) ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK); ok(b == VARIANT_TRUE, "got %x\n", b); + /* different mode combinations */ + hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForAppending, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = IFileSystem3_OpenTextFile(fs3, name, ForReading | ForAppending, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForReading, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextStream_Read(stream, 1, &data); + ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr); + ITextStream_Release(stream); + + hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextStream_Read(stream, 1, &data); + ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr); + ITextStream_Release(stream); + hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -1192,6 +1214,57 @@ static void test_DriveCollection(void) IDriveCollection_Release(drives); } +static void test_CreateTextFile(void) +{ + static const WCHAR scrrunW[] = {'s','c','r','r','u','n','\\',0}; + static const WCHAR testfileW[] = {'t','e','s','t','.','t','x','t',0}; + WCHAR pathW[MAX_PATH], dirW[MAX_PATH]; + ITextStream *stream; + BSTR nameW, str; + HANDLE file; + HRESULT hr; + BOOL ret; + + GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW); + lstrcatW(pathW, scrrunW); + lstrcpyW(dirW, pathW); + lstrcatW(pathW, testfileW); + + /* dir doesn't exist */ + nameW = SysAllocString(pathW); + hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream); + ok(hr == CTL_E_PATHNOTFOUND, "got 0x%08x\n", hr); + + ret = CreateDirectoryW(dirW, NULL); + ok(ret, "got %d, %d\n", ret, GetLastError()); + + hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextStream_Read(stream, 1, &str); + ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr); + + ITextStream_Release(stream); + + /* check it's created */ + file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "got %p\n", file); + CloseHandle(file); + + /* try to create again with no-overwrite mode */ + hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream); + ok(hr == CTL_E_FILEALREADYEXISTS, "got 0x%08x\n", hr); + + /* now overwrite */ + hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + ITextStream_Release(stream); + + DeleteFileW(nameW); + RemoveDirectoryW(dirW); + SysFreeString(nameW); +} + START_TEST(filesystem) { HRESULT hr; @@ -1220,6 +1293,7 @@ START_TEST(filesystem) test_FolderCollection(); test_FileCollection(); test_DriveCollection(); + test_CreateTextFile(); IFileSystem3_Release(fs3);