From 7a9210fa85c28dd1a5bba33c81beddbdd194e6ae Mon Sep 17 00:00:00 2001 From: Andrey Turkin Date: Sat, 10 Nov 2007 01:12:16 +0300 Subject: [PATCH] server: Pass Information field from async I/O APCs. --- dlls/ntdll/directory.c | 4 ++-- dlls/ntdll/file.c | 8 ++++---- dlls/ntdll/sync.c | 3 ++- dlls/ntdll/tests/file.c | 2 -- dlls/ws2_32/socket.c | 8 ++++---- include/wine/server_protocol.h | 5 +++-- server/async.c | 4 ++-- server/file.h | 2 +- server/protocol.def | 3 ++- server/thread.c | 2 +- 10 files changed, 21 insertions(+), 20 deletions(-) diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 981d2a1d380..0be99421489 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -2254,7 +2254,7 @@ static void WINAPI read_changes_user_apc( void *arg, IO_STATUS_BLOCK *io, ULONG RtlFreeHeap( GetProcessHeap(), 0, info ); } -static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status ) +static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, ULONG_PTR *total ) { struct read_changes_info *info = user; char path[PATH_MAX]; @@ -2299,7 +2299,7 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st } iosb->u.Status = ret; - iosb->Information = len; + iosb->Information = *total = len; return ret; } diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index e84bc3d3afd..b9a763f40ad 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -338,7 +338,7 @@ NTSTATUS FILE_GetNtStatus(void) /*********************************************************************** * FILE_AsyncReadService (INTERNAL) */ -static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status) +static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATUS status, ULONG_PTR *total) { async_fileio_read *fileio = user; int fd, needs_close, result; @@ -389,7 +389,7 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU if (status != STATUS_PENDING) { iosb->u.Status = status; - iosb->Information = fileio->already; + iosb->Information = *total = fileio->already; } return status; } @@ -718,7 +718,7 @@ err: /*********************************************************************** * FILE_AsyncWriteService (INTERNAL) */ -static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status) +static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTATUS status, ULONG_PTR *total) { async_fileio_write *fileio = user; int result, fd, needs_close; @@ -759,7 +759,7 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT if (status != STATUS_PENDING) { iosb->u.Status = status; - iosb->Information = fileio->already; + iosb->Information = *total = fileio->already; } return status; } diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index ec8aa590328..fd7630f5eb0 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -786,7 +786,8 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result ) result->type = call->type; result->async_io.status = call->async_io.func( call->async_io.user, call->async_io.sb, - call->async_io.status ); + call->async_io.status, + &result->async_io.total ); break; case APC_VIRTUAL_ALLOC: result->type = call->type; diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 55927116b93..8ea454c4d11 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -524,9 +524,7 @@ static void test_iocp_fileio(HANDLE h) if (get_msg(h)) { ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); - todo_wine { ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information ); - } ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status); ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); } diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index eab1550b551..3abb5a06693 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1118,7 +1118,7 @@ static int WS2_recv( int fd, struct iovec* iov, int count, * * Handler for overlapped recv() operations. */ -static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status) +static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, ULONG_PTR *total ) { ws2_async* wsa = user; int result = 0, fd; @@ -1155,7 +1155,7 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat if (status != STATUS_PENDING) { iosb->u.Status = status; - iosb->Information = result; + iosb->Information = *total = result; } return status; } @@ -1222,7 +1222,7 @@ static int WS2_send( int fd, struct iovec* iov, int count, * * Handler for overlapped send() operations. */ -static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status) +static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS status, ULONG_PTR *total ) { ws2_async* wsa = user; int result = 0, fd; @@ -1262,7 +1262,7 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu if (status != STATUS_PENDING) { iosb->u.Status = status; - iosb->Information = result; + iosb->Information = *total = result; } return status; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 8598aefdf1e..9c56089a9ac 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -271,7 +271,7 @@ typedef union struct { enum apc_type type; - unsigned int (*func)(void*, void*, unsigned int); + unsigned int (*func)(void*, void*, unsigned int, unsigned long *); void *user; void *sb; unsigned int status; @@ -356,6 +356,7 @@ typedef union { enum apc_type type; unsigned int status; + unsigned long total; } async_io; struct { @@ -4904,6 +4905,6 @@ union generic_reply struct add_fd_completion_reply add_fd_completion_reply; }; -#define SERVER_PROTOCOL_VERSION 330 +#define SERVER_PROTOCOL_VERSION 331 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/async.c b/server/async.c index 98d60751da8..acf61d8b551 100644 --- a/server/async.c +++ b/server/async.c @@ -231,7 +231,7 @@ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int sta } /* store the result of the client-side async callback */ -void async_set_result( struct object *obj, unsigned int status ) +void async_set_result( struct object *obj, unsigned int status, unsigned long total ) { struct async *async = (struct async *)obj; @@ -256,7 +256,7 @@ void async_set_result( struct object *obj, unsigned int status ) async->timeout = NULL; async->status = status; if (async->data.cvalue && async->queue && async->queue->fd) - fd_add_completion( async->queue->fd, async->data.cvalue, status, 0 ); /* TODO pass Information field */ + fd_add_completion( async->queue->fd, async->data.cvalue, status, total ); if (async->data.apc) { apc_call_t data; diff --git a/server/file.h b/server/file.h index dbf09303430..1c659beceec 100644 --- a/server/file.h +++ b/server/file.h @@ -136,7 +136,7 @@ extern void free_async_queue( struct async_queue *queue ); extern struct async *create_async( struct thread *thread, struct async_queue *queue, const async_data_t *data ); extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status ); -extern void async_set_result( struct object *obj, unsigned int status ); +extern void async_set_result( struct object *obj, unsigned int status, unsigned long total ); extern int async_waiting( struct async_queue *queue ); extern void async_terminate( struct async *async, unsigned int status ); extern void async_wake_up( struct async_queue *queue, unsigned int status ); diff --git a/server/protocol.def b/server/protocol.def index cf3ffa1bf71..dfb5d484e0a 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -287,7 +287,7 @@ typedef union struct { enum apc_type type; /* APC_ASYNC_IO */ - unsigned int (*func)(void*, void*, unsigned int); + unsigned int (*func)(void*, void*, unsigned int, unsigned long *); void *user; /* user pointer */ void *sb; /* status block */ unsigned int status; /* I/O status */ @@ -372,6 +372,7 @@ typedef union { enum apc_type type; /* APC_ASYNC_IO */ unsigned int status; /* new status of async operation */ + unsigned long total; /* bytes transferred */ } async_io; struct { diff --git a/server/thread.c b/server/thread.c index 99cf89692f5..6eb43eeda02 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1199,7 +1199,7 @@ DECL_HANDLER(select) } else if (apc->result.type == APC_ASYNC_IO) { - if (apc->owner) async_set_result( apc->owner, apc->result.async_io.status ); + if (apc->owner) async_set_result( apc->owner, apc->result.async_io.status, apc->result.async_io.total ); } wake_up( &apc->obj, 0 ); close_handle( current->process, req->prev_apc );