From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 64 +++++++++++++++++++++++++++++++++++--- dlls/win32u/tests/d3dkmt.c | 46 +++++++++++++-------------- server/d3dkmt.c | 21 +++++++++++++ server/protocol.def | 12 +++++++ 4 files changed, 116 insertions(+), 27 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 665a7b36175..3afdcabfcf8 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -407,6 +407,20 @@ static BOOL d3dkmt_use_vulkan(void) return !!d3dkmt_vk_instance; }
+static unsigned int validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) +{ + if (!attr || attr->Length != sizeof(*attr)) return STATUS_INVALID_PARAMETER; + + if (attr->ObjectName) + { + if ((ULONG_PTR)attr->ObjectName->Buffer & (sizeof(WCHAR) - 1)) return STATUS_DATATYPE_MISALIGNMENT; + if (attr->ObjectName->Length & (sizeof(WCHAR) - 1)) return STATUS_OBJECT_NAME_INVALID; + } + else if (attr->RootDirectory) return STATUS_OBJECT_NAME_INVALID; + + return STATUS_SUCCESS; +} + /****************************************************************************** * NtGdiDdDDIOpenAdapterFromHdc (win32u.@) */ @@ -1234,15 +1248,37 @@ failed: return status; }
+ /****************************************************************************** * NtGdiDdDDIOpenNtHandleFromName (win32u.@) */ NTSTATUS WINAPI NtGdiDdDDIOpenNtHandleFromName( D3DKMT_OPENNTHANDLEFROMNAME *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + OBJECT_ATTRIBUTES *attr = params->pObjAttrib; + DWORD access = params->dwDesiredAccess; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + params->hNtHandle = 0; + if ((status = validate_open_object_attributes( attr ))) return status; + + SERVER_START_REQ( d3dkmt_object_open_name ) + { + req->type = D3DKMT_RESOURCE; + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + status = wine_server_call( req ); + params->hNtHandle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + return status; }
+ /****************************************************************************** * NtGdiDdDDIQueryResourceInfo (win32u.@) */ @@ -1531,8 +1567,28 @@ failed: */ NTSTATUS WINAPI NtGdiDdDDIOpenSyncObjectNtHandleFromName( D3DKMT_OPENSYNCOBJECTNTHANDLEFROMNAME *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + OBJECT_ATTRIBUTES *attr = params->pObjAttrib; + DWORD access = params->dwDesiredAccess; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + params->hNtHandle = 0; + if ((status = validate_open_object_attributes( attr ))) return status; + + SERVER_START_REQ( d3dkmt_object_open_name ) + { + req->type = D3DKMT_SYNC; + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + if (attr->ObjectName) wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + status = wine_server_call( req ); + params->hNtHandle = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + + return status; }
/****************************************************************************** diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index 4a7578f2588..5385c25a9d0 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -2254,18 +2254,18 @@ static void test_D3DKMTShareObjects( void )
status = D3DKMTOpenSyncObjectNtHandleFromName( &open_sync_name ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); InitializeObjectAttributes( &attr, &name_invalid, 0, 0, NULL ); open_sync_name.pObjAttrib = &attr; status = D3DKMTOpenSyncObjectNtHandleFromName( &open_sync_name ); - todo_wine ok_nt( STATUS_OBJECT_NAME_NOT_FOUND, status ); + ok_nt( STATUS_OBJECT_NAME_NOT_FOUND, status ); InitializeObjectAttributes( &attr, &name_lower, 0, 0, NULL ); open_sync_name.pObjAttrib = &attr; status = D3DKMTOpenSyncObjectNtHandleFromName( &open_sync_name ); - todo_wine ok_nt( STATUS_ACCESS_DENIED, status ); + ok_nt( STATUS_ACCESS_DENIED, status ); open_sync_name.dwDesiredAccess = STANDARD_RIGHTS_WRITE; status = D3DKMTOpenSyncObjectNtHandleFromName( &open_sync_name ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); ok( !((UINT_PTR)open_sync_name.hNtHandle & 0xc0000000), "got %p\n", open_sync_name.hNtHandle );
@@ -2276,8 +2276,8 @@ static void test_D3DKMTShareObjects( void ) open_sync2.hNtHandle = open_sync_name.hNtHandle; open_sync2.hSyncObject = 0x1eadbeed; status = D3DKMTOpenSyncObjectFromNtHandle2( &open_sync2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open_sync2.hSyncObject, NULL ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open_sync2.hSyncObject, NULL );
CloseHandle( open_sync_name.hNtHandle );
@@ -2286,26 +2286,26 @@ static void test_D3DKMTShareObjects( void ) InitializeObjectAttributes( &attr, &name_lower, 0, 0, NULL ); open_sync_name.pObjAttrib = &attr; status = D3DKMTOpenSyncObjectNtHandleFromName( &open_sync_name ); - todo_wine ok_nt( STATUS_OBJECT_NAME_NOT_FOUND, status ); + ok_nt( STATUS_OBJECT_NAME_NOT_FOUND, status );
/* but object still exists and can be re-shared */ InitializeObjectAttributes( &attr, &name, 0, 0, NULL ); handle = (HANDLE)0xdeadbeef; status = D3DKMTShareObjects( 1, &open_sync2.hSyncObject, &attr, STANDARD_RIGHTS_READ, &handle ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* can be opened again by name */ open_sync_name.pObjAttrib = &attr; open_sync_name.dwDesiredAccess = STANDARD_RIGHTS_READ; status = D3DKMTOpenSyncObjectNtHandleFromName( &open_sync_name ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
CloseHandle( open_sync_name.hNtHandle ); CloseHandle( handle );
destroy_sync.hSyncObject = open_sync2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy_sync ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* D3DKMTShareObjects doesn't work with keyed mutex objects alone */ @@ -2403,18 +2403,18 @@ static void test_D3DKMTShareObjects( void )
status = D3DKMTOpenNtHandleFromName( &open_resource_name ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); InitializeObjectAttributes( &attr, &name_invalid, 0, 0, NULL ); open_resource_name.pObjAttrib = &attr; status = D3DKMTOpenNtHandleFromName( &open_resource_name ); - todo_wine ok_nt( STATUS_OBJECT_NAME_NOT_FOUND, status ); + ok_nt( STATUS_OBJECT_NAME_NOT_FOUND, status ); InitializeObjectAttributes( &attr, &name_lower, 0, 0, NULL ); open_resource_name.pObjAttrib = &attr; status = D3DKMTOpenNtHandleFromName( &open_resource_name ); - todo_wine ok_nt( STATUS_ACCESS_DENIED, status ); + ok_nt( STATUS_ACCESS_DENIED, status ); open_resource_name.dwDesiredAccess = GENERIC_ALL; status = D3DKMTOpenNtHandleFromName( &open_resource_name ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); ok( !((UINT_PTR)open_resource_name.hNtHandle & 0xc0000000), "got %p\n", open_resource_name.hNtHandle );
query_resource.hDevice = create_device.hDevice; @@ -2424,19 +2424,19 @@ static void test_D3DKMTShareObjects( void ) query_resource.ResourcePrivateDriverDataSize = 0xdeadbeef; query_resource.NumAllocations = 0xdeadbeef; status = D3DKMTQueryResourceInfoFromNtHandle( &query_resource ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); - ok_x4( query_resource.TotalPrivateDriverDataSize, >, 0 ); - todo_wine ok_x4( query_resource.TotalPrivateDriverDataSize, <, sizeof(driver_data) ); - todo_wine ok_x4( query_resource.ResourcePrivateDriverDataSize, ==, 0 ); - todo_wine ok_u4( query_resource.NumAllocations, ==, 1 ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + todo_wine ok_x4( query_resource.TotalPrivateDriverDataSize, >, 0 ); + ok_x4( query_resource.TotalPrivateDriverDataSize, <, sizeof(driver_data) ); + ok_x4( query_resource.ResourcePrivateDriverDataSize, ==, 0 ); + ok_u4( query_resource.NumAllocations, ==, 1 );
memset( runtime_data, 0xcd, sizeof(runtime_data) ); query_resource.pPrivateRuntimeData = runtime_data; query_resource.PrivateRuntimeDataSize = 0; /* sizeof(runtime_data); */ status = D3DKMTQueryResourceInfoFromNtHandle( &query_resource ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); ok_u1( runtime_data[0], ==, 0xcd );
CloseHandle( open_resource_name.hNtHandle ); @@ -2468,7 +2468,7 @@ static void test_D3DKMTShareObjects( void ) todo_wine check_d3dkmt_local( open_alloc.hAllocation, NULL ); todo_wine ok_x4( open_alloc.PrivateDriverDataSize, >, 0 ); ok_x4( open_alloc.PrivateDriverDataSize, <, sizeof(alloc_data) ); - todo_wine ok( !memcmp( runtime_data, expect_runtime_data, sizeof(expect_runtime_data) ), "got data %#x\n", runtime_data[0] ); + ok( !memcmp( runtime_data, expect_runtime_data, sizeof(expect_runtime_data) ), "got data %#x\n", runtime_data[0] ); todo_wine ok_u1( driver_data[0], !=, 0xcd );
destroy_alloc.hResource = open_resource.hResource; diff --git a/server/d3dkmt.c b/server/d3dkmt.c index 4cc4f3ad0bd..8dba86df97d 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -470,3 +470,24 @@ done: if (mutex) release_object( mutex ); if (sync) release_object( sync ); } + +/* open a shared d3dkmt object from its name */ +DECL_HANDLER(d3dkmt_object_open_name) +{ + struct unicode_str name = get_req_unicode_str(); + + switch (req->type) + { + case D3DKMT_SYNC: + reply->handle = open_object( current->process, req->rootdir, req->access, &dxgk_shared_sync_ops, + &name, req->attributes | OBJ_CASE_INSENSITIVE ); + break; + case D3DKMT_RESOURCE: + reply->handle = open_object( current->process, req->rootdir, req->access, &dxgk_shared_resource_ops, + &name, req->attributes | OBJ_CASE_INSENSITIVE ); + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + break; + } +} diff --git a/server/protocol.def b/server/protocol.def index 29f05cf1273..6013cbf8841 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4196,3 +4196,15 @@ enum inproc_sync_type @REPLY obj_handle_t handle; /* shared object handle */ @END + + +/* Open a shared d3dkmt object from a name */ +@REQ(d3dkmt_object_open_name) + unsigned int type; /* d3dkmt object type */ + unsigned int access; /* wanted access rights */ + unsigned int attributes; /* object attributes */ + obj_handle_t rootdir; /* root directory */ + VARARG(name,unicode_str); /* object name */ +@REPLY + obj_handle_t handle; /* shared object handle */ +@END