Nikolay Sivov : scrrun: Implement CreateTextFile().

Alexandre Julliard julliard at winehq.org
Mon Mar 17 15:51:35 CDT 2014


Module: wine
Branch: master
Commit: 63db2d2e922b2b796f4d37202579a4f1220e236b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=63db2d2e922b2b796f4d37202579a4f1220e236b

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun Mar 16 16:06:28 2014 +0400

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 d87ba30..1d47d73 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 c62b2bc..3e8d4bb 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);
 




More information about the wine-cvs mailing list