[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>.
This commit is contained in:
Katayama Hirofumi MZ 2025-01-20 08:50:26 +09:00 committed by GitHub
parent aa52c3f5eb
commit 157e18b215
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 194 additions and 22 deletions

View file

@ -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
*/

View file

@ -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)
{

View file

@ -47,6 +47,7 @@ list(APPEND SOURCE
SHGetUserDisplayName.cpp
SHLimitInputEdit.cpp
SHSetUnreadMailCountW.cpp
StrRStr.cpp
menu.cpp
shelltest.cpp)

View file

@ -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@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();
}

View file

@ -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 }
};

View file

@ -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);