https://git.reactos.org/?p=reactos.git;a=commitdiff;h=157e18b215ce0f5334c4f…
commit 157e18b215ce0f5334c4f2ca895447a28d650d16
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Jan 20 08:50:26 2025 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Jan 20 08:50:26 2025 +0900
[SHELL32][SHELL32_APITEST][SDK] Implement StrRStrA/W (#7621)
Implementing missing features...
JIRA issue: CORE-19278
- Move function definitions from stubs.cpp to utils.cpp.
- Add prototypes to <undocshell.h>.
---
dll/win32/shell32/stubs.cpp | 22 ------
dll/win32/shell32/utils.cpp | 82 ++++++++++++++++++++
modules/rostests/apitests/shell32/CMakeLists.txt | 1 +
modules/rostests/apitests/shell32/StrRStr.cpp | 97 ++++++++++++++++++++++++
modules/rostests/apitests/shell32/testlist.c | 2 +
sdk/include/reactos/undocshell.h | 12 +++
6 files changed, 194 insertions(+), 22 deletions(-)
diff --git a/dll/win32/shell32/stubs.cpp b/dll/win32/shell32/stubs.cpp
index 8967dd49ab8..5698b7dc0c8 100644
--- a/dll/win32/shell32/stubs.cpp
+++ b/dll/win32/shell32/stubs.cpp
@@ -235,28 +235,6 @@ RealDriveTypeFlags(INT iDrive, BOOL bUnknown)
return 1;
}
-/*
- * Unimplemented
- */
-EXTERN_C LPWSTR
-WINAPI
-StrRStrW(LPWSTR lpSrc, LPWSTR lpLast, LPWSTR lpSearch)
-{
- FIXME("StrRStrW() stub\n");
- return NULL;
-}
-
-/*
- * Unimplemented
- */
-EXTERN_C LPWSTR
-WINAPI
-StrRStrA(LPSTR lpSrc, LPSTR lpLast, LPSTR lpSearch)
-{
- FIXME("StrRStrA() stub\n");
- return NULL;
-}
-
/*
* Unimplemented
*/
diff --git a/dll/win32/shell32/utils.cpp b/dll/win32/shell32/utils.cpp
index 1f4ff07a88e..831d52d3c1e 100644
--- a/dll/win32/shell32/utils.cpp
+++ b/dll/win32/shell32/utils.cpp
@@ -13,6 +13,88 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+static PCSTR StrEndNA(_In_ PCSTR psz, _In_ INT_PTR cch)
+{
+ PCSTR pch, pchEnd = &psz[cch];
+ for (pch = psz; *pch && pch < pchEnd; pch = CharNextA(pch))
+ ;
+ if (pchEnd < pch) // A double-byte character detected at last?
+ pch -= 2; // The width of a double-byte character is 2
+ return pch;
+}
+
+static PCWSTR StrEndNW(_In_ PCWSTR psz, _In_ INT_PTR cch)
+{
+ PCWSTR pch, pchEnd = &psz[cch];
+ for (pch = psz; *pch && pch < pchEnd; ++pch)
+ ;
+ return pch;
+}
+
+/*************************************************************************
+ * StrRStrA [SHELL32.389]
+ */
+EXTERN_C
+PSTR WINAPI
+StrRStrA(
+ _In_ PCSTR pszSrc,
+ _In_opt_ PCSTR pszLast,
+ _In_ PCSTR pszSearch)
+{
+ INT cchSearch = lstrlenA(pszSearch);
+
+ PCSTR pchEnd = pszLast ? pszLast : &pszSrc[lstrlenA(pszSrc)];
+ if (pchEnd == pszSrc)
+ return NULL;
+
+ INT_PTR cchEnd = pchEnd - pszSrc;
+ for (;;)
+ {
+ --pchEnd;
+ --cchEnd;
+ if (!pchEnd)
+ break;
+ if (!StrCmpNA(pchEnd, pszSearch, cchSearch) && pchEnd == StrEndNA(pszSrc,
cchEnd))
+ break;
+ if (pchEnd == pszSrc)
+ return NULL;
+ }
+
+ return const_cast<PSTR>(pchEnd);
+}
+
+/*************************************************************************
+ * StrRStrW [SHELL32.392]
+ */
+EXTERN_C
+PWSTR WINAPI
+StrRStrW(
+ _In_ PCWSTR pszSrc,
+ _In_opt_ PCWSTR pszLast,
+ _In_ PCWSTR pszSearch)
+{
+ INT cchSearch = lstrlenW(pszSearch);
+
+ PCWSTR pchEnd = pszLast ? pszLast : &pszSrc[lstrlenW(pszSrc)];
+ if (pchEnd == pszSrc)
+ return NULL;
+
+ INT_PTR cchEnd = pchEnd - pszSrc;
+ for (;;)
+ {
+ --pchEnd;
+ --cchEnd;
+ if (!pchEnd)
+ break;
+ if (!StrCmpNW(pchEnd, pszSearch, cchSearch) && pchEnd == StrEndNW(pszSrc,
cchEnd))
+ break;
+ if (pchEnd == pszSrc)
+ return NULL;
+ }
+
+ return const_cast<PWSTR>(pchEnd);
+}
+
HWND
CStubWindow32::FindStubWindow(UINT Type, LPCWSTR Path)
{
diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt
b/modules/rostests/apitests/shell32/CMakeLists.txt
index aff71a65c90..cb6c11bcf8e 100644
--- a/modules/rostests/apitests/shell32/CMakeLists.txt
+++ b/modules/rostests/apitests/shell32/CMakeLists.txt
@@ -47,6 +47,7 @@ list(APPEND SOURCE
SHGetUserDisplayName.cpp
SHLimitInputEdit.cpp
SHSetUnreadMailCountW.cpp
+ StrRStr.cpp
menu.cpp
shelltest.cpp)
diff --git a/modules/rostests/apitests/shell32/StrRStr.cpp
b/modules/rostests/apitests/shell32/StrRStr.cpp
new file mode 100644
index 00000000000..a78181f791f
--- /dev/null
+++ b/modules/rostests/apitests/shell32/StrRStr.cpp
@@ -0,0 +1,97 @@
+/*
+ * PROJECT: ReactOS API tests
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Test for StrRStrA/W
+ * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
+ */
+
+#include "shelltest.h"
+#include <versionhelpers.h>
+
+typedef PSTR (WINAPI *FN_StrRStrA)(PCSTR, PCSTR, PCSTR pszSearch);
+typedef PWSTR (WINAPI *FN_StrRStrW)(PCWSTR, PCWSTR, PCWSTR pszSearch);
+
+static VOID TEST_StrRStrA(VOID)
+{
+ PCSTR psz, pch;
+ PSTR ret;
+ FN_StrRStrA StrRStrA =
(FN_StrRStrA)GetProcAddress(GetModuleHandleW(L"shell32"),
MAKEINTRESOURCEA(389));
+
+ if (!StrRStrA)
+ {
+ skip("StrRStrA not found\n");
+ return;
+ }
+
+ psz = "ABCBC";
+ ret = StrRStrA(psz, NULL, "BC");
+ ok_ptr(ret, psz + 3);
+
+ psz = "ABCBC";
+ pch = &psz[2];
+ ret = StrRStrA(psz, pch, "BC");
+ ok_ptr(ret, &psz[1]);
+
+ psz = "ABCBC";
+ ret = StrRStrA(psz, psz, "BC");
+ ok(!ret, "ret was '%s'\n", ret);
+
+ psz = "ABCBC";
+ pch = &psz[lstrlenA(psz)];
+ ret = StrRStrA(psz, pch, "BC");
+ ok_ptr(ret, psz + 3);
+}
+
+static VOID TEST_StrRStrW(VOID)
+{
+ PCWSTR psz, pch;
+ PWSTR ret;
+ FN_StrRStrW StrRStrW =
(FN_StrRStrW)GetProcAddress(GetModuleHandleW(L"shell32"),
MAKEINTRESOURCEA(392));
+
+ if (!StrRStrW)
+ {
+ skip("StrRStrW not found\n");
+ return;
+ }
+
+ psz = L"ABCBC";
+ ret = StrRStrW(psz, NULL, L"BC");
+ ok_ptr(ret, psz + 3);
+
+ psz = L"ABCBC";
+ pch = &psz[2];
+ ret = StrRStrW(psz, pch, L"BC");
+ ok_ptr(ret, &psz[1]);
+
+ psz = L"ABCBC";
+ ret = StrRStrW(psz, psz, L"BC");
+ ok(!ret, "ret was '%S'\n", ret);
+
+ psz = L"ABCBC";
+ pch = &psz[lstrlenW(psz)];
+ ret = StrRStrW(psz, pch, L"BC");
+ ok_ptr(ret, psz + 3);
+}
+
+static BOOL IsWindowsServer2003SP2OrGreater(VOID)
+{
+ return IsWindowsVersionOrGreater(5, 2, 2);
+}
+
+START_TEST(StrRStr)
+{
+ if (IsWindowsVistaOrGreater())
+ {
+ skip("Vista+\n");
+ return;
+ }
+
+ if (!IsWindowsServer2003SP2OrGreater())
+ {
+ skip("Before 2K3 SP3\n");
+ return;
+ }
+
+ TEST_StrRStrA();
+ TEST_StrRStrW();
+}
diff --git a/modules/rostests/apitests/shell32/testlist.c
b/modules/rostests/apitests/shell32/testlist.c
index daa699a8e32..fc879889ebe 100644
--- a/modules/rostests/apitests/shell32/testlist.c
+++ b/modules/rostests/apitests/shell32/testlist.c
@@ -51,6 +51,7 @@ extern void func_SHShouldShowWizards(void);
extern void func_SHSimpleIDListFromPath(void);
extern void func_SHRestricted(void);
extern void func_SHSetUnreadMailCountW(void);
+extern void func_StrRStr(void);
const struct test winetest_testlist[] =
{
@@ -102,6 +103,7 @@ const struct test winetest_testlist[] =
{ "SHSimpleIDListFromPath", func_SHSimpleIDListFromPath },
{ "SHRestricted", func_SHRestricted },
{ "SHSetUnreadMailCountW", func_SHSetUnreadMailCountW },
+ { "StrRStr", func_StrRStr },
{ 0, 0 }
};
diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h
index beb840c89e2..797979334ee 100644
--- a/sdk/include/reactos/undocshell.h
+++ b/sdk/include/reactos/undocshell.h
@@ -794,6 +794,18 @@ BOOL WINAPI GUIDFromStringW(
_In_ PCWSTR psz,
_Out_ LPGUID pguid);
+PSTR WINAPI
+StrRStrA(
+ _In_ PCSTR pszSrc,
+ _In_opt_ PCSTR pszLast,
+ _In_ PCSTR pszSearch);
+
+PWSTR WINAPI
+StrRStrW(
+ _In_ PCWSTR pszSrc,
+ _In_opt_ PCWSTR pszLast,
+ _In_ PCWSTR pszSearch);
+
LPSTR WINAPI SheRemoveQuotesA(LPSTR psz);
LPWSTR WINAPI SheRemoveQuotesW(LPWSTR psz);