From: Paul Gofman pgofman@codeweavers.com
--- dlls/windows.devices.enumeration/async.c | 62 +++++++++++-------- .../async_private.idl | 2 +- dlls/windows.devices.enumeration/main.c | 6 +- 3 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/dlls/windows.devices.enumeration/async.c b/dlls/windows.devices.enumeration/async.c index 0c4f6d647d2..2d9246c237c 100644 --- a/dlls/windows.devices.enumeration/async.c +++ b/dlls/windows.devices.enumeration/async.c @@ -175,6 +175,39 @@ static HRESULT WINAPI async_impl_get_Result( IAsyncInfoImpl *iface, PROPVARIANT return hr; }
+static BOOL async_info_complete( struct async_info *impl, BOOL called_async ) +{ + IInspectable *operation = impl->IInspectable_outer; + PROPVARIANT result = {0}; + HRESULT hr; + + hr = impl->callback( impl->invoker, impl->param, &result, called_async ); + if (!called_async && hr == STATUS_PENDING) return FALSE; + + EnterCriticalSection( &impl->cs ); + if (impl->status != Closed) impl->status = FAILED(hr) ? Error : Completed; + PropVariantCopy( &impl->result, &result ); + impl->hr = hr; + + if (impl->handler != NULL && impl->handler != HANDLER_NOT_SET) + { + IAsyncOperationCompletedHandlerImpl *handler = impl->handler; + AsyncStatus status = impl->status; + impl->handler = NULL; /* Prevent concurrent invoke. */ + LeaveCriticalSection( &impl->cs ); + + IAsyncOperationCompletedHandlerImpl_Invoke( handler, operation, status ); + IAsyncOperationCompletedHandlerImpl_Release( handler ); + } + else LeaveCriticalSection( &impl->cs ); + + /* release refcount acquired in Start */ + IInspectable_Release( operation ); + + PropVariantClear( &result ); + return TRUE; +} + static HRESULT WINAPI async_impl_Start( IAsyncInfoImpl *iface ) { struct async_info *impl = impl_from_IAsyncInfoImpl( iface ); @@ -183,7 +216,7 @@ static HRESULT WINAPI async_impl_Start( IAsyncInfoImpl *iface )
/* keep the async alive in the callback */ IInspectable_AddRef( impl->IInspectable_outer ); - SubmitThreadpoolWork( impl->async_run_work ); + if (!async_info_complete( impl, FALSE )) SubmitThreadpoolWork( impl->async_run_work );
return S_OK; } @@ -305,33 +338,8 @@ static const struct IAsyncInfoVtbl async_info_vtbl = static void CALLBACK async_info_callback( TP_CALLBACK_INSTANCE *instance, void *iface, TP_WORK *work ) { struct async_info *impl = impl_from_IAsyncInfoImpl( iface ); - IInspectable *operation = impl->IInspectable_outer; - PROPVARIANT result = {0}; - HRESULT hr; - - hr = impl->callback( impl->invoker, impl->param, &result ); - - EnterCriticalSection( &impl->cs ); - if (impl->status != Closed) impl->status = FAILED(hr) ? Error : Completed; - PropVariantCopy( &impl->result, &result ); - impl->hr = hr;
- if (impl->handler != NULL && impl->handler != HANDLER_NOT_SET) - { - IAsyncOperationCompletedHandlerImpl *handler = impl->handler; - AsyncStatus status = impl->status; - impl->handler = NULL; /* Prevent concurrent invoke. */ - LeaveCriticalSection( &impl->cs ); - - IAsyncOperationCompletedHandlerImpl_Invoke( handler, operation, status ); - IAsyncOperationCompletedHandlerImpl_Release( handler ); - } - else LeaveCriticalSection( &impl->cs ); - - /* release refcount acquired in Start */ - IInspectable_Release( operation ); - - PropVariantClear( &result ); + async_info_complete( impl, TRUE ); }
static HRESULT async_info_create( IUnknown *invoker, IUnknown *param, async_operation_callback callback, diff --git a/dlls/windows.devices.enumeration/async_private.idl b/dlls/windows.devices.enumeration/async_private.idl index 10741572601..40ea63ca4c1 100644 --- a/dlls/windows.devices.enumeration/async_private.idl +++ b/dlls/windows.devices.enumeration/async_private.idl @@ -42,5 +42,5 @@ namespace Wine.Internal { HRESULT Start(); }
- typedef HRESULT (*async_operation_callback)( IUnknown *invoker, IUnknown *param, PROPVARIANT *result ); + typedef HRESULT (*async_operation_callback)( IUnknown *invoker, IUnknown *param, PROPVARIANT *result, BOOL called_async ); } diff --git a/dlls/windows.devices.enumeration/main.c b/dlls/windows.devices.enumeration/main.c index 6a4505c9649..081260da759 100644 --- a/dlls/windows.devices.enumeration/main.c +++ b/dlls/windows.devices.enumeration/main.c @@ -725,7 +725,7 @@ static HRESULT WINAPI device_statics_CreateFromIdAsyncAdditionalProperties( IDev return E_NOTIMPL; }
-static HRESULT find_all_async( IUnknown *invoker, IUnknown *param, PROPVARIANT *result ) +static HRESULT find_all_async( IUnknown *invoker, IUnknown *param, PROPVARIANT *result, BOOL called_async ) { static const struct vector_iids iids = { @@ -742,7 +742,9 @@ static HRESULT find_all_async( IUnknown *invoker, IUnknown *param, PROPVARIANT * const DEV_OBJECT *objects; HRESULT hr;
- TRACE( "invoker %p, param %p, result %p\n", invoker, param, result ); + TRACE( "invoker %p, param %p, result %p, called_async %d\n", invoker, param, result, called_async ); + + if (!called_async) return STATUS_PENDING;
params = impl_from_IUnknown( param ); if (params->expr)