Alexandre Julliard : ntdll: Allow specifying the user APC argument in the system APC callback.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Mar 3 09:42:10 CST 2015


Module: wine
Branch: master
Commit: 0a241b0fcc550cc60d8a59dfec0bdcd99bd0f1b6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0a241b0fcc550cc60d8a59dfec0bdcd99bd0f1b6

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Mar  3 16:06:51 2015 +0900

ntdll: Allow specifying the user APC argument in the system APC callback.

---

 dlls/ntdll/file.c    | 26 +++++++++++++++++++++-----
 dlls/ntdll/server.c  |  8 ++++----
 dlls/ws2_32/socket.c | 27 +++++++++++++++++++--------
 server/protocol.def  |  2 +-
 4 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 43b6097..1cd6546 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -448,7 +448,8 @@ NTSTATUS FILE_GetNtStatus(void)
 /***********************************************************************
  *             FILE_AsyncReadService      (INTERNAL)
  */
-static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc)
+static NTSTATUS FILE_AsyncReadService( void *user, IO_STATUS_BLOCK *iosb,
+                                       NTSTATUS status, void **apc, void **arg )
 {
     struct async_fileio_read *fileio = user;
     int fd, needs_close, result;
@@ -501,7 +502,10 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
         iosb->u.Status = status;
         iosb->Information = fileio->already;
         if (fileio->io.apc)
+        {
             *apc = fileio_apc;
+            *arg = &fileio->io;
+        }
         else
             release_fileio( &fileio->io );
     }
@@ -956,7 +960,8 @@ NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE ap
 /***********************************************************************
  *             FILE_AsyncWriteService      (INTERNAL)
  */
-static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc)
+static NTSTATUS FILE_AsyncWriteService( void *user, IO_STATUS_BLOCK *iosb,
+                                        NTSTATUS status, void **apc, void **arg )
 {
     struct async_fileio_write *fileio = user;
     int result, fd, needs_close;
@@ -999,7 +1004,10 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
         iosb->u.Status = status;
         iosb->Information = fileio->already;
         if (fileio->io.apc)
+        {
             *apc = fileio_apc;
+            *arg = &fileio->io;
+        }
         else
             release_fileio( &fileio->io );
     }
@@ -1370,9 +1378,10 @@ struct async_ioctl
 };
 
 /* callback for ioctl async I/O completion */
-static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS status, void **apc )
+static NTSTATUS ioctl_completion( void *user, IO_STATUS_BLOCK *io,
+                                  NTSTATUS status, void **apc, void **arg )
 {
-    struct async_ioctl *async = arg;
+    struct async_ioctl *async = user;
 
     if (status == STATUS_ALERTED)
     {
@@ -1390,7 +1399,10 @@ static NTSTATUS ioctl_completion( void *arg, IO_STATUS_BLOCK *io, NTSTATUS statu
     {
         io->u.Status = status;
         if (async->io.apc)
+        {
             *apc = fileio_apc;
+            *arg = &async->io;
+        }
         else
             release_fileio( &async->io );
     }
@@ -1709,7 +1721,8 @@ struct read_changes_fileio
     char                data[1];
 };
 
-static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc )
+static NTSTATUS read_changes_apc( void *user, IO_STATUS_BLOCK *iosb,
+                                  NTSTATUS status, void **apc, void **arg )
 {
     struct read_changes_fileio *fileio = user;
     NTSTATUS ret;
@@ -1776,7 +1789,10 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st
     iosb->u.Status = ret;
     iosb->Information = size;
     if (fileio->io.apc)
+    {
         *apc = fileio_apc;
+        *arg = &fileio->io;
+    }
     else
         release_fileio( &fileio->io );
     return ret;
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index e3f1694..2c99cbe 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -391,17 +391,17 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
     }
     case APC_ASYNC_IO:
     {
-        void *apc = NULL;
+        void *apc = NULL, *arg = NULL;
         IO_STATUS_BLOCK *iosb = wine_server_get_ptr( call->async_io.sb );
-        NTSTATUS (*func)(void *, IO_STATUS_BLOCK *, NTSTATUS, void **) = wine_server_get_ptr( call->async_io.func );
+        NTSTATUS (*func)(void *, IO_STATUS_BLOCK *, NTSTATUS, void **, void **) = wine_server_get_ptr( call->async_io.func );
         result->type = call->type;
         result->async_io.status = func( wine_server_get_ptr( call->async_io.user ),
-                                        iosb, call->async_io.status, &apc );
+                                        iosb, call->async_io.status, &apc, &arg );
         if (result->async_io.status != STATUS_PENDING)
         {
             result->async_io.total = iosb->Information;
             result->async_io.apc   = wine_server_client_ptr( apc );
-            result->async_io.arg   = call->async_io.user;
+            result->async_io.arg   = wine_server_client_ptr( arg );
         }
         break;
     }
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index f1f00eb..5bfdecf 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2013,7 +2013,8 @@ static int WS2_recv( int fd, struct ws2_async *wsa )
  *
  * Handler for overlapped recv() operations.
  */
-static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
+static NTSTATUS WS2_async_recv( void *user, IO_STATUS_BLOCK *iosb,
+                                NTSTATUS status, void **apc, void **arg )
 {
     struct ws2_async *wsa = user;
     int result = 0, fd;
@@ -2051,7 +2052,10 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat
         iosb->u.Status = status;
         iosb->Information = result;
         if (wsa->completion_func)
+        {
             *apc = ws2_async_apc;
+            *arg = wsa;
+        }
         else
             release_async_io( &wsa->io );
     }
@@ -2064,12 +2068,13 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat
  * This function is used to finish the read part of an accept request. It is
  * needed to place the completion on the correct socket (listener).
  */
-static NTSTATUS WS2_async_accept_recv( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc )
+static NTSTATUS WS2_async_accept_recv( void *user, IO_STATUS_BLOCK *iosb,
+                                       NTSTATUS status, void **apc, void **arg )
 {
     void *junk;
-    struct ws2_accept_async *wsa = arg;
+    struct ws2_accept_async *wsa = user;
 
-    status = WS2_async_recv( wsa->read, iosb, status, &junk );
+    status = WS2_async_recv( wsa->read, iosb, status, &junk, &junk );
     if (status == STATUS_PENDING)
         return status;
 
@@ -2087,9 +2092,10 @@ static NTSTATUS WS2_async_accept_recv( void *arg, IO_STATUS_BLOCK *iosb, NTSTATU
  *
  * This is the function called to satisfy the AcceptEx callback
  */
-static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc )
+static NTSTATUS WS2_async_accept( void *user, IO_STATUS_BLOCK *iosb,
+                                  NTSTATUS status, void **apc, void **arg )
 {
-    struct ws2_accept_async *wsa = arg;
+    struct ws2_accept_async *wsa = user;
     int len;
     char *addr;
 
@@ -2241,7 +2247,8 @@ static int WS2_send( int fd, struct ws2_async *wsa )
  *
  * Handler for overlapped send() operations.
  */
-static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, void **apc)
+static NTSTATUS WS2_async_send( void *user, IO_STATUS_BLOCK *iosb,
+                                NTSTATUS status, void **apc, void **arg )
 {
     struct ws2_async *wsa = user;
     int result = 0, fd;
@@ -2285,7 +2292,10 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
     {
         iosb->u.Status = status;
         if (wsa->completion_func)
+        {
             *apc = ws2_async_apc;
+            *arg = wsa;
+        }
         else
             release_async_io( &wsa->io );
     }
@@ -2297,7 +2307,8 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
  *
  * Handler for shutdown() operations on overlapped sockets.
  */
-static NTSTATUS WS2_async_shutdown( void* user, PIO_STATUS_BLOCK iosb, NTSTATUS status, void **apc )
+static NTSTATUS WS2_async_shutdown( void *user, IO_STATUS_BLOCK *iosb,
+                                    NTSTATUS status, void **apc, void **arg )
 {
     struct ws2_async_shutdown *wsa = user;
     int fd, err = 1;
diff --git a/server/protocol.def b/server/protocol.def
index f2a5a9a..7ec380b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -480,7 +480,7 @@ typedef union
     {
         enum apc_type    type;     /* APC_ASYNC_IO */
         unsigned int     status;   /* I/O status */
-        client_ptr_t     func;     /* unsigned int (*func)(void*, void*, unsigned int, void **); */
+        client_ptr_t     func;     /* unsigned int (*func)(void*, void*, unsigned int, void**, void**); */
         client_ptr_t     user;     /* user pointer */
         client_ptr_t     sb;       /* status block */
     } async_io;




More information about the wine-cvs mailing list