[PATCH v2 2/2] scrrun: Implement folder_CreateTextFile.

Robert Wilhelm robert.wilhelm at gmx.net
Tue Nov 23 15:46:44 CST 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51971
Signed-off-by: Robert Wilhelm <robert.wilhelm at gmx.net>
---
 dlls/scrrun/filesystem.c       | 16 ++++++-
 dlls/scrrun/tests/filesystem.c | 81 ++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c
index e55615eb4da..c42a3155c4f 100644
--- a/dlls/scrrun/filesystem.c
+++ b/dlls/scrrun/filesystem.c
@@ -2522,9 +2522,21 @@ static HRESULT WINAPI folder_get_Files(IFolder *iface, IFileCollection **files)
 static HRESULT WINAPI folder_CreateTextFile(IFolder *iface, BSTR filename, VARIANT_BOOL overwrite,
     VARIANT_BOOL unicode, ITextStream **stream)
 {
+    DWORD disposition;
+    BSTR path;
+    HRESULT hres;
+
     struct folder *This = impl_from_IFolder(iface);
-    FIXME("(%p)->(%s %x %x %p): stub\n", This, debugstr_w(filename), overwrite, unicode, stream);
-    return E_NOTIMPL;
+
+    TRACE("%p %s %d %d %p\n", iface, debugstr_w(filename), overwrite, unicode, stream);
+
+    hres = build_path(This->path, filename, &path);
+    if (FAILED(hres)) return hres;
+
+    disposition = overwrite == VARIANT_TRUE ? CREATE_ALWAYS : CREATE_NEW;
+    hres = create_textstream(path, disposition, ForWriting, unicode ? TristateTrue : TristateFalse, stream);
+    SysFreeString(path);
+    return hres;
 }

 static const IFolderVtbl foldervtbl = {
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c
index 5c55965ce88..bdd5de77775 100644
--- a/dlls/scrrun/tests/filesystem.c
+++ b/dlls/scrrun/tests/filesystem.c
@@ -1535,6 +1535,86 @@ static void test_CreateTextFile(void)
     SysFreeString(nameW);
 }

+/* shameless copy of test_CreateTextFile(void) */
+static void test_FolderCreateTextFile(void)
+{
+    WCHAR pathW[MAX_PATH], dirW[MAX_PATH], buffW[10];
+    ITextStream *stream;
+    BSTR nameW, str;
+    HANDLE file;
+    IFolder *folder;
+    HRESULT hr;
+    BOOL ret;
+
+    get_temp_filepath(testfileW, pathW, dirW);
+    nameW = SysAllocString(L"foo.txt");
+    lstrcpyW(pathW, dirW);
+    lstrcatW(pathW, nameW);
+
+    ret = CreateDirectoryW(dirW, NULL);
+    ok(ret, "got %d, %d\n", ret, GetLastError());
+
+    str = SysAllocString(dirW);
+    hr = IFileSystem3_GetFolder(fs3, str, &folder);
+    ok(ret, "got %d, %d\n", ret, GetLastError());
+    SysFreeString(str);
+
+    hr = IFolder_CreateTextFile(folder, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    test_provideclassinfo(stream, &CLSID_TextStream);
+
+    hr = ITextStream_Read(stream, 1, &str);
+    ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
+
+    hr = ITextStream_Close(stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = ITextStream_Read(stream, 1, &str);
+    ok(hr == CTL_E_BADFILEMODE || hr == E_VAR_NOT_SET, "got 0x%08x\n", hr);
+
+    hr = ITextStream_Close(stream);
+    ok(hr == S_FALSE || hr == E_VAR_NOT_SET, "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 = IFolder_CreateTextFile(folder, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
+    ok(hr == CTL_E_FILEALREADYEXISTS, "got 0x%08x\n", hr);
+
+    /* now overwrite */
+    hr = IFolder_CreateTextFile(folder, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ITextStream_Release(stream);
+
+    /* overwrite in Unicode mode, check for BOM */
+    hr = IFolder_CreateTextFile(folder, nameW, VARIANT_TRUE, VARIANT_TRUE, &stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ITextStream_Release(stream);
+
+    /* File was created in Unicode mode, it contains 0xfffe BOM. Opening it in non-Unicode mode
+       treats BOM like a valuable data with appropriate CP_ACP -> WCHAR conversion. */
+    buffW[0] = 0;
+    MultiByteToWideChar(CP_ACP, 0, utf16bom, -1, buffW, ARRAY_SIZE(buffW));
+
+    hr = IFileSystem3_OpenTextFile(fs3, pathW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = ITextStream_ReadAll(stream, &str);
+    ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(str, buffW), "got %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(buffW));
+    SysFreeString(str);
+    ITextStream_Release(stream);
+
+    DeleteFileW(pathW);
+    RemoveDirectoryW(dirW);
+    SysFreeString(nameW);
+}
+
 static void test_WriteLine(void)
 {
     WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
@@ -2516,6 +2596,7 @@ START_TEST(filesystem)
     test_FileCollection();
     test_DriveCollection();
     test_CreateTextFile();
+    test_FolderCreateTextFile();
     test_WriteLine();
     test_ReadAll();
     test_Read();
--
2.31.1






More information about the wine-devel mailing list