1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-08 03:45:57 +00:00

scrrun: Fix FileSystemObject.OpenTextFile when writing to existing files.

OpenTextFile(...,ForWriting,True) should either create a new file,
or open and truncate an existing one

OpenTextFile(...,ForAppending,?,True) should write a BOM
if appending to an existing-but-empty file
This commit is contained in:
Kevin Puetz 2022-09-20 16:53:08 -05:00 committed by Alexandre Julliard
parent 7b44c6895f
commit 3265d7b542
2 changed files with 46 additions and 3 deletions

View File

@ -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);
}

View File

@ -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;