Module: wine Branch: master Commit: b22236d1b158bfeef4fe57e7df0bf4b87c0673dd URL: https://source.winehq.org/git/wine.git/?a=commit;h=b22236d1b158bfeef4fe57e7d...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Sep 30 16:33:49 2019 +0200
scrrun: Add support for TristateUseDefault text stream format.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 1713d5bb28..3c0ee0821e 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,14 +731,39 @@ 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); @@ -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); + disposition = create == VARIANT_TRUE ? OPEN_ALWAYS : OPEN_EXISTING; + 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 566f6f922b..ed49856921 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);