Jacek Caban : scrrun: Add support for TristateUseDefault text stream format.

Alexandre Julliard julliard at winehq.org
Mon Sep 30 16:19:07 CDT 2019


Module: wine
Branch: master
Commit: b22236d1b158bfeef4fe57e7df0bf4b87c0673dd
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b22236d1b158bfeef4fe57e7df0bf4b87c0673dd

Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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);




More information about the wine-cvs mailing list