Qian Hong : server: Forbid shrinking files which are mapped to memory.

Alexandre Julliard julliard at winehq.org
Tue Jun 29 15:58:26 CDT 2021


Module: wine
Branch: master
Commit: be55038f3d139964de0daf2e7b6086b5de11a136
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=be55038f3d139964de0daf2e7b6086b5de11a136

Author: Qian Hong <qhong at codeweavers.com>
Date:   Fri Jun 25 00:28:52 2021 -0500

server: Forbid shrinking files which are mapped to memory.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/file.c | 18 +++++++++---------
 server/fd.c                | 26 ++++++++++++++++++--------
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index c09438e09bd..ea0a32f258d 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -6052,11 +6052,11 @@ static void test_eof(void)
         SetLastError(0xdeadbeef);
         SetFilePointer(file, 6, NULL, SEEK_SET);
         ret = SetEndOfFile(file);
-        todo_wine ok(!ret, "expected failure\n");
-        todo_wine ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %u\n", GetLastError());
+        ok(!ret, "expected failure\n");
+        ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %u\n", GetLastError());
         ret = GetFileSizeEx(file, &file_size);
         ok(ret, "failed to get size, error %u\n", GetLastError());
-        todo_wine ok(file_size.QuadPart == 8, "got size %I64d\n", file_size.QuadPart);
+        ok(file_size.QuadPart == 8, "got size %I64d\n", file_size.QuadPart);
 
         SetFilePointer(file, 8192, NULL, SEEK_SET);
         ret = SetEndOfFile(file);
@@ -6067,11 +6067,11 @@ static void test_eof(void)
 
         SetFilePointer(file, 8191, NULL, SEEK_SET);
         ret = SetEndOfFile(file);
-        todo_wine ok(!ret, "expected failure\n");
-        todo_wine ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %u\n", GetLastError());
+        ok(!ret, "expected failure\n");
+        ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %u\n", GetLastError());
         ret = GetFileSizeEx(file, &file_size);
         ok(ret, "failed to get size, error %u\n", GetLastError());
-        todo_wine ok(file_size.QuadPart == 8192, "got size %I64d\n", file_size.QuadPart);
+        ok(file_size.QuadPart == 8192, "got size %I64d\n", file_size.QuadPart);
 
         view = MapViewOfFile(mapping, map_tests[i].view_access, 0, 0, 4);
         ok(!!view, "failed to map view, error %u\n", GetLastError());
@@ -6087,11 +6087,11 @@ static void test_eof(void)
 
         SetFilePointer(file, 16383, NULL, SEEK_SET);
         ret = SetEndOfFile(file);
-        todo_wine ok(!ret, "expected failure\n");
-        todo_wine ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %u\n", GetLastError());
+        ok(!ret, "expected failure\n");
+        ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %u\n", GetLastError());
         ret = GetFileSizeEx(file, &file_size);
         ok(ret, "failed to get size, error %u\n", GetLastError());
-        todo_wine ok(file_size.QuadPart == 16384, "got size %I64d\n", file_size.QuadPart);
+        ok(file_size.QuadPart == 16384, "got size %I64d\n", file_size.QuadPart);
 
         ret = UnmapViewOfFile(view);
         ok(ret, "failed to unmap view, error %u\n", GetLastError());
diff --git a/server/fd.c b/server/fd.c
index 7204a8c51ba..b953da2ab85 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2645,15 +2645,25 @@ static void set_fd_eof( struct fd *fd, file_pos_t eof )
         set_error( fd->no_fd_status );
         return;
     }
-
-    /* first try normal truncate */
-    if (ftruncate( fd->unix_fd, eof ) != -1) return;
-
-    /* now check for the need to extend the file */
-    if (fstat( fd->unix_fd, &st ) != -1 && eof > st.st_size)
-        grow_file( fd->unix_fd, eof );
-    else
+    if (fstat( fd->unix_fd, &st) == -1)
+    {
         file_set_error();
+        return;
+    }
+    if (eof < st.st_size)
+    {
+        struct fd *fd_ptr;
+        LIST_FOR_EACH_ENTRY( fd_ptr, &fd->inode->open, struct fd, inode_entry )
+        {
+            if (fd_ptr->access & FILE_MAPPING_ACCESS)
+            {
+                set_error( STATUS_USER_MAPPED_FILE );
+                return;
+            }
+        }
+        if (ftruncate( fd->unix_fd, eof ) == -1) file_set_error();
+    }
+    else grow_file( fd->unix_fd, eof );
 }
 
 struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key )




More information about the wine-cvs mailing list