From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 160 ++++++++++++++++++++++++++++++++++--- dlls/win32u/tests/d3dkmt.c | 121 +++++++++++++--------------- dlls/wow64win/gdi.c | 13 ++- server/d3dkmt.c | 26 ++++++ server/protocol.def | 12 +++ 5 files changed, 254 insertions(+), 78 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index e073c11a832..f21a7728581 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -202,6 +202,30 @@ static NTSTATUS d3dkmt_object_create( struct d3dkmt_object *object, BOOL shared, return status; }
+static NTSTATUS d3dkmt_object_open( struct d3dkmt_object *obj, D3DKMT_HANDLE global, + void *runtime, UINT *runtime_size ) +{ + NTSTATUS status; + + SERVER_START_REQ( d3dkmt_object_open ) + { + req->type = obj->type; + req->global = global; + if (runtime) wine_server_set_reply( req, runtime, *runtime_size ); + status = wine_server_call( req ); + obj->handle = wine_server_ptr_handle( reply->handle ); + obj->global = reply->global; + obj->shared = !global; + *runtime_size = reply->runtime_size; + } + SERVER_END_REQ; + if (!status) status = alloc_object_handle( obj ); + + if (status) WARN( "Failed to open global object %#x, status %#x\n", global, status ); + else TRACE( "Opened global object %#x as %p/%#x\n", global, obj, obj->local ); + return status; +} + static NTSTATUS d3dkmt_object_query( enum d3dkmt_type type, D3DKMT_HANDLE global, UINT *runtime_size ) { NTSTATUS status; @@ -215,8 +239,8 @@ static NTSTATUS d3dkmt_object_query( enum d3dkmt_type type, D3DKMT_HANDLE global } SERVER_END_REQ;
- if (status) WARN( "Failed to query object %#x, status %#x\n", global, status ); - else TRACE( "Found object %#x with runtime size %#x\n", global, *runtime_size ); + if (status) WARN( "Failed to query global object %#x, status %#x\n", global, status ); + else TRACE( "Found global object %#x with runtime size %#x\n", global, *runtime_size ); return status; }
@@ -930,8 +954,42 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyAllocation( const D3DKMT_DESTROYALLOCATION *par */ NTSTATUS WINAPI NtGdiDdDDIOpenResource( D3DKMT_OPENRESOURCE *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *device, *allocation; + D3DDDI_OPENALLOCATIONINFO *alloc_info; + struct d3dkmt_resource *resource; + UINT runtime_size; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + if (!(device = get_d3dkmt_object( params->hDevice, D3DKMT_DEVICE ))) return STATUS_INVALID_PARAMETER; + if (!is_d3dkmt_global( params->hGlobalShare )) return STATUS_INVALID_PARAMETER; + if (params->ResourcePrivateDriverDataSize) return STATUS_INVALID_PARAMETER; + + if (!params->NumAllocations) return STATUS_INVALID_PARAMETER; + if (!(alloc_info = params->pOpenAllocationInfo)) return STATUS_INVALID_PARAMETER; + + if ((status = d3dkmt_object_alloc( sizeof(*resource), D3DKMT_RESOURCE, (void **)&resource ))) return status; + if ((status = d3dkmt_object_alloc( sizeof(*allocation), D3DKMT_ALLOCATION, (void **)&allocation ))) goto failed; + + runtime_size = params->PrivateRuntimeDataSize; + if ((status = d3dkmt_object_open( &resource->obj, params->hGlobalShare, params->pPrivateRuntimeData, &runtime_size ))) goto failed; + + if ((status = alloc_object_handle( allocation ))) goto failed; + resource->allocation = allocation->local; + alloc_info->hAllocation = allocation->local; + alloc_info->PrivateDriverDataSize = 0; + + params->hResource = resource->obj.local; + params->PrivateRuntimeDataSize = runtime_size; + params->TotalPrivateDriverDataBufferSize = 0; + params->ResourcePrivateDriverDataSize = 0; + return STATUS_SUCCESS; + +failed: + d3dkmt_object_free( &resource->obj ); + return status; }
/****************************************************************************** @@ -939,8 +997,42 @@ NTSTATUS WINAPI NtGdiDdDDIOpenResource( D3DKMT_OPENRESOURCE *params ) */ NTSTATUS WINAPI NtGdiDdDDIOpenResource2( D3DKMT_OPENRESOURCE *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *device, *allocation; + D3DDDI_OPENALLOCATIONINFO2 *alloc_info; + struct d3dkmt_resource *resource; + UINT runtime_size; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + if (!(device = get_d3dkmt_object( params->hDevice, D3DKMT_DEVICE ))) return STATUS_INVALID_PARAMETER; + if (!is_d3dkmt_global( params->hGlobalShare )) return STATUS_INVALID_PARAMETER; + if (params->ResourcePrivateDriverDataSize) return STATUS_INVALID_PARAMETER; + + if (!params->NumAllocations) return STATUS_INVALID_PARAMETER; + if (!(alloc_info = params->pOpenAllocationInfo2)) return STATUS_INVALID_PARAMETER; + + if ((status = d3dkmt_object_alloc( sizeof(*resource), D3DKMT_RESOURCE, (void **)&resource ))) return status; + if ((status = d3dkmt_object_alloc( sizeof(*allocation), D3DKMT_ALLOCATION, (void **)&allocation ))) goto failed; + + runtime_size = params->PrivateRuntimeDataSize; + if ((status = d3dkmt_object_open( &resource->obj, params->hGlobalShare, params->pPrivateRuntimeData, &runtime_size ))) goto failed; + + if ((status = alloc_object_handle( allocation ))) goto failed; + resource->allocation = allocation->local; + alloc_info->hAllocation = allocation->local; + alloc_info->PrivateDriverDataSize = 0; + + params->hResource = resource->obj.local; + params->PrivateRuntimeDataSize = runtime_size; + params->TotalPrivateDriverDataBufferSize = 0; + params->ResourcePrivateDriverDataSize = 0; + return STATUS_SUCCESS; + +failed: + d3dkmt_object_free( &resource->obj ); + return status; }
/****************************************************************************** @@ -1060,8 +1152,27 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyKeyedMutex( const D3DKMT_DESTROYKEYEDMUTEX *par */ NTSTATUS WINAPI NtGdiDdDDIOpenKeyedMutex2( D3DKMT_OPENKEYEDMUTEX2 *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *mutex; + UINT runtime_size; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + if (!is_d3dkmt_global( params->hSharedHandle )) return STATUS_INVALID_PARAMETER; + if (params->PrivateRuntimeDataSize && !params->pPrivateRuntimeData) return STATUS_INVALID_PARAMETER; + + if ((status = d3dkmt_object_alloc( sizeof(*mutex), D3DKMT_MUTEX, (void **)&mutex ))) return status; + + runtime_size = params->PrivateRuntimeDataSize; + if ((status = d3dkmt_object_open( mutex, params->hSharedHandle, params->pPrivateRuntimeData, &runtime_size ))) goto failed; + + params->hKeyedMutex = mutex->local; + return STATUS_SUCCESS; + +failed: + d3dkmt_object_free( mutex ); + return status; }
/****************************************************************************** @@ -1069,8 +1180,17 @@ NTSTATUS WINAPI NtGdiDdDDIOpenKeyedMutex2( D3DKMT_OPENKEYEDMUTEX2 *params ) */ NTSTATUS WINAPI NtGdiDdDDIOpenKeyedMutex( D3DKMT_OPENKEYEDMUTEX *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + D3DKMT_OPENKEYEDMUTEX2 params2 = {0}; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + + params2.hSharedHandle = params->hSharedHandle; + status = NtGdiDdDDIOpenKeyedMutex2( ¶ms2 ); + params->hKeyedMutex = params2.hKeyedMutex; + return status; }
/****************************************************************************** @@ -1172,8 +1292,24 @@ NTSTATUS WINAPI NtGdiDdDDIOpenSyncObjectNtHandleFromName( D3DKMT_OPENSYNCOBJECTN */ NTSTATUS WINAPI NtGdiDdDDIOpenSynchronizationObject( D3DKMT_OPENSYNCHRONIZATIONOBJECT *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *sync; + NTSTATUS status; + UINT dummy = 0; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + if (!is_d3dkmt_global( params->hSharedHandle )) return STATUS_INVALID_PARAMETER; + + if ((status = d3dkmt_object_alloc( sizeof(*sync), D3DKMT_SYNC, (void **)&sync ))) return status; + if ((status = d3dkmt_object_open( sync, params->hSharedHandle, NULL, &dummy ))) goto failed; + + params->hSyncObject = sync->local; + return STATUS_SUCCESS; + +failed: + d3dkmt_object_free( sync ); + return status; }
/****************************************************************************** diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index b6080dbe604..83ed9f0dfd0 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -1230,8 +1230,8 @@ static void test_D3DKMTCreateSynchronizationObject_process( const char *arg ) open.hSharedHandle = global; open.hSyncObject = 0x1eadbeed; status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open.hSyncObject, &next_local ); /* leak the object */ }
@@ -1401,22 +1401,22 @@ static void test_D3DKMTCreateSynchronizationObject( void ) /* D3DKMTOpenSynchronizationObject creates a new local D3DKMT_HANDLE */ open.hSharedHandle = 0x1eadbeed; status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.hSharedHandle = 0; status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.hSyncObject = create2.hSyncObject; status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.hSyncObject = 0x1eadbeed; open.hSharedHandle = create2.Info.SharedHandle; status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open.hSyncObject, &next_local );
destroy.hSyncObject = open.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); /* destroying multiple times fails */ status = D3DKMTDestroySynchronizationObject( &destroy ); ok_nt( STATUS_INVALID_PARAMETER, status ); @@ -1424,20 +1424,19 @@ static void test_D3DKMTCreateSynchronizationObject( void ) /* the D3DKMT object can still be opened */ open.hSyncObject = 0x1eadbeed; status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open.hSyncObject, &next_local ); - next_local = 0; + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open.hSyncObject, &next_local );
destroy.hSyncObject = open.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); ok_nt( STATUS_SUCCESS, status ); /* the global D3DKMT_HANDLE is destroyed with last reference */ status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
/* NtSecuritySharing requires Shared, doesn't creates a global handle */ @@ -1483,7 +1482,7 @@ static void test_D3DKMTCreateSynchronizationObject( void )
open.hSharedHandle = create2.Info.SharedHandle; status = D3DKMTOpenSynchronizationObject( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
destroy_device.hDevice = create_device.hDevice; @@ -1514,16 +1513,15 @@ static void test_D3DKMTCreateKeyedMutex( void ) check_d3dkmt_global( create.hSharedHandle );
status = D3DKMTOpenKeyedMutex( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.hKeyedMutex = create.hKeyedMutex; status = D3DKMTOpenKeyedMutex( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.hKeyedMutex = 0x1eadbeed; open.hSharedHandle = create.hSharedHandle; status = D3DKMTOpenKeyedMutex( &open ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open.hKeyedMutex, &next_local ); - next_local = 0; + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open.hKeyedMutex, &next_local );
status = D3DKMTDestroyKeyedMutex( &destroy ); ok_nt( STATUS_INVALID_PARAMETER, status ); @@ -1533,12 +1531,12 @@ static void test_D3DKMTCreateKeyedMutex( void ) /* older W10 lets you destroy the global D3DKMT_HANDLE, it causes random failures in the tests below */ destroy.hKeyedMutex = create.hSharedHandle; status = D3DKMTDestroyKeyedMutex( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); }
destroy.hKeyedMutex = open.hKeyedMutex; status = D3DKMTDestroyKeyedMutex( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); /* destroying multiple times fails */ status = D3DKMTDestroyKeyedMutex( &destroy ); ok_nt( STATUS_INVALID_PARAMETER, status ); @@ -1549,7 +1547,7 @@ static void test_D3DKMTCreateKeyedMutex( void )
/* the global D3DKMT_HANDLE is destroyed with last reference */ status = D3DKMTOpenKeyedMutex( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
status = D3DKMTCreateKeyedMutex2( NULL ); @@ -1568,16 +1566,15 @@ static void test_D3DKMTCreateKeyedMutex( void ) check_d3dkmt_global( create2.hSharedHandle );
status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open2.hKeyedMutex = create2.hKeyedMutex; status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open2.hKeyedMutex = 0x1eadbeed; open2.hSharedHandle = create2.hSharedHandle; status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open2.hKeyedMutex, &next_local ); - next_local = 0; + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open2.hKeyedMutex, &next_local );
status = D3DKMTDestroyKeyedMutex( &destroy ); ok_nt( STATUS_SUCCESS, status ); @@ -1586,7 +1583,7 @@ static void test_D3DKMTCreateKeyedMutex( void ) ok_nt( STATUS_SUCCESS, status ); destroy.hKeyedMutex = open2.hKeyedMutex; status = D3DKMTDestroyKeyedMutex( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* PrivateRuntimeDataSize must be 0 if no buffer is provided */ @@ -1600,17 +1597,16 @@ static void test_D3DKMTCreateKeyedMutex( void ) open2.hSharedHandle = create2.hSharedHandle; open2.PrivateRuntimeDataSize = sizeof(buffer); status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open2.pPrivateRuntimeData = buffer; status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open2.hKeyedMutex, &next_local ); - next_local = 0; + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open2.hKeyedMutex, &next_local ); ok_x4( open2.PrivateRuntimeDataSize, ==, sizeof(buffer) );
destroy.hKeyedMutex = open2.hKeyedMutex; status = D3DKMTDestroyKeyedMutex( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); destroy.hKeyedMutex = create2.hKeyedMutex; status = D3DKMTDestroyKeyedMutex( &destroy ); ok_nt( STATUS_SUCCESS, status ); @@ -1628,30 +1624,28 @@ static void test_D3DKMTCreateKeyedMutex( void ) open2.PrivateRuntimeDataSize = 0; open2.pPrivateRuntimeData = NULL; status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open2.hKeyedMutex, &next_local ); - next_local = 0; + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open2.hKeyedMutex, &next_local ); ok_x4( open2.PrivateRuntimeDataSize, ==, 0 );
open2.PrivateRuntimeDataSize = sizeof(buffer); status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open2.PrivateRuntimeDataSize = sizeof(runtime_data) - 1; open2.pPrivateRuntimeData = buffer; status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open2.PrivateRuntimeDataSize = sizeof(runtime_data); memset( buffer, 0xcd, sizeof(buffer) ); status = D3DKMTOpenKeyedMutex2( &open2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( open2.hKeyedMutex, &next_local ); - next_local = 0; + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( open2.hKeyedMutex, &next_local ); ok_x4( open2.PrivateRuntimeDataSize, ==, sizeof(runtime_data) ); - ok_u1( buffer[0], ==, 0xcd ); + todo_wine ok_u1( buffer[0], ==, 0xcd );
destroy.hKeyedMutex = open2.hKeyedMutex; status = D3DKMTDestroyKeyedMutex( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); destroy.hKeyedMutex = create2.hKeyedMutex; status = D3DKMTDestroyKeyedMutex( &destroy ); ok_nt( STATUS_SUCCESS, status ); @@ -1957,7 +1951,7 @@ static void test_D3DKMTCreateAllocation( void ) open.hDevice = create_device.hDevice; open.hGlobalShare = create.hResource; status = D3DKMTOpenResource( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
destroy.hResource = create.hResource; status = D3DKMTDestroyAllocation( &destroy ); @@ -2010,41 +2004,41 @@ static void test_D3DKMTCreateAllocation( void ) open_alloc.PrivateDriverDataSize = sizeof(alloc_data); open.hResource = 0x1eadbeed; status = D3DKMTOpenResource( &open ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); ok_x4( open.hGlobalShare, ==, create.hGlobalShare ); - todo_wine check_d3dkmt_local( open.hResource, &next_local ); + check_d3dkmt_local( open.hResource, &next_local ); ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); - ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); - todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); + todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); + ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); ok_x4( open.ResourcePrivateDriverDataSize, ==, 0 ); ok_u4( open.NumAllocations, ==, 1 ); - todo_wine check_d3dkmt_local( open_alloc.hAllocation, &next_local ); - ok_x4( open_alloc.PrivateDriverDataSize, >, 0 ); - todo_wine 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] ); + check_d3dkmt_local( open_alloc.hAllocation, &next_local ); + todo_wine ok_x4( open_alloc.PrivateDriverDataSize, >, 0 ); + ok_x4( open_alloc.PrivateDriverDataSize, <, sizeof(alloc_data) ); + 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 ); ok_u1( resource_data[0], ==, 0xcd ); ok_u1( alloc_data[0], ==, 0xcd );
destroy.hResource = open.hResource; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); open.hResource = 0;
/* NumAllocations must be set */ open.NumAllocations = 0; status = D3DKMTOpenResource( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.NumAllocations = 1;
/* buffer sizes must match exactly */ open.PrivateRuntimeDataSize += 1; status = D3DKMTOpenResource( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.PrivateRuntimeDataSize -= 1; open.ResourcePrivateDriverDataSize += 1; status = D3DKMTOpenResource( &open ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); open.ResourcePrivateDriverDataSize -= 1;
/* D3DKMTOpenResource2 works as well */ @@ -2053,18 +2047,17 @@ static void test_D3DKMTCreateAllocation( void ) open_alloc2.PrivateDriverDataSize = sizeof(alloc2_data); open_alloc2.hAllocation = 0x1eadbeed; status = D3DKMTOpenResource2( &open ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); ok_x4( open.hGlobalShare, ==, create.hGlobalShare ); - todo_wine check_d3dkmt_local( open.hResource, &next_local ); + check_d3dkmt_local( open.hResource, &next_local ); ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); - ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); - todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); + todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); + ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); ok_x4( open.ResourcePrivateDriverDataSize, ==, 0 ); ok_u4( open.NumAllocations, ==, 1 ); - todo_wine check_d3dkmt_local( open_alloc2.hAllocation, &next_local ); - next_local = 0; - ok_x4( open_alloc2.PrivateDriverDataSize, >, 0 ); - todo_wine ok_x4( open_alloc2.PrivateDriverDataSize, <, sizeof(alloc_data) ); + check_d3dkmt_local( open_alloc2.hAllocation, &next_local ); + todo_wine ok_x4( open_alloc2.PrivateDriverDataSize, >, 0 ); + ok_x4( open_alloc2.PrivateDriverDataSize, <, sizeof(alloc_data) ); open.pOpenAllocationInfo = &open_alloc;
destroy.hResource = open.hResource; diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c index 40dbd811e01..7b96e7d3a34 100644 --- a/dlls/wow64win/gdi.c +++ b/dlls/wow64win/gdi.c @@ -1049,13 +1049,13 @@ NTSTATUS WINAPI wow64_NtGdiDdDDIOpenResource( UINT *args ) desc.hDevice = desc32->hDevice; desc.hGlobalShare = desc32->hGlobalShare; desc.NumAllocations = desc32->NumAllocations; + allocs32 = UlongToPtr( desc32->pOpenAllocationInfo ); desc.pOpenAllocationInfo = NULL; if (desc32->pOpenAllocationInfo && desc32->NumAllocations) { if (!(desc.pOpenAllocationInfo = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pOpenAllocationInfo) ))) return STATUS_NO_MEMORY;
- allocs32 = UlongToPtr( desc32->pOpenAllocationInfo ); for (i = 0; i < desc32->NumAllocations; i++) { desc.pOpenAllocationInfo[i].hAllocation = allocs32->hAllocation; @@ -1074,6 +1074,11 @@ NTSTATUS WINAPI wow64_NtGdiDdDDIOpenResource( UINT *args ) status = NtGdiDdDDIOpenResource( &desc ); desc32->TotalPrivateDriverDataBufferSize = desc.TotalPrivateDriverDataBufferSize; desc32->hResource = desc.hResource; + for (i = 0; desc32->pOpenAllocationInfo && i < desc32->NumAllocations; i++) + { + allocs32->hAllocation = desc.pOpenAllocationInfo[i].hAllocation; + allocs32->PrivateDriverDataSize = desc.pOpenAllocationInfo[i].PrivateDriverDataSize; + } return status; }
@@ -1108,13 +1113,13 @@ NTSTATUS WINAPI wow64_NtGdiDdDDIOpenResource2( UINT *args ) desc.hDevice = desc32->hDevice; desc.hGlobalShare = desc32->hGlobalShare; desc.NumAllocations = desc32->NumAllocations; + allocs32 = UlongToPtr( desc32->pOpenAllocationInfo2 ); desc.pOpenAllocationInfo2 = NULL; if (desc32->pOpenAllocationInfo2 && desc32->NumAllocations) { if (!(desc.pOpenAllocationInfo2 = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pOpenAllocationInfo2) ))) return STATUS_NO_MEMORY;
- allocs32 = UlongToPtr( desc32->pOpenAllocationInfo2 ); for (i = 0; i < desc32->NumAllocations; i++) { desc.pOpenAllocationInfo2[i].hAllocation = allocs32->hAllocation; @@ -1135,7 +1140,11 @@ NTSTATUS WINAPI wow64_NtGdiDdDDIOpenResource2( UINT *args ) desc32->TotalPrivateDriverDataBufferSize = desc.TotalPrivateDriverDataBufferSize; desc32->hResource = desc.hResource; for (i = 0; desc32->pOpenAllocationInfo2 && i < desc32->NumAllocations; i++) + { + allocs32->hAllocation = desc.pOpenAllocationInfo2[i].hAllocation; + allocs32->PrivateDriverDataSize = desc.pOpenAllocationInfo2[i].PrivateDriverDataSize; allocs32->GpuVirtualAddress = desc.pOpenAllocationInfo2[i].GpuVirtualAddress; + } return status; }
diff --git a/server/d3dkmt.c b/server/d3dkmt.c index 599d037f0af..23f0e6d4a71 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -234,3 +234,29 @@ DECL_HANDLER(d3dkmt_object_query) reply->runtime_size = object->runtime_size; release_object( object ); } + +/* open a global d3dkmt object */ +DECL_HANDLER(d3dkmt_object_open) +{ + data_size_t runtime_size = get_reply_max_size(); + struct d3dkmt_object *object; + obj_handle_t handle; + + if (!req->global) return; + object = d3dkmt_object_open( req->global, req->type ); + if (!object) return; + + /* only resource objects require exact runtime buffer size match */ + if (object->type != D3DKMT_RESOURCE && runtime_size > object->runtime_size) runtime_size = object->runtime_size; + + if (runtime_size && object->runtime_size != runtime_size) set_error( STATUS_INVALID_PARAMETER ); + else if ((handle = alloc_handle( current->process, object, STANDARD_RIGHTS_ALL, OBJ_INHERIT ))) + { + reply->handle = handle; + reply->global = object->global; + reply->runtime_size = object->runtime_size; + if (runtime_size) set_reply_data( object->runtime, runtime_size ); + } + + release_object( object ); +} diff --git a/server/protocol.def b/server/protocol.def index c9c77b1cf17..6b1d1dd1cfb 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4170,3 +4170,15 @@ enum inproc_sync_type @REPLY data_size_t runtime_size; /* size of client runtime data */ @END + + +/* Open a global d3dkmt object */ +@REQ(d3dkmt_object_open) + unsigned int type; /* d3dkmt object type */ + d3dkmt_handle_t global; /* global d3dkmt handle */ +@REPLY + d3dkmt_handle_t global; /* global d3dkmt handle */ + obj_handle_t handle; /* internal handle of the server object */ + data_size_t runtime_size; /* size of client runtime data */ + VARARG(runtime,bytes); /* client runtime data */ +@END