Skip to content

Commit 157e18b

Browse files
authored
[SHELL32][SHELL32_APITEST][SDK] Implement StrRStrA/W (reactos#7621)
Implementing missing features... JIRA issue: CORE-19278 - Move function definitions from stubs.cpp to utils.cpp. - Add prototypes to <undocshell.h>.
1 parent aa52c3f commit 157e18b

File tree

6 files changed

+194
-22
lines changed

6 files changed

+194
-22
lines changed

dll/win32/shell32/stubs.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -235,28 +235,6 @@ RealDriveTypeFlags(INT iDrive, BOOL bUnknown)
235235
return 1;
236236
}
237237

238-
/*
239-
* Unimplemented
240-
*/
241-
EXTERN_C LPWSTR
242-
WINAPI
243-
StrRStrW(LPWSTR lpSrc, LPWSTR lpLast, LPWSTR lpSearch)
244-
{
245-
FIXME("StrRStrW() stub\n");
246-
return NULL;
247-
}
248-
249-
/*
250-
* Unimplemented
251-
*/
252-
EXTERN_C LPWSTR
253-
WINAPI
254-
StrRStrA(LPSTR lpSrc, LPSTR lpLast, LPSTR lpSearch)
255-
{
256-
FIXME("StrRStrA() stub\n");
257-
return NULL;
258-
}
259-
260238
/*
261239
* Unimplemented
262240
*/

dll/win32/shell32/utils.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,88 @@
1313

1414
WINE_DEFAULT_DEBUG_CHANNEL(shell);
1515

16+
static PCSTR StrEndNA(_In_ PCSTR psz, _In_ INT_PTR cch)
17+
{
18+
PCSTR pch, pchEnd = &psz[cch];
19+
for (pch = psz; *pch && pch < pchEnd; pch = CharNextA(pch))
20+
;
21+
if (pchEnd < pch) // A double-byte character detected at last?
22+
pch -= 2; // The width of a double-byte character is 2
23+
return pch;
24+
}
25+
26+
static PCWSTR StrEndNW(_In_ PCWSTR psz, _In_ INT_PTR cch)
27+
{
28+
PCWSTR pch, pchEnd = &psz[cch];
29+
for (pch = psz; *pch && pch < pchEnd; ++pch)
30+
;
31+
return pch;
32+
}
33+
34+
/*************************************************************************
35+
* StrRStrA [SHELL32.389]
36+
*/
37+
EXTERN_C
38+
PSTR WINAPI
39+
StrRStrA(
40+
_In_ PCSTR pszSrc,
41+
_In_opt_ PCSTR pszLast,
42+
_In_ PCSTR pszSearch)
43+
{
44+
INT cchSearch = lstrlenA(pszSearch);
45+
46+
PCSTR pchEnd = pszLast ? pszLast : &pszSrc[lstrlenA(pszSrc)];
47+
if (pchEnd == pszSrc)
48+
return NULL;
49+
50+
INT_PTR cchEnd = pchEnd - pszSrc;
51+
for (;;)
52+
{
53+
--pchEnd;
54+
--cchEnd;
55+
if (!pchEnd)
56+
break;
57+
if (!StrCmpNA(pchEnd, pszSearch, cchSearch) && pchEnd == StrEndNA(pszSrc, cchEnd))
58+
break;
59+
if (pchEnd == pszSrc)
60+
return NULL;
61+
}
62+
63+
return const_cast<PSTR>(pchEnd);
64+
}
65+
66+
/*************************************************************************
67+
* StrRStrW [SHELL32.392]
68+
*/
69+
EXTERN_C
70+
PWSTR WINAPI
71+
StrRStrW(
72+
_In_ PCWSTR pszSrc,
73+
_In_opt_ PCWSTR pszLast,
74+
_In_ PCWSTR pszSearch)
75+
{
76+
INT cchSearch = lstrlenW(pszSearch);
77+
78+
PCWSTR pchEnd = pszLast ? pszLast : &pszSrc[lstrlenW(pszSrc)];
79+
if (pchEnd == pszSrc)
80+
return NULL;
81+
82+
INT_PTR cchEnd = pchEnd - pszSrc;
83+
for (;;)
84+
{
85+
--pchEnd;
86+
--cchEnd;
87+
if (!pchEnd)
88+
break;
89+
if (!StrCmpNW(pchEnd, pszSearch, cchSearch) && pchEnd == StrEndNW(pszSrc, cchEnd))
90+
break;
91+
if (pchEnd == pszSrc)
92+
return NULL;
93+
}
94+
95+
return const_cast<PWSTR>(pchEnd);
96+
}
97+
1698
HWND
1799
CStubWindow32::FindStubWindow(UINT Type, LPCWSTR Path)
18100
{

modules/rostests/apitests/shell32/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ list(APPEND SOURCE
4747
SHGetUserDisplayName.cpp
4848
SHLimitInputEdit.cpp
4949
SHSetUnreadMailCountW.cpp
50+
StrRStr.cpp
5051
menu.cpp
5152
shelltest.cpp)
5253

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* PROJECT: ReactOS API tests
3+
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4+
* PURPOSE: Test for StrRStrA/W
5+
* COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ ([email protected])
6+
*/
7+
8+
#include "shelltest.h"
9+
#include <versionhelpers.h>
10+
11+
typedef PSTR (WINAPI *FN_StrRStrA)(PCSTR, PCSTR, PCSTR pszSearch);
12+
typedef PWSTR (WINAPI *FN_StrRStrW)(PCWSTR, PCWSTR, PCWSTR pszSearch);
13+
14+
static VOID TEST_StrRStrA(VOID)
15+
{
16+
PCSTR psz, pch;
17+
PSTR ret;
18+
FN_StrRStrA StrRStrA = (FN_StrRStrA)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(389));
19+
20+
if (!StrRStrA)
21+
{
22+
skip("StrRStrA not found\n");
23+
return;
24+
}
25+
26+
psz = "ABCBC";
27+
ret = StrRStrA(psz, NULL, "BC");
28+
ok_ptr(ret, psz + 3);
29+
30+
psz = "ABCBC";
31+
pch = &psz[2];
32+
ret = StrRStrA(psz, pch, "BC");
33+
ok_ptr(ret, &psz[1]);
34+
35+
psz = "ABCBC";
36+
ret = StrRStrA(psz, psz, "BC");
37+
ok(!ret, "ret was '%s'\n", ret);
38+
39+
psz = "ABCBC";
40+
pch = &psz[lstrlenA(psz)];
41+
ret = StrRStrA(psz, pch, "BC");
42+
ok_ptr(ret, psz + 3);
43+
}
44+
45+
static VOID TEST_StrRStrW(VOID)
46+
{
47+
PCWSTR psz, pch;
48+
PWSTR ret;
49+
FN_StrRStrW StrRStrW = (FN_StrRStrW)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(392));
50+
51+
if (!StrRStrW)
52+
{
53+
skip("StrRStrW not found\n");
54+
return;
55+
}
56+
57+
psz = L"ABCBC";
58+
ret = StrRStrW(psz, NULL, L"BC");
59+
ok_ptr(ret, psz + 3);
60+
61+
psz = L"ABCBC";
62+
pch = &psz[2];
63+
ret = StrRStrW(psz, pch, L"BC");
64+
ok_ptr(ret, &psz[1]);
65+
66+
psz = L"ABCBC";
67+
ret = StrRStrW(psz, psz, L"BC");
68+
ok(!ret, "ret was '%S'\n", ret);
69+
70+
psz = L"ABCBC";
71+
pch = &psz[lstrlenW(psz)];
72+
ret = StrRStrW(psz, pch, L"BC");
73+
ok_ptr(ret, psz + 3);
74+
}
75+
76+
static BOOL IsWindowsServer2003SP2OrGreater(VOID)
77+
{
78+
return IsWindowsVersionOrGreater(5, 2, 2);
79+
}
80+
81+
START_TEST(StrRStr)
82+
{
83+
if (IsWindowsVistaOrGreater())
84+
{
85+
skip("Vista+\n");
86+
return;
87+
}
88+
89+
if (!IsWindowsServer2003SP2OrGreater())
90+
{
91+
skip("Before 2K3 SP3\n");
92+
return;
93+
}
94+
95+
TEST_StrRStrA();
96+
TEST_StrRStrW();
97+
}

modules/rostests/apitests/shell32/testlist.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ extern void func_SHShouldShowWizards(void);
5151
extern void func_SHSimpleIDListFromPath(void);
5252
extern void func_SHRestricted(void);
5353
extern void func_SHSetUnreadMailCountW(void);
54+
extern void func_StrRStr(void);
5455

5556
const struct test winetest_testlist[] =
5657
{
@@ -102,6 +103,7 @@ const struct test winetest_testlist[] =
102103
{ "SHSimpleIDListFromPath", func_SHSimpleIDListFromPath },
103104
{ "SHRestricted", func_SHRestricted },
104105
{ "SHSetUnreadMailCountW", func_SHSetUnreadMailCountW },
106+
{ "StrRStr", func_StrRStr },
105107

106108
{ 0, 0 }
107109
};

sdk/include/reactos/undocshell.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,18 @@ BOOL WINAPI GUIDFromStringW(
794794
_In_ PCWSTR psz,
795795
_Out_ LPGUID pguid);
796796

797+
PSTR WINAPI
798+
StrRStrA(
799+
_In_ PCSTR pszSrc,
800+
_In_opt_ PCSTR pszLast,
801+
_In_ PCSTR pszSearch);
802+
803+
PWSTR WINAPI
804+
StrRStrW(
805+
_In_ PCWSTR pszSrc,
806+
_In_opt_ PCWSTR pszLast,
807+
_In_ PCWSTR pszSearch);
808+
797809
LPSTR WINAPI SheRemoveQuotesA(LPSTR psz);
798810
LPWSTR WINAPI SheRemoveQuotesW(LPWSTR psz);
799811

0 commit comments

Comments
 (0)