From: Anna R Békefi <annareginabekefi@gmail.com> --- dlls/combase/tests/Makefile.in | 2 +- dlls/combase/tests/roapi.c | 271 +++++++++++++++++++++++++++++++++ 2 files changed, 272 insertions(+), 1 deletion(-) diff --git a/dlls/combase/tests/Makefile.in b/dlls/combase/tests/Makefile.in index 21597b38d51..85b337cceec 100644 --- a/dlls/combase/tests/Makefile.in +++ b/dlls/combase/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = combase.dll -IMPORTS = combase uuid user32 +IMPORTS = combase uuid user32 oleaut32 SOURCES = \ combase.rc \ diff --git a/dlls/combase/tests/roapi.c b/dlls/combase/tests/roapi.c index e4100cb11bc..7d2230e7000 100644 --- a/dlls/combase/tests/roapi.c +++ b/dlls/combase/tests/roapi.c @@ -23,6 +23,7 @@ #include "winerror.h" #include "winstring.h" #include "winternl.h" +#include "oleauto.h" #include "initguid.h" #include "roapi.h" @@ -639,6 +640,275 @@ static void test_RoGetErrorReportingFlags(void) ok(flags == RO_ERROR_REPORTING_USESETERRORINFO, "Got unexpected flag %#x.\n", flags); } +struct test_restricted_error_info +{ + IRestrictedErrorInfo IRestrictedErrorInfo_iface; + IErrorInfo IErrorInfo_iface; + LONG refcount; + HRESULT hr; + BSTR description; + BSTR restricted_description; + BSTR capability_sid; + BSTR reference; +}; + +static struct test_restricted_error_info *impl_from_test_IRestrictedErrorInfo(IRestrictedErrorInfo *iface) +{ + return CONTAINING_RECORD(iface, struct test_restricted_error_info, IRestrictedErrorInfo_iface); +} + +static struct test_restricted_error_info *impl_from_test_IErrorInfo(IErrorInfo *iface) +{ + return CONTAINING_RECORD(iface, struct test_restricted_error_info, IErrorInfo_iface); +} + +static ULONG test_restricted_error_info_addref(struct test_restricted_error_info *info) +{ + return InterlockedIncrement(&info->refcount); +} + +static ULONG test_restricted_error_info_release(struct test_restricted_error_info *info) +{ + ULONG refcount = InterlockedDecrement(&info->refcount); + + if (!refcount) + { + SysFreeString(info->description); + SysFreeString(info->restricted_description); + SysFreeString(info->capability_sid); + SysFreeString(info->reference); + free(info); + } + + return refcount; +} + +static HRESULT WINAPI test_restricted_error_info_QueryInterface(IRestrictedErrorInfo *iface, REFIID riid, void **obj) +{ + struct test_restricted_error_info *info = impl_from_test_IRestrictedErrorInfo(iface); + + if (!obj) return E_POINTER; + *obj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IRestrictedErrorInfo)) + *obj = &info->IRestrictedErrorInfo_iface; + else if (IsEqualIID(riid, &IID_IErrorInfo)) + *obj = &info->IErrorInfo_iface; + + if (*obj) + { + test_restricted_error_info_addref(info); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI test_restricted_error_info_AddRef(IRestrictedErrorInfo *iface) +{ + struct test_restricted_error_info *info = impl_from_test_IRestrictedErrorInfo(iface); + return test_restricted_error_info_addref(info); +} + +static ULONG WINAPI test_restricted_error_info_Release(IRestrictedErrorInfo *iface) +{ + struct test_restricted_error_info *info = impl_from_test_IRestrictedErrorInfo(iface); + return test_restricted_error_info_release(info); +} + +static HRESULT WINAPI test_restricted_error_info_GetErrorDetails(IRestrictedErrorInfo *iface, + BSTR *description, HRESULT *error, BSTR *restricted_description, BSTR *capability_sid) +{ + struct test_restricted_error_info *info = impl_from_test_IRestrictedErrorInfo(iface); + + if (description) + *description = info->description ? SysAllocString(info->description) : NULL; + if (error) + *error = info->hr; + if (restricted_description) + *restricted_description = info->restricted_description ? SysAllocString(info->restricted_description) : NULL; + if (capability_sid) + *capability_sid = info->capability_sid ? SysAllocString(info->capability_sid) : NULL; + + return S_OK; +} + +static HRESULT WINAPI test_restricted_error_info_GetReference(IRestrictedErrorInfo *iface, BSTR *reference) +{ + struct test_restricted_error_info *info = impl_from_test_IRestrictedErrorInfo(iface); + + if (!reference) return E_POINTER; + *reference = info->reference ? SysAllocString(info->reference) : NULL; + return S_OK; +} + +static HRESULT WINAPI test_restricted_error_info_ierror_QueryInterface(IErrorInfo *iface, REFIID riid, void **obj) +{ + struct test_restricted_error_info *info = impl_from_test_IErrorInfo(iface); + return IRestrictedErrorInfo_QueryInterface(&info->IRestrictedErrorInfo_iface, riid, obj); +} + +static ULONG WINAPI test_restricted_error_info_ierror_AddRef(IErrorInfo *iface) +{ + struct test_restricted_error_info *info = impl_from_test_IErrorInfo(iface); + return test_restricted_error_info_addref(info); +} + +static ULONG WINAPI test_restricted_error_info_ierror_Release(IErrorInfo *iface) +{ + struct test_restricted_error_info *info = impl_from_test_IErrorInfo(iface); + return test_restricted_error_info_release(info); +} + +static HRESULT WINAPI test_restricted_error_info_ierror_GetGUID(IErrorInfo *iface, GUID *guid) +{ + if (!guid) return E_INVALIDARG; + *guid = GUID_NULL; + return S_OK; +} + +static HRESULT WINAPI test_restricted_error_info_ierror_GetSource(IErrorInfo *iface, BSTR *source) +{ + if (!source) return E_INVALIDARG; + *source = NULL; + return S_OK; +} + +static HRESULT WINAPI test_restricted_error_info_ierror_GetDescription(IErrorInfo *iface, BSTR *description) +{ + struct test_restricted_error_info *info = impl_from_test_IErrorInfo(iface); + + if (!description) return E_INVALIDARG; + *description = info->description ? SysAllocString(info->description) : NULL; + return S_OK; +} + +static HRESULT WINAPI test_restricted_error_info_ierror_GetHelpFile(IErrorInfo *iface, BSTR *helpfile) +{ + if (!helpfile) return E_INVALIDARG; + *helpfile = NULL; + return S_OK; +} + +static HRESULT WINAPI test_restricted_error_info_ierror_GetHelpContext(IErrorInfo *iface, DWORD *help_context) +{ + if (!help_context) return E_INVALIDARG; + *help_context = 0; + return S_OK; +} + +static const IRestrictedErrorInfoVtbl test_restricted_error_info_vtbl = +{ + test_restricted_error_info_QueryInterface, + test_restricted_error_info_AddRef, + test_restricted_error_info_Release, + test_restricted_error_info_GetErrorDetails, + test_restricted_error_info_GetReference +}; + +static const IErrorInfoVtbl test_restricted_error_info_ierror_vtbl = +{ + test_restricted_error_info_ierror_QueryInterface, + test_restricted_error_info_ierror_AddRef, + test_restricted_error_info_ierror_Release, + test_restricted_error_info_ierror_GetGUID, + test_restricted_error_info_ierror_GetSource, + test_restricted_error_info_ierror_GetDescription, + test_restricted_error_info_ierror_GetHelpFile, + test_restricted_error_info_ierror_GetHelpContext +}; + +static IRestrictedErrorInfo *create_test_restricted_error_info(HRESULT hr, const WCHAR *description, + const WCHAR *restricted_description, const WCHAR *reference) +{ + struct test_restricted_error_info *info; + + info = calloc(1, sizeof(*info)); + ok(!!info, "Failed to allocate test restricted error info.\n"); + if (!info) return NULL; + + info->IRestrictedErrorInfo_iface.lpVtbl = &test_restricted_error_info_vtbl; + info->IErrorInfo_iface.lpVtbl = &test_restricted_error_info_ierror_vtbl; + info->refcount = 1; + info->hr = hr; + info->description = description ? SysAllocString(description) : NULL; + info->restricted_description = restricted_description ? SysAllocString(restricted_description) : NULL; + info->reference = reference ? SysAllocString(reference) : NULL; + info->capability_sid = NULL; + + return &info->IRestrictedErrorInfo_iface; +} + +static void test_GetSetRestrictedErrorInfo(void) +{ + static const WCHAR test_description[] = L"test-description"; + static const WCHAR test_restricted_description[] = L"test-restricted-description"; + static const WCHAR test_reference[] = L"test-reference"; + IRestrictedErrorInfo *info, *retrieved = NULL; + BSTR description = NULL, restricted_description = NULL, capability_sid = NULL, reference = NULL; + HRESULT hr, error = S_OK; + BOOL uninit = FALSE; + + hr = RoInitialize(RO_INIT_MULTITHREADED); + ok(hr == S_OK || hr == S_FALSE, "RoInitialize returned %#lx.\n", hr); + if (SUCCEEDED(hr)) + uninit = TRUE; + + hr = SetRestrictedErrorInfo(NULL); + ok(hr == S_OK, "SetRestrictedErrorInfo(NULL) returned %#lx.\n", hr); + + hr = GetRestrictedErrorInfo(NULL); + ok(hr == E_POINTER, "GetRestrictedErrorInfo(NULL) returned %#lx.\n", hr); + + hr = GetRestrictedErrorInfo(&retrieved); + ok(hr == S_FALSE, "GetRestrictedErrorInfo returned %#lx.\n", hr); + ok(!retrieved, "got info %p.\n", retrieved); + + info = create_test_restricted_error_info(E_ACCESSDENIED, test_description, + test_restricted_description, test_reference); + ok(!!info, "Failed to create test restricted error info.\n"); + + hr = SetRestrictedErrorInfo(info); + ok(hr == S_OK, "SetRestrictedErrorInfo returned %#lx.\n", hr); + IRestrictedErrorInfo_Release(info); + + hr = GetRestrictedErrorInfo(&retrieved); + ok(hr == S_OK, "GetRestrictedErrorInfo returned %#lx.\n", hr); + ok(!!retrieved, "got info %p.\n", retrieved); + + hr = IRestrictedErrorInfo_GetErrorDetails(retrieved, &description, &error, + &restricted_description, &capability_sid); + ok(hr == S_OK, "GetErrorDetails returned %#lx.\n", hr); + ok(error == E_ACCESSDENIED, "got error %#lx.\n", error); + ok(description && !lstrcmpW(description, test_description), + "got description %s.\n", wine_dbgstr_w(description)); + ok(restricted_description && !lstrcmpW(restricted_description, test_restricted_description), + "got restricted description %s.\n", wine_dbgstr_w(restricted_description)); + ok(!capability_sid, "got capability sid %s.\n", wine_dbgstr_w(capability_sid)); + + hr = IRestrictedErrorInfo_GetReference(retrieved, &reference); + ok(hr == S_OK, "GetReference returned %#lx.\n", hr); + ok(reference && !lstrcmpW(reference, test_reference), + "got reference %s.\n", wine_dbgstr_w(reference)); + + SysFreeString(description); + SysFreeString(restricted_description); + SysFreeString(capability_sid); + SysFreeString(reference); + IRestrictedErrorInfo_Release(retrieved); + retrieved = NULL; + + hr = GetRestrictedErrorInfo(&retrieved); + ok(hr == S_FALSE, "GetRestrictedErrorInfo returned %#lx.\n", hr); + ok(!retrieved, "got info %p.\n", retrieved); + + hr = SetRestrictedErrorInfo(NULL); + ok(hr == S_OK, "SetRestrictedErrorInfo(NULL) returned %#lx.\n", hr); + + if (uninit) + RoUninitialize(); +} + START_TEST(roapi) { BOOL ret; @@ -649,6 +919,7 @@ START_TEST(roapi) test_ActivationFactories(); test_RoGetAgileReference(); test_RoGetErrorReportingFlags(); + test_GetSetRestrictedErrorInfo(); SetLastError(0xdeadbeef); ret = DeleteFileW(L"wine.combase.test.dll"); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10659