Alexandre Julliard : server: Make the FILE_SHARE_DELETE sharing checks depend on DELETE

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jan 27 09:19:16 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 8b0feb253bc569a39e724a8da006735166fc1b32
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=8b0feb253bc569a39e724a8da006735166fc1b32

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Jan 27 15:50:38 2006 +0100

server: Make the FILE_SHARE_DELETE sharing checks depend on DELETE
access instead of on the FILE_DELETE_ON_CLOSE flag (based on a patch
by Mike McCormack).

---

 dlls/kernel/file.c        |    3 +++
 dlls/kernel/path.c        |    2 +-
 dlls/kernel/tests/file.c  |   20 ++++++++++++++------
 dlls/ntdll/file.c         |    4 ++--
 dlls/ntdll/tests/change.c |    2 --
 server/fd.c               |   12 ++++++++----
 6 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/dlls/kernel/file.c b/dlls/kernel/file.c
index 34a4215..9c5973a 100644
--- a/dlls/kernel/file.c
+++ b/dlls/kernel/file.c
@@ -1348,7 +1348,10 @@ HANDLE WINAPI CreateFileW( LPCWSTR filen
     else
         options |= FILE_NON_DIRECTORY_FILE;
     if (attributes & FILE_FLAG_DELETE_ON_CLOSE)
+    {
         options |= FILE_DELETE_ON_CLOSE;
+        access |= DELETE;
+    }
     if (!(attributes & FILE_FLAG_OVERLAPPED))
         options |= FILE_SYNCHRONOUS_IO_ALERT;
     if (attributes & FILE_FLAG_RANDOM_ACCESS)
diff --git a/dlls/kernel/path.c b/dlls/kernel/path.c
index 0608f17..66c1e84 100644
--- a/dlls/kernel/path.c
+++ b/dlls/kernel/path.c
@@ -1277,7 +1277,7 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR pa
     attr.SecurityDescriptor = NULL;
     attr.SecurityQualityOfService = NULL;
 
-    status = NtOpenFile( &handle, GENERIC_READ, &attr, &io,
+    status = NtOpenFile( &handle, DELETE, &attr, &io,
                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
     if (status == STATUS_SUCCESS)
diff --git a/dlls/kernel/tests/file.c b/dlls/kernel/tests/file.c
index 3310670..093a893 100644
--- a/dlls/kernel/tests/file.c
+++ b/dlls/kernel/tests/file.c
@@ -1081,15 +1081,23 @@ static inline int is_sharing_compatible(
     if (!access1 || !access2) return 1;
     if ((access1 & GENERIC_READ) && !(sharing2 & FILE_SHARE_READ)) return 0;
     if ((access1 & GENERIC_WRITE) && !(sharing2 & FILE_SHARE_WRITE)) return 0;
+    if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return 0;
     if ((access2 & GENERIC_READ) && !(sharing1 & FILE_SHARE_READ)) return 0;
     if ((access2 & GENERIC_WRITE) && !(sharing1 & FILE_SHARE_WRITE)) return 0;
+    if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return 0;
     return 1;
 }
 
 static void test_file_sharing(void)
 {
-    static const DWORD access_modes[4] = { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE };
-    static const DWORD sharing_modes[4] = { 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE };
+    static const DWORD access_modes[] =
+        { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
+          DELETE, GENERIC_READ|DELETE, GENERIC_WRITE|DELETE, GENERIC_READ|GENERIC_WRITE|DELETE };
+    static const DWORD sharing_modes[] =
+        { 0, FILE_SHARE_READ,
+          FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+          FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE,
+          FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE };
     int a1, s1, a2, s2;
     int ret;
     HANDLE h, h2;
@@ -1103,9 +1111,9 @@ static void test_file_sharing(void)
     }
     CloseHandle( h );
 
-    for (a1 = 0; a1 < 4; a1++)
+    for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++)
     {
-        for (s1 = 0; s1 < 4; s1++)
+        for (s1 = 0; s1 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s1++)
         {
             h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
                              NULL, OPEN_EXISTING, 0, 0 );
@@ -1114,9 +1122,9 @@ static void test_file_sharing(void)
                 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
                 return;
             }
-            for (a2 = 0; a2 < 4; a2++)
+            for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
             {
-                for (s2 = 0; s2 < 4; s2++)
+                for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
                 {
                     SetLastError(0xdeadbeef);
                     h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 9ef2262..b817283 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -2052,8 +2052,8 @@ NTSTATUS WINAPI NtDeleteFile( POBJECT_AT
     IO_STATUS_BLOCK io;
 
     TRACE("%p\n", ObjectAttributes);
-    status = NtCreateFile( &hFile, GENERIC_READ | GENERIC_WRITE, ObjectAttributes, 
-                           &io, NULL, 0,
+    status = NtCreateFile( &hFile, GENERIC_READ | GENERIC_WRITE | DELETE,
+                           ObjectAttributes, &io, NULL, 0,
                            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 
                            FILE_OPEN, FILE_DELETE_ON_CLOSE, NULL, 0 );
     if (status == STATUS_SUCCESS) status = NtClose(hFile);
diff --git a/dlls/ntdll/tests/change.c b/dlls/ntdll/tests/change.c
index d07cb84..c347799 100644
--- a/dlls/ntdll/tests/change.c
+++ b/dlls/ntdll/tests/change.c
@@ -113,7 +113,6 @@ static void test_ntncdf(void)
     r = WaitForSingleObject( hdir, 0 );
     ok( r == WAIT_OBJECT_0, "event wasn't ready\n" );
 
-    todo_wine {
     r = RemoveDirectoryW( path );
     ok( r == FALSE, "failed to remove directory\n");
 
@@ -121,7 +120,6 @@ static void test_ntncdf(void)
 
     r = RemoveDirectoryW( path );
     ok( r == TRUE, "failed to remove directory\n");
-    }
 }
 
 START_TEST(change)
diff --git a/server/fd.c b/server/fd.c
index a142acd..ed98821 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1283,7 +1283,6 @@ static int check_sharing( struct fd *fd,
 {
     unsigned int existing_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
     unsigned int existing_access = 0;
-    int unlink = 0;
     struct list *ptr;
 
     /* if access mode is 0, sharing mode is ignored */
@@ -1298,16 +1297,15 @@ static int check_sharing( struct fd *fd,
         {
             existing_sharing &= fd_ptr->sharing;
             existing_access  |= fd_ptr->access;
-            if (fd_ptr->closed->unlink[0]) unlink = 1;
         }
     }
 
     if ((access & FILE_UNIX_READ_ACCESS) && !(existing_sharing & FILE_SHARE_READ)) return 0;
     if ((access & FILE_UNIX_WRITE_ACCESS) && !(existing_sharing & FILE_SHARE_WRITE)) return 0;
+    if ((access & DELETE) && !(existing_sharing & FILE_SHARE_DELETE)) return 0;
     if ((existing_access & FILE_UNIX_READ_ACCESS) && !(sharing & FILE_SHARE_READ)) return 0;
     if ((existing_access & FILE_UNIX_WRITE_ACCESS) && !(sharing & FILE_SHARE_WRITE)) return 0;
-    if (fd->closed->unlink[0] && !(existing_sharing & FILE_SHARE_DELETE)) return 0;
-    if (unlink && !(sharing & FILE_SHARE_DELETE)) return 0;
+    if ((existing_access & DELETE) && !(sharing & FILE_SHARE_DELETE)) return 0;
     return 1;
 }
 
@@ -1329,6 +1327,12 @@ struct fd *open_fd( const char *name, in
     const char *unlink_name = "";
     int rw_mode;
 
+    if ((options & FILE_DELETE_ON_CLOSE) && !(access & DELETE))
+    {
+        set_error( STATUS_INVALID_PARAMETER );
+        return NULL;
+    }
+
     if (!(fd = alloc_fd_object())) return NULL;
 
     if (options & FILE_DELETE_ON_CLOSE) unlink_name = name;




More information about the wine-cvs mailing list