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