wineps: Handle EMR_INVERTRGN record in spool files.
[wine.git] / dlls / windows.gaming.input / async.c
blobc41abe96cd144948260ea64aa34b45957272da50
1 /* WinRT Windows.Gaming.Input implementation
3 * Copyright 2022 Bernhard Kölbl for CodeWeavers
4 * Copyright 2022 Rémi Bernon for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "private.h"
22 #include "provider.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(input);
28 #define Closed 4
29 #define HANDLER_NOT_SET ((void *)~(ULONG_PTR)0)
31 struct async_info
33 IWineAsyncInfoImpl IWineAsyncInfoImpl_iface;
34 IAsyncInfo IAsyncInfo_iface;
35 IInspectable *IInspectable_outer;
36 LONG ref;
38 async_operation_callback callback;
39 TP_WORK *async_run_work;
40 IUnknown *invoker;
41 IUnknown *param;
43 CRITICAL_SECTION cs;
44 IWineAsyncOperationCompletedHandler *handler;
45 PROPVARIANT result;
46 AsyncStatus status;
47 HRESULT hr;
50 static inline struct async_info *impl_from_IWineAsyncInfoImpl( IWineAsyncInfoImpl *iface )
52 return CONTAINING_RECORD( iface, struct async_info, IWineAsyncInfoImpl_iface );
55 static HRESULT WINAPI async_impl_QueryInterface( IWineAsyncInfoImpl *iface, REFIID iid, void **out )
57 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
59 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
61 if (IsEqualGUID( iid, &IID_IUnknown ) ||
62 IsEqualGUID( iid, &IID_IInspectable ) ||
63 IsEqualGUID( iid, &IID_IAgileObject ) ||
64 IsEqualGUID( iid, &IID_IWineAsyncInfoImpl ))
66 IInspectable_AddRef( (*out = &impl->IWineAsyncInfoImpl_iface) );
67 return S_OK;
70 if (IsEqualGUID( iid, &IID_IAsyncInfo ))
72 IInspectable_AddRef( (*out = &impl->IAsyncInfo_iface) );
73 return S_OK;
76 FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
77 *out = NULL;
78 return E_NOINTERFACE;
81 static ULONG WINAPI async_impl_AddRef( IWineAsyncInfoImpl *iface )
83 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
84 ULONG ref = InterlockedIncrement( &impl->ref );
85 TRACE( "iface %p, ref %lu.\n", iface, ref );
86 return ref;
89 static ULONG WINAPI async_impl_Release( IWineAsyncInfoImpl *iface )
91 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
92 ULONG ref = InterlockedDecrement( &impl->ref );
93 TRACE( "iface %p, ref %lu.\n", iface, ref );
95 if (!ref)
97 if (impl->handler && impl->handler != HANDLER_NOT_SET) IWineAsyncOperationCompletedHandler_Release( impl->handler );
98 IAsyncInfo_Close( &impl->IAsyncInfo_iface );
99 if (impl->param) IUnknown_Release( impl->param );
100 if (impl->invoker) IUnknown_Release( impl->invoker );
101 impl->cs.DebugInfo->Spare[0] = 0;
102 DeleteCriticalSection( &impl->cs );
103 free( impl );
106 return ref;
109 static HRESULT WINAPI async_impl_put_Completed( IWineAsyncInfoImpl *iface, IWineAsyncOperationCompletedHandler *handler )
111 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
112 HRESULT hr = S_OK;
114 TRACE( "iface %p, handler %p.\n", iface, handler );
116 EnterCriticalSection( &impl->cs );
117 if (impl->status == Closed) hr = E_ILLEGAL_METHOD_CALL;
118 else if (impl->handler != HANDLER_NOT_SET) hr = E_ILLEGAL_DELEGATE_ASSIGNMENT;
119 else if ((impl->handler = handler))
121 IWineAsyncOperationCompletedHandler_AddRef( impl->handler );
123 if (impl->status > Started)
125 IInspectable *operation = impl->IInspectable_outer;
126 AsyncStatus status = impl->status;
127 impl->handler = NULL; /* Prevent concurrent invoke. */
128 LeaveCriticalSection( &impl->cs );
130 IWineAsyncOperationCompletedHandler_Invoke( handler, operation, status );
131 IWineAsyncOperationCompletedHandler_Release( handler );
133 return S_OK;
136 LeaveCriticalSection( &impl->cs );
138 return hr;
141 static HRESULT WINAPI async_impl_get_Completed( IWineAsyncInfoImpl *iface, IWineAsyncOperationCompletedHandler **handler )
143 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
144 HRESULT hr = S_OK;
146 TRACE( "iface %p, handler %p.\n", iface, handler );
148 EnterCriticalSection( &impl->cs );
149 if (impl->status == Closed) hr = E_ILLEGAL_METHOD_CALL;
150 if (impl->handler == NULL || impl->handler == HANDLER_NOT_SET) *handler = NULL;
151 else IWineAsyncOperationCompletedHandler_AddRef( (*handler = impl->handler) );
152 LeaveCriticalSection( &impl->cs );
154 return hr;
157 static HRESULT WINAPI async_impl_get_Result( IWineAsyncInfoImpl *iface, PROPVARIANT *result )
159 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
160 HRESULT hr = E_ILLEGAL_METHOD_CALL;
162 TRACE( "iface %p, result %p.\n", iface, result );
164 EnterCriticalSection( &impl->cs );
165 if (impl->status == Completed || impl->status == Error)
167 PropVariantCopy( result, &impl->result );
168 hr = impl->hr;
170 LeaveCriticalSection( &impl->cs );
172 return hr;
175 static HRESULT WINAPI async_impl_Start( IWineAsyncInfoImpl *iface )
177 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
179 TRACE( "iface %p.\n", iface );
181 /* keep the async alive in the callback */
182 IInspectable_AddRef( impl->IInspectable_outer );
183 SubmitThreadpoolWork( impl->async_run_work );
185 return S_OK;
188 static const struct IWineAsyncInfoImplVtbl async_impl_vtbl =
190 /* IUnknown methods */
191 async_impl_QueryInterface,
192 async_impl_AddRef,
193 async_impl_Release,
194 /* IWineAsyncInfoImpl */
195 async_impl_put_Completed,
196 async_impl_get_Completed,
197 async_impl_get_Result,
198 async_impl_Start,
201 DEFINE_IINSPECTABLE_OUTER( async_info, IAsyncInfo, struct async_info, IInspectable_outer )
203 static HRESULT WINAPI async_info_get_Id( IAsyncInfo *iface, UINT32 *id )
205 struct async_info *impl = impl_from_IAsyncInfo( iface );
206 HRESULT hr = S_OK;
208 TRACE( "iface %p, id %p.\n", iface, id );
210 EnterCriticalSection( &impl->cs );
211 if (impl->status == Closed) hr = E_ILLEGAL_METHOD_CALL;
212 *id = 1;
213 LeaveCriticalSection( &impl->cs );
215 return hr;
218 static HRESULT WINAPI async_info_get_Status( IAsyncInfo *iface, AsyncStatus *status )
220 struct async_info *impl = impl_from_IAsyncInfo( iface );
221 HRESULT hr = S_OK;
223 TRACE( "iface %p, status %p.\n", iface, status );
225 EnterCriticalSection( &impl->cs );
226 if (impl->status == Closed) hr = E_ILLEGAL_METHOD_CALL;
227 *status = impl->status;
228 LeaveCriticalSection( &impl->cs );
230 return hr;
233 static HRESULT WINAPI async_info_get_ErrorCode( IAsyncInfo *iface, HRESULT *error_code )
235 struct async_info *impl = impl_from_IAsyncInfo( iface );
236 HRESULT hr = S_OK;
238 TRACE( "iface %p, error_code %p.\n", iface, error_code );
240 EnterCriticalSection( &impl->cs );
241 if (impl->status == Closed) *error_code = hr = E_ILLEGAL_METHOD_CALL;
242 else *error_code = impl->hr;
243 LeaveCriticalSection( &impl->cs );
245 return hr;
248 static HRESULT WINAPI async_info_Cancel( IAsyncInfo *iface )
250 struct async_info *impl = impl_from_IAsyncInfo( iface );
251 HRESULT hr = S_OK;
253 TRACE( "iface %p.\n", iface );
255 EnterCriticalSection( &impl->cs );
256 if (impl->status == Closed) hr = E_ILLEGAL_METHOD_CALL;
257 else if (impl->status == Started) impl->status = Canceled;
258 LeaveCriticalSection( &impl->cs );
260 return hr;
263 static HRESULT WINAPI async_info_Close( IAsyncInfo *iface )
265 struct async_info *impl = impl_from_IAsyncInfo( iface );
266 HRESULT hr = S_OK;
268 TRACE( "iface %p.\n", iface );
270 EnterCriticalSection( &impl->cs );
271 if (impl->status == Started)
272 hr = E_ILLEGAL_STATE_CHANGE;
273 else if (impl->status != Closed)
275 CloseThreadpoolWork( impl->async_run_work );
276 impl->async_run_work = NULL;
277 impl->status = Closed;
279 LeaveCriticalSection( &impl->cs );
281 return hr;
284 static const struct IAsyncInfoVtbl async_info_vtbl =
286 /* IUnknown methods */
287 async_info_QueryInterface,
288 async_info_AddRef,
289 async_info_Release,
290 /* IInspectable methods */
291 async_info_GetIids,
292 async_info_GetRuntimeClassName,
293 async_info_GetTrustLevel,
294 /* IAsyncInfo */
295 async_info_get_Id,
296 async_info_get_Status,
297 async_info_get_ErrorCode,
298 async_info_Cancel,
299 async_info_Close,
302 static void CALLBACK async_info_callback( TP_CALLBACK_INSTANCE *instance, void *iface, TP_WORK *work )
304 struct async_info *impl = impl_from_IWineAsyncInfoImpl( iface );
305 IInspectable *operation = impl->IInspectable_outer;
306 PROPVARIANT result;
307 HRESULT hr;
309 hr = impl->callback( impl->invoker, impl->param, &result );
311 EnterCriticalSection( &impl->cs );
312 if (impl->status != Closed) impl->status = FAILED(hr) ? Error : Completed;
313 PropVariantCopy( &impl->result, &result );
314 impl->hr = hr;
316 if (impl->handler != NULL && impl->handler != HANDLER_NOT_SET)
318 IWineAsyncOperationCompletedHandler *handler = impl->handler;
319 AsyncStatus status = impl->status;
320 impl->handler = NULL; /* Prevent concurrent invoke. */
321 LeaveCriticalSection( &impl->cs );
323 IWineAsyncOperationCompletedHandler_Invoke( handler, operation, status );
324 IWineAsyncOperationCompletedHandler_Release( handler );
326 else LeaveCriticalSection( &impl->cs );
328 /* release refcount acquired in Start */
329 IInspectable_Release( operation );
331 PropVariantClear( &result );
334 static HRESULT async_info_create( IUnknown *invoker, IUnknown *param, async_operation_callback callback,
335 IInspectable *outer, IWineAsyncInfoImpl **out )
337 struct async_info *impl;
338 HRESULT hr;
340 if (!(impl = calloc( 1, sizeof(struct async_info) ))) return E_OUTOFMEMORY;
341 impl->IWineAsyncInfoImpl_iface.lpVtbl = &async_impl_vtbl;
342 impl->IAsyncInfo_iface.lpVtbl = &async_info_vtbl;
343 impl->IInspectable_outer = outer;
344 impl->ref = 1;
346 impl->callback = callback;
347 impl->handler = HANDLER_NOT_SET;
348 impl->status = Started;
349 if (!(impl->async_run_work = CreateThreadpoolWork( async_info_callback, &impl->IWineAsyncInfoImpl_iface, NULL )))
351 hr = HRESULT_FROM_WIN32( GetLastError() );
352 free( impl );
353 return hr;
356 if ((impl->invoker = invoker)) IUnknown_AddRef( impl->invoker );
357 if ((impl->param = param)) IUnknown_AddRef( impl->param );
359 InitializeCriticalSection( &impl->cs );
360 impl->cs.DebugInfo->Spare[0] = (DWORD_PTR)( __FILE__ ": async_info.cs" );
362 *out = &impl->IWineAsyncInfoImpl_iface;
363 return S_OK;
366 struct async_bool
368 IAsyncOperation_boolean IAsyncOperation_boolean_iface;
369 IWineAsyncInfoImpl *IWineAsyncInfoImpl_inner;
370 LONG ref;
373 static inline struct async_bool *impl_from_IAsyncOperation_boolean( IAsyncOperation_boolean *iface )
375 return CONTAINING_RECORD( iface, struct async_bool, IAsyncOperation_boolean_iface );
378 static HRESULT WINAPI async_bool_QueryInterface( IAsyncOperation_boolean *iface, REFIID iid, void **out )
380 struct async_bool *impl = impl_from_IAsyncOperation_boolean( iface );
382 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
384 if (IsEqualGUID( iid, &IID_IUnknown ) ||
385 IsEqualGUID( iid, &IID_IInspectable ) ||
386 IsEqualGUID( iid, &IID_IAgileObject ) ||
387 IsEqualGUID( iid, &IID_IAsyncOperation_boolean ))
389 IInspectable_AddRef( (*out = &impl->IAsyncOperation_boolean_iface) );
390 return S_OK;
393 return IWineAsyncInfoImpl_QueryInterface( impl->IWineAsyncInfoImpl_inner, iid, out );
396 static ULONG WINAPI async_bool_AddRef( IAsyncOperation_boolean *iface )
398 struct async_bool *impl = impl_from_IAsyncOperation_boolean( iface );
399 ULONG ref = InterlockedIncrement( &impl->ref );
400 TRACE( "iface %p, ref %lu.\n", iface, ref );
401 return ref;
404 static ULONG WINAPI async_bool_Release( IAsyncOperation_boolean *iface )
406 struct async_bool *impl = impl_from_IAsyncOperation_boolean( iface );
407 ULONG ref = InterlockedDecrement( &impl->ref );
408 TRACE( "iface %p, ref %lu.\n", iface, ref );
410 if (!ref)
412 /* guard against re-entry if inner releases an outer iface */
413 InterlockedIncrement( &impl->ref );
414 IWineAsyncInfoImpl_Release( impl->IWineAsyncInfoImpl_inner );
415 free( impl );
418 return ref;
421 static HRESULT WINAPI async_bool_GetIids( IAsyncOperation_boolean *iface, ULONG *iid_count, IID **iids )
423 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
424 return E_NOTIMPL;
427 static HRESULT WINAPI async_bool_GetRuntimeClassName( IAsyncOperation_boolean *iface, HSTRING *class_name )
429 return WindowsCreateString( L"Windows.Foundation.IAsyncOperation`1<Boolean>",
430 ARRAY_SIZE(L"Windows.Foundation.IAsyncOperation`1<Boolean>"),
431 class_name );
434 static HRESULT WINAPI async_bool_GetTrustLevel( IAsyncOperation_boolean *iface, TrustLevel *trust_level )
436 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
437 return E_NOTIMPL;
440 static HRESULT WINAPI async_bool_put_Completed( IAsyncOperation_boolean *iface, IAsyncOperationCompletedHandler_boolean *bool_handler )
442 IWineAsyncOperationCompletedHandler *handler = (IWineAsyncOperationCompletedHandler *)bool_handler;
443 struct async_bool *impl = impl_from_IAsyncOperation_boolean( iface );
444 TRACE( "iface %p, handler %p.\n", iface, handler );
445 return IWineAsyncInfoImpl_put_Completed( impl->IWineAsyncInfoImpl_inner, (IWineAsyncOperationCompletedHandler *)handler );
448 static HRESULT WINAPI async_bool_get_Completed( IAsyncOperation_boolean *iface, IAsyncOperationCompletedHandler_boolean **bool_handler )
450 IWineAsyncOperationCompletedHandler **handler = (IWineAsyncOperationCompletedHandler **)bool_handler;
451 struct async_bool *impl = impl_from_IAsyncOperation_boolean( iface );
452 TRACE( "iface %p, handler %p.\n", iface, handler );
453 return IWineAsyncInfoImpl_get_Completed( impl->IWineAsyncInfoImpl_inner, (IWineAsyncOperationCompletedHandler **)handler );
456 static HRESULT WINAPI async_bool_GetResults( IAsyncOperation_boolean *iface, BOOLEAN *results )
458 struct async_bool *impl = impl_from_IAsyncOperation_boolean( iface );
459 PROPVARIANT result = {.vt = VT_BOOL};
460 HRESULT hr;
462 TRACE( "iface %p, results %p.\n", iface, results );
464 hr = IWineAsyncInfoImpl_get_Result( impl->IWineAsyncInfoImpl_inner, &result );
466 *results = result.boolVal;
467 PropVariantClear( &result );
468 return hr;
471 static const struct IAsyncOperation_booleanVtbl async_bool_vtbl =
473 /* IUnknown methods */
474 async_bool_QueryInterface,
475 async_bool_AddRef,
476 async_bool_Release,
477 /* IInspectable methods */
478 async_bool_GetIids,
479 async_bool_GetRuntimeClassName,
480 async_bool_GetTrustLevel,
481 /* IAsyncOperation<boolean> */
482 async_bool_put_Completed,
483 async_bool_get_Completed,
484 async_bool_GetResults,
487 HRESULT async_operation_boolean_create( IUnknown *invoker, IUnknown *param, async_operation_callback callback,
488 IAsyncOperation_boolean **out )
490 struct async_bool *impl;
491 HRESULT hr;
493 *out = NULL;
494 if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY;
495 impl->IAsyncOperation_boolean_iface.lpVtbl = &async_bool_vtbl;
496 impl->ref = 1;
498 if (FAILED(hr = async_info_create( invoker, param, callback, (IInspectable *)&impl->IAsyncOperation_boolean_iface, &impl->IWineAsyncInfoImpl_inner )) ||
499 FAILED(hr = IWineAsyncInfoImpl_Start( impl->IWineAsyncInfoImpl_inner )))
501 if (impl->IWineAsyncInfoImpl_inner) IWineAsyncInfoImpl_Release( impl->IWineAsyncInfoImpl_inner );
502 free( impl );
503 return hr;
506 *out = &impl->IAsyncOperation_boolean_iface;
507 TRACE( "created IAsyncOperation_boolean %p\n", *out );
508 return S_OK;
511 struct async_result
513 IAsyncOperation_ForceFeedbackLoadEffectResult IAsyncOperation_ForceFeedbackLoadEffectResult_iface;
514 IWineAsyncInfoImpl *IWineAsyncInfoImpl_inner;
515 LONG ref;
518 static inline struct async_result *impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult( IAsyncOperation_ForceFeedbackLoadEffectResult *iface )
520 return CONTAINING_RECORD( iface, struct async_result, IAsyncOperation_ForceFeedbackLoadEffectResult_iface );
523 static HRESULT WINAPI async_result_QueryInterface( IAsyncOperation_ForceFeedbackLoadEffectResult *iface, REFIID iid, void **out )
525 struct async_result *impl = impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult( iface );
527 TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );
529 if (IsEqualGUID( iid, &IID_IUnknown ) ||
530 IsEqualGUID( iid, &IID_IInspectable ) ||
531 IsEqualGUID( iid, &IID_IAgileObject ) ||
532 IsEqualGUID( iid, &IID_IAsyncOperation_ForceFeedbackLoadEffectResult ))
534 IInspectable_AddRef( (*out = &impl->IAsyncOperation_ForceFeedbackLoadEffectResult_iface) );
535 return S_OK;
538 return IWineAsyncInfoImpl_QueryInterface( impl->IWineAsyncInfoImpl_inner, iid, out );
541 static ULONG WINAPI async_result_AddRef( IAsyncOperation_ForceFeedbackLoadEffectResult *iface )
543 struct async_result *impl = impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult( iface );
544 ULONG ref = InterlockedIncrement( &impl->ref );
545 TRACE( "iface %p, ref %lu.\n", iface, ref );
546 return ref;
549 static ULONG WINAPI async_result_Release( IAsyncOperation_ForceFeedbackLoadEffectResult *iface )
551 struct async_result *impl = impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult( iface );
552 ULONG ref = InterlockedDecrement( &impl->ref );
553 TRACE( "iface %p, ref %lu.\n", iface, ref );
555 if (!ref)
557 /* guard against re-entry if inner releases an outer iface */
558 InterlockedIncrement( &impl->ref );
559 IWineAsyncInfoImpl_Release( impl->IWineAsyncInfoImpl_inner );
560 free( impl );
563 return ref;
566 static HRESULT WINAPI async_result_GetIids( IAsyncOperation_ForceFeedbackLoadEffectResult *iface, ULONG *iid_count, IID **iids )
568 FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
569 return E_NOTIMPL;
572 static HRESULT WINAPI async_result_GetRuntimeClassName( IAsyncOperation_ForceFeedbackLoadEffectResult *iface, HSTRING *class_name )
574 return WindowsCreateString( L"Windows.Foundation.IAsyncOperation`1<Windows.Gaming.Input.ForceFeedback.ForceFeedbackLoadEffectResult>",
575 ARRAY_SIZE(L"Windows.Foundation.IAsyncOperation`1<Windows.Gaming.Input.ForceFeedback.ForceFeedbackLoadEffectResult>"),
576 class_name );
579 static HRESULT WINAPI async_result_GetTrustLevel( IAsyncOperation_ForceFeedbackLoadEffectResult *iface, TrustLevel *trust_level )
581 FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
582 return E_NOTIMPL;
585 static HRESULT WINAPI async_result_put_Completed( IAsyncOperation_ForceFeedbackLoadEffectResult *iface, IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult *handler )
587 struct async_result *impl = impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult( iface );
588 TRACE( "iface %p, handler %p.\n", iface, handler );
589 return IWineAsyncInfoImpl_put_Completed( impl->IWineAsyncInfoImpl_inner, (IWineAsyncOperationCompletedHandler *)handler );
592 static HRESULT WINAPI async_result_get_Completed( IAsyncOperation_ForceFeedbackLoadEffectResult *iface, IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult **handler )
594 struct async_result *impl = impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult( iface );
595 TRACE( "iface %p, handler %p.\n", iface, handler );
596 return IWineAsyncInfoImpl_get_Completed( impl->IWineAsyncInfoImpl_inner, (IWineAsyncOperationCompletedHandler **)handler );
599 static HRESULT WINAPI async_result_GetResults( IAsyncOperation_ForceFeedbackLoadEffectResult *iface, ForceFeedbackLoadEffectResult *results )
601 struct async_result *impl = impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult( iface );
602 PROPVARIANT result = {.vt = VT_UI4};
603 HRESULT hr;
605 TRACE( "iface %p, results %p.\n", iface, results );
607 hr = IWineAsyncInfoImpl_get_Result( impl->IWineAsyncInfoImpl_inner, &result );
609 *results = result.ulVal;
610 PropVariantClear( &result );
611 return hr;
614 static const struct IAsyncOperation_ForceFeedbackLoadEffectResultVtbl async_result_vtbl =
616 /* IUnknown methods */
617 async_result_QueryInterface,
618 async_result_AddRef,
619 async_result_Release,
620 /* IInspectable methods */
621 async_result_GetIids,
622 async_result_GetRuntimeClassName,
623 async_result_GetTrustLevel,
624 /* IAsyncOperation<ForceFeedbackLoadEffectResult> */
625 async_result_put_Completed,
626 async_result_get_Completed,
627 async_result_GetResults,
630 HRESULT async_operation_effect_result_create( IUnknown *invoker, IUnknown *param, async_operation_callback callback,
631 IAsyncOperation_ForceFeedbackLoadEffectResult **out )
633 struct async_result *impl;
634 HRESULT hr;
636 *out = NULL;
637 if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY;
638 impl->IAsyncOperation_ForceFeedbackLoadEffectResult_iface.lpVtbl = &async_result_vtbl;
639 impl->ref = 1;
641 if (FAILED(hr = async_info_create( invoker, param, callback, (IInspectable *)&impl->IAsyncOperation_ForceFeedbackLoadEffectResult_iface, &impl->IWineAsyncInfoImpl_inner )) ||
642 FAILED(hr = IWineAsyncInfoImpl_Start( impl->IWineAsyncInfoImpl_inner )))
644 if (impl->IWineAsyncInfoImpl_inner) IWineAsyncInfoImpl_Release( impl->IWineAsyncInfoImpl_inner );
645 free( impl );
646 return hr;
649 *out = &impl->IAsyncOperation_ForceFeedbackLoadEffectResult_iface;
650 TRACE( "created IAsyncOperation_ForceFeedbackLoadEffectResult %p\n", *out );
651 return S_OK;