https://git.reactos.org/?p=reactos.git;a=commitdiff;h=99b52df014e004531ab63…
commit 99b52df014e004531ab6389284e087b9bb8837cf
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu May 28 10:58:26 2020 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu May 28 10:58:26 2020 +0900
[SHELL32][INCLUDE] Improve CheckEscapesA/W (#2795)
Fix and improve shell32!CheckEscapesA/W functions.
Add a testcase for shell32!CheckEscapesA/W to shell32_apitest.
---
dll/win32/shell32/wine/shellstring.c | 38 ++---
modules/rostests/apitests/shell32/CMakeLists.txt | 1 +
modules/rostests/apitests/shell32/CheckEscapes.cpp | 177 +++++++++++++++++++++
modules/rostests/apitests/shell32/testlist.c | 2 +
sdk/include/reactos/undocshell.h | 4 +-
5 files changed, 198 insertions(+), 24 deletions(-)
diff --git a/dll/win32/shell32/wine/shellstring.c b/dll/win32/shell32/wine/shellstring.c
index 8bccd1c1563..8796f3813c3 100644
--- a/dll/win32/shell32/wine/shellstring.c
+++ b/dll/win32/shell32/wine/shellstring.c
@@ -30,6 +30,7 @@
#include "shell32_main.h"
#include "undocshell.h"
+#include "shlwapi_undoc.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -222,30 +223,25 @@ BOOL WINAPI OleStrToStrNAW (LPVOID lpOut, INT nOut, LPCVOID lpIn,
INT nIn)
* PARAMS
* string [I/O] string to check and on return eventually quoted
* len [I] length of string
- *
- * RETURNS
- * length of actual string
- *
- * NOTES
- * Not really sure if this function returns actually a value at all.
*/
-DWORD WINAPI CheckEscapesA(
+VOID WINAPI CheckEscapesA(
LPSTR string, /* [I/O] string to check ??*/
DWORD len) /* [I] is 0 */
{
- LPWSTR wString;
- DWORD ret = 0;
+ LPWSTR wString;
+ TRACE("(%s %d)\n", debugstr_a(string), len);
- TRACE("(%s %d)\n", debugstr_a(string), len);
- wString = LocalAlloc(LPTR, len * sizeof(WCHAR));
- if (wString)
- {
- MultiByteToWideChar(CP_ACP, 0, string, len, wString, len);
- ret = CheckEscapesW(wString, len);
- WideCharToMultiByte(CP_ACP, 0, wString, len, string, len, NULL, NULL);
- LocalFree(wString);
- }
- return ret;
+ if (!string || !string[0])
+ return;
+
+ wString = LocalAlloc(LPTR, len * sizeof(WCHAR));
+ if (!wString)
+ return;
+
+ SHAnsiToUnicode(string, wString, len);
+ CheckEscapesW(wString, len);
+ SHUnicodeToAnsi(wString, string, len);
+ LocalFree(wString);
}
static const WCHAR strEscapedChars[] = {'
','"',',',';','^',0};
@@ -255,7 +251,7 @@ static const WCHAR strEscapedChars[] = {'
','"',',',';','^',0};
*
* See CheckEscapesA.
*/
-DWORD WINAPI CheckEscapesW(
+VOID WINAPI CheckEscapesW(
LPWSTR string,
DWORD len)
{
@@ -273,7 +269,5 @@ DWORD WINAPI CheckEscapesW(
for (;d > string;)
*d-- = *s--;
*d = '"';
- return size + 2;
}
- return size;
}
diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt
b/modules/rostests/apitests/shell32/CMakeLists.txt
index 3425c187d73..9bff4a9c09a 100644
--- a/modules/rostests/apitests/shell32/CMakeLists.txt
+++ b/modules/rostests/apitests/shell32/CMakeLists.txt
@@ -11,6 +11,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl)
list(APPEND SOURCE
AddCommas.cpp
CFSFolder.cpp
+ CheckEscapes.cpp
CIDLData.cpp
CMyComputer.cpp
CShellDesktop.cpp
diff --git a/modules/rostests/apitests/shell32/CheckEscapes.cpp
b/modules/rostests/apitests/shell32/CheckEscapes.cpp
new file mode 100644
index 00000000000..095dbaf766d
--- /dev/null
+++ b/modules/rostests/apitests/shell32/CheckEscapes.cpp
@@ -0,0 +1,177 @@
+/*
+ * PROJECT: ReactOS API tests
+ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE: Test for CheckEscapesA/W
+ * PROGRAMMER: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
+ */
+#include "shelltest.h"
+
+typedef void (WINAPI *FN_CheckEscapesA)(LPSTR string, DWORD len);
+typedef void (WINAPI *FN_CheckEscapesW)(LPWSTR string, DWORD len);
+
+static FN_CheckEscapesA s_pCheckEscapesA;
+static FN_CheckEscapesW s_pCheckEscapesW;
+
+typedef struct TESTENTRYA
+{
+ INT lineno;
+ LPCSTR input;
+ DWORD len;
+ LPCSTR output;
+} TESTENTRYA;
+
+typedef struct TESTENTRYW
+{
+ INT lineno;
+ LPCWSTR input;
+ DWORD len;
+ LPCWSTR output;
+} TESTENTRYW;
+
+static const TESTENTRYA s_entriesA[] =
+{
+ { __LINE__, "", 0, "" },
+ { __LINE__, "", 1, "" },
+ { __LINE__, "", 2, "" },
+ { __LINE__, "", 3, "" },
+ { __LINE__, "", 4, "" },
+ { __LINE__, "", 5, "" },
+ { __LINE__, "", 6, "" },
+ { __LINE__, "ABC", 1, "" },
+ { __LINE__, "ABC", 2, "A" },
+ { __LINE__, "ABC", 3, "AB" },
+ { __LINE__, "ABC", 4, "ABC" },
+ { __LINE__, "ABC", 5, "ABC" },
+ { __LINE__, "ABC", 6, "ABC" },
+ { __LINE__, "AB C", 1, "" },
+ { __LINE__, "AB C", 2, "A" },
+ { __LINE__, "AB C", 3, "AB" },
+ { __LINE__, "AB C", 4, "AB " },
+ { __LINE__, "AB C", 5, "AB C" },
+ { __LINE__, "AB C", 6, "\"AB C" },
+ { __LINE__, "AB C ", 1, "" },
+ { __LINE__, "AB C ", 2, "A" },
+ { __LINE__, "AB C ", 3, "AB" },
+ { __LINE__, "AB C ", 4, "AB " },
+ { __LINE__, "AB C ", 5, "AB C" },
+ { __LINE__, "AB C ", 6, "AB C " },
+ { __LINE__, "AB,", 1, "" },
+ { __LINE__, "AB,", 2, "A" },
+ { __LINE__, "AB,", 3, "AB" },
+ { __LINE__, "AB,", 4, "AB," },
+ { __LINE__, "AB,", 5, "\"AB," },
+ { __LINE__, "AB,", 6, "\"AB,\"" },
+ { __LINE__, "AB\"", 1, "" },
+ { __LINE__, "AB\"", 2, "A" },
+ { __LINE__, "AB\"", 3, "AB" },
+ { __LINE__, "AB\"", 4, "AB\"" },
+ { __LINE__, "AB\"", 5, "\"AB\"" },
+ { __LINE__, "AB\"", 6, "\"AB\"\"" },
+ { __LINE__, "AB;", 1, "" },
+ { __LINE__, "AB;", 2, "A" },
+ { __LINE__, "AB;", 3, "AB" },
+ { __LINE__, "AB;", 4, "AB;" },
+ { __LINE__, "AB;", 5, "\"AB;" },
+ { __LINE__, "AB;", 6, "\"AB;\"" },
+ { __LINE__, "AB^", 1, "" },
+ { __LINE__, "AB^", 2, "A" },
+ { __LINE__, "AB^", 3, "AB" },
+ { __LINE__, "AB^", 4, "AB^" },
+ { __LINE__, "AB^", 5, "\"AB^" },
+ { __LINE__, "AB^", 6, "\"AB^\"" },
+};
+
+static const TESTENTRYW s_entriesW[] =
+{
+ { __LINE__, L"", 0, L"" },
+ { __LINE__, L"", 1, L"" },
+ { __LINE__, L"", 2, L"" },
+ { __LINE__, L"", 3, L"" },
+ { __LINE__, L"", 4, L"" },
+ { __LINE__, L"", 5, L"" },
+ { __LINE__, L"", 6, L"" },
+ { __LINE__, L"ABC", 1, L"ABC" },
+ { __LINE__, L"ABC", 2, L"ABC" },
+ { __LINE__, L"ABC", 3, L"ABC" },
+ { __LINE__, L"ABC", 4, L"ABC" },
+ { __LINE__, L"ABC", 5, L"ABC" },
+ { __LINE__, L"ABC", 6, L"ABC" },
+ { __LINE__, L"AB C", 1, L"AB C" },
+ { __LINE__, L"AB C", 2, L"AB C" },
+ { __LINE__, L"AB C", 3, L"AB C" },
+ { __LINE__, L"AB C", 4, L"AB C" },
+ { __LINE__, L"AB C", 5, L"AB C" },
+ { __LINE__, L"AB C", 6, L"\"AB C\"" },
+ { __LINE__, L"AB C ", 1, L"AB C " },
+ { __LINE__, L"AB C ", 2, L"AB C " },
+ { __LINE__, L"AB C ", 3, L"AB C " },
+ { __LINE__, L"AB C ", 4, L"AB C " },
+ { __LINE__, L"AB C ", 5, L"AB C " },
+ { __LINE__, L"AB C ", 6, L"AB C " },
+ { __LINE__, L"AB,", 1, L"AB," },
+ { __LINE__, L"AB,", 2, L"AB," },
+ { __LINE__, L"AB,", 3, L"AB," },
+ { __LINE__, L"AB,", 4, L"AB," },
+ { __LINE__, L"AB,", 5, L"\"AB,\"" },
+ { __LINE__, L"AB,", 6, L"\"AB,\"" },
+ { __LINE__, L"AB\"", 1, L"AB\"" },
+ { __LINE__, L"AB\"", 2, L"AB\"" },
+ { __LINE__, L"AB\"", 3, L"AB\"" },
+ { __LINE__, L"AB\"", 4, L"AB\"" },
+ { __LINE__, L"AB\"", 5, L"\"AB\"\"" },
+ { __LINE__, L"AB\"", 6, L"\"AB\"\"" },
+ { __LINE__, L"AB;", 1, L"AB;" },
+ { __LINE__, L"AB;", 2, L"AB;" },
+ { __LINE__, L"AB;", 3, L"AB;" },
+ { __LINE__, L"AB;", 4, L"AB;" },
+ { __LINE__, L"AB;", 5, L"\"AB;\"" },
+ { __LINE__, L"AB;", 6, L"\"AB;\"" },
+ { __LINE__, L"AB^", 1, L"AB^" },
+ { __LINE__, L"AB^", 2, L"AB^" },
+ { __LINE__, L"AB^", 3, L"AB^" },
+ { __LINE__, L"AB^", 4, L"AB^" },
+ { __LINE__, L"AB^", 5, L"\"AB^\"" },
+ { __LINE__, L"AB^", 6, L"\"AB^\"" },
+};
+
+static void JustDoIt(void)
+{
+ SIZE_T i, count;
+ CHAR bufA[MAX_PATH];
+ WCHAR bufW[MAX_PATH];
+
+ count = _countof(s_entriesA);
+ for (i = 0; i < count; ++i)
+ {
+ lstrcpynA(bufA, s_entriesA[i].input, _countof(bufA));
+ s_pCheckEscapesA(bufA, s_entriesA[i].len);
+ ok(lstrcmpA(bufA, s_entriesA[i].output) == 0,
+ "Line %d: output expected '%s' vs got '%s'\n",
+ s_entriesA[i].lineno, s_entriesA[i].output, bufA);
+ }
+
+ count = _countof(s_entriesW);
+ for (i = 0; i < count; ++i)
+ {
+ lstrcpynW(bufW, s_entriesW[i].input, _countof(bufW));
+ s_pCheckEscapesW(bufW, s_entriesW[i].len);
+ ok(lstrcmpW(bufW, s_entriesW[i].output) == 0,
+ "Line %d: output expected '%ls' vs got '%ls'\n",
+ s_entriesW[i].lineno, s_entriesW[i].output, bufW);
+ }
+}
+
+START_TEST(CheckEscapes)
+{
+ HINSTANCE hShell32 = GetModuleHandleA("shell32");
+ s_pCheckEscapesA = (FN_CheckEscapesA)GetProcAddress(hShell32,
"CheckEscapesA");
+ s_pCheckEscapesW = (FN_CheckEscapesW)GetProcAddress(hShell32,
"CheckEscapesW");
+ if (s_pCheckEscapesA && s_pCheckEscapesW)
+ {
+ JustDoIt();
+ }
+ else
+ {
+ skip("There is no CheckEscapesA/W\n");
+ }
+}
diff --git a/modules/rostests/apitests/shell32/testlist.c
b/modules/rostests/apitests/shell32/testlist.c
index ba56769a97a..74c90e013c6 100644
--- a/modules/rostests/apitests/shell32/testlist.c
+++ b/modules/rostests/apitests/shell32/testlist.c
@@ -6,6 +6,7 @@
extern void func_AddCommas(void);
extern void func_Control_RunDLLW(void);
extern void func_CFSFolder(void);
+extern void func_CheckEscapes(void);
extern void func_CIDLData(void);
extern void func_CMyComputer(void);
extern void func_CShellDesktop(void);
@@ -33,6 +34,7 @@ const struct test winetest_testlist[] =
{ "AddCommas", func_AddCommas },
{ "Control_RunDLLW", func_Control_RunDLLW },
{ "CFSFolder", func_CFSFolder },
+ { "CheckEscapes", func_CheckEscapes },
{ "CIDLData", func_CIDLData },
{ "CMyComputer", func_CMyComputer },
{ "CShellDesktop", func_CShellDesktop },
diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h
index 3b7c5d6463c..4e55a38e274 100644
--- a/sdk/include/reactos/undocshell.h
+++ b/sdk/include/reactos/undocshell.h
@@ -611,8 +611,8 @@ HRESULT WINAPI SHCreateLinks(
UINT uFlags,
LPITEMIDLIST *lppidlLinks);
-DWORD WINAPI CheckEscapesA(LPSTR string, DWORD len);
-DWORD WINAPI CheckEscapesW(LPWSTR string, DWORD len);
+VOID WINAPI CheckEscapesA(LPSTR string, DWORD len);
+VOID WINAPI CheckEscapesW(LPWSTR string, DWORD len);
/* policy functions */
BOOL WINAPI SHInitRestricted(LPCVOID unused, LPCVOID inpRegKey);