diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index dc6919371ec..866a29a3f04 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -3986,17 +3986,6 @@ todo_wine } else { - /* FIXME: remove once Wine is fixed */ - if (!ret && (td[i].access & FILE_APPEND_DATA)) - { -todo_wine - ok(ret, "%d: WriteFile error %d\n", i, GetLastError()); -todo_wine - ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes); - CloseHandle(hfile); - continue; - } - ok(ret, "%d: WriteFile error %d\n", i, GetLastError()); ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes); } diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 62ae135a3d5..a8c25d60d30 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -952,7 +952,8 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, ULONG total = 0; enum server_fd_type type; ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user; - BOOL send_completion = FALSE, async_write; + BOOL send_completion = FALSE, async_write, append_write = FALSE; + LARGE_INTEGER offset_eof; TRACE("(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p)!\n", hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key); @@ -961,6 +962,12 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, status = server_get_unix_fd( hFile, FILE_WRITE_DATA, &unix_handle, &needs_close, &type, &options ); + if (status == STATUS_ACCESS_DENIED) + { + status = server_get_unix_fd( hFile, FILE_APPEND_DATA, &unix_handle, + &needs_close, &type, &options ); + append_write = TRUE; + } if (status) return status; if (!virtual_check_buffer_for_read( buffer, length )) @@ -979,6 +986,12 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent, goto done; } + if (append_write) + { + offset_eof.QuadPart = (LONGLONG)-1; /* FILE_WRITE_TO_END_OF_FILE */ + offset = &offset_eof; + } + if (offset && offset->QuadPart != (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */) { off_t off = offset->QuadPart; diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 4740d42fd21..1c2a918355d 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -883,30 +883,22 @@ static void append_file_test(void) iosb.Information = -1; offset.QuadPart = 1; status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 2, 2, &offset, NULL); -todo_wine ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); -todo_wine ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", iosb.Status); -todo_wine ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information); ret = SetFilePointer(handle, 0, NULL, FILE_CURRENT); -todo_wine ok(ret == 4, "expected 4, got %u\n", ret); U(iosb).Status = -1; iosb.Information = -1; offset.QuadPart = 3; status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 4, 2, &offset, NULL); -todo_wine ok(status == STATUS_SUCCESS, "NtWriteFile error %#x\n", status); -todo_wine ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", iosb.Status); -todo_wine ok(iosb.Information == 2, "expected 2, got %lu\n", iosb.Information); ret = SetFilePointer(handle, 0, NULL, FILE_CURRENT); -todo_wine ok(ret == 6, "expected 6, got %u\n", ret); CloseHandle(handle); @@ -921,10 +913,8 @@ todo_wine status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL); ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", iosb.Status); -todo_wine ok(iosb.Information == 6, "expected 6, got %lu\n", iosb.Information); buf[6] = 0; -todo_wine ok(memcmp(buf, text, 6) == 0, "wrong file contents: %s\n", buf); U(iosb).Status = -1; @@ -942,10 +932,8 @@ todo_wine status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL); ok(status == STATUS_SUCCESS, "NtReadFile error %#x\n", status); ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x\n", iosb.Status); -todo_wine ok(iosb.Information == 6, "expected 6, got %lu\n", iosb.Information); buf[6] = 0; -todo_wine ok(memcmp(buf, "barbar", 6) == 0, "wrong file contents: %s\n", buf); CloseHandle(handle);