[1/6] ntdll: NtWriteFile should fail for overlapped IO on files if offset is NULL.

Dmitry Timoshkov dmitry at baikal.ru
Mon Sep 2 04:29:38 CDT 2013


---
 dlls/ntdll/file.c       | 37 +++++++++++++++++++++++--------------
 dlls/ntdll/tests/file.c |  6 ------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 3ffc632..3637b69 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -950,26 +950,35 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
         goto done;
     }
 
-    if (type == FD_TYPE_FILE && offset && offset->QuadPart != (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */ )
+    if (type == FD_TYPE_FILE)
     {
-        /* async I/O doesn't make sense on regular files */
-        while ((result = pwrite( unix_handle, buffer, length, offset->QuadPart )) == -1)
+        if (!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) && !offset)
         {
-            if (errno != EINTR)
+            status = STATUS_INVALID_PARAMETER;
+            goto done;
+        }
+
+        if (offset && offset->QuadPart != (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */)
+        {
+            /* async I/O doesn't make sense on regular files */
+            while ((result = pwrite( unix_handle, buffer, length, offset->QuadPart )) == -1)
             {
-                if (errno == EFAULT) status = STATUS_INVALID_USER_BUFFER;
-                else status = FILE_GetNtStatus();
-                goto done;
+                if (errno != EINTR)
+                {
+                    if (errno == EFAULT) status = STATUS_INVALID_USER_BUFFER;
+                    else status = FILE_GetNtStatus();
+                    goto done;
+                }
             }
-        }
 
-        if (options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
-            /* update file pointer position */
-            lseek( unix_handle, offset->QuadPart + result, SEEK_SET );
+            if (options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
+                /* update file pointer position */
+                lseek( unix_handle, offset->QuadPart + result, SEEK_SET );
 
-        total = result;
-        status = STATUS_SUCCESS;
-        goto done;
+            total = result;
+            status = STATUS_SUCCESS;
+            goto done;
+        }
     }
 
     for (;;)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 1f9d60e..cde299c 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2109,21 +2109,15 @@ todo_wine
     bytes = 0xdeadbeef;
     SetLastError(0xdeadbeef);
     ret = WriteFile(hfile, contents, sizeof(contents), &bytes, NULL);
-todo_wine
     ok(!ret, "WriteFile should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
-todo_wine
     ok(bytes == 0, "bytes %u\n", bytes);
 
     iob.Status = -1;
     iob.Information = -1;
     status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), NULL, NULL);
-todo_wine
     ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#x\n", status);
-todo_wine
     ok(iob.Status == -1, "expected -1, got %#x\n", iob.Status);
-todo_wine
     ok(iob.Information == -1, "expected -1, got %ld\n", iob.Information);
 
     iob.Status = -1;
-- 
1.8.3.4




More information about the wine-patches mailing list