From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 3 +++ server/d3dkmt.c | 44 +++++++++++++++++++++++++++++++++++++++++++- server/protocol.def | 1 + 3 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index d7f1cfd34c5..07f135671b2 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -187,9 +187,12 @@ static NTSTATUS d3dkmt_object_create( struct d3dkmt_object *object, BOOL shared, { NTSTATUS status;
+ if (object->fd >= 0) wine_server_send_fd( object->fd ); + SERVER_START_REQ( d3dkmt_object_create ) { req->type = object->type; + req->fd = object->fd; if (runtime_size) wine_server_add_data( req, runtime, runtime_size ); status = wine_server_call( req ); object->handle = wine_server_ptr_handle( reply->handle ); diff --git a/server/d3dkmt.c b/server/d3dkmt.c index c253740a7bb..d8899346c70 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -23,6 +23,7 @@ #include <assert.h> #include <stdbool.h> #include <stdio.h> +#include <unistd.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -42,6 +43,7 @@ struct d3dkmt_object d3dkmt_handle_t global; /* object global handle */ void *runtime; /* client runtime data */ data_size_t runtime_size; /* size of client runtime data */ + struct fd *fd; /* fd object for unix fds */ };
static void d3dkmt_object_dump( struct object *obj, int verbose ); @@ -72,6 +74,27 @@ static const struct object_ops d3dkmt_object_ops = d3dkmt_object_destroy, /* destroy */ };
+static enum server_fd_type d3dkmt_get_fd_type( struct fd *fd ) +{ + return FD_TYPE_INVALID; +} + +static const struct fd_ops d3dkmt_fd_ops = +{ + default_fd_get_poll_events, /* get_poll_events */ + default_poll_event, /* poll_event */ + d3dkmt_get_fd_type, /* get_fd_type */ + no_fd_read, /* read */ + no_fd_write, /* write */ + no_fd_flush, /* flush */ + no_fd_get_file_info, /* get_file_info */ + no_fd_get_volume_info, /* get_volume_info */ + no_fd_ioctl, /* ioctl */ + default_fd_cancel_async, /* cancel_async */ + no_fd_queue_async, /* queue_async */ + default_fd_reselect_async /* reselect_async */ +}; + #define DXGK_SHARED_SYNC_QUERY_STATE 0x0001 #define DXGK_SHARED_SYNC_MODIFY_STATE 0x0002 #define DXGK_SHARED_SYNC_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) @@ -312,6 +335,7 @@ static void d3dkmt_object_destroy( struct object *obj ) assert( obj->ops == &d3dkmt_object_ops );
if (object->global) free_object_handle( object->global ); + if (object->fd) release_object( object->fd ); free( object->runtime ); }
@@ -323,6 +347,7 @@ static struct d3dkmt_object *d3dkmt_object_create( enum d3dkmt_type type, data_s object->type = type; object->global = 0; object->runtime_size = runtime_size; + object->fd = NULL;
if (!(object->runtime = memdup( runtime, runtime_size )) || !(object->global = alloc_object_handle( object ))) @@ -381,11 +406,28 @@ static struct d3dkmt_object *d3dkmt_object_open_shared( obj_handle_t handle, enu DECL_HANDLER(d3dkmt_object_create) { struct d3dkmt_object *object; + struct fd *fd = NULL; + + if (req->fd >= 0) + { + int unix_fd; + if ((unix_fd = thread_get_inflight_fd( current, req->fd )) < 0) return; + if (!(fd = create_anonymous_fd( NULL, unix_fd, NULL, 0 ))) return; + } + + if (!(object = d3dkmt_object_create( req->type, get_req_data_size(), get_req_data() ))) goto done; + if (fd) + { + set_fd_user( fd, &d3dkmt_fd_ops, &object->obj ); + object->fd = (struct fd *)grab_object( fd ); + }
- if (!(object = d3dkmt_object_create( req->type, get_req_data_size(), get_req_data() ))) return; reply->handle = alloc_handle( current->process, object, STANDARD_RIGHTS_ALL, OBJ_INHERIT ); reply->global = object->global; release_object( object ); + +done: + if (fd) release_object( fd ); }
/* update a global d3dkmt object */ diff --git a/server/protocol.def b/server/protocol.def index 87b8730f92a..45fa52858e7 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4177,6 +4177,7 @@ enum inproc_sync_type /* Create a global d3dkmt object */ @REQ(d3dkmt_object_create) unsigned int type; /* d3dkmt object type */ + int fd; /* host specific fd */ VARARG(runtime,bytes); /* client runtime data */ @REPLY d3dkmt_handle_t global; /* global d3dkmt handle */