Commit 7a9210fa authored by Andrey Turkin's avatar Andrey Turkin Committed by Alexandre Julliard

server: Pass Information field from async I/O APCs.

parent 793453f7
...@@ -2254,7 +2254,7 @@ static void WINAPI read_changes_user_apc( void *arg, IO_STATUS_BLOCK *io, ULONG ...@@ -2254,7 +2254,7 @@ static void WINAPI read_changes_user_apc( void *arg, IO_STATUS_BLOCK *io, ULONG
RtlFreeHeap( GetProcessHeap(), 0, info ); 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; struct read_changes_info *info = user;
char path[PATH_MAX]; char path[PATH_MAX];
...@@ -2299,7 +2299,7 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st ...@@ -2299,7 +2299,7 @@ static NTSTATUS read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, NTSTATUS st
} }
iosb->u.Status = ret; iosb->u.Status = ret;
iosb->Information = len; iosb->Information = *total = len;
return ret; return ret;
} }
......
...@@ -338,7 +338,7 @@ NTSTATUS FILE_GetNtStatus(void) ...@@ -338,7 +338,7 @@ NTSTATUS FILE_GetNtStatus(void)
/*********************************************************************** /***********************************************************************
* FILE_AsyncReadService (INTERNAL) * 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; async_fileio_read *fileio = user;
int fd, needs_close, result; int fd, needs_close, result;
...@@ -389,7 +389,7 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU ...@@ -389,7 +389,7 @@ static NTSTATUS FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, NTSTATU
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = fileio->already; iosb->Information = *total = fileio->already;
} }
return status; return status;
} }
...@@ -718,7 +718,7 @@ err: ...@@ -718,7 +718,7 @@ err:
/*********************************************************************** /***********************************************************************
* FILE_AsyncWriteService (INTERNAL) * 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; async_fileio_write *fileio = user;
int result, fd, needs_close; int result, fd, needs_close;
...@@ -759,7 +759,7 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT ...@@ -759,7 +759,7 @@ static NTSTATUS FILE_AsyncWriteService(void *user, IO_STATUS_BLOCK *iosb, NTSTAT
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = fileio->already; iosb->Information = *total = fileio->already;
} }
return status; return status;
} }
......
...@@ -786,7 +786,8 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result ) ...@@ -786,7 +786,8 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
result->type = call->type; result->type = call->type;
result->async_io.status = call->async_io.func( call->async_io.user, result->async_io.status = call->async_io.func( call->async_io.user,
call->async_io.sb, call->async_io.sb,
call->async_io.status ); call->async_io.status,
&result->async_io.total );
break; break;
case APC_VIRTUAL_ALLOC: case APC_VIRTUAL_ALLOC:
result->type = call->type; result->type = call->type;
......
...@@ -524,9 +524,7 @@ static void test_iocp_fileio(HANDLE h) ...@@ -524,9 +524,7 @@ static void test_iocp_fileio(HANDLE h)
if (get_msg(h)) if (get_msg(h))
{ {
ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey ); ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
todo_wine {
ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information ); 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( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue ); ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
} }
......
...@@ -1118,7 +1118,7 @@ static int WS2_recv( int fd, struct iovec* iov, int count, ...@@ -1118,7 +1118,7 @@ static int WS2_recv( int fd, struct iovec* iov, int count,
* *
* Handler for overlapped recv() operations. * 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; ws2_async* wsa = user;
int result = 0, fd; int result = 0, fd;
...@@ -1155,7 +1155,7 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat ...@@ -1155,7 +1155,7 @@ static NTSTATUS WS2_async_recv( void* user, IO_STATUS_BLOCK* iosb, NTSTATUS stat
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = result; iosb->Information = *total = result;
} }
return status; return status;
} }
...@@ -1222,7 +1222,7 @@ static int WS2_send( int fd, struct iovec* iov, int count, ...@@ -1222,7 +1222,7 @@ static int WS2_send( int fd, struct iovec* iov, int count,
* *
* Handler for overlapped send() operations. * 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; ws2_async* wsa = user;
int result = 0, fd; int result = 0, fd;
...@@ -1262,7 +1262,7 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu ...@@ -1262,7 +1262,7 @@ static NTSTATUS WS2_async_send(void* user, IO_STATUS_BLOCK* iosb, NTSTATUS statu
if (status != STATUS_PENDING) if (status != STATUS_PENDING)
{ {
iosb->u.Status = status; iosb->u.Status = status;
iosb->Information = result; iosb->Information = *total = result;
} }
return status; return status;
} }
......
...@@ -271,7 +271,7 @@ typedef union ...@@ -271,7 +271,7 @@ typedef union
struct struct
{ {
enum apc_type type; enum apc_type type;
unsigned int (*func)(void*, void*, unsigned int); unsigned int (*func)(void*, void*, unsigned int, unsigned long *);
void *user; void *user;
void *sb; void *sb;
unsigned int status; unsigned int status;
...@@ -356,6 +356,7 @@ typedef union ...@@ -356,6 +356,7 @@ typedef union
{ {
enum apc_type type; enum apc_type type;
unsigned int status; unsigned int status;
unsigned long total;
} async_io; } async_io;
struct struct
{ {
...@@ -4904,6 +4905,6 @@ union generic_reply ...@@ -4904,6 +4905,6 @@ union generic_reply
struct add_fd_completion_reply add_fd_completion_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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -231,7 +231,7 @@ void async_set_timeout( struct async *async, timeout_t timeout, unsigned int sta ...@@ -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 */ /* 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; struct async *async = (struct async *)obj;
...@@ -256,7 +256,7 @@ void async_set_result( struct object *obj, unsigned int status ) ...@@ -256,7 +256,7 @@ void async_set_result( struct object *obj, unsigned int status )
async->timeout = NULL; async->timeout = NULL;
async->status = status; async->status = status;
if (async->data.cvalue && async->queue && async->queue->fd) 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) if (async->data.apc)
{ {
apc_call_t data; apc_call_t data;
......
...@@ -136,7 +136,7 @@ extern void free_async_queue( struct async_queue *queue ); ...@@ -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, extern struct async *create_async( struct thread *thread, struct async_queue *queue,
const async_data_t *data ); const async_data_t *data );
extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status ); 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 int async_waiting( struct async_queue *queue );
extern void async_terminate( struct async *async, unsigned int status ); extern void async_terminate( struct async *async, unsigned int status );
extern void async_wake_up( struct async_queue *queue, unsigned int status ); extern void async_wake_up( struct async_queue *queue, unsigned int status );
......
...@@ -287,7 +287,7 @@ typedef union ...@@ -287,7 +287,7 @@ typedef union
struct struct
{ {
enum apc_type type; /* APC_ASYNC_IO */ 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 *user; /* user pointer */
void *sb; /* status block */ void *sb; /* status block */
unsigned int status; /* I/O status */ unsigned int status; /* I/O status */
...@@ -372,6 +372,7 @@ typedef union ...@@ -372,6 +372,7 @@ typedef union
{ {
enum apc_type type; /* APC_ASYNC_IO */ enum apc_type type; /* APC_ASYNC_IO */
unsigned int status; /* new status of async operation */ unsigned int status; /* new status of async operation */
unsigned long total; /* bytes transferred */
} async_io; } async_io;
struct struct
{ {
......
...@@ -1199,7 +1199,7 @@ DECL_HANDLER(select) ...@@ -1199,7 +1199,7 @@ DECL_HANDLER(select)
} }
else if (apc->result.type == APC_ASYNC_IO) 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 ); wake_up( &apc->obj, 0 );
close_handle( current->process, req->prev_apc ); close_handle( current->process, req->prev_apc );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment