[Wine-patches] [eter-1.0.12] Disable locks and sharing flags support for dlls (eterbug #5643).

Alexander Morozov amorozov на etersoft.ru
Ср Июн 9 21:16:01 MSD 2010


----------- следующая часть -----------
From cb5752f5f1c8a2195e6c41fb16aaae0bf1010495 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 9 Jun 2010 20:08:12 +0400
Subject: [eter-1.0.12] Disable locks and sharing flags support for dlls (eterbug #5643).

---
 dlls/kernel32/process.c        |    1 +
 dlls/ntdll/loader.c            |   10 +++++++++
 include/wine/server_protocol.h |    4 +-
 server/fd.c                    |   44 +++++++++++++++++++++++++++++----------
 server/protocol.def            |    1 +
 server/request.h               |    2 +
 server/trace.c                 |    2 +
 7 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index e1f0ac4..da4a3ac 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1459,6 +1459,7 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA
             /* Close file descriptor for locks to prevent ETXTBSY error */
             SERVER_START_REQ( close_lock_fd )
             {
+                req->handle = 0;
                 wine_server_add_data( req, filename, strlen(filename) + 1 );
                 wine_server_call( req );
             }
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 6a78a22..a8785fe 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1933,6 +1933,16 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
         if (!(filename = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return STATUS_NO_MEMORY;
     }
 
+    if (handle)
+    {
+        SERVER_START_REQ( close_lock_fd )
+        {
+            req->handle = wine_server_obj_handle( handle );
+            wine_server_call( req );
+        }
+        SERVER_END_REQ;
+    }
+
     if (*pwm)  /* found already loaded module */
     {
         if ((*pwm)->ldr.LoadCount != -1) (*pwm)->ldr.LoadCount++;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index e872f3c..b1a8c10 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4525,8 +4525,8 @@ struct get_device_reply
 struct close_lock_fd_request
 {
     struct request_header __header;
+    obj_handle_t handle;
     /* VARARG(filename,string); */
-    char __pad_12[4];
 };
 struct close_lock_fd_reply
 {
@@ -5281,6 +5281,6 @@ union generic_reply
     struct kill_wineserver_reply kill_wineserver_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 10386
+#define SERVER_PROTOCOL_VERSION 10387
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/fd.c b/server/fd.c
index 73d3fef..e35b940 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1484,7 +1484,8 @@ static void fd_destroy( struct object *obj )
     if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index );
 
     /* special case for file on CIFS - remove in any case */
-    if (fd->cifs) {
+    /* also close descriptors which can not be locked */
+    if (fd->cifs || !fd->fs_locks) {
         if (fd->unix_fd != -1) {
             close( fd->unix_fd );
             fd->unix_fd = -1;
@@ -2263,23 +2264,42 @@ DECL_HANDLER(add_fd_completion)
 /* close file descriptor used for locks */
 DECL_HANDLER(close_lock_fd)
 {
-    int fd;
+    int unix_fd = -1;
     struct stat st;
     struct inode *inode;
+    struct fd *fd = NULL;
     const char *name = get_req_data();
 
-    if (name[get_req_data_size() - 1] != 0) return;
-    fd = open( name, O_RDONLY );
-    if (fd < 0) return;
-    fstat( fd, &st );
-    if ((inode = get_inode( st.st_dev, st.st_ino, fd )))
+    if (req->handle)
+    {
+        fd = get_handle_fd_obj( current->process, req->handle, 0 );
+        if (!fd) return;
+        inode = fd->inode;
+    }
+    else
+    {
+        if (name[get_req_data_size() - 1] != 0) return;
+        unix_fd = open( name, O_RDONLY );
+        if (unix_fd < 0) return;
+        fstat( unix_fd, &st );
+        inode = get_inode( st.st_dev, st.st_ino, unix_fd );
+    }
+
+    if (inode)
     {
-        if (inode->lock_fd != -1)
+        int lock_fd = inode_get_lock_fd( inode );
+        if (lock_fd != -1)
         {
-            close( inode->lock_fd );
-            inode->lock_fd = -1;
+            inode_set_lock_fd( inode, -1 );
+            close( lock_fd );
         }
-        release_object( inode );
+        if (fd) fd->fs_locks = 0;
+    }
+
+    if (fd) release_object( fd );
+    if (unix_fd != -1)
+    {
+        close( unix_fd );
+        if (inode) release_object( inode );
     }
-    close( fd );
 }
diff --git a/server/protocol.def b/server/protocol.def
index 5395ad0..08d1573 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3138,6 +3138,7 @@ enum message_type
 
 /* Close file descriptor used for locks */
 @REQ(close_lock_fd)
+    obj_handle_t handle;          /* handle to the file */
     VARARG(filename,string);      /* file name */
 @END
 
diff --git a/server/request.h b/server/request.h
index 148bab9..a6c8035 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1900,7 +1900,9 @@ C_ASSERT( FIELD_OFFSET(struct get_device_request, rootdir) == 16 );
 C_ASSERT( FIELD_OFFSET(struct get_device_request, manager) == 20 );
 C_ASSERT( FIELD_OFFSET(struct get_device_reply, user_ptr) == 8 );
 C_ASSERT( sizeof(struct get_device_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct close_lock_fd_request, handle) == 12 );
 C_ASSERT( sizeof(struct close_lock_fd_request) == 16 );
+C_ASSERT( FIELD_OFFSET(struct kill_wineserver_request, signal) == 12 );
 C_ASSERT( sizeof(struct kill_wineserver_request) == 16 );
 
 #endif  /* WANT_REQUEST_HANDLERS */
diff --git a/server/trace.c b/server/trace.c
index 2e7a543..1958cd0 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -4042,12 +4042,14 @@ static void dump_get_device_reply( const struct get_device_reply *req )
 
 static void dump_close_lock_fd_request( const struct close_lock_fd_request *req )
 {
+    fprintf( stderr, " handle=%04x,", req->handle );
     fprintf( stderr, " filename=" );
     dump_varargs_string( cur_size );
 }
 
 static void dump_kill_wineserver_request( const struct kill_wineserver_request *req )
 {
+    fprintf( stderr, " signal=%d", req->signal );
 }
 
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
-- 
1.6.5.8



Подробная информация о списке рассылки Wine-patches