server: Pass Information field from async I/O APCs.
This commit is contained in:
parent
793453f768
commit
7a9210fa85
@ -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
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* 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
|
|||||||
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:
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* 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
|
|||||||
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 )
|
|||||||
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)
|
|||||||
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,
|
|||||||
*
|
*
|
||||||
* 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
|
|||||||
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,
|
|||||||
*
|
*
|
||||||
* 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
|
|||||||
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
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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 )
|
|||||||
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 );
|
|||||||
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
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
}
|
}
|
||||||
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 );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user