From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 58 ++++++++++++++-- dlls/win32u/tests/d3dkmt.c | 136 ++++++++++++++++++------------------- dlls/wow64win/gdi.c | 1 + server/protocol.def | 1 + 4 files changed, 121 insertions(+), 75 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 14b2b5ca4dd..9703a3421a7 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -948,8 +948,32 @@ NTSTATUS WINAPI NtGdiDdDDIOpenKeyedMutexFromNtHandle( D3DKMT_OPENKEYEDMUTEXFROMN */ NTSTATUS WINAPI NtGdiDdDDICreateSynchronizationObject2( D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *device, *sync; + NTSTATUS status; + + FIXME( "params %p semi-stub!\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + if (!(device = get_d3dkmt_object( params->hDevice, D3DKMT_DEVICE ))) return STATUS_INVALID_PARAMETER; + + if (params->Info.Type < D3DDDI_SYNCHRONIZATION_MUTEX || params->Info.Type > D3DDDI_MONITORED_FENCE) + return STATUS_INVALID_PARAMETER; + + if (params->Info.Type == D3DDDI_CPU_NOTIFICATION && !params->Info.CPUNotification.Event) return STATUS_INVALID_HANDLE; + if (params->Info.Flags.NtSecuritySharing && !params->Info.Flags.Shared) return STATUS_INVALID_PARAMETER; + + if ((status = d3dkmt_object_alloc( sizeof(*sync), D3DKMT_SYNC, (void **)&sync ))) return status; + if (!params->Info.Flags.Shared) status = alloc_object_handle( sync ); + else status = d3dkmt_object_create( sync, params->Info.Flags.NtSecuritySharing ); + if (status) goto failed; + + if (params->Info.Flags.Shared) params->Info.SharedHandle = sync->shared ? 0 : sync->global; + params->hSyncObject = sync->local; + return STATUS_SUCCESS; + +failed: + d3dkmt_object_free( sync ); + return status; }
/****************************************************************************** @@ -957,8 +981,23 @@ NTSTATUS WINAPI NtGdiDdDDICreateSynchronizationObject2( D3DKMT_CREATESYNCHRONIZA */ NTSTATUS WINAPI NtGdiDdDDICreateSynchronizationObject( D3DKMT_CREATESYNCHRONIZATIONOBJECT *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + D3DKMT_CREATESYNCHRONIZATIONOBJECT2 params2 = {0}; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + + if (params->Info.Type != D3DDDI_SYNCHRONIZATION_MUTEX && params->Info.Type != D3DDDI_SEMAPHORE) + return STATUS_INVALID_PARAMETER; + + params2.hDevice = params->hDevice; + params2.Info.Type = params->Info.Type; + params2.Info.Flags.Shared = 1; + memcpy( ¶ms2.Info.Reserved, ¶ms->Info.Reserved, sizeof(params->Info.Reserved) ); + status = NtGdiDdDDICreateSynchronizationObject2( ¶ms2 ); + params->hSyncObject = params2.hSyncObject; + return status; }
/****************************************************************************** @@ -1002,6 +1041,13 @@ NTSTATUS WINAPI NtGdiDdDDIOpenSynchronizationObject( D3DKMT_OPENSYNCHRONIZATIONO */ NTSTATUS WINAPI NtGdiDdDDIDestroySynchronizationObject( const D3DKMT_DESTROYSYNCHRONIZATIONOBJECT *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *sync; + + TRACE( "params %p\n", params ); + + if (!(sync = get_d3dkmt_object( params->hSyncObject, D3DKMT_SYNC ))) + return STATUS_INVALID_PARAMETER; + d3dkmt_object_free( sync ); + + return STATUS_SUCCESS; } diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index 60168c3f316..d43640c7e03 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -1260,145 +1260,142 @@ static void test_D3DKMTCreateSynchronizationObject( void )
/* D3DKMTCreateSynchronizationObject creates a local D3DKMT_HANDLE */ status = D3DKMTCreateSynchronizationObject( NULL ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); status = D3DKMTCreateSynchronizationObject( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.hDevice = create_device.hDevice; status = D3DKMTCreateSynchronizationObject( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.hDevice = 0; create.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; status = D3DKMTCreateSynchronizationObject( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.hDevice = create_device.hDevice; create.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; create.hSyncObject = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create.hSyncObject, &next_local ); destroy.hSyncObject = create.hSyncObject;
/* local handles are monotonically increasing */ create.hSyncObject = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create.hSyncObject, &next_local );
status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); /* destroying multiple times fails */ status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
destroy.hSyncObject = create.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
create.Info.Type = D3DDDI_SEMAPHORE; create.hSyncObject = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create.hSyncObject, &next_local ); destroy.hSyncObject = create.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
create.Info.Type = D3DDDI_FENCE; status = D3DKMTCreateSynchronizationObject( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
/* D3DKMTCreateSynchronizationObject2 can create local D3DKMT_HANDLE */ status = D3DKMTCreateSynchronizationObject2( NULL ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create2.hDevice = create_device.hDevice; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create2.hDevice = 0; create2.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create2.hDevice = create_device.hDevice; create2.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local );
destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
create2.Info.Type = D3DDDI_SEMAPHORE; create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
create2.Info.Type = D3DDDI_FENCE; create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
create2.Info.Type = D3DDDI_CPU_NOTIFICATION; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_INVALID_HANDLE, status ); + ok_nt( STATUS_INVALID_HANDLE, status ); create2.Info.CPUNotification.Event = CreateEventW( NULL, FALSE, FALSE, NULL ); create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); CloseHandle( create2.Info.CPUNotification.Event ); create2.Info.CPUNotification.Event = NULL;
create2.Info.Type = D3DDDI_MONITORED_FENCE; create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - if (status == STATUS_SUCCESS) - { - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); - destroy.hSyncObject = create2.hSyncObject; - status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - } + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); + destroy.hSyncObject = create2.hSyncObject; + status = D3DKMTDestroySynchronizationObject( &destroy ); + ok_nt( STATUS_SUCCESS, status );
create2.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; create2.Info.Flags.Shared = 1; create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); - todo_wine check_d3dkmt_global( create2.Info.SharedHandle ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); + check_d3dkmt_global( create2.Info.SharedHandle ); destroy.hSyncObject = create2.hSyncObject;
create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); - todo_wine check_d3dkmt_global( create2.Info.SharedHandle ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); + check_d3dkmt_global( create2.Info.SharedHandle );
status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* cannot destroy the global D3DKMT_HANDLE */ destroy.hSyncObject = create2.Info.SharedHandle; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
/* D3DKMTOpenSynchronizationObject creates a new local D3DKMT_HANDLE */ @@ -1422,13 +1419,14 @@ static void test_D3DKMTCreateSynchronizationObject( void ) todo_wine ok_nt( STATUS_SUCCESS, status ); /* destroying multiple times fails */ status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
/* 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;
destroy.hSyncObject = open.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); @@ -1436,7 +1434,7 @@ static void test_D3DKMTCreateSynchronizationObject( void )
destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + 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 ); @@ -1446,7 +1444,7 @@ static void test_D3DKMTCreateSynchronizationObject( void ) create2.Info.Flags.Shared = 0; create2.Info.Flags.NtSecuritySharing = 1; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); if (broken( !status )) { check_d3dkmt_local( create2.hSyncObject, &next_local ); @@ -1459,29 +1457,29 @@ static void test_D3DKMTCreateSynchronizationObject( void ) create2.Info.Flags.NtSecuritySharing = 1; create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); ok( create2.Info.SharedHandle == 0x1eadbeed || !create2.Info.SharedHandle, "got Info.SharedHandle %#x\n", create2.Info.SharedHandle );
destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
create2.Info.Flags.NtSecuritySharing = 0; create2.hSyncObject = create2.Info.SharedHandle = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject2( &create2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_local( create2.hSyncObject, &next_local ); - todo_wine check_d3dkmt_global( create2.Info.SharedHandle ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_local( create2.hSyncObject, &next_local ); + check_d3dkmt_global( create2.Info.SharedHandle );
sprintf( buffer, "test_D3DKMTCreateSynchronizationObject %u", create2.Info.SharedHandle ); run_in_process( buffer );
destroy.hSyncObject = create2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
open.hSharedHandle = create2.Info.SharedHandle; status = D3DKMTOpenSynchronizationObject( &open ); @@ -2160,43 +2158,43 @@ static void test_D3DKMTShareObjects( void ) create_sync.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; create_sync.hSyncObject = 0x1eadbeed; status = D3DKMTCreateSynchronizationObject( &create_sync ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); handle = (HANDLE)0xdeadbeef; status = D3DKMTShareObjects( 1, &create_sync.hSyncObject, &attr, STANDARD_RIGHTS_WRITE, &handle ); todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); if (broken( !status )) CloseHandle( handle ); destroy_sync.hSyncObject = create_sync.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy_sync ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* D3DKMTShareObjects doesn't work with Shared = 1/0 alone */ create_sync2.hDevice = create_device.hDevice; create_sync2.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; status = D3DKMTCreateSynchronizationObject2( &create_sync2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); handle = (HANDLE)0xdeadbeef; status = D3DKMTShareObjects( 1, &create_sync2.hSyncObject, &attr, STANDARD_RIGHTS_WRITE, &handle ); todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); if (broken( !status )) CloseHandle( handle ); destroy_sync.hSyncObject = create_sync2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy_sync ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
create_sync2.Info.Flags.Shared = 1; status = D3DKMTCreateSynchronizationObject2( &create_sync2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); handle = (HANDLE)0xdeadbeef; status = D3DKMTShareObjects( 1, &create_sync2.hSyncObject, &attr, STANDARD_RIGHTS_WRITE, &handle ); todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); if (broken( !status )) CloseHandle( handle ); destroy_sync.hSyncObject = create_sync2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy_sync ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* D3DKMTShareObjects requires NtSecuritySharing (which requires Shared = 1) */ create_sync2.Info.Flags.NtSecuritySharing = 1; status = D3DKMTCreateSynchronizationObject2( &create_sync2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); InitializeObjectAttributes( &attr, &name, 0, 0, NULL ); handle = (HANDLE)0xdeadbeef; status = D3DKMTShareObjects( 1, &create_sync2.hSyncObject, &attr, STANDARD_RIGHTS_WRITE, &handle ); @@ -2210,11 +2208,11 @@ static void test_D3DKMTShareObjects( void ) /* cannot destroy the handle */ destroy_sync.hSyncObject = (UINT_PTR)handle; status = D3DKMTDestroySynchronizationObject( &destroy_sync ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
destroy_sync.hSyncObject = create_sync2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy_sync ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* the sync object can be opened from the NT handle */ @@ -2522,7 +2520,7 @@ static void test_D3DKMTShareObjects( void ) create_sync2.hDevice = create_device.hDevice; create_sync2.Info.Type = D3DDDI_SYNCHRONIZATION_MUTEX; status = D3DKMTCreateSynchronizationObject2( &create_sync2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); handle = (HANDLE)0xdeadbeef;
create_mutex2.Flags.NtSecuritySharing = 1; @@ -2582,7 +2580,7 @@ static void test_D3DKMTShareObjects( void )
destroy_sync.hSyncObject = create_sync2.hSyncObject; status = D3DKMTDestroySynchronizationObject( &destroy_sync ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); create_sync2.hSyncObject = 0;
destroy_alloc.hResource = create_alloc.hResource; diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c index f8e3056c932..cfa67e82ebb 100644 --- a/dlls/wow64win/gdi.c +++ b/dlls/wow64win/gdi.c @@ -750,6 +750,7 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateSynchronizationObject2( UINT *args ) { D3DKMT_CREATESYNCHRONIZATIONOBJECT2 *desc = get_ptr( &args );
+ if (!desc) return STATUS_INVALID_PARAMETER; if (desc->Info.Type == D3DDDI_CPU_NOTIFICATION) { ULONG event = HandleToUlong( desc->Info.CPUNotification.Event ); diff --git a/server/protocol.def b/server/protocol.def index 4c9ba8243cb..81d1e55ed69 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -975,6 +975,7 @@ enum d3dkmt_type D3DKMT_DEVICE = 2, D3DKMT_SOURCE = 3, D3DKMT_MUTEX = 4, + D3DKMT_SYNC = 5, };
/****************************************************************/
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 115 ++++++++++++++++++++++++-- dlls/win32u/tests/d3dkmt.c | 165 +++++++++++++++++++------------------ dlls/wow64win/gdi.c | 11 ++- server/protocol.def | 2 + 4 files changed, 200 insertions(+), 93 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 9703a3421a7..4d7b2b5e198 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -42,6 +42,12 @@ struct d3dkmt_object HANDLE handle; /* internal handle of the server object */ };
+struct d3dkmt_resource +{ + struct d3dkmt_object obj; + D3DKMT_HANDLE allocation; +}; + struct d3dkmt_adapter { struct d3dkmt_object obj; /* object header */ @@ -770,8 +776,64 @@ NTSTATUS WINAPI NtGdiDdDDIShareObjects( UINT count, const D3DKMT_HANDLE *handles */ NTSTATUS WINAPI NtGdiDdDDICreateAllocation2( D3DKMT_CREATEALLOCATION *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + D3DKMT_CREATESTANDARDALLOCATION *standard; + struct d3dkmt_resource *resource = NULL; + D3DDDI_ALLOCATIONINFO *alloc_info; + struct d3dkmt_object *allocation; + struct d3dkmt_device *device; + NTSTATUS status; + + FIXME( "params %p semi-stub!\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + if (!(device = get_d3dkmt_object( params->hDevice, D3DKMT_DEVICE ))) return STATUS_INVALID_PARAMETER; + + if (!params->Flags.StandardAllocation) return STATUS_INVALID_PARAMETER; + if (params->PrivateDriverDataSize) return STATUS_INVALID_PARAMETER; + + if (params->NumAllocations != 1) return STATUS_INVALID_PARAMETER; + if (!(alloc_info = params->pAllocationInfo)) return STATUS_INVALID_PARAMETER; + + if (!(standard = params->pStandardAllocation)) return STATUS_INVALID_PARAMETER; + if (standard->Type != D3DKMT_STANDARDALLOCATIONTYPE_EXISTINGHEAP) return STATUS_INVALID_PARAMETER; + if (standard->ExistingHeapData.Size & 0xfff) return STATUS_INVALID_PARAMETER; + if (!params->Flags.ExistingSysMem) return STATUS_INVALID_PARAMETER; + if (!alloc_info->pSystemMem) return STATUS_INVALID_PARAMETER; + + if (params->Flags.CreateResource) + { + if (params->hResource && !(resource = get_d3dkmt_object( params->hResource, D3DKMT_RESOURCE ))) + return STATUS_INVALID_HANDLE; + 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; + + if (!params->Flags.CreateShared) status = alloc_object_handle( &resource->obj ); + else status = d3dkmt_object_create( &resource->obj, params->Flags.NtSecuritySharing ); + if (status) goto failed; + + params->hGlobalShare = resource->obj.shared ? 0 : resource->obj.global; + params->hResource = resource->obj.local; + } + else + { + if (params->Flags.CreateShared) return STATUS_INVALID_PARAMETER; + if (params->hResource) + { + resource = get_d3dkmt_object( params->hResource, D3DKMT_RESOURCE ); + return resource ? STATUS_INVALID_PARAMETER : STATUS_INVALID_HANDLE; + } + if ((status = d3dkmt_object_alloc( sizeof(*allocation), D3DKMT_ALLOCATION, (void **)&allocation ))) return status; + params->hGlobalShare = 0; + } + + if ((status = alloc_object_handle( allocation ))) goto failed; + if (resource) resource->allocation = allocation->local; + alloc_info->hAllocation = allocation->local; + return STATUS_SUCCESS; + +failed: + if (resource) d3dkmt_object_free( &resource->obj ); + return status; }
/****************************************************************************** @@ -779,8 +841,7 @@ NTSTATUS WINAPI NtGdiDdDDICreateAllocation2( D3DKMT_CREATEALLOCATION *params ) */ NTSTATUS WINAPI NtGdiDdDDICreateAllocation( D3DKMT_CREATEALLOCATION *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + return NtGdiDdDDICreateAllocation2( params ); }
/****************************************************************************** @@ -788,8 +849,37 @@ NTSTATUS WINAPI NtGdiDdDDICreateAllocation( D3DKMT_CREATEALLOCATION *params ) */ NTSTATUS WINAPI NtGdiDdDDIDestroyAllocation2( const D3DKMT_DESTROYALLOCATION2 *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *device, *allocation; + D3DKMT_HANDLE alloc_handle = 0; + UINT i; + + 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 (params->AllocationCount && !params->phAllocationList) return STATUS_INVALID_PARAMETER; + + if (params->hResource) + { + struct d3dkmt_resource *resource; + if (!(resource = get_d3dkmt_object( params->hResource, D3DKMT_RESOURCE ))) + return STATUS_INVALID_PARAMETER; + alloc_handle = resource->allocation; + d3dkmt_object_free( &resource->obj ); + } + + for (i = 0; i < params->AllocationCount; i++) + { + if (!(allocation = get_d3dkmt_object( params->phAllocationList[i], D3DKMT_ALLOCATION ))) + return STATUS_INVALID_PARAMETER; + d3dkmt_object_free( allocation ); + } + + if (alloc_handle && (allocation = get_d3dkmt_object( alloc_handle, D3DKMT_ALLOCATION ))) + d3dkmt_object_free( allocation ); + + return STATUS_SUCCESS; }
/****************************************************************************** @@ -797,8 +887,17 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyAllocation2( const D3DKMT_DESTROYALLOCATION2 *p */ NTSTATUS WINAPI NtGdiDdDDIDestroyAllocation( const D3DKMT_DESTROYALLOCATION *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + D3DKMT_DESTROYALLOCATION2 params2 = {0}; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + + params2.hDevice = params->hDevice; + params2.hResource = params->hResource; + params2.phAllocationList = params->phAllocationList; + params2.AllocationCount = params->AllocationCount; + return NtGdiDdDDIDestroyAllocation2( ¶ms2 ); }
/****************************************************************************** diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index d43640c7e03..01525caacc5 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -1701,7 +1701,7 @@ static void test_D3DKMTCreateAllocation( void ) status = D3DKMTCreateAllocation( NULL );
status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
wcscpy( open_adapter.DeviceName, L"\\.\DISPLAY1" ); status = D3DKMTOpenAdapterFromGdiDisplayName( &open_adapter ); @@ -1730,34 +1730,34 @@ static void test_D3DKMTCreateAllocation( void ) allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; create.hPrivateRuntimeResourceHandle = (HANDLE)0xdeadbeef; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); ok_x4( create.hResource, ==, 0 ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local ); ok_ptr( create.hPrivateRuntimeResourceHandle, ==, (HANDLE)0xdeadbeef );
destroy.hDevice = create_device.hDevice; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); destroy.AllocationCount = 1; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); destroy.phAllocationList = &allocs[0].hAllocation; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); /* allocation has already been destroyed */ status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
/* D3DKMTCreateAllocation2 also works with the same parameters, with extra alloc info */ create.pAllocationInfo2 = allocs2; allocs2[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation2( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); ok_x4( create.hResource, ==, 0 ); - todo_wine check_d3dkmt_local( allocs2[0].hAllocation, &next_local ); + check_d3dkmt_local( allocs2[0].hAllocation, &next_local ); ok_x4( create.PrivateRuntimeDataSize, ==, 0 ); ok_x4( create.PrivateDriverDataSize, ==, 0 ); ok_x4( allocs2[0].PrivateDriverDataSize, ==, 0 ); @@ -1765,23 +1765,23 @@ static void test_D3DKMTCreateAllocation( void )
destroy.phAllocationList = &allocs2[0].hAllocation; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); destroy.phAllocationList = &allocs[0].hAllocation;
/* D3DKMTDestroyAllocation2 works as well */ allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); ok_x4( create.hResource, ==, 0 ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local );
destroy2.hDevice = create_device.hDevice; destroy2.AllocationCount = 1; destroy2.phAllocationList = &allocs[0].hAllocation; status = D3DKMTDestroyAllocation2( &destroy2 ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* alloc PrivateDriverDataSize can be set */ @@ -1789,88 +1789,88 @@ static void test_D3DKMTCreateAllocation( void ) allocs[0].PrivateDriverDataSize = sizeof(expect_alloc_data); allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); ok_x4( create.hResource, ==, 0 ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local ); status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* PrivateRuntimeDataSize can be set */ create.pPrivateRuntimeData = expect_runtime_data; create.PrivateRuntimeDataSize = sizeof(expect_runtime_data); allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); ok_x4( create.hResource, ==, 0 ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local ); status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status );
/* PrivateDriverDataSize must be 0 for standard allocations */ create.PrivateDriverDataSize = 64; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.PrivateDriverDataSize = 0;
/* device handle is required */ create.hDevice = 0; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.hDevice = create_device.hDevice;
/* hResource must be valid or 0 */ create.hResource = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_HANDLE, status ); + ok_nt( STATUS_INVALID_HANDLE, status ); create.hResource = 0;
/* NumAllocations is required */ create.NumAllocations = 0; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.NumAllocations = 1;
/* standard.Type must be set */ standard[0].Type = 0; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); standard[0].Type = D3DKMT_STANDARDALLOCATIONTYPE_EXISTINGHEAP;
/* pSystemMem must be set */ allocs[0].pSystemMem = 0; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); allocs[0].pSystemMem = allocs2[0].pSystemMem;
/* creating multiple allocations doesn't work */ create.NumAllocations = 2; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.NumAllocations = 1;
/* ExistingHeapData.Size must be page aligned */ standard[0].ExistingHeapData.Size = 0x1100; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); standard[0].ExistingHeapData.Size = 0x10000;
/* specific flags are required for standard allocations */ create.Flags.ExistingSysMem = 0; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.Flags.ExistingSysMem = 1; create.Flags.StandardAllocation = 0; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.Flags.StandardAllocation = 1;
/* CreateShared doesn't work without CreateResource */ create.Flags.CreateShared = 1; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.Flags.CreateShared = 0;
@@ -1879,24 +1879,24 @@ static void test_D3DKMTCreateAllocation( void ) allocs[0].hAllocation = create.hGlobalShare = create.hResource = 0x1eadbeed; create.hPrivateRuntimeResourceHandle = (HANDLE)0xdeadbeef; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_HANDLE, status ); + ok_nt( STATUS_INVALID_HANDLE, status ); create.hResource = 0; /* hResource must be set to 0, even with CreateResource */ status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); - todo_wine check_d3dkmt_local( create.hResource, &next_local ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); + check_d3dkmt_local( create.hResource, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local ); ok_ptr( create.hPrivateRuntimeResourceHandle, ==, (HANDLE)0xdeadbeef );
/* destroying the allocation doesn't destroys the resource */ status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); destroy.hResource = create.hResource; destroy.AllocationCount = 0; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); destroy.AllocationCount = 1; create.hResource = 0;
@@ -1904,28 +1904,28 @@ static void test_D3DKMTCreateAllocation( void ) create.Flags.CreateResource = 1; allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); - todo_wine check_d3dkmt_local( create.hResource, &next_local ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); + check_d3dkmt_local( create.hResource, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local );
/* cannot create allocations with an existing resource */ create.Flags.CreateResource = 0; create.pAllocationInfo = &allocs[1]; allocs[1].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.pAllocationInfo = &allocs[0];
/* destroying resource destroys its allocations */ destroy.hResource = create.hResource; destroy.AllocationCount = 0; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); destroy.hResource = 0; destroy.AllocationCount = 1; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.hResource = 0;
@@ -1933,7 +1933,7 @@ static void test_D3DKMTCreateAllocation( void ) create.Flags.CreateResource = 1; create.NumAllocations = 0; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status ); create.NumAllocations = 1;
/* destroy resource at once from here */ @@ -1942,10 +1942,10 @@ static void test_D3DKMTCreateAllocation( void )
allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); - todo_wine check_d3dkmt_local( create.hResource, &next_local ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); + check_d3dkmt_local( create.hResource, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local );
/* D3DKMTQueryResourceInfo requires a global handle */ query.hDevice = create_device.hDevice; @@ -1961,7 +1961,7 @@ static void test_D3DKMTCreateAllocation( void )
destroy.hResource = create.hResource; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); create.hResource = 0;
@@ -1969,10 +1969,10 @@ static void test_D3DKMTCreateAllocation( void ) create.Flags.CreateShared = 1; allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_global( create.hGlobalShare ); - todo_wine check_d3dkmt_local( create.hResource, &next_local ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_global( create.hGlobalShare ); + check_d3dkmt_local( create.hResource, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local );
/* D3DKMTQueryResourceInfo works with global handle */ memset( runtime_data, 0xcd, sizeof(runtime_data) ); @@ -2062,18 +2062,19 @@ static void test_D3DKMTCreateAllocation( void ) 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) ); open.pOpenAllocationInfo = &open_alloc;
destroy.hResource = open.hResource; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); open.hResource = 0;
destroy.hResource = create.hResource; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); create.hResource = 0;
@@ -2082,14 +2083,14 @@ static void test_D3DKMTCreateAllocation( void ) create.Flags.CreateShared = 1; allocs[0].hAllocation = create.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create.hGlobalShare, ==, 0 ); - todo_wine check_d3dkmt_local( create.hResource, &next_local ); - todo_wine check_d3dkmt_local( allocs[0].hAllocation, &next_local ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create.hGlobalShare, ==, 0 ); + check_d3dkmt_local( create.hResource, &next_local ); + check_d3dkmt_local( allocs[0].hAllocation, &next_local );
destroy.hResource = create.hResource; status = D3DKMTDestroyAllocation( &destroy ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); create.hResource = 0;
@@ -2354,10 +2355,10 @@ static void test_D3DKMTShareObjects( void ) alloc.PrivateDriverDataSize = sizeof(expect_alloc_data); alloc.hAllocation = create_alloc.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create_alloc ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create_alloc.hGlobalShare, ==, 0 ); - todo_wine check_d3dkmt_local( create_alloc.hResource, NULL ); - todo_wine check_d3dkmt_local( alloc.hAllocation, NULL ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create_alloc.hGlobalShare, ==, 0 ); + check_d3dkmt_local( create_alloc.hResource, NULL ); + check_d3dkmt_local( alloc.hAllocation, NULL );
status = D3DKMTShareObjects( 1, &alloc.hAllocation, &attr, STANDARD_RIGHTS_READ, &handle ); todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); @@ -2367,17 +2368,17 @@ static void test_D3DKMTShareObjects( void ) destroy_alloc.hDevice = create_device.hDevice; destroy_alloc.hResource = create_alloc.hResource; status = D3DKMTDestroyAllocation( &destroy_alloc ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); create_alloc.hResource = 0;
create_alloc.Flags.CreateShared = 1; alloc.hAllocation = create_alloc.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create_alloc ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine check_d3dkmt_global( create_alloc.hGlobalShare ); - todo_wine check_d3dkmt_local( create_alloc.hResource, NULL ); - todo_wine check_d3dkmt_local( alloc.hAllocation, NULL ); + ok_nt( STATUS_SUCCESS, status ); + check_d3dkmt_global( create_alloc.hGlobalShare ); + check_d3dkmt_local( create_alloc.hResource, NULL ); + check_d3dkmt_local( alloc.hAllocation, NULL );
status = D3DKMTShareObjects( 1, &alloc.hAllocation, &attr, STANDARD_RIGHTS_READ, &handle ); todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); @@ -2386,17 +2387,17 @@ static void test_D3DKMTShareObjects( void )
destroy_alloc.hResource = create_alloc.hResource; status = D3DKMTDestroyAllocation( &destroy_alloc ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); create_alloc.hResource = 0;
create_alloc.Flags.NtSecuritySharing = 1; alloc.hAllocation = create_alloc.hGlobalShare = 0x1eadbeed; status = D3DKMTCreateAllocation( &create_alloc ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( create_alloc.hGlobalShare, ==, 0 ); - todo_wine check_d3dkmt_local( create_alloc.hResource, NULL ); - todo_wine check_d3dkmt_local( alloc.hAllocation, NULL ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( create_alloc.hGlobalShare, ==, 0 ); + check_d3dkmt_local( create_alloc.hResource, NULL ); + check_d3dkmt_local( alloc.hAllocation, NULL );
/* can only share resources, not allocations */ status = D3DKMTShareObjects( 1, &alloc.hAllocation, &attr, STANDARD_RIGHTS_READ, &handle ); @@ -2585,7 +2586,7 @@ static void test_D3DKMTShareObjects( void )
destroy_alloc.hResource = create_alloc.hResource; status = D3DKMTDestroyAllocation( &destroy_alloc ); - todo_wine ok_nt( STATUS_SUCCESS, status ); + ok_nt( STATUS_SUCCESS, status ); create_alloc.hResource = 0;
diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c index cfa67e82ebb..bf5705f52a6 100644 --- a/dlls/wow64win/gdi.c +++ b/dlls/wow64win/gdi.c @@ -497,16 +497,16 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateAllocation( UINT *args ) standard.Flags = standard32->Flags;
desc.pStandardAllocation = &standard; - desc.PrivateDriverDataSize = sizeof(standard); + desc.PrivateDriverDataSize = desc32->PrivateDriverDataSize; } desc.NumAllocations = desc32->NumAllocations; + allocs32 = UlongToPtr( desc32->pAllocationInfo ); desc.pAllocationInfo = NULL; if (desc32->pAllocationInfo && desc32->NumAllocations) { if (!(desc.pAllocationInfo = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pAllocationInfo) ))) return STATUS_NO_MEMORY;
- allocs32 = UlongToPtr( desc32->pAllocationInfo ); for (i = 0; i < desc32->NumAllocations; i++) { desc.pAllocationInfo[i].hAllocation = allocs32->hAllocation; @@ -523,6 +523,8 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateAllocation( UINT *args ) status = NtGdiDdDDICreateAllocation( &desc ); desc32->hResource = desc.hResource; desc32->hGlobalShare = desc.hGlobalShare; + for (i = 0; desc32->pAllocationInfo && i < desc32->NumAllocations; i++) + allocs32->hAllocation = desc.pAllocationInfo[i].hAllocation; return status; }
@@ -607,13 +609,13 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateAllocation2( UINT *args ) desc.PrivateDriverDataSize = sizeof(standard); } desc.NumAllocations = desc32->NumAllocations; + allocs32 = UlongToPtr( desc32->pAllocationInfo2 ); desc.pAllocationInfo2 = NULL; if (desc32->pAllocationInfo2 && desc32->NumAllocations) { if (!(desc.pAllocationInfo2 = Wow64AllocateTemp( desc32->NumAllocations + sizeof(*desc.pAllocationInfo2) ))) return STATUS_NO_MEMORY;
- allocs32 = UlongToPtr( desc32->pAllocationInfo2 ); for (i = 0; i < desc32->NumAllocations; i++) { desc.pAllocationInfo2[i].hAllocation = allocs32->hAllocation; @@ -632,7 +634,10 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateAllocation2( UINT *args ) desc32->hResource = desc.hResource; desc32->hGlobalShare = desc.hGlobalShare; for (i = 0; desc32->pAllocationInfo2 && i < desc32->NumAllocations; i++) + { + allocs32->hAllocation = desc.pAllocationInfo2[i].hAllocation; allocs32->GpuVirtualAddress = desc.pAllocationInfo2[i].GpuVirtualAddress; + } return status; }
diff --git a/server/protocol.def b/server/protocol.def index 81d1e55ed69..b2d75931599 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -976,6 +976,8 @@ enum d3dkmt_type D3DKMT_SOURCE = 3, D3DKMT_MUTEX = 4, D3DKMT_SYNC = 5, + D3DKMT_RESOURCE = 6, + D3DKMT_ALLOCATION = 7, };
/****************************************************************/
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 12 ++++++++---- dlls/wow64win/gdi.c | 2 +- server/d3dkmt.c | 15 ++++++++++----- server/protocol.def | 1 + 4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 4d7b2b5e198..d0473360201 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -175,13 +175,14 @@ static NTSTATUS d3dkmt_object_alloc( UINT size, enum d3dkmt_type type, void **ob }
/* create a global D3DKMT object, either with a global handle or later shareable */ -static NTSTATUS d3dkmt_object_create( struct d3dkmt_object *object, BOOL shared ) +static NTSTATUS d3dkmt_object_create( struct d3dkmt_object *object, BOOL shared, const void *runtime, UINT runtime_size ) { NTSTATUS status;
SERVER_START_REQ( d3dkmt_object_create ) { req->type = object->type; + if (runtime_size) wine_server_add_data( req, runtime, runtime_size ); status = wine_server_call( req ); object->handle = wine_server_ptr_handle( reply->handle ); object->global = reply->global; @@ -808,7 +809,8 @@ NTSTATUS WINAPI NtGdiDdDDICreateAllocation2( D3DKMT_CREATEALLOCATION *params ) if ((status = d3dkmt_object_alloc( sizeof(*allocation), D3DKMT_ALLOCATION, (void **)&allocation ))) goto failed;
if (!params->Flags.CreateShared) status = alloc_object_handle( &resource->obj ); - else status = d3dkmt_object_create( &resource->obj, params->Flags.NtSecuritySharing ); + else status = d3dkmt_object_create( &resource->obj, params->Flags.NtSecuritySharing, + params->pPrivateRuntimeData, params->PrivateRuntimeDataSize ); if (status) goto failed;
params->hGlobalShare = resource->obj.shared ? 0 : resource->obj.global; @@ -968,7 +970,9 @@ NTSTATUS WINAPI NtGdiDdDDICreateKeyedMutex2( D3DKMT_CREATEKEYEDMUTEX2 *params ) if (!params) return STATUS_INVALID_PARAMETER;
if ((status = d3dkmt_object_alloc( sizeof(*mutex), D3DKMT_MUTEX, (void **)&mutex ))) return status; - if ((status = d3dkmt_object_create( mutex, params->Flags.NtSecuritySharing ))) goto failed; + if ((status = d3dkmt_object_create( mutex, params->Flags.NtSecuritySharing, + params->pPrivateRuntimeData, params->PrivateRuntimeDataSize ))) + goto failed;
params->hSharedHandle = mutex->shared ? 0 : mutex->global; params->hKeyedMutex = mutex->local; @@ -1063,7 +1067,7 @@ NTSTATUS WINAPI NtGdiDdDDICreateSynchronizationObject2( D3DKMT_CREATESYNCHRONIZA
if ((status = d3dkmt_object_alloc( sizeof(*sync), D3DKMT_SYNC, (void **)&sync ))) return status; if (!params->Info.Flags.Shared) status = alloc_object_handle( sync ); - else status = d3dkmt_object_create( sync, params->Info.Flags.NtSecuritySharing ); + else status = d3dkmt_object_create( sync, params->Info.Flags.NtSecuritySharing, NULL, 0 ); if (status) goto failed;
if (params->Info.Flags.Shared) params->Info.SharedHandle = sync->shared ? 0 : sync->global; diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c index bf5705f52a6..40dbd811e01 100644 --- a/dlls/wow64win/gdi.c +++ b/dlls/wow64win/gdi.c @@ -606,7 +606,7 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateAllocation2( UINT *args ) standard.Flags = standard32->Flags;
desc.pStandardAllocation = &standard; - desc.PrivateDriverDataSize = sizeof(standard); + desc.PrivateDriverDataSize = desc32->PrivateDriverDataSize; } desc.NumAllocations = desc32->NumAllocations; allocs32 = UlongToPtr( desc32->pAllocationInfo2 ); diff --git a/server/d3dkmt.c b/server/d3dkmt.c index b99fabd3292..3f1c0c49283 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -40,6 +40,8 @@ struct d3dkmt_object struct object obj; /* object header */ enum d3dkmt_type type; /* object type */ d3dkmt_handle_t global; /* object global handle */ + char *runtime; /* client runtime data */ + mem_size_t runtime_size; /* size of client runtime data */ };
static void d3dkmt_object_dump( struct object *obj, int verbose ); @@ -161,17 +163,20 @@ static void d3dkmt_object_destroy( struct object *obj ) assert( obj->ops == &d3dkmt_object_ops );
if (object->global) free_object_handle( object->global ); + free( object->runtime ); }
-static struct d3dkmt_object *d3dkmt_object_create( enum d3dkmt_type type ) +static struct d3dkmt_object *d3dkmt_object_create( enum d3dkmt_type type, mem_size_t runtime_size, const void *runtime ) { struct d3dkmt_object *object;
if (!(object = alloc_object( &d3dkmt_object_ops ))) return NULL; - object->type = type; - object->global = 0; + object->type = type; + object->global = 0; + object->runtime_size = runtime_size;
- if (!(object->global = alloc_object_handle( object ))) + if (!(object->runtime = memdup( runtime, runtime_size )) || + !(object->global = alloc_object_handle( object ))) { release_object( object ); return NULL; @@ -185,7 +190,7 @@ DECL_HANDLER(d3dkmt_object_create) { struct d3dkmt_object *object;
- if (!(object = d3dkmt_object_create( req->type ))) return; + 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 ); diff --git a/server/protocol.def b/server/protocol.def index b2d75931599..67a79a01736 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4156,6 +4156,7 @@ enum inproc_sync_type /* Create a global d3dkmt object */ @REQ(d3dkmt_object_create) unsigned int type; /* d3dkmt object type */ + VARARG(runtime,bytes); /* client runtime data */ @REPLY d3dkmt_handle_t global; /* global d3dkmt handle */ obj_handle_t handle; /* internal handle of the server object */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 41 ++++++++++++++++++++++++++++++++++++-- dlls/win32u/tests/d3dkmt.c | 12 +++++------ server/d3dkmt.c | 39 ++++++++++++++++++++++++++++++++++++ server/protocol.def | 9 +++++++++ 4 files changed, 93 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index d0473360201..e073c11a832 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -75,6 +75,11 @@ static struct d3dkmt_object **objects, **objects_end, **objects_next;
#define D3DKMT_HANDLE_BIT 0x40000000
+static BOOL is_d3dkmt_global( D3DKMT_HANDLE handle ) +{ + return (handle & 0xc0000000) && (handle & 0x3f) == 2; +} + static D3DKMT_HANDLE index_to_handle( int index ) { return (index << 6) | D3DKMT_HANDLE_BIT; @@ -197,6 +202,24 @@ static NTSTATUS d3dkmt_object_create( struct d3dkmt_object *object, BOOL shared, return status; }
+static NTSTATUS d3dkmt_object_query( enum d3dkmt_type type, D3DKMT_HANDLE global, UINT *runtime_size ) +{ + NTSTATUS status; + + SERVER_START_REQ( d3dkmt_object_query ) + { + req->type = type; + req->global = global; + status = wine_server_call( req ); + *runtime_size = reply->runtime_size; + } + 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 ); + return status; +} + static void d3dkmt_object_free( struct d3dkmt_object *object ) { TRACE( "object %p/%#x, global %#x\n", object, object->local, object->global ); @@ -943,8 +966,22 @@ NTSTATUS WINAPI NtGdiDdDDIOpenNtHandleFromName( D3DKMT_OPENNTHANDLEFROMNAME *par */ NTSTATUS WINAPI NtGdiDdDDIQueryResourceInfo( D3DKMT_QUERYRESOURCEINFO *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *device; + 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 ((status = d3dkmt_object_query( D3DKMT_RESOURCE, params->hGlobalShare, ¶ms->PrivateRuntimeDataSize ))) + return status; + + params->TotalPrivateDriverDataSize = 0; + params->ResourcePrivateDriverDataSize = 0; + params->NumAllocations = 1; + return STATUS_SUCCESS; }
/****************************************************************************** diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index 01525caacc5..720f7a64f86 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -1951,7 +1951,7 @@ static void test_D3DKMTCreateAllocation( void ) query.hDevice = create_device.hDevice; query.hGlobalShare = create.hResource; status = D3DKMTQueryResourceInfo( &query ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
/* D3DKMTOpenResource requires a global handle */ open.hDevice = create_device.hDevice; @@ -1982,12 +1982,12 @@ static void test_D3DKMTCreateAllocation( void ) query.PrivateRuntimeDataSize = sizeof(runtime_data); query.ResourcePrivateDriverDataSize = 0; status = D3DKMTQueryResourceInfo( &query ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( query.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( query.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); todo_wine ok_x4( query.TotalPrivateDriverDataSize, >, 0 ); ok_x4( query.TotalPrivateDriverDataSize, <, sizeof(driver_data) ); ok_x4( query.ResourcePrivateDriverDataSize, ==, 0 ); - todo_wine ok_u4( query.NumAllocations, ==, 1 ); + ok_u4( query.NumAllocations, ==, 1 ); /* runtime data doesn't get updated ? */ ok_u1( runtime_data[0], ==, 0xcd );
@@ -2013,7 +2013,7 @@ static void test_D3DKMTCreateAllocation( void ) todo_wine ok_nt( STATUS_SUCCESS, status ); ok_x4( open.hGlobalShare, ==, create.hGlobalShare ); todo_wine check_d3dkmt_local( open.hResource, &next_local ); - todo_wine ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); ok_x4( open.ResourcePrivateDriverDataSize, ==, 0 ); @@ -2056,7 +2056,7 @@ static void test_D3DKMTCreateAllocation( void ) todo_wine ok_nt( STATUS_SUCCESS, status ); ok_x4( open.hGlobalShare, ==, create.hGlobalShare ); todo_wine check_d3dkmt_local( open.hResource, &next_local ); - todo_wine ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); ok_x4( open.ResourcePrivateDriverDataSize, ==, 0 ); diff --git a/server/d3dkmt.c b/server/d3dkmt.c index 3f1c0c49283..f75c85765de 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -149,6 +149,19 @@ static void free_object_handle( d3dkmt_handle_t global ) objects[index] = NULL; }
+/* return a pointer to a d3dkmt object from its global handle */ +static void *get_d3dkmt_object( d3dkmt_handle_t global, enum d3dkmt_type type ) +{ + unsigned int index = handle_to_index( global ); + struct d3dkmt_object *object; + + if (objects + index >= objects_end) object = NULL; + else object = objects[index]; + + if (!object || object->global != global || object->type != type) return NULL; + return object; +} + static void d3dkmt_object_dump( struct object *obj, int verbose ) { struct d3dkmt_object *object = (struct d3dkmt_object *)obj; @@ -185,6 +198,19 @@ static struct d3dkmt_object *d3dkmt_object_create( enum d3dkmt_type type, mem_si return object; }
+/* return a pointer to a d3dkmt object from its global handle */ +static void *d3dkmt_object_open( d3dkmt_handle_t global, enum d3dkmt_type type ) +{ + struct d3dkmt_object *object; + + if (!(object = get_d3dkmt_object( global, type ))) + { + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + return grab_object( object ); +} + /* create a global d3dkmt object */ DECL_HANDLER(d3dkmt_object_create) { @@ -195,3 +221,16 @@ DECL_HANDLER(d3dkmt_object_create) reply->global = object->global; release_object( object ); } + +/* query a global d3dkmt object */ +DECL_HANDLER(d3dkmt_object_query) +{ + struct d3dkmt_object *object; + + if (!req->global) return; + object = d3dkmt_object_open( req->global, req->type ); + if (!object) return; + + reply->runtime_size = object->runtime_size; + release_object( object ); +} diff --git a/server/protocol.def b/server/protocol.def index 67a79a01736..6e29a5b9424 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4161,3 +4161,12 @@ enum inproc_sync_type d3dkmt_handle_t global; /* global d3dkmt handle */ obj_handle_t handle; /* internal handle of the server object */ @END + + +/* Query a global d3dkmt object */ +@REQ(d3dkmt_object_query) + unsigned int type; /* d3dkmt object type */ + d3dkmt_handle_t global; /* global d3dkmt handle */ +@REPLY + mem_size_t runtime_size; /* size of client runtime data */ +@END
Derek Lesho (@dlesho) commented about dlls/win32u/d3dkmt.c:
*/ NTSTATUS WINAPI NtGdiDdDDIQueryResourceInfo( D3DKMT_QUERYRESOURCEINFO *params ) {
- FIXME( "params %p stub!\n", params );
- return STATUS_NOT_IMPLEMENTED;
- struct d3dkmt_object *device;
- NTSTATUS status;
- TRACE( "params %p\n", params );
Should we not at least add an error path or mark this as a semi-stub if we're not (yet?) handling D3DKMT_QUERYRESOURCEINFO::pPrivateRuntimeData?