From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/coremessaging/main.c | 299 ++++++++++++++++++++++- dlls/coremessaging/tests/coremessaging.c | 6 +- 2 files changed, 299 insertions(+), 6 deletions(-)
diff --git a/dlls/coremessaging/main.c b/dlls/coremessaging/main.c index 5bb4a99ee57..02e7de09da6 100644 --- a/dlls/coremessaging/main.c +++ b/dlls/coremessaging/main.c @@ -116,12 +116,307 @@ 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 ); + + FIXME( "iface %p, operation %p stub!\n", iface, operation ); + + if (!operation) return E_POINTER; + + *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 ) { - FIXME( "iface %p, result %p stub!\n", iface, result ); - return E_NOTIMPL; + struct dispatcher_queue_controller *impl; + HRESULT hr; + + FIXME( "iface %p, result %p semi-stub!\n", iface, result ); + + if (!result) return E_POINTER; + if (!(impl = calloc( 1, sizeof( *impl ) ))) return E_OUTOFMEMORY; + + impl->IDispatcherQueueController_iface.lpVtbl = &dispatcher_queue_controller_vtbl; + impl->ref = 1; + if (FAILED(hr = async_action_create( &impl->action ))) + { + free( impl ); + return hr; + } + + *result = &impl->IDispatcherQueueController_iface; + TRACE( "created IDispatcherQueueController %p.\n", *result ); + return S_OK; }
static const struct IDispatcherQueueControllerStaticsVtbl dispatcher_queue_controller_statics_vtbl = diff --git a/dlls/coremessaging/tests/coremessaging.c b/dlls/coremessaging/tests/coremessaging.c index 60e88c3f733..9055ec71c9f 100644 --- a/dlls/coremessaging/tests/coremessaging.c +++ b/dlls/coremessaging/tests/coremessaging.c @@ -249,12 +249,9 @@ static void test_DispatcherQueueController_Statics(void) ok( hr == S_OK, "got hr %#lx.\n", hr );
hr = IDispatcherQueueControllerStatics_CreateOnDedicatedThread( dispatcher_queue_controller_statics, NULL ); - todo_wine ok( hr == E_POINTER || hr == 0x80000005 /* E_POINTER #if !defined(_WIN32) */, "got hr %#lx.\n", hr ); hr = IDispatcherQueueControllerStatics_CreateOnDedicatedThread( dispatcher_queue_controller_statics, &dispatcher_queue_controller ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); - if (FAILED(hr)) goto done;
hr = IDispatcherQueueController_get_DispatcherQueue( dispatcher_queue_controller, NULL ); todo_wine @@ -262,6 +259,7 @@ static void test_DispatcherQueueController_Statics(void) hr = IDispatcherQueueController_get_DispatcherQueue( dispatcher_queue_controller, &dispatcher_queue ); todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (FAILED(hr)) goto done;
check_interface( dispatcher_queue, &IID_IUnknown ); check_interface( dispatcher_queue, &IID_IInspectable ); @@ -337,9 +335,9 @@ static void test_DispatcherQueueController_Statics(void) ok( ref == 0, "got ref %ld.\n", ref ); ref = IDispatcherQueue_Release( dispatcher_queue ); ok( ref == 1 || broken(ref == 2) /* Race condition */, "got ref %ld.\n", ref ); +done: ref = IDispatcherQueueController_Release( dispatcher_queue_controller ); ok( ref == 0 || broken(ref == 1) /* Race condition */, "got ref %ld.\n", ref ); -done: ref = IDispatcherQueueControllerStatics_Release( dispatcher_queue_controller_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );