From: Anna R Békefi <annareginabekefi@gmail.com> --- dlls/combase/roapi.c | 75 ++++++++++++++++++++++++++------------ dlls/combase/tests/roapi.c | 42 ++++++++++++++++++--- 2 files changed, 88 insertions(+), 29 deletions(-) diff --git a/dlls/combase/roapi.c b/dlls/combase/roapi.c index 7137294e201..53d401de685 100644 --- a/dlls/combase/roapi.c +++ b/dlls/combase/roapi.c @@ -122,9 +122,6 @@ static WCHAR *get_generic_error_message(HRESULT error) if (!len || !system_message) return wcsdup(L"Unspecified error"); - while (len && (system_message[len - 1] == '\r' || system_message[len - 1] == '\n')) - system_message[--len] = 0; - if (len > 511) len = 511; @@ -768,7 +765,7 @@ BOOL WINAPI RoOriginateError(HRESULT error, HSTRING message) BOOL WINAPI RoOriginateErrorW(HRESULT error, UINT max_len, const WCHAR *message) { IRestrictedErrorInfo *info = NULL; - WCHAR *text = NULL; + WCHAR *generic_text = NULL, *restricted_text = NULL; HRESULT hr; TRACE("%#lx, %u, %s.\n", error, max_len, debugstr_w(message)); @@ -776,24 +773,39 @@ BOOL WINAPI RoOriginateErrorW(HRESULT error, UINT max_len, const WCHAR *message) if (!FAILED(error)) return FALSE; + generic_text = get_generic_error_message(error); + if (!generic_text) + return FALSE; + if (message) - text = duplicate_bounded_message(message, max_len); + restricted_text = duplicate_bounded_message(message, max_len); else - text = get_generic_error_message(error); + restricted_text = wcsdup(generic_text); - if (message && !text) + if (message && !restricted_text) + { + free(generic_text); return FALSE; + } + + if (!restricted_text) + { + free(generic_text); + return FALSE; + } /* The call still succeeds even if we don't attach the error object * to the COM channel. */ if (!should_use_seterrorinfo()) { - free(text); + free(generic_text); + free(restricted_text); return TRUE; } - hr = create_restricted_error_info(error, text, NULL, NULL, NULL, &info); - free(text); + hr = create_restricted_error_info(error, generic_text, restricted_text, NULL, NULL, &info); + free(generic_text); + free(restricted_text); if (FAILED(hr)) { WARN("create_restricted_error_info failed, hr %#lx.\n", hr); @@ -880,8 +892,7 @@ BOOL WINAPI RoTransformErrorW(HRESULT old_error, HRESULT new_error, IRestrictedErrorInfo *old_info = NULL, *new_info = NULL; BSTR desc = NULL, restricted_desc = NULL, cap_sid = NULL, reference = NULL; HRESULT hr, stored_hr = S_OK; - WCHAR *bounded_message = NULL; - const WCHAR *new_desc = NULL, *new_restricted_desc = NULL; + WCHAR *generic_text = NULL, *restricted_text = NULL; TRACE("%#lx, %#lx, %u, %s.\n", old_error, new_error, max_len, debugstr_w(message)); @@ -890,24 +901,35 @@ BOOL WINAPI RoTransformErrorW(HRESULT old_error, HRESULT new_error, if (!FAILED(old_error) && !FAILED(new_error)) return FALSE; + generic_text = get_generic_error_message(new_error); + if (!generic_text) + return FALSE; + if (message) { - bounded_message = duplicate_bounded_message(message, max_len); - if (!bounded_message) + restricted_text = duplicate_bounded_message(message, max_len); + if (!restricted_text) + { + free(generic_text); return FALSE; + } } else { - bounded_message = get_generic_error_message(new_error); - if (!bounded_message) + restricted_text = wcsdup(generic_text); + if (!restricted_text) + { + free(generic_text); return FALSE; + } } /* As with RoOriginateErrorW(), the call can still succeed even if * we don't attach the transformed error object to the COM channel. */ if (!should_use_seterrorinfo()) { - free(bounded_message); + free(generic_text); + free(restricted_text); return TRUE; } @@ -915,7 +937,8 @@ BOOL WINAPI RoTransformErrorW(HRESULT old_error, HRESULT new_error, if (FAILED(hr)) { WARN("RoGetMatchingRestrictedErrorInfo failed, hr %#lx.\n", hr); - free(bounded_message); + free(generic_text); + free(restricted_text); return FALSE; } @@ -935,10 +958,7 @@ BOOL WINAPI RoTransformErrorW(HRESULT old_error, HRESULT new_error, reference = NULL; } - new_desc = bounded_message; - new_restricted_desc = desc ? desc : restricted_desc; - - hr = create_restricted_error_info(new_error, new_desc, new_restricted_desc, + hr = create_restricted_error_info(new_error, generic_text, restricted_text, cap_sid, reference, &new_info); if (FAILED(hr)) { @@ -976,7 +996,8 @@ done: SysFreeString(cap_sid); if (reference) SysFreeString(reference); - free(bounded_message); + free(generic_text); + free(restricted_text); return SUCCEEDED(hr); } @@ -1007,6 +1028,7 @@ HRESULT WINAPI RoGetMatchingRestrictedErrorInfo(HRESULT error, IRestrictedErrorI { IRestrictedErrorInfo *current = NULL; HRESULT hr, stored_hr = S_OK; + WCHAR *generic_text = NULL; TRACE("%#lx, %p.\n", error, info); @@ -1046,7 +1068,12 @@ HRESULT WINAPI RoGetMatchingRestrictedErrorInfo(HRESULT error, IRestrictedErrorI current = NULL; } - hr = create_restricted_error_info(error, NULL, NULL, NULL, NULL, ¤t); + generic_text = get_generic_error_message(error); + if (!generic_text) + return E_OUTOFMEMORY; + + hr = create_restricted_error_info(error, generic_text, generic_text, NULL, NULL, ¤t); + free(generic_text); if (FAILED(hr)) { WARN("create_restricted_error_info failed, hr %#lx.\n", hr); diff --git a/dlls/combase/tests/roapi.c b/dlls/combase/tests/roapi.c index 16452bfd21d..c31ae8b340d 100644 --- a/dlls/combase/tests/roapi.c +++ b/dlls/combase/tests/roapi.c @@ -652,6 +652,27 @@ static BOOL wstr_equal_nullsafe(const WCHAR *a, const WCHAR *b) return !lstrcmpW(a, b); } +static WCHAR *get_expected_system_message(HRESULT hr) +{ + WCHAR *msg = NULL; + DWORD len; + + len = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, hr, 0, (WCHAR *)&msg, 0, NULL); + if (!len) + { + len = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, E_FAIL, 0, (WCHAR *)&msg, 0, NULL); + } + + ok(msg != NULL, "FormatMessageW failed for %#lx.\n", hr); + return msg; +} + static void check_restricted_error_details_(unsigned int line, IRestrictedErrorInfo *info, HRESULT expected_hr, const WCHAR *expected_desc, const WCHAR *expected_restricted) { @@ -702,6 +723,8 @@ static void test_restricted_error_handling(void) HRESULT hr; UINT32 flags = 0; BOOL uninit = FALSE; + WCHAR *access_denied_msg; + WCHAR *bounds_msg; hr = RoInitialize(RO_INIT_MULTITHREADED); ok(hr == S_OK || hr == S_FALSE, "RoInitialize returned %#lx.\n", hr); @@ -710,6 +733,12 @@ static void test_restricted_error_handling(void) clear_restricted_error_state(); + access_denied_msg = get_expected_system_message(E_ACCESSDENIED); + bounds_msg = get_expected_system_message(E_BOUNDS); + + ok(access_denied_msg != NULL, "Failed to get expected message for E_ACCESSDENIED.\n"); + ok(bounds_msg != NULL, "Failed to get expected message for E_BOUNDS.\n"); + hr = GetRestrictedErrorInfo(&info); ok(hr == S_FALSE, "GetRestrictedErrorInfo returned %#lx.\n", hr); ok(!info, "got info %p.\n", info); @@ -725,7 +754,7 @@ static void test_restricted_error_handling(void) hr = GetRestrictedErrorInfo(&info); ok(hr == S_OK, "GetRestrictedErrorInfo returned %#lx.\n", hr); - check_restricted_error_details(info, E_ACCESSDENIED, originate_msg, NULL); + check_restricted_error_details(info, E_ACCESSDENIED, access_denied_msg, originate_msg); IRestrictedErrorInfo_Release(info); info = NULL; @@ -735,7 +764,7 @@ static void test_restricted_error_handling(void) hr = RoGetMatchingRestrictedErrorInfo(E_ACCESSDENIED, &info); ok(hr == S_OK, "RoGetMatchingRestrictedErrorInfo returned %#lx.\n", hr); - check_restricted_error_details(info, E_ACCESSDENIED, NULL, NULL); + check_restricted_error_details(info, E_ACCESSDENIED, access_denied_msg, access_denied_msg); hr = SetRestrictedErrorInfo(info); ok(hr == S_OK, "SetRestrictedErrorInfo returned %#lx.\n", hr); @@ -744,7 +773,7 @@ static void test_restricted_error_handling(void) hr = GetRestrictedErrorInfo(&info); ok(hr == S_OK, "GetRestrictedErrorInfo returned %#lx.\n", hr); - check_restricted_error_details(info, E_ACCESSDENIED, NULL, NULL); + check_restricted_error_details(info, E_ACCESSDENIED, access_denied_msg, access_denied_msg); IRestrictedErrorInfo_Release(info); info = NULL; @@ -764,7 +793,7 @@ static void test_restricted_error_handling(void) hr = GetRestrictedErrorInfo(&info); ok(hr == S_OK, "GetRestrictedErrorInfo returned %#lx.\n", hr); - check_restricted_error_details(info, E_ACCESSDENIED, new_msg, old_msg); + check_restricted_error_details(info, E_ACCESSDENIED, access_denied_msg, new_msg); IRestrictedErrorInfo_Release(info); info = NULL; @@ -781,7 +810,7 @@ static void test_restricted_error_handling(void) hr = GetRestrictedErrorInfo(&info); ok(hr == S_OK, "GetRestrictedErrorInfo returned %#lx.\n", hr); - check_restricted_error_details(info, E_BOUNDS, NULL, NULL); + check_restricted_error_details(info, E_BOUNDS, bounds_msg, bounds_msg); IRestrictedErrorInfo_Release(info); info = NULL; @@ -804,6 +833,9 @@ static void test_restricted_error_handling(void) clear_restricted_error_state(); + LocalFree(access_denied_msg); + LocalFree(bounds_msg); + if (uninit) RoUninitialize(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10659