diff options
author | Eric Hameleers <alien@slackware.com> | 2012-05-20 10:12:06 +0000 |
---|---|---|
committer | Eric Hameleers <alien@slackware.com> | 2012-05-20 10:12:06 +0000 |
commit | 36fe652198e83d5c6b4a3b5cba8834b68b87158e (patch) | |
tree | c882dd56b0ed60453ba259e913ffcaa282447fa2 /wine/build/wine_acceptex.patch | |
parent | fc712a4b0bdd542beb59a47cb04d49c9d3f49842 (diff) | |
download | asb-36fe652198e83d5c6b4a3b5cba8834b68b87158e.tar.gz asb-36fe652198e83d5c6b4a3b5cba8834b68b87158e.tar.xz |
Initial revision
Diffstat (limited to 'wine/build/wine_acceptex.patch')
-rw-r--r-- | wine/build/wine_acceptex.patch | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/wine/build/wine_acceptex.patch b/wine/build/wine_acceptex.patch new file mode 100644 index 00000000..ed627531 --- /dev/null +++ b/wine/build/wine_acceptex.patch @@ -0,0 +1,529 @@ +# +# Three patches taken from: +# http://appdb.winehq.org/objectManager.php?sClass=version&iId=25953 +# to make Diablo 3 installer work. +# +From: "Erich E. Hoover" <ehoover@mymail.mines.edu> +Subject: [PATCH 1/3] server: Update stored completion information even after an async IO is queued (try 2). +Message-Id: <CAEU2+vrVkMiUKAV235mMKd22OW_+OLNZ90vXs+9jOn3DLa=hAA@mail.gmail.com> +Date: Mon, 14 May 2012 16:12:03 -0600 + +Real Name: + Erich Hoover + +Description: + The completion information for a file handle can be updated after +an async IO has been queued and this information will still be valid +for the async operation (even if the handle is closed before the async +completes!). The attached patch adds a file operation to update the +completion information for a queued async operation so that such a +change can be properly propagated to the async object. This version +of the patch has been rebased to not deal with a stored completion +handle. + +Changelog: + server: Update stored completion information even after an async +IO is queued. + +From 777ab1f5de8ed8d7a702197fe824afb3fb0650bd Mon Sep 17 00:00:00 2001 +From: Erich Hoover <ehoover@mines.edu> +Date: Mon, 14 May 2012 15:31:14 -0600 +Subject: server: Update stored completion information even after an async IO + is queued. + +--- + server/async.c | 20 +++++++++++++++++++- + server/fd.c | 9 +++++++++ + server/file.c | 3 ++- + server/file.h | 4 ++++ + server/mailslot.c | 9 ++++++--- + server/mapping.c | 3 ++- + server/named_pipe.c | 7 +++++-- + server/serial.c | 3 ++- + server/signal.c | 3 ++- + server/sock.c | 13 ++++++++++++- + server/thread.c | 3 ++- + 11 files changed, 65 insertions(+), 12 deletions(-) + +diff --git a/server/async.c b/server/async.c +index dd28dff..01d1ca1 100644 +--- a/server/async.c ++++ b/server/async.c +@@ -214,11 +214,12 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co + async->timeout = NULL; + async->queue = (struct async_queue *)grab_object( queue ); + async->completion = NULL; +- if (queue->fd) async->completion = fd_get_completion( queue->fd, &async->comp_key ); + + list_add_tail( &queue->queue, &async->queue_entry ); + grab_object( async ); + ++ async_update( async->queue ); ++ + if (queue->fd) set_fd_signaled( queue->fd, 0 ); + if (event) reset_event( event ); + return async; +@@ -330,3 +331,20 @@ void async_wake_up( struct async_queue *queue, unsigned int status ) + if (status == STATUS_ALERTED) break; /* only wake up the first one */ + } + } ++ ++/* update an async to correspond to new file object information */ ++void async_update( struct async_queue *queue ) ++{ ++ struct list *ptr, *next; ++ ++ if (!queue) return; ++ ++ LIST_FOR_EACH_SAFE( ptr, next, &queue->queue ) ++ { ++ struct async *async = LIST_ENTRY( ptr, struct async, queue_entry ); ++ ++ if (!async->completion && async->queue->fd) ++ async->completion = fd_get_completion( async->queue->fd, &async->comp_key ); ++ } ++} ++ +diff --git a/server/fd.c b/server/fd.c +index a8b3a5f..07db476 100644 +--- a/server/fd.c ++++ b/server/fd.c +@@ -2103,6 +2103,14 @@ void default_fd_cancel_async( struct fd *fd, struct process *process, struct thr + set_error( STATUS_NOT_FOUND ); + } + ++/* default update_async() fd routine */ ++void default_fd_update_async( struct fd *fd ) ++{ ++ async_update( fd->read_q ); ++ async_update( fd->write_q ); ++ async_update( fd->wait_q ); ++} ++ + /* default flush() routine */ + void no_flush( struct fd *fd, struct event **event ) + { +@@ -2350,6 +2358,7 @@ DECL_HANDLER(set_completion_info) + { + fd->completion = get_completion_obj( current->process, req->chandle, IO_COMPLETION_MODIFY_STATE ); + fd->comp_key = req->ckey; ++ fd->fd_ops->update_async( fd ); + } + else set_error( STATUS_INVALID_PARAMETER ); + release_object( fd ); +diff --git a/server/file.c b/server/file.c +index 02a1e37..83634c5 100644 +--- a/server/file.c ++++ b/server/file.c +@@ -102,7 +102,8 @@ static const struct fd_ops file_fd_ops = + default_fd_ioctl, /* ioctl */ + default_fd_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + static inline int is_overlapped( const struct file *file ) +diff --git a/server/file.h b/server/file.h +index ead356d..bb3c420 100644 +--- a/server/file.h ++++ b/server/file.h +@@ -48,6 +48,8 @@ struct fd_ops + void (*reselect_async)( struct fd *, struct async_queue *queue ); + /* cancel an async operation */ + void (*cancel_async)(struct fd *, struct process *process, struct thread *thread, client_ptr_t iosb); ++ /* update an async operation to correspond to changes in the file object */ ++ void (*update_async)(struct fd *); + }; + + /* file descriptor functions */ +@@ -92,6 +94,7 @@ extern void no_fd_queue_async( struct fd *fd, const async_data_t *data, int type + extern void default_fd_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); + extern void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ); + extern void default_fd_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ); ++extern void default_fd_update_async( struct fd *fd ); + extern void no_flush( struct fd *fd, struct event **event ); + extern void main_loop(void); + extern void remove_process_locks( struct process *process ); +@@ -164,6 +167,7 @@ extern void async_terminate( struct async *async, unsigned int status ); + extern int async_wake_up_by( struct async_queue *queue, struct process *process, + struct thread *thread, client_ptr_t iosb, unsigned int status ); + extern void async_wake_up( struct async_queue *queue, unsigned int status ); ++extern void async_update( struct async_queue *queue ); + extern struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key ); + extern void fd_copy_completion( struct fd *src, struct fd *dst ); + +diff --git a/server/mailslot.c b/server/mailslot.c +index 051f0ad..b29c168 100644 +--- a/server/mailslot.c ++++ b/server/mailslot.c +@@ -102,7 +102,8 @@ static const struct fd_ops mailslot_fd_ops = + default_fd_ioctl, /* ioctl */ + mailslot_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + +@@ -152,7 +153,8 @@ static const struct fd_ops mail_writer_fd_ops = + default_fd_ioctl, /* ioctl */ + default_fd_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + +@@ -202,7 +204,8 @@ static const struct fd_ops mailslot_device_fd_ops = + default_fd_ioctl, /* ioctl */ + default_fd_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + static void mailslot_destroy( struct object *obj) +diff --git a/server/mapping.c b/server/mapping.c +index 90956e9..60e9c5f 100644 +--- a/server/mapping.c ++++ b/server/mapping.c +@@ -103,7 +103,8 @@ static const struct fd_ops mapping_fd_ops = + no_fd_ioctl, /* ioctl */ + no_fd_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + static struct list shared_list = LIST_INIT(shared_list); +diff --git a/server/named_pipe.c b/server/named_pipe.c +index 590adca..2bd3827 100644 +--- a/server/named_pipe.c ++++ b/server/named_pipe.c +@@ -173,6 +173,7 @@ static const struct fd_ops pipe_server_fd_ops = + default_fd_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ + default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + /* client end functions */ +@@ -212,7 +213,8 @@ static const struct fd_ops pipe_client_fd_ops = + default_fd_ioctl, /* ioctl */ + default_fd_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + static void named_pipe_device_dump( struct object *obj, int verbose ); +@@ -256,7 +258,8 @@ static const struct fd_ops named_pipe_device_fd_ops = + named_pipe_device_ioctl, /* ioctl */ + default_fd_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + static void named_pipe_dump( struct object *obj, int verbose ) +diff --git a/server/serial.c b/server/serial.c +index 587fee1..57ba51c 100644 +--- a/server/serial.c ++++ b/server/serial.c +@@ -112,7 +112,8 @@ static const struct fd_ops serial_fd_ops = + default_fd_ioctl, /* ioctl */ + serial_queue_async, /* queue_async */ + default_fd_reselect_async, /* reselect_async */ +- default_fd_cancel_async /* cancel_async */ ++ default_fd_cancel_async, /* cancel_async */ ++ default_fd_update_async /* update_async */ + }; + + /* check if the given fd is a serial port */ +diff --git a/server/signal.c b/server/signal.c +index 5e4fe33..79dee43 100644 +--- a/server/signal.c ++++ b/server/signal.c +@@ -90,7 +90,8 @@ static const struct fd_ops handler_fd_ops = + NULL, /* ioctl */ + NULL, /* queue_async */ + NULL, /* reselect_async */ +- NULL /* cancel_async */ ++ NULL, /* cancel_async */ ++ NULL /* update_async */ + }; + + static struct handler *handler_sighup; +diff --git a/server/sock.c b/server/sock.c +index 7e4acd8..7d21a1e 100644 +--- a/server/sock.c ++++ b/server/sock.c +@@ -119,6 +119,7 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd ); + static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ); + static void sock_reselect_async( struct fd *fd, struct async_queue *queue ); + static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb ); ++static void sock_update_async( struct fd *fd ); + + static int sock_get_ntstatus( int err ); + static int sock_get_error( int err ); +@@ -153,7 +154,8 @@ static const struct fd_ops sock_fd_ops = + default_fd_ioctl, /* ioctl */ + sock_queue_async, /* queue_async */ + sock_reselect_async, /* reselect_async */ +- sock_cancel_async /* cancel_async */ ++ sock_cancel_async, /* cancel_async */ ++ sock_update_async /* update_async */ + }; + + +@@ -573,6 +575,15 @@ static void sock_cancel_async( struct fd *fd, struct process *process, struct th + set_error( STATUS_NOT_FOUND ); + } + ++static void sock_update_async( struct fd *fd ) ++{ ++ struct sock *sock = get_fd_user( fd ); ++ assert( sock->obj.ops == &sock_ops ); ++ ++ async_update( sock->read_q ); ++ async_update( sock->write_q ); ++} ++ + static struct fd *sock_get_fd( struct object *obj ) + { + struct sock *sock = (struct sock *)obj; +diff --git a/server/thread.c b/server/thread.c +index f9a575e..3ee9486 100644 +--- a/server/thread.c ++++ b/server/thread.c +@@ -157,7 +157,8 @@ static const struct fd_ops thread_fd_ops = + NULL, /* ioctl */ + NULL, /* queue_async */ + NULL, /* reselect_async */ +- NULL /* cancel_async */ ++ NULL, /* cancel_async */ ++ NULL /* update_async */ + }; + + static struct list thread_list = LIST_INIT(thread_list); +-- +1.7.5.4 + +From: "Erich E. Hoover" <ehoover@mymail.mines.edu> +Subject: [PATCH 2/3] server: STATUS_MORE_PROCESSING_REQUIRED does not indicate that an async operation is complete (try 2). +Message-Id: <CAEU2+vrQd0wT_virCOLPoa3R0CAUriNCw4yfa1ffwzgNUhnHcQ@mail.gmail.com> +Date: Mon, 14 May 2012 16:13:29 -0600 + +Real Name: + Erich Hoover + +Description: + Several MSDN articles indicate that kernel drivers can respond +with STATUS_MORE_PROCESSING_REQUIRED to indicate that an IRP is +incomplete and that a completion should not be processed. Handling +the return value of our async operations in this way permits us to +handle completions for closed AcceptEx socket handles (part 3). I +realize that my previous attempt at this (using STATUS_ALERTED) was +considered to be hackish, but I now have some evidence to support this +method and I have added a variety of tests that establish that +AcceptEx needs to work this way. Since there isn't enough room to add +the completion port and the completion key to apc_call_t and it would +be unacceptable to use the handle to the APC to send the completion, I +can't see any other way to solve this issue except to have the +callback return a value that means "I'm not done yet." + +Changelog: + server: STATUS_MORE_PROCESSING_REQUIRED does not indicate that an +async operation is complete. + +From 44442aada83546eb64a35f35105565d2ed4c1c31 Mon Sep 17 00:00:00 2001 +From: Erich Hoover <ehoover@mines.edu> +Date: Mon, 14 May 2012 15:41:19 -0600 +Subject: server: STATUS_MORE_PROCESSING_REQUIRED does not indicate that an + async operation is complete. + +--- + server/async.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/server/async.c b/server/async.c +index 01d1ca1..0e6fe05 100644 +--- a/server/async.c ++++ b/server/async.c +@@ -259,7 +259,9 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot + if (async->timeout) remove_timeout_user( async->timeout ); + async->timeout = NULL; + async->status = status; +- if (async->completion && async->data.cvalue) ++ if (status == STATUS_MORE_PROCESSING_REQUIRED) ++ async->status = STATUS_PENDING; ++ else if (async->completion && async->data.cvalue) + add_completion( async->completion, async->comp_key, async->data.cvalue, status, total ); + if (apc) + { +-- +1.7.5.4 + +From: "Erich E. Hoover" <ehoover@mymail.mines.edu> +Subject: [PATCH 3/3] ws2_32: Use STATUS_MORE_PROCESSING_REQUIRED to indicate that the AcceptEx async is incomplete (try 3). +Message-Id: <CAEU2+vrV0aS-op=9+tdaZLaRJMUtrAp=YFFfV_uX1ecYcK4kow@mail.gmail.com> +Date: Mon, 14 May 2012 16:14:24 -0600 + +Real Name: + Erich Hoover + +Description: + This patch changes the way AcceptEx handles completions so that +canceled sockets can still send completion notifications. The patch +fixes a significant issue with the WoW launcher and the Diablo 3 +installer (Bug #28898). + +Changelog: + ws2_32: Use STATUS_MORE_PROCESSING_REQUIRED to indicate that the +AcceptEx async is incomplete. + +From bd886c015470c786e464f92e2ea7b75c84d73b91 Mon Sep 17 00:00:00 2001 +From: Erich Hoover <ehoover@mines.edu> +Date: Mon, 14 May 2012 15:50:16 -0600 +Subject: ws2_32: Use STATUS_MORE_PROCESSING_REQUIRED to indicate that the + AcceptEx async is incomplete. + +--- + dlls/ws2_32/socket.c | 8 +++--- + dlls/ws2_32/tests/sock.c | 50 +++++++++++++++++++++++----------------------- + 2 files changed, 29 insertions(+), 29 deletions(-) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index 21e084b..007514c 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -1706,7 +1706,7 @@ static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS sta + if (status != STATUS_PENDING) + goto finish; + +- return STATUS_SUCCESS; ++ return STATUS_MORE_PROCESSING_REQUIRED; + + finish: + iosb->u.Status = status; +@@ -1714,8 +1714,6 @@ finish: + + if (wsa->user_overlapped->hEvent) + SetEvent(wsa->user_overlapped->hEvent); +- if (wsa->cvalue) +- WS_AddCompletion( HANDLE2SOCKET(wsa->listen_socket), wsa->cvalue, iosb->u.Status, iosb->Information ); + + *apc = ws2_async_accept_apc; + return status; +@@ -2046,7 +2044,9 @@ static BOOL WINAPI WS2_AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DW + req->async.callback = wine_server_client_ptr( WS2_async_accept ); + req->async.iosb = wine_server_client_ptr( overlapped ); + req->async.arg = wine_server_client_ptr( wsa ); +- /* We don't set event or completion since we may also have to read */ ++ req->async.cvalue = cvalue; ++ /* We don't set event since we may also have to read, the APC returns STATUS_MORE_PROCESSING_REQUIRED ++ * to indicate that the async operation is incomplete and that no completion should be queued. */ + status = wine_server_call( req ); + } + SERVER_END_REQ; +diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c +index e9814e3..29616b2 100644 +--- a/dlls/ws2_32/tests/sock.c ++++ b/dlls/ws2_32/tests/sock.c +@@ -5494,11 +5494,11 @@ static void test_completion_port(void) + + bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100); + ok(bret == FALSE, "failed to get completion status %u\n", bret); +- todo_wine ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); +- todo_wine ok(key == 125, "Key is %lu\n", key); +- todo_wine ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); +- todo_wine ok(olp == &ov, "Overlapped structure is at %p\n", olp); +- todo_wine ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); ++ ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); ++ ok(key == 125, "Key is %lu\n", key); ++ ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); ++ ok(olp == &ov, "Overlapped structure is at %p\n", olp); ++ ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); + + SetLastError(0xdeadbeef); + key = 0xdeadbeef; +@@ -5537,11 +5537,11 @@ static void test_completion_port(void) + + bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100); + ok(bret == FALSE, "failed to get completion status %u\n", bret); +- todo_wine ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); +- todo_wine ok(key == 125, "Key is %lu\n", key); +- todo_wine ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); +- todo_wine ok(olp == &ov, "Overlapped structure is at %p\n", olp); +- todo_wine ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); ++ ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); ++ ok(key == 125, "Key is %lu\n", key); ++ ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); ++ ok(olp == &ov, "Overlapped structure is at %p\n", olp); ++ ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); + + SetLastError(0xdeadbeef); + key = 0xdeadbeef; +@@ -5596,11 +5596,11 @@ static void test_completion_port(void) + olp = (WSAOVERLAPPED *)0xdeadbeef; + bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100); + ok(bret == FALSE, "failed to get completion status %u\n", bret); +- todo_wine ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); +- todo_wine ok(key == 125, "Key is %lu\n", key); +- todo_wine ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); +- todo_wine ok(olp == &ov, "Overlapped structure is at %p\n", olp); +- todo_wine ok(olp && olp->Internal == (ULONG)STATUS_CANCELLED, "Internal status is %lx\n", olp ? olp->Internal : 0); ++ ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); ++ ok(key == 125, "Key is %lu\n", key); ++ ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); ++ ok(olp == &ov, "Overlapped structure is at %p\n", olp); ++ ok(olp && olp->Internal == (ULONG)STATUS_CANCELLED, "Internal status is %lx\n", olp ? olp->Internal : 0); + + SetLastError(0xdeadbeef); + key = 0xdeadbeef; +@@ -5663,11 +5663,11 @@ static void test_completion_port(void) + + bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100); + ok(bret == FALSE, "failed to get completion status %u\n", bret); +- todo_wine ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); +- todo_wine ok(key == 125, "Key is %lu\n", key); +- todo_wine ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); +- todo_wine ok(olp == &ov, "Overlapped structure is at %p\n", olp); +- todo_wine ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); ++ ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); ++ ok(key == 125, "Key is %lu\n", key); ++ ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); ++ ok(olp == &ov, "Overlapped structure is at %p\n", olp); ++ ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); + + SetLastError(0xdeadbeef); + key = 0xdeadbeef; +@@ -5719,11 +5719,11 @@ static void test_completion_port(void) + + bret = GetQueuedCompletionStatus(io_port, &num_bytes, &key, &olp, 100); + ok(bret == FALSE, "failed to get completion status %u\n", bret); +- todo_wine ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); +- todo_wine ok(key == 125, "Key is %lu\n", key); +- todo_wine ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); +- todo_wine ok(olp == &ov, "Overlapped structure is at %p\n", olp); +- todo_wine ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); ++ ok(GetLastError() == ERROR_OPERATION_ABORTED, "Last error was %d\n", GetLastError()); ++ ok(key == 125, "Key is %lu\n", key); ++ ok(num_bytes == 0, "Number of bytes transferred is %u\n", num_bytes); ++ ok(olp == &ov, "Overlapped structure is at %p\n", olp); ++ ok(olp && (olp->Internal == (ULONG)STATUS_CANCELLED), "Internal status is %lx\n", olp ? olp->Internal : 0); + + SetLastError(0xdeadbeef); + key = 0xdeadbeef; +-- +1.7.5.4 + + |