From 31ce37da2ace6cf1c3fc35c1dd6ce138263f65f7 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Fri, 12 Apr 2024 21:29:07 +0900 Subject: [PATCH] [SHELL32][SHELL32_APITEST][SDK] Implement GUIDFromStringA (#6734) Implementing missing features... JIRA issue: CORE-19278 - Add GUIDFromString testcase. - Implement GUIDFromStringA function. - Add NULL check to GUIDFromStringW. - Add GUIDFromStringA prototype to "undocshell.h". --- dll/win32/shell32/wine/shellord.c | 13 +- .../rostests/apitests/shell32/CMakeLists.txt | 1 + .../apitests/shell32/GUIDFromString.cpp | 119 ++++++++++++++++++ modules/rostests/apitests/shell32/testlist.c | 2 + sdk/include/reactos/undocshell.h | 6 +- 5 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 modules/rostests/apitests/shell32/GUIDFromString.cpp diff --git a/dll/win32/shell32/wine/shellord.c b/dll/win32/shell32/wine/shellord.c index 3779b2e7e56..b02da92b1bf 100644 --- a/dll/win32/shell32/wine/shellord.c +++ b/dll/win32/shell32/wine/shellord.c @@ -1889,8 +1889,14 @@ DWORD WINAPI DoEnvironmentSubstAW(LPVOID x, UINT y) */ BOOL WINAPI GUIDFromStringA(LPCSTR str, LPGUID guid) { - TRACE("GUIDFromStringA() stub\n"); - return FALSE; + ANSI_STRING ansi_str; + WCHAR szWide[40]; + UNICODE_STRING guid_str = { 0, sizeof(szWide), szWide }; + if (*str != '{') + return FALSE; + RtlInitAnsiString(&ansi_str, str); + return !RtlAnsiStringToUnicodeString(&guid_str, &ansi_str, FALSE) && + !RtlGUIDFromString(&guid_str, guid); } /************************************************************************* @@ -1899,7 +1905,8 @@ BOOL WINAPI GUIDFromStringA(LPCSTR str, LPGUID guid) BOOL WINAPI GUIDFromStringW(LPCWSTR str, LPGUID guid) { UNICODE_STRING guid_str; - + if (!str || *str != L'{') + return FALSE; RtlInitUnicodeString(&guid_str, str); return !RtlGUIDFromString(&guid_str, guid); } diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt b/modules/rostests/apitests/shell32/CMakeLists.txt index 62cbc898ee6..acd85a23c3f 100644 --- a/modules/rostests/apitests/shell32/CMakeLists.txt +++ b/modules/rostests/apitests/shell32/CMakeLists.txt @@ -17,6 +17,7 @@ list(APPEND SOURCE ExtractIconEx.cpp FindExecutable.cpp GetDisplayNameOf.cpp + GUIDFromString.cpp Int64ToString.cpp IShellFolderViewCB.cpp OpenAs_RunDLL.cpp diff --git a/modules/rostests/apitests/shell32/GUIDFromString.cpp b/modules/rostests/apitests/shell32/GUIDFromString.cpp new file mode 100644 index 00000000000..597892c755d --- /dev/null +++ b/modules/rostests/apitests/shell32/GUIDFromString.cpp @@ -0,0 +1,119 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for GUIDFromStringA/W + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#include +#include +#include +#include + +DEFINE_GUID(invalid_guid, 0xDEADDEAD, 0xDEAD, 0xDEAD, 0xED, 0xED, 0xED, 0xED, + 0xED, 0xED, 0xED, 0xED); + +//DEFINE_GUID(IID_IShellLinkW, 0x000214F9, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x46); +//DEFINE_GUID(IID_IShellLinkW_Invalid, 0x000214F9, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0xED); + +static void TEST_GUIDFromStringA(void) +{ + GUID guid; + BOOL ret; + + guid = invalid_guid; + _SEH2_TRY + { + ret = GUIDFromStringA(NULL, &guid); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ret = 0xDEADBEEF; + } + _SEH2_END; + + if (IsWindowsVistaOrGreater()) + ok_int(ret, FALSE); + else + ok_int(ret, 0xDEADBEEF); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringA("", &guid), FALSE); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringA("{", &guid), FALSE); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringA("{000214F9-0000-0000-C000-000000000046", &guid), FALSE); + //ok_int(memcmp(&guid, &IID_IShellLinkW_Invalid, sizeof(guid)) == 0, TRUE); // Ignorable corner case + + guid = invalid_guid; + ok_int(GUIDFromStringA("{000214F9-0000-0000-C000-000000000046}", &guid), TRUE); + ok_int(memcmp(&guid, &IID_IShellLinkW, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringA("{000214F9-0000-0000-C000-000000000046}g", &guid), TRUE); + ok_int(memcmp(&guid, &IID_IShellLinkW, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringA(" {000214F9-0000-0000-C000-000000000046}", &guid), FALSE); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); +} + +static void TEST_GUIDFromStringW(void) +{ + GUID guid; + BOOL ret; + + guid = invalid_guid; + _SEH2_TRY + { + ret = GUIDFromStringW(NULL, &guid); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ret = 0xDEADBEEF; + } + _SEH2_END; + + if (IsWindowsVistaOrGreater()) + ok_int(ret, 0xDEADBEEF); + else + ok_int(ret, FALSE); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringW(L"", &guid), FALSE); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringW(L"{", &guid), FALSE); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringW(L"{000214F9-0000-0000-C000-000000000046", &guid), FALSE); + //ok_int(memcmp(&guid, &IID_IShellLinkW_Invalid, sizeof(guid)) == 0, TRUE); // Ignorable corner case + + guid = invalid_guid; + ok_int(GUIDFromStringW(L"{000214F9-0000-0000-C000-000000000046}", &guid), TRUE); + ok_int(memcmp(&guid, &IID_IShellLinkW, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringW(L"{000214F9-0000-0000-C000-000000000046}g", &guid), TRUE); + ok_int(memcmp(&guid, &IID_IShellLinkW, sizeof(guid)) == 0, TRUE); + + guid = invalid_guid; + ok_int(GUIDFromStringW(L" {000214F9-0000-0000-C000-000000000046}", &guid), FALSE); + ok_int(memcmp(&guid, &invalid_guid, sizeof(guid)) == 0, TRUE); +} + +START_TEST(GUIDFromString) +{ + TEST_GUIDFromStringA(); + TEST_GUIDFromStringW(); +} diff --git a/modules/rostests/apitests/shell32/testlist.c b/modules/rostests/apitests/shell32/testlist.c index e3a83c19106..7e42b733569 100644 --- a/modules/rostests/apitests/shell32/testlist.c +++ b/modules/rostests/apitests/shell32/testlist.c @@ -17,6 +17,7 @@ extern void func_DragDrop(void); extern void func_ExtractIconEx(void); extern void func_FindExecutable(void); extern void func_GetDisplayNameOf(void); +extern void func_GUIDFromString(void); extern void func_Int64ToString(void); extern void func_IShellFolderViewCB(void); extern void func_menu(void); @@ -57,6 +58,7 @@ const struct test winetest_testlist[] = { "ExtractIconEx", func_ExtractIconEx }, { "FindExecutable", func_FindExecutable }, { "GetDisplayNameOf", func_GetDisplayNameOf }, + { "GUIDFromString", func_GUIDFromString }, { "Int64ToString", func_Int64ToString }, { "IShellFolderViewCB", func_IShellFolderViewCB }, { "menu", func_menu }, diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index bb216df8ad8..0460a261cb7 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -727,10 +727,12 @@ HRESULT WINAPI SHCreatePropertyBag(_In_ REFIID riid, _Out_ void **ppvObj); HRESULT WINAPI SHLimitInputCombo(HWND hWnd, IShellFolder *psf); HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv); +BOOL WINAPI GUIDFromStringA( + _In_ PCSTR psz, + _Out_ LPGUID pguid); BOOL WINAPI GUIDFromStringW( _In_ PCWSTR psz, - _Out_ LPGUID pguid - ); + _Out_ LPGUID pguid); LPSTR WINAPI SheRemoveQuotesA(LPSTR psz); LPWSTR WINAPI SheRemoveQuotesW(LPWSTR psz);