From b22236d1b158bfeef4fe57e7df0bf4b87c0673dd Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 30 Sep 2019 16:33:49 +0200 Subject: [PATCH] scrrun: Add support for TristateUseDefault text stream format. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/scrrun/filesystem.c | 62 ++++++++++------- dlls/scrrun/tests/filesystem.c | 121 +++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 24 deletions(-) diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 1713d5bb284..3c0ee0821e2 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -689,7 +689,7 @@ static const ITextStreamVtbl textstreamvtbl = { textstream_Close }; -static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMode mode, BOOL unicode, ITextStream **ret) +static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMode mode, Tristate format, ITextStream **ret) { struct textstream *stream; DWORD access = 0; @@ -704,7 +704,7 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod access = GENERIC_WRITE; break; case ForAppending: - access = FILE_APPEND_DATA; + access = GENERIC_READ | GENERIC_WRITE; break; default: return E_INVALIDARG; @@ -716,7 +716,6 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod stream->ITextStream_iface.lpVtbl = &textstreamvtbl; stream->ref = 1; stream->mode = mode; - stream->unicode = unicode; stream->first_read = TRUE; stream->file = CreateFileW(filename, access, 0, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL); @@ -732,15 +731,40 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod else stream->size.QuadPart = 0; - /* Write Unicode BOM */ - if (unicode && mode == ForWriting && (disposition == CREATE_ALWAYS || disposition == CREATE_NEW)) { - DWORD written = 0; - BOOL ret = WriteFile(stream->file, &utf16bom, sizeof(utf16bom), &written, NULL); - if (!ret || written != sizeof(utf16bom)) { - ITextStream_Release(&stream->ITextStream_iface); - return create_error(GetLastError()); + if (mode == ForWriting) + { + stream->unicode = format == TristateTrue; + /* Write Unicode BOM */ + if (stream->unicode && (disposition == CREATE_ALWAYS || disposition == CREATE_NEW)) { + DWORD written = 0; + BOOL ret = WriteFile(stream->file, &utf16bom, sizeof(utf16bom), &written, NULL); + if (!ret || written != sizeof(utf16bom)) { + ITextStream_Release(&stream->ITextStream_iface); + return create_error(GetLastError()); + } } } + else + { + if (format == TristateUseDefault) + { + BYTE buf[64]; + DWORD read; + BOOL ret; + + ret = ReadFile(stream->file, buf, sizeof(buf), &read, NULL); + if (!ret) { + ITextStream_Release(&stream->ITextStream_iface); + return create_error(GetLastError()); + } + + stream->unicode = IsTextUnicode(buf, read, NULL); + if (mode == ForReading) SetFilePointer(stream->file, 0, 0, FILE_BEGIN); + } + else stream->unicode = format != TristateFalse; + + if (mode == ForAppending) SetFilePointer(stream->file, 0, 0, FILE_END); + } init_classinfo(&CLSID_TextStream, (IUnknown *)&stream->ITextStream_iface, &stream->classinfo); *ret = &stream->ITextStream_iface; @@ -2811,12 +2835,7 @@ static HRESULT WINAPI file_OpenAsTextStream(IFile *iface, IOMode mode, Tristate TRACE("(%p)->(%d %d %p)\n", This, mode, format, stream); - if (format == TristateUseDefault) { - FIXME("default format not handled, defaulting to unicode\n"); - format = TristateTrue; - } - - return create_textstream(This->path, OPEN_EXISTING, mode, format == TristateTrue, stream); + return create_textstream(This->path, OPEN_EXISTING, mode, format, stream); } static const IFileVtbl file_vtbl = { @@ -3851,7 +3870,7 @@ static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR filename, 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, !!unicode, stream); + return create_textstream(filename, disposition, ForWriting, unicode ? TristateTrue : TristateFalse, stream); } static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename, @@ -3861,14 +3880,9 @@ static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename, 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; - - if (format == TristateUseDefault) { - FIXME("default format not handled, defaulting to unicode\n"); - format = TristateTrue; - } - - return create_textstream(filename, disposition, mode, format == TristateTrue, stream); + return create_textstream(filename, disposition, mode, format, stream); } static HRESULT WINAPI filesys_GetStandardStream(IFileSystem3 *iface, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 566f6f922b9..ed49856921c 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -1887,6 +1887,127 @@ todo_wine SysFreeString(str); ITextStream_Release(stream); + /* default read will use Unicode */ + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateUseDefault, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + lstrcpyW(buffW, nameW); + lstrcatW(buffW, crlfW); + lstrcatW(buffW, secondlineW); + lstrcatW(buffW, crlfW); + str = NULL; + hr = ITextStream_Read(stream, 500, &str); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + ITextStream_Release(stream); + + /* default append will use Unicode */ + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = SysAllocString(L"123"); + hr = ITextStream_Write(stream, str); + ok(hr == S_OK, "got %08x\n", hr); + SysFreeString(str); + + ITextStream_Release(stream); + + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + lstrcatW(buffW, L"123"); + str = NULL; + hr = ITextStream_Read(stream, 500, &str); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + ITextStream_Release(stream); + + /* default write will use ASCII */ + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForWriting, VARIANT_FALSE, TristateUseDefault, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = SysAllocString(L"123"); + hr = ITextStream_Write(stream, str); + ok(hr == S_OK, "got %08x\n", hr); + SysFreeString(str); + + ITextStream_Release(stream); + + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = (void*)0xdeadbeef; + hr = ITextStream_Read(stream, 500, &str); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(!wcscmp(str, L"123"), "got %s\n", wine_dbgstr_w(str)); + + ITextStream_Release(stream); + /* ASCII file, read with default stream */ + hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + str = SysAllocString(L"test"); + hr = ITextStream_Write(stream, str); + ok(hr == S_OK, "got 0x%08x\n", hr); + SysFreeString(str); + ITextStream_Release(stream); + + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateUseDefault, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = (void*)0xdeadbeef; + hr = ITextStream_Read(stream, 500, &str); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(!wcscmp(str, L"test"), "got %s\n", wine_dbgstr_w(str)); + + ITextStream_Release(stream); + + /* default append will use Unicode */ + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = SysAllocString(L"123"); + hr = ITextStream_Write(stream, str); + ok(hr == S_OK, "got %08x\n", hr); + SysFreeString(str); + + ITextStream_Release(stream); + + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = NULL; + hr = ITextStream_Read(stream, 500, &str); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(!lstrcmpW(L"test123", str), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + ITextStream_Release(stream); + + /* default write will use ASCII as well */ + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForWriting, VARIANT_FALSE, TristateUseDefault, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = SysAllocString(L"test string"); + hr = ITextStream_Write(stream, str); + ok(hr == S_OK, "got %08x\n", hr); + SysFreeString(str); + + ITextStream_Release(stream); + + hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + str = (void*)0xdeadbeef; + hr = ITextStream_Read(stream, 500, &str); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(!wcscmp(str, L"test string"), "got %s\n", wine_dbgstr_w(str)); + + ITextStream_Release(stream); + /* ASCII file, read with Unicode stream */ /* 1. one byte content, not enough for Unicode read */ hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);