summaryrefslogtreecommitdiffstats
path: root/wine
diff options
context:
space:
mode:
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
commit36fe652198e83d5c6b4a3b5cba8834b68b87158e (patch)
treec882dd56b0ed60453ba259e913ffcaa282447fa2 /wine
parentfc712a4b0bdd542beb59a47cb04d49c9d3f49842 (diff)
downloadasb-36fe652198e83d5c6b4a3b5cba8834b68b87158e.tar.gz
asb-36fe652198e83d5c6b4a3b5cba8834b68b87158e.tar.xz
Initial revision
Diffstat (limited to 'wine')
-rw-r--r--wine/build/wine_acceptex.patch529
-rw-r--r--wine/build/wine_d3d_reset.patch24
2 files changed, 553 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
+
+
diff --git a/wine/build/wine_d3d_reset.patch b/wine/build/wine_d3d_reset.patch
new file mode 100644
index 00000000..45197358
--- /dev/null
+++ b/wine/build/wine_d3d_reset.patch
@@ -0,0 +1,24 @@
+--- a/dlls/wined3d/device.c
++++ a/dlls/wined3d/device.c
+@@ -5294,6 +5294,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
+ wined3d_surface_decref(device->onscreen_depth_stencil);
+ device->onscreen_depth_stencil = NULL;
+ }
++ wined3d_device_set_depth_stencil(device, NULL);
+
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+@@ -5393,11 +5394,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
+ device->onscreen_depth_stencil = NULL;
+ }
+
+- /* Reset the depth stencil */
++ /* Apply the auto depth stencil if the app requested one */
+ if (swapchain_desc->enable_auto_depth_stencil)
+ wined3d_device_set_depth_stencil(device, device->auto_depth_stencil);
+- else
+- wined3d_device_set_depth_stencil(device, NULL);
+
+ TRACE("Resetting stateblock\n");
+ wined3d_stateblock_decref(device->updateStateBlock);
+