diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index cfeb5bb1532..e53355267db 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -897,7 +897,7 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod { stream->unicode = format == TristateTrue; /* Write Unicode BOM */ - if (stream->unicode && (disposition == CREATE_ALWAYS || disposition == CREATE_NEW)) { + if (stream->unicode && (disposition == CREATE_ALWAYS || disposition == CREATE_NEW || disposition == TRUNCATE_EXISTING)) { DWORD written = 0; BOOL ret = WriteFile(stream->file, &utf16bom, sizeof(utf16bom), &written, NULL); if (!ret || written != sizeof(utf16bom)) { @@ -939,7 +939,20 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod stream->eof = read != sizeof(buf); } - else SetFilePointer(stream->file, 0, 0, FILE_END); + else + { + LONG filePosHigh = 0; + DWORD filePosLow = SetFilePointer(stream->file, 0, &filePosHigh, FILE_END); + if(stream->unicode && filePosHigh == 0 && filePosLow == 0) { + /* unicode ForAppending to an empty file, write BOM */ + 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()); + } + } + } } init_classinfo(&CLSID_TextStream, (IUnknown *)&stream->ITextStream_iface, &stream->classinfo); @@ -4049,7 +4062,11 @@ static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename, 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(mode == ForWriting) { + disposition = create == VARIANT_TRUE ? CREATE_ALWAYS : TRUNCATE_EXISTING; + } else { + disposition = create == VARIANT_TRUE ? OPEN_ALWAYS : OPEN_EXISTING; + } return create_textstream(filename, disposition, mode, format, stream); } diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 41d7f8b5500..e53bd092ce9 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -263,6 +263,7 @@ static void test_createfolder(void) static void test_textstream(void) { + WCHAR ExpectedW[10]; ITextStream *stream; VARIANT_BOOL b; DWORD written; @@ -378,6 +379,31 @@ todo_wine { ok(ret && written == sizeof(testfileW), "got %d\n", ret); CloseHandle(file); + /* opening a non-empty file (from above) for writing should truncate it */ + hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ITextStream_Release(stream); + + test_file_contents(testfileW,0,""); + + /* appending to an empty file file and specifying unicode should immediately write a BOM */ + hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateTrue, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ITextStream_Release(stream); + + test_file_contents(testfileW,2,L"\ufeff"); + + /* appending to a file that contains a BOM should detect unicode mode, but not write a second BOM */ + hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = ITextStream_Write(stream, name); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ITextStream_Release(stream); + + lstrcpyW(ExpectedW, L"\ufeff"); + lstrcatW(ExpectedW, name); + test_file_contents(testfileW,lstrlenW(ExpectedW)*sizeof(WCHAR),ExpectedW); + hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); b = 10;