cryptowinrt/tests: Add IKeyCredentialManagerStatics::IsSupportedAsync() tests.

This commit is contained in:
Mohamad Al-Jaf 2022-12-01 06:25:36 -05:00 committed by Alexandre Julliard
parent bbd7a6ffb9
commit b7cccbce92

View file

@ -37,6 +37,25 @@
#include "wine/test.h"
static HRESULT (WINAPI *pWindowsDeleteString)( HSTRING str );
static const WCHAR* (WINAPI *pWindowsGetStringRawBuffer)( HSTRING, UINT32* );
static BOOL load_combase_functions(void)
{
HMODULE combase = GetModuleHandleW( L"combase.dll" );
#define LOAD_FUNC(m, f) if (!(p ## f = (void *)GetProcAddress( m, #f ))) goto failed;
LOAD_FUNC( combase, WindowsDeleteString );
LOAD_FUNC( combase, WindowsGetStringRawBuffer );
#undef LOAD_FUNC
return TRUE;
failed:
win_skip("Failed to load combase.dll functions, skipping tests\n");
return FALSE;
}
#define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid )
static void check_interface_( unsigned int line, void *obj, const IID *iid )
{
@ -49,6 +68,143 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid )
IUnknown_Release( unk );
}
#define check_runtimeclass( a, b ) check_runtimeclass_( __LINE__, (IInspectable *)a, b )
static void check_runtimeclass_( int line, IInspectable *inspectable, const WCHAR *class_name )
{
const WCHAR *buffer;
UINT32 length;
HSTRING str;
HRESULT hr;
hr = IInspectable_GetRuntimeClassName( inspectable, &str );
ok_(__FILE__, line)( hr == S_OK, "GetRuntimeClassName returned %#lx\n", hr );
buffer = pWindowsGetStringRawBuffer( str, &length );
ok_(__FILE__, line)( !wcscmp( buffer, class_name ), "got class name %s\n", debugstr_w(buffer) );
pWindowsDeleteString( str );
}
#define check_bool_async( a, b, c, d, e ) check_bool_async_( __LINE__, a, b, c, d, e )
static void check_bool_async_( int line, IAsyncOperation_boolean *async, UINT32 expect_id, AsyncStatus expect_status,
HRESULT expect_hr, BOOLEAN expect_result )
{
AsyncStatus async_status;
IAsyncInfo *async_info;
HRESULT hr, async_hr;
UINT32 async_id;
BOOLEAN result;
hr = IAsyncOperation_boolean_QueryInterface( async, &IID_IAsyncInfo, (void **)&async_info );
ok_(__FILE__, line)( hr == S_OK, "QueryInterface returned %#lx\n", hr );
async_id = 0xdeadbeef;
hr = IAsyncInfo_get_Id( async_info, &async_id );
if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Id returned %#lx\n", hr );
else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Id returned %#lx\n", hr );
if (expect_id) ok_(__FILE__, line)( async_id == expect_id, "got id %u\n", async_id );
else trace("Skipping async_id check, got id %u\n", async_id );
async_status = 0xdeadbeef;
hr = IAsyncInfo_get_Status( async_info, &async_status );
if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_Status returned %#lx\n", hr );
else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_Status returned %#lx\n", hr );
ok_(__FILE__, line)( async_status == expect_status || broken( async_status == Error ), "got status %u\n", async_status );
async_hr = 0xdeadbeef;
hr = IAsyncInfo_get_ErrorCode( async_info, &async_hr );
if (expect_status < 4) ok_(__FILE__, line)( hr == S_OK, "get_ErrorCode returned %#lx\n", hr );
else ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "get_ErrorCode returned %#lx\n", hr );
if (expect_status < 4)
todo_wine_if(FAILED(expect_hr)) ok_(__FILE__, line)( async_hr == expect_hr || broken( async_hr == E_INVALIDARG), "got error %#lx\n", async_hr );
else ok_(__FILE__, line)( async_hr == E_ILLEGAL_METHOD_CALL, "got error %#lx\n", async_hr );
IAsyncInfo_Release( async_info );
result = !expect_result;
hr = IAsyncOperation_boolean_GetResults( async, &result );
switch (expect_status)
{
case Completed:
case Error:
todo_wine_if(FAILED(expect_hr))
ok_(__FILE__, line)( hr == expect_hr || broken( hr == E_INVALIDARG ), "GetResults returned %#lx\n", hr );
ok_(__FILE__, line)( result == expect_result, "got result %u\n", result );
break;
case Canceled:
case Started:
default:
ok_(__FILE__, line)( hr == E_ILLEGAL_METHOD_CALL, "GetResults returned %#lx\n", hr );
break;
}
}
struct bool_async_handler
{
IAsyncOperationCompletedHandler_boolean IAsyncOperationCompletedHandler_boolean_iface;
IAsyncOperation_boolean *async;
AsyncStatus status;
BOOL invoked;
HANDLE event;
};
static inline struct bool_async_handler *impl_from_IAsyncOperationCompletedHandler_boolean( IAsyncOperationCompletedHandler_boolean *iface )
{
return CONTAINING_RECORD( iface, struct bool_async_handler, IAsyncOperationCompletedHandler_boolean_iface );
}
static HRESULT WINAPI bool_async_handler_QueryInterface( IAsyncOperationCompletedHandler_boolean *iface, REFIID iid, void **out )
{
if (IsEqualGUID( iid, &IID_IUnknown ) ||
IsEqualGUID( iid, &IID_IAgileObject ) ||
IsEqualGUID( iid, &IID_IAsyncOperationCompletedHandler_boolean ))
{
IUnknown_AddRef( iface );
*out = iface;
return S_OK;
}
trace( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
*out = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI bool_async_handler_AddRef( IAsyncOperationCompletedHandler_boolean *iface )
{
return 2;
}
static ULONG WINAPI bool_async_handler_Release( IAsyncOperationCompletedHandler_boolean *iface )
{
return 1;
}
static HRESULT WINAPI bool_async_handler_Invoke( IAsyncOperationCompletedHandler_boolean *iface,
IAsyncOperation_boolean *async, AsyncStatus status )
{
struct bool_async_handler *impl = impl_from_IAsyncOperationCompletedHandler_boolean( iface );
trace( "iface %p, async %p, status %u\n", iface, async, status );
ok( !impl->invoked, "invoked twice\n" );
impl->invoked = TRUE;
impl->async = async;
impl->status = status;
if (impl->event) SetEvent( impl->event );
return S_OK;
}
static IAsyncOperationCompletedHandler_booleanVtbl bool_async_handler_vtbl =
{
/*** IUnknown methods ***/
bool_async_handler_QueryInterface,
bool_async_handler_AddRef,
bool_async_handler_Release,
/*** IAsyncOperationCompletedHandler<boolean> methods ***/
bool_async_handler_Invoke,
};
static struct bool_async_handler default_bool_async_handler = {{&bool_async_handler_vtbl}};
static void test_CryptobufferStatics(void)
{
static const WCHAR *cryptobuffer_statics_name = L"Windows.Security.Cryptography.CryptographicBuffer";
@ -86,10 +242,15 @@ static void test_CryptobufferStatics(void)
static void test_Credentials_Statics(void)
{
static const WCHAR *credentials_statics_name = L"Windows.Security.Credentials.KeyCredentialManager";
IAsyncOperationCompletedHandler_boolean *tmp_handler;
IKeyCredentialManagerStatics *credentials_statics;
struct bool_async_handler bool_async_handler;
IAsyncOperation_boolean *bool_async;
IActivationFactory *factory;
IAsyncInfo *async_info;
HSTRING str;
HRESULT hr;
DWORD ret;
LONG ref;
hr = WindowsCreateString( credentials_statics_name, wcslen( credentials_statics_name ), &str );
@ -111,6 +272,51 @@ static void test_Credentials_Statics(void)
hr = IActivationFactory_QueryInterface( factory, &IID_IKeyCredentialManagerStatics, (void **)&credentials_statics );
ok( hr == S_OK, "got hr %#lx.\n", hr );
if (!load_combase_functions()) return;
hr = IKeyCredentialManagerStatics_IsSupportedAsync( credentials_statics, &bool_async );
ok( hr == S_OK, "IsSupportedAsync returned %#lx\n", hr );
check_interface( bool_async, &IID_IUnknown );
check_interface( bool_async, &IID_IInspectable );
check_interface( bool_async, &IID_IAgileObject );
check_interface( bool_async, &IID_IAsyncInfo );
check_interface( bool_async, &IID_IAsyncOperation_boolean );
check_runtimeclass( bool_async, L"Windows.Foundation.IAsyncOperation`1<Boolean>" );
hr = IAsyncOperation_boolean_get_Completed( bool_async, &tmp_handler );
ok( hr == S_OK, "get_Completed returned %#lx\n", hr );
ok( tmp_handler == NULL, "got handler %p\n", tmp_handler );
bool_async_handler = default_bool_async_handler;
bool_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL );
hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler.IAsyncOperationCompletedHandler_boolean_iface );
ok( hr == S_OK, "put_Completed returned %#lx\n", hr );
ret = WaitForSingleObject( bool_async_handler.event, 1000 );
ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
ret = CloseHandle( bool_async_handler.event );
ok( ret, "CloseHandle failed, error %lu\n", GetLastError() );
ok( bool_async_handler.invoked, "handler not invoked\n" );
ok( bool_async_handler.async == bool_async, "got async %p\n", bool_async_handler.async );
ok( bool_async_handler.status == Completed || broken( bool_async_handler.status == Error ), "got status %u\n", bool_async_handler.status );
bool_async_handler = default_bool_async_handler;
hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler.IAsyncOperationCompletedHandler_boolean_iface );
ok( hr == E_ILLEGAL_DELEGATE_ASSIGNMENT, "put_Completed returned %#lx\n", hr );
ok( !bool_async_handler.invoked, "handler invoked\n" );
ok( bool_async_handler.async == NULL, "got async %p\n", bool_async_handler.async );
ok( bool_async_handler.status == Started, "got status %u\n", bool_async_handler.status );
hr = IAsyncOperation_boolean_QueryInterface( bool_async, &IID_IAsyncInfo, (void **)&async_info );
ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
hr = IAsyncInfo_Cancel( async_info );
ok( hr == S_OK, "Cancel returned %#lx\n", hr );
check_bool_async( bool_async, 0, Completed, S_OK, FALSE );
hr = IAsyncInfo_Close( async_info );
ok( hr == S_OK, "Close returned %#lx\n", hr );
check_bool_async( bool_async, 0, 4, S_OK, FALSE );
IAsyncInfo_Release( async_info );
IAsyncOperation_boolean_Release( bool_async );
ref = IKeyCredentialManagerStatics_Release( credentials_statics );
ok( ref == 2, "got ref %ld.\n", ref );
ref = IActivationFactory_Release( factory );