From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by Paint.NET. --- dlls/coremessaging/main.c | 301 ++++++++++++++++++++++- dlls/coremessaging/tests/coremessaging.c | 5 +- 2 files changed, 300 insertions(+), 6 deletions(-)
diff --git a/dlls/coremessaging/main.c b/dlls/coremessaging/main.c index 5bb4a99ee57..f4d9c889fa8 100644 --- a/dlls/coremessaging/main.c +++ b/dlls/coremessaging/main.c @@ -116,6 +116,290 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+struct async_action +{ + IAsyncAction IAsyncAction_iface; + IAsyncInfo IAsyncInfo_iface; + LONG ref; +}; + +static inline struct async_action *impl_from_IAsyncAction( IAsyncAction *iface ) +{ + return CONTAINING_RECORD( iface, struct async_action, IAsyncAction_iface ); +} + +static HRESULT WINAPI async_action_QueryInterface( IAsyncAction *iface, REFIID iid, void **out ) +{ + struct async_action *impl = impl_from_IAsyncAction( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IAsyncAction )) + { + *out = &impl->IAsyncAction_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + if (IsEqualGUID( iid, &IID_IAsyncInfo )) + { + *out = &impl->IAsyncInfo_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI async_action_AddRef( IAsyncAction *iface ) +{ + struct async_action *impl = impl_from_IAsyncAction( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p, ref %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI async_action_Release( IAsyncAction *iface ) +{ + struct async_action *impl = impl_from_IAsyncAction( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p, ref %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI async_action_GetIids( IAsyncAction *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_action_GetRuntimeClassName( IAsyncAction *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_action_GetTrustLevel( IAsyncAction *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_action_put_Completed( IAsyncAction *iface, IAsyncActionCompletedHandler *handler ) +{ + FIXME( "iface %p, handler %p stub!\n", iface, handler ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_action_get_Completed( IAsyncAction *iface, IAsyncActionCompletedHandler **handler ) +{ + FIXME( "iface %p, handler %p stub!\n", iface, handler ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_action_GetResults( IAsyncAction *iface ) +{ + FIXME( "iface %p stub!\n", iface ); + return E_NOTIMPL; +} + +static const IAsyncActionVtbl async_action_vtbl = +{ + async_action_QueryInterface, + async_action_AddRef, + async_action_Release, + /* IInspectable methods */ + async_action_GetIids, + async_action_GetRuntimeClassName, + async_action_GetTrustLevel, + /* IAsyncAction methods */ + async_action_put_Completed, + async_action_get_Completed, + async_action_GetResults, +}; + +DEFINE_IINSPECTABLE( async_info, IAsyncInfo, struct async_action, IAsyncAction_iface ) + +static HRESULT WINAPI async_info_get_Id( IAsyncInfo *iface, UINT32 *id ) +{ + FIXME( "iface %p, id %p stub!\n", iface, id ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_info_get_Status( IAsyncInfo *iface, AsyncStatus *status ) +{ + FIXME( "iface %p, status %p stub!\n", iface, status ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_info_get_ErrorCode( IAsyncInfo *iface, HRESULT *error_code ) +{ + FIXME( "iface %p, error_code %p stub!\n", iface, error_code ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_info_Cancel( IAsyncInfo *iface ) +{ + FIXME( "iface %p stub!\n", iface ); + return E_NOTIMPL; +} + +static HRESULT WINAPI async_info_Close( IAsyncInfo *iface ) +{ + FIXME( "iface %p stub!\n", iface ); + return E_NOTIMPL; +} + +static const IAsyncInfoVtbl async_info_vtbl = +{ + async_info_QueryInterface, + async_info_AddRef, + async_info_Release, + /* IInspectable methods */ + async_info_GetIids, + async_info_GetRuntimeClassName, + async_info_GetTrustLevel, + /* IAsyncInfo methods */ + async_info_get_Id, + async_info_get_Status, + async_info_get_ErrorCode, + async_info_Cancel, + async_info_Close, +}; + +static HRESULT async_action_create( IAsyncAction **out ) +{ + struct async_action *impl; + + *out = NULL; + + if (!(impl = calloc( 1, sizeof( *impl ) ))) return E_OUTOFMEMORY; + + impl->IAsyncAction_iface.lpVtbl = &async_action_vtbl; + impl->IAsyncInfo_iface.lpVtbl = &async_info_vtbl; + impl->ref = 1; + + *out = &impl->IAsyncAction_iface; + return S_OK; +} + +struct dispatcher_queue_controller +{ + IDispatcherQueueController IDispatcherQueueController_iface; + LONG ref; + + IAsyncAction *action; +}; + +static inline struct dispatcher_queue_controller *impl_from_IDispatcherQueueController( IDispatcherQueueController *iface ) +{ + return CONTAINING_RECORD( iface, struct dispatcher_queue_controller, IDispatcherQueueController_iface ); +} + +static HRESULT WINAPI dispatcher_queue_controller_QueryInterface( IDispatcherQueueController *iface, REFIID iid, void **out ) +{ + struct dispatcher_queue_controller *impl = impl_from_IDispatcherQueueController( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IDispatcherQueueController )) + { + *out = &impl->IDispatcherQueueController_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI dispatcher_queue_controller_AddRef( IDispatcherQueueController *iface ) +{ + struct dispatcher_queue_controller *impl = impl_from_IDispatcherQueueController( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing ref to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI dispatcher_queue_controller_Release( IDispatcherQueueController *iface ) +{ + struct dispatcher_queue_controller *impl = impl_from_IDispatcherQueueController( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing ref to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI dispatcher_queue_controller_GetIids( IDispatcherQueueController *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispatcher_queue_controller_GetRuntimeClassName( IDispatcherQueueController *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispatcher_queue_controller_GetTrustLevel( IDispatcherQueueController *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispatcher_queue_controller_get_DispatcherQueue( IDispatcherQueueController *iface, IDispatcherQueue **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispatcher_queue_controller_ShutdownQueueAsync( IDispatcherQueueController *iface, IAsyncAction **operation ) +{ + struct dispatcher_queue_controller *impl = impl_from_IDispatcherQueueController( iface ); + HRESULT hr; + + FIXME( "iface %p, operation %p stub!\n", iface, operation ); + + if (!operation) return E_POINTER; + if (FAILED(hr = async_action_create( &impl->action ))) + { + *operation = NULL; + return hr; + } + + *operation = impl->action; + return S_OK; +} + +static const struct IDispatcherQueueControllerVtbl dispatcher_queue_controller_vtbl = +{ + dispatcher_queue_controller_QueryInterface, + dispatcher_queue_controller_AddRef, + dispatcher_queue_controller_Release, + /* IInspectable methods */ + dispatcher_queue_controller_GetIids, + dispatcher_queue_controller_GetRuntimeClassName, + dispatcher_queue_controller_GetTrustLevel, + /* IDispatcherQueueController methods */ + dispatcher_queue_controller_get_DispatcherQueue, + dispatcher_queue_controller_ShutdownQueueAsync, +}; + DEFINE_IINSPECTABLE( dispatcher_queue_controller_statics, IDispatcherQueueControllerStatics, struct dispatcher_queue_controller_statics, IActivationFactory_iface )
static HRESULT WINAPI dispatcher_queue_controller_statics_CreateOnDedicatedThread( IDispatcherQueueControllerStatics *iface, IDispatcherQueueController **result ) @@ -163,7 +447,20 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **fa
HRESULT WINAPI CreateDispatcherQueueController( DispatcherQueueOptions options, PDISPATCHERQUEUECONTROLLER *queue_controller ) { - FIXME( "options.dwSize = %lu, options.threadType = %d, options.apartmentType = %d, queue_controller %p stub!\n", + struct dispatcher_queue_controller *impl; + + FIXME( "options.dwSize = %lu, options.threadType = %d, options.apartmentType = %d, queue_controller %p semi-stub!\n", options.dwSize, options.threadType, options.apartmentType, queue_controller ); - return E_NOTIMPL; + + if (!queue_controller) return E_POINTER; + if (options.dwSize != sizeof( DispatcherQueueOptions )) return E_INVALIDARG; + if (options.threadType != DQTYPE_THREAD_DEDICATED && options.threadType != DQTYPE_THREAD_CURRENT) return E_INVALIDARG; + if (!(impl = calloc( 1, sizeof( *impl ) ))) return E_OUTOFMEMORY; + + impl->IDispatcherQueueController_iface.lpVtbl = &dispatcher_queue_controller_vtbl; + impl->ref = 1; + + *queue_controller = &impl->IDispatcherQueueController_iface; + TRACE( "created IDispatcherQueueController %p.\n", *queue_controller ); + return S_OK; } diff --git a/dlls/coremessaging/tests/coremessaging.c b/dlls/coremessaging/tests/coremessaging.c index 54f3fd5483d..07c24892c3b 100644 --- a/dlls/coremessaging/tests/coremessaging.c +++ b/dlls/coremessaging/tests/coremessaging.c @@ -236,9 +236,8 @@ static void check_create_dispatcher_queue_controller_( unsigned int line, DWORD options.apartmentType = apartment_type;
hr = CreateDispatcherQueueController( options, &dispatcher_queue_controller ); - todo_wine ok_(__FILE__, line)( hr == expected_hr, "got CreateDispatcherQueueController hr %#lx.\n", hr ); - if (FAILED(hr)) return; + if (hr == E_INVALIDARG) return;
hr = IDispatcherQueueController_get_DispatcherQueue( dispatcher_queue_controller, &dispatcher_queue ); todo_wine @@ -316,10 +315,8 @@ static void test_CreateDispatcherQueueController(void) HRESULT hr;
hr = CreateDispatcherQueueController( options, NULL ); - todo_wine ok( hr == E_POINTER || hr == 0x80000005 /* E_POINTER #if !defined(_WIN32) && defined(_MAC) */, "got hr %#lx.\n", hr ); hr = CreateDispatcherQueueController( options, &dispatcher_queue_controller ); - todo_wine ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); ok( dispatcher_queue_controller == (void *)0xdeadbeef, "got dispatcher_queue_controller %p.\n", dispatcher_queue_controller );