https://git.reactos.org/?p=reactos.git;a=commitdiff;h=157e18b215ce0f5334c4f2ca895447a28d650d16

commit 157e18b215ce0f5334c4f2ca895447a28d650d16
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Mon Jan 20 08:50:26 2025 +0900
Commit:     GitHub <nore...@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...@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);
 

Reply via email to