[Wine-patches] [eterhack] eterbug #4125

Alexander Morozov amorozov на etersoft.ru
Сб Июн 4 19:13:15 MSD 2011


----------- следующая часть -----------
From 9e9c77aede15123d37405cf316b06e6fbaf437db Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 20 Jul 2009 15:03:37 +0400
Subject: [eterhack 1/3] server: Close CIFS file descriptors immediately.

---
 server/fd.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/server/fd.c b/server/fd.c
index 337f9c9..1df9ceb 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1580,8 +1580,6 @@ static void fd_destroy( struct object *obj )
     list_remove( &fd->inode_entry );
     if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index );
 
-/* disable this hack due fixing http://bugs.etersoft.ru/show_bug.cgi?id=3237 since etercifs 4.3.0 */
-#if 0
     /* special case for file on CIFS - remove in any case */
     if (fd->cifs) {
         if (fd->unix_fd != -1) {
@@ -1589,7 +1587,6 @@ static void fd_destroy( struct object *obj )
             fd->unix_fd = -1;
         }
     }
-#endif
 
     if (fd->inode)
     {
-- 
1.7.4.5

----------- следующая часть -----------
From d5051ae02aa5bfbc90a3b99834e4a16f89d679ae Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 9 Jun 2010 20:08:12 +0400
Subject: [eterhack 2/3] 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               |    1 +
 server/trace.c                 |    3 +-
 7 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 5447619..9ca7855 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1725,6 +1725,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 aff8166..d3fe98f 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1930,6 +1930,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 e69cf1d..152eabc 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4797,8 +4797,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
 {
@@ -5592,6 +5592,6 @@ union generic_reply
     struct set_cursor_reply set_cursor_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 10411
+#define SERVER_PROTOCOL_VERSION 10412
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/fd.c b/server/fd.c
index 1df9ceb..511a8d0 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1581,7 +1581,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;
@@ -2580,23 +2581,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 dad5e06..fe3d756 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3307,6 +3307,7 @@ enum coords_relative
 
 /* 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 71f4376..879a79b 100644
--- a/server/request.h
+++ b/server/request.h
@@ -2115,6 +2115,7 @@ C_ASSERT( FIELD_OFFSET(struct get_device_request, manager) == 20 );
 C_ASSERT( sizeof(struct get_device_request) == 24 );
 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 );
diff --git a/server/trace.c b/server/trace.c
index cc8cb91..2092fd1 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3892,7 +3892,8 @@ 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 )
 {
-    dump_varargs_string( " filename=", cur_size );
+    fprintf( stderr, " handle=%04x", req->handle );
+    dump_varargs_string( ", filename=", cur_size );
 }
 
 static void dump_kill_wineserver_request( const struct kill_wineserver_request *req )
-- 
1.7.4.5

----------- следующая часть -----------
From 1c79bb828312c0f6c9c9a02bfc6c2bd363b71884 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Sat, 4 Jun 2011 03:17:10 +0400
Subject: [eterhack 3/3] Close file handle before running UNIX binary (eterbug
 #4125).

---
 dlls/kernel32/process.c        |   16 ++------------
 dlls/ntdll/loader.c            |    2 +-
 include/wine/server_protocol.h |   14 ++++++------
 server/fd.c                    |   43 +++++----------------------------------
 server/protocol.def            |    6 ++--
 server/request.h               |    8 +++---
 server/trace.c                 |    7 ++---
 7 files changed, 27 insertions(+), 69 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 9ca7855..4f8ae2a 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1720,19 +1720,7 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA
 
         if (newdir) chdir(newdir);
 
-        if (argv && envp)
-        {
-            /* 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 );
-            }
-            SERVER_END_REQ;
-
-            execve( filename, argv, envp );
-        }
+        if (argv && envp) execve( filename, argv, envp );
         err = errno;
         write( fd[1], &err, sizeof(err) );
         _exit(1);
@@ -2529,6 +2517,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW( LPCWSTR app_name, LPWSTR cmd_line,
 
             if ((unix_name = wine_get_unix_file_name( name )))
             {
+                CloseHandle( hFile );
+                hFile = 0;
                 retv = (fork_and_exec( unix_name, tidy_cmdline, envW, unixdir, flags, startup_info ) != -1);
                 HeapFree( GetProcessHeap(), 0, unix_name );
             }
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index d3fe98f..31a900d 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1932,7 +1932,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
 
     if (handle)
     {
-        SERVER_START_REQ( close_lock_fd )
+        SERVER_START_REQ( ignore_locks )
         {
             req->handle = wine_server_obj_handle( handle );
             wine_server_call( req );
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 152eabc..1faa364 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4794,18 +4794,18 @@ struct get_device_reply
 
 
 
-struct close_lock_fd_request
+struct ignore_locks_request
 {
     struct request_header __header;
     obj_handle_t handle;
-    /* VARARG(filename,string); */
 };
-struct close_lock_fd_reply
+struct ignore_locks_reply
 {
     struct reply_header __header;
 };
 
 
+
 struct kill_wineserver_request
 {
     struct request_header __header;
@@ -5081,7 +5081,7 @@ enum request
     REQ_free_user_handle,
     REQ_get_device_name,
     REQ_get_device,
-    REQ_close_lock_fd,
+    REQ_ignore_locks,
     REQ_kill_wineserver,
     REQ_set_cursor,
     REQ_NB_REQUESTS
@@ -5335,7 +5335,7 @@ union generic_request
     struct free_user_handle_request free_user_handle_request;
     struct get_device_name_request get_device_name_request;
     struct get_device_request get_device_request;
-    struct close_lock_fd_request close_lock_fd_request;
+    struct ignore_locks_request ignore_locks_request;
     struct kill_wineserver_request kill_wineserver_request;
     struct set_cursor_request set_cursor_request;
 };
@@ -5587,11 +5587,11 @@ union generic_reply
     struct free_user_handle_reply free_user_handle_reply;
     struct get_device_name_reply get_device_name_reply;
     struct get_device_reply get_device_reply;
-    struct close_lock_fd_reply close_lock_fd_reply;
+    struct ignore_locks_reply ignore_locks_reply;
     struct kill_wineserver_reply kill_wineserver_reply;
     struct set_cursor_reply set_cursor_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 10412
+#define SERVER_PROTOCOL_VERSION 10413
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/fd.c b/server/fd.c
index 511a8d0..5d8b3a1 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2578,45 +2578,14 @@ DECL_HANDLER(add_fd_completion)
     }
 }
 
-/* close file descriptor used for locks */
-DECL_HANDLER(close_lock_fd)
+/* ignore locks and share flags */
+DECL_HANDLER(ignore_locks)
 {
-    int unix_fd = -1;
-    struct stat st;
-    struct inode *inode;
-    struct fd *fd = NULL;
-    const char *name = get_req_data();
-
-    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)
-    {
-        int lock_fd = inode_get_lock_fd( inode );
-        if (lock_fd != -1)
-        {
-            inode_set_lock_fd( inode, -1 );
-            close( lock_fd );
-        }
-        if (fd) fd->fs_locks = 0;
-    }
+    struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
 
-    if (fd) release_object( fd );
-    if (unix_fd != -1)
+    if (fd)
     {
-        close( unix_fd );
-        if (inode) release_object( inode );
+        fd->fs_locks = 0;
+        release_object( fd );
     }
 }
diff --git a/server/protocol.def b/server/protocol.def
index fe3d756..2a7cb6e 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3305,12 +3305,12 @@ enum coords_relative
 @END
 
 
-/* Close file descriptor used for locks */
- на REQ(close_lock_fd)
+/* Ignore locks and share flags */
+ на REQ(ignore_locks)
     obj_handle_t handle;          /* handle to the file */
-    VARARG(filename,string);      /* file name */
 @END
 
+
 /* Kill the wineserver process */
 @REQ(kill_wineserver)
     int signal;                   /* sending signal */
diff --git a/server/request.h b/server/request.h
index 879a79b..f5be73b 100644
--- a/server/request.h
+++ b/server/request.h
@@ -355,7 +355,7 @@ DECL_HANDLER(alloc_user_handle);
 DECL_HANDLER(free_user_handle);
 DECL_HANDLER(get_device_name);
 DECL_HANDLER(get_device);
-DECL_HANDLER(close_lock_fd);
+DECL_HANDLER(ignore_locks);
 DECL_HANDLER(kill_wineserver);
 DECL_HANDLER(set_cursor);
 
@@ -608,7 +608,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_free_user_handle,
     (req_handler)req_get_device_name,
     (req_handler)req_get_device,
-    (req_handler)req_close_lock_fd,
+    (req_handler)req_ignore_locks,
     (req_handler)req_kill_wineserver,
     (req_handler)req_set_cursor,
 };
@@ -2115,8 +2115,8 @@ C_ASSERT( FIELD_OFFSET(struct get_device_request, manager) == 20 );
 C_ASSERT( sizeof(struct get_device_request) == 24 );
 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 ignore_locks_request, handle) == 12 );
+C_ASSERT( sizeof(struct ignore_locks_request) == 16 );
 C_ASSERT( FIELD_OFFSET(struct kill_wineserver_request, signal) == 12 );
 C_ASSERT( sizeof(struct kill_wineserver_request) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_cursor_request, flags) == 12 );
diff --git a/server/trace.c b/server/trace.c
index 2092fd1..4e2a658 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3890,10 +3890,9 @@ static void dump_get_device_reply( const struct get_device_reply *req )
     dump_uint64( " user_ptr=", &req->user_ptr );
 }
 
-static void dump_close_lock_fd_request( const struct close_lock_fd_request *req )
+static void dump_ignore_locks_request( const struct ignore_locks_request *req )
 {
     fprintf( stderr, " handle=%04x", req->handle );
-    dump_varargs_string( ", filename=", cur_size );
 }
 
 static void dump_kill_wineserver_request( const struct kill_wineserver_request *req )
@@ -4159,7 +4158,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_free_user_handle_request,
     (dump_func)dump_get_device_name_request,
     (dump_func)dump_get_device_request,
-    (dump_func)dump_close_lock_fd_request,
+    (dump_func)dump_ignore_locks_request,
     (dump_func)dump_kill_wineserver_request,
     (dump_func)dump_set_cursor_request,
 };
@@ -4659,7 +4658,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "free_user_handle",
     "get_device_name",
     "get_device",
-    "close_lock_fd",
+    "ignore_locks",
     "kill_wineserver",
     "set_cursor",
 };
-- 
1.7.4.5



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