https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fccea84dd4d4fd5fdee15…
commit fccea84dd4d4fd5fdee15f083365fd51aa68dd34
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Jun 6 06:51:42 2021 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Jun 6 06:51:42 2021 +0900
[SHELL32_APITEST] Add FindExecutable testcase (#3723)
Investigate the implementation of shell32!FindExecutable function.
CORE-17351, CORE-16898, CORE-17612
---
modules/rostests/apitests/shell32/CMakeLists.txt | 13 +-
.../rostests/apitests/shell32/FindExecutable.cpp | 232 +++++++++++++++++++++
.../rostests/apitests/shell32/SHChangeNotify.cpp | 8 +-
.../{shell-notify.cpp => shell32_apitest_sub.cpp} | 3 +
modules/rostests/apitests/shell32/testlist.c | 2 +
5 files changed, 248 insertions(+), 10 deletions(-)
diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt
b/modules/rostests/apitests/shell32/CMakeLists.txt
index 81b40767113..990e1463d48 100644
--- a/modules/rostests/apitests/shell32/CMakeLists.txt
+++ b/modules/rostests/apitests/shell32/CMakeLists.txt
@@ -13,6 +13,7 @@ list(APPEND SOURCE
Control_RunDLLW.cpp
DragDrop.cpp
ExtractIconEx.cpp
+ FindExecutable.cpp
IShellFolderViewCB.cpp
OpenAs_RunDLL.cpp
PathResolve.cpp
@@ -45,9 +46,9 @@ add_importlibs(shell32_apitest user32 gdi32 shell32 ole32 oleaut32
advapi32 shlw
add_pch(shell32_apitest shelltest.h "${PCH_SKIP_SOURCE}")
add_rostests_file(TARGET shell32_apitest)
-# shell-notify.exe
-add_executable(shell-notify shell-notify.cpp)
-target_link_libraries(shell-notify cpprt atl_classes)
-set_module_type(shell-notify win32gui UNICODE)
-add_importlibs(shell-notify msvcrt kernel32 user32 shell32 shlwapi ole32)
-add_rostests_file(TARGET shell-notify SUBDIR testdata)
+# shell32_apitest_sub.exe
+add_executable(shell32_apitest_sub shell32_apitest_sub.cpp)
+target_link_libraries(shell32_apitest_sub cpprt atl_classes)
+set_module_type(shell32_apitest_sub win32gui UNICODE)
+add_importlibs(shell32_apitest_sub msvcrt kernel32 user32 shell32 shlwapi ole32)
+add_rostests_file(TARGET shell32_apitest_sub SUBDIR testdata)
diff --git a/modules/rostests/apitests/shell32/FindExecutable.cpp
b/modules/rostests/apitests/shell32/FindExecutable.cpp
new file mode 100644
index 00000000000..2e18974dac4
--- /dev/null
+++ b/modules/rostests/apitests/shell32/FindExecutable.cpp
@@ -0,0 +1,232 @@
+/*
+ * PROJECT: ReactOS api tests
+ * LICENSE: LGPL-2.0-or-later (
https://spdx.org/licenses/LGPL-2.0-or-later)
+ * PURPOSE: Test for FindExecutable
+ * COPYRIGHT: Copyright 2021 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
+ */
+
+#include "shelltest.h"
+#include <stdio.h>
+#include <shlwapi.h>
+
+static char s_sub_program[MAX_PATH];
+
+static BOOL
+GetSubProgramPath(void)
+{
+ GetModuleFileNameA(NULL, s_sub_program, _countof(s_sub_program));
+ PathRemoveFileSpecA(s_sub_program);
+ PathAppendA(s_sub_program, "shell32_apitest_sub.exe");
+
+ if (!PathFileExistsA(s_sub_program))
+ {
+ PathRemoveFileSpecA(s_sub_program);
+ PathAppendA(s_sub_program, "testdata\\shell32_apitest_sub.exe");
+
+ if (!PathFileExistsA(s_sub_program))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+typedef struct TEST_ENTRY
+{
+ INT lineno;
+ BOOL ret;
+ LPCSTR file;
+ LPCSTR dir;
+ LPCSTR result;
+} TEST_ENTRY;
+
+static char s_win_dir[MAX_PATH];
+static char s_win_notepad[MAX_PATH];
+static char s_sys_notepad[MAX_PATH];
+static char s_win_test_exe[MAX_PATH];
+static char s_sys_test_exe[MAX_PATH];
+static char s_win_bat_file[MAX_PATH];
+static char s_sys_bat_file[MAX_PATH];
+
+#define DIR_0 NULL
+#define DIR_1 "."
+#define DIR_2 ".."
+#define DIR_3 s_win_dir
+#define DIR_4 "(invalid)"
+
+static const TEST_ENTRY s_entries[] =
+{
+ { __LINE__, TRUE, "notepad", DIR_0, s_sys_notepad },
+ { __LINE__, TRUE, "notepad", DIR_1, s_sys_notepad },
+ { __LINE__, TRUE, "notepad", DIR_2, s_sys_notepad },
+ { __LINE__, TRUE, "notepad", DIR_3, s_win_notepad },
+ { __LINE__, TRUE, "notepad", DIR_4, s_sys_notepad },
+ { __LINE__, FALSE, " notepad", DIR_0, "" },
+ { __LINE__, FALSE, " notepad", DIR_1, "" },
+ { __LINE__, FALSE, " notepad", DIR_2, "" },
+ { __LINE__, FALSE, " notepad", DIR_3, "" },
+ { __LINE__, FALSE, " notepad", DIR_4, "" },
+ { __LINE__, FALSE, "notepad ", DIR_0, "" },
+ { __LINE__, FALSE, "notepad ", DIR_1, "" },
+ { __LINE__, FALSE, "notepad ", DIR_2, "" },
+ { __LINE__, FALSE, "notepad ", DIR_3, "" },
+ { __LINE__, FALSE, "notepad ", DIR_4, "" },
+ { __LINE__, TRUE, "\"notepad\"", DIR_0, s_sys_notepad },
+ { __LINE__, TRUE, "\"notepad\"", DIR_1, s_sys_notepad },
+ { __LINE__, TRUE, "\"notepad\"", DIR_2, s_sys_notepad },
+ { __LINE__, TRUE, "\"notepad\"", DIR_3, s_win_notepad },
+ { __LINE__, TRUE, "\"notepad\"", DIR_4, s_sys_notepad },
+ { __LINE__, TRUE, "notepad.exe", DIR_0, s_sys_notepad },
+ { __LINE__, TRUE, "notepad.exe", DIR_1, s_sys_notepad },
+ { __LINE__, TRUE, "notepad.exe", DIR_2, s_sys_notepad },
+ { __LINE__, TRUE, "notepad.exe", DIR_3, s_win_notepad },
+ { __LINE__, TRUE, "notepad.exe", DIR_4, s_sys_notepad },
+ { __LINE__, FALSE, "notepad.bat", DIR_0, "" },
+ { __LINE__, FALSE, "notepad.bat", DIR_1, "" },
+ { __LINE__, FALSE, "notepad.bat", DIR_2, "" },
+ { __LINE__, FALSE, "notepad.bat", DIR_3, "" },
+ { __LINE__, FALSE, "notepad.bat", DIR_4, "" },
+ { __LINE__, FALSE, "C:\\notepad.exe", DIR_0, "" },
+ { __LINE__, FALSE, "C:\\notepad.exe", DIR_1, "" },
+ { __LINE__, FALSE, "C:\\notepad.exe", DIR_2, "" },
+ { __LINE__, FALSE, "C:\\notepad.exe", DIR_3, "" },
+ { __LINE__, FALSE, "C:\\notepad.exe", DIR_4, "" },
+ { __LINE__, FALSE, "..\\notepad.exe", DIR_0, "" },
+ { __LINE__, FALSE, "..\\notepad.exe", DIR_1, "" },
+ { __LINE__, FALSE, "..\\notepad.exe", DIR_2, "" },
+ { __LINE__, FALSE, "..\\notepad.exe", DIR_3, "" },
+ { __LINE__, FALSE, "..\\notepad.exe", DIR_4, "" },
+ { __LINE__, TRUE, "test program", DIR_0, s_sys_test_exe },
+ { __LINE__, TRUE, "test program", DIR_1, s_sys_test_exe },
+ { __LINE__, TRUE, "test program", DIR_2, s_sys_test_exe },
+ { __LINE__, TRUE, "test program", DIR_3, s_win_test_exe },
+ { __LINE__, TRUE, "test program", DIR_4, s_sys_test_exe },
+ { __LINE__, FALSE, " test program", DIR_0, "" },
+ { __LINE__, FALSE, " test program", DIR_1, "" },
+ { __LINE__, FALSE, " test program", DIR_2, "" },
+ { __LINE__, FALSE, " test program", DIR_3, "" },
+ { __LINE__, FALSE, " test program", DIR_4, "" },
+ { __LINE__, FALSE, "test program ", DIR_0, "" },
+ { __LINE__, FALSE, "test program ", DIR_1, "" },
+ { __LINE__, FALSE, "test program ", DIR_2, "" },
+ { __LINE__, FALSE, "test program ", DIR_3, "" },
+ { __LINE__, FALSE, "test program ", DIR_4, "" },
+ { __LINE__, TRUE, "\"test program\"", DIR_0, s_sys_test_exe },
+ { __LINE__, TRUE, "\"test program\"", DIR_1, s_sys_test_exe },
+ { __LINE__, TRUE, "\"test program\"", DIR_2, s_sys_test_exe },
+ { __LINE__, TRUE, "\"test program\"", DIR_3, s_win_test_exe },
+ { __LINE__, TRUE, "\"test program\"", DIR_4, s_sys_test_exe },
+ { __LINE__, TRUE, "test program.exe", DIR_0, s_sys_test_exe },
+ { __LINE__, TRUE, "test program.exe", DIR_1, s_sys_test_exe },
+ { __LINE__, TRUE, "test program.exe", DIR_2, s_sys_test_exe },
+ { __LINE__, TRUE, "test program.exe", DIR_3, s_win_test_exe },
+ { __LINE__, TRUE, "test program.exe", DIR_4, s_sys_test_exe },
+ { __LINE__, TRUE, "\"test program.exe\"", DIR_0, s_sys_test_exe
},
+ { __LINE__, TRUE, "\"test program.exe\"", DIR_1, s_sys_test_exe
},
+ { __LINE__, TRUE, "\"test program.exe\"", DIR_2, s_sys_test_exe
},
+ { __LINE__, TRUE, "\"test program.exe\"", DIR_3, s_win_test_exe
},
+ { __LINE__, TRUE, "\"test program.exe\"", DIR_4, s_sys_test_exe
},
+ { __LINE__, FALSE, "\"test program.exe \"", DIR_0, ""
},
+ { __LINE__, FALSE, "\"test program.exe \"", DIR_1, ""
},
+ { __LINE__, FALSE, "\"test program.exe \"", DIR_2, ""
},
+ { __LINE__, FALSE, "\"test program.exe \"", DIR_3, ""
},
+ { __LINE__, FALSE, "\"test program.exe \"", DIR_4, ""
},
+ { __LINE__, FALSE, "\" test program.exe\"", DIR_0, ""
},
+ { __LINE__, FALSE, "\" test program.exe\"", DIR_1, ""
},
+ { __LINE__, FALSE, "\" test program.exe\"", DIR_2, ""
},
+ { __LINE__, FALSE, "\" test program.exe\"", DIR_3, ""
},
+ { __LINE__, FALSE, "\" test program.exe\"", DIR_4, ""
},
+ { __LINE__, TRUE, "test program.bat", DIR_0, s_sys_bat_file },
+ { __LINE__, TRUE, "test program.bat", DIR_1, s_sys_bat_file },
+ { __LINE__, TRUE, "test program.bat", DIR_2, s_sys_bat_file },
+ { __LINE__, TRUE, "test program.bat", DIR_3, s_win_bat_file },
+ { __LINE__, TRUE, "test program.bat", DIR_4, s_sys_bat_file },
+ { __LINE__, FALSE, " test program.bat ", DIR_0, "" },
+ { __LINE__, FALSE, " test program.bat ", DIR_1, "" },
+ { __LINE__, FALSE, " test program.bat ", DIR_2, "" },
+ { __LINE__, FALSE, " test program.bat ", DIR_3, "" },
+ { __LINE__, FALSE, " test program.bat ", DIR_4, "" },
+ { __LINE__, TRUE, "\"test program.bat\"", DIR_0, s_sys_bat_file
},
+ { __LINE__, TRUE, "\"test program.bat\"", DIR_1, s_sys_bat_file
},
+ { __LINE__, TRUE, "\"test program.bat\"", DIR_2, s_sys_bat_file
},
+ { __LINE__, TRUE, "\"test program.bat\"", DIR_3, s_win_bat_file
},
+ { __LINE__, TRUE, "\"test program.bat\"", DIR_4, s_sys_bat_file
},
+ { __LINE__, TRUE, "shell32_apitest_sub.exe", DIR_0, s_sub_program },
+ { __LINE__, TRUE, "shell32_apitest_sub.exe", DIR_1,
"shell32_apitest_sub.exe" },
+ { __LINE__, FALSE, "shell32_apitest_sub.exe", DIR_2, "" },
+ { __LINE__, FALSE, "shell32_apitest_sub.exe", DIR_3, "" },
+ { __LINE__, FALSE, "shell32_apitest_sub.exe", DIR_4, "" },
+};
+
+static void DoTestEntry(const TEST_ENTRY *pEntry)
+{
+ char result[MAX_PATH];
+ result[0] = 0;
+ BOOL ret = ((INT_PTR)FindExecutableA(pEntry->file, pEntry->dir, result) >
32);
+ ok(ret == pEntry->ret, "Line %u: ret expected %d, got %d\n",
pEntry->lineno, pEntry->ret, ret);
+
+ GetLongPathNameA(result, result, _countof(result));
+
+ ok(lstrcmpiA(result, pEntry->result) == 0,
+ "Line %u: result expected '%s', got '%s'\n",
+ pEntry->lineno, pEntry->result, result);
+}
+
+START_TEST(FindExecutable)
+{
+ if (!GetSubProgramPath())
+ {
+ skip("shell32_apitest_sub.exe not found\n");
+ return;
+ }
+
+ char cur_dir[MAX_PATH];
+ GetCurrentDirectoryA(_countof(cur_dir), cur_dir);
+ if (PathIsRootA(cur_dir))
+ {
+ skip("Don't use this program at root directory\n");
+ return;
+ }
+
+ GetWindowsDirectoryA(s_win_dir, _countof(s_win_dir));
+
+ GetWindowsDirectoryA(s_win_notepad, _countof(s_win_notepad));
+ PathAppendA(s_win_notepad, "notepad.exe");
+
+ GetSystemDirectoryA(s_sys_notepad, _countof(s_sys_notepad));
+ PathAppendA(s_sys_notepad, "notepad.exe");
+
+ GetWindowsDirectoryA(s_win_test_exe, _countof(s_win_test_exe));
+ PathAppendA(s_win_test_exe, "test program.exe");
+ BOOL ret = CopyFileA(s_sub_program, s_win_test_exe, FALSE);
+ if (!ret)
+ {
+ skip("Please retry with admin rights\n");
+ return;
+ }
+
+ GetSystemDirectoryA(s_sys_test_exe, _countof(s_sys_test_exe));
+ PathAppendA(s_sys_test_exe, "test program.exe");
+ ok_int(CopyFileA(s_sub_program, s_sys_test_exe, FALSE), TRUE);
+
+ GetWindowsDirectoryA(s_win_bat_file, _countof(s_win_bat_file));
+ PathAppendA(s_win_bat_file, "test program.bat");
+ fclose(fopen(s_win_bat_file, "wb"));
+ ok_int(PathFileExistsA(s_win_bat_file), TRUE);
+
+ GetSystemDirectoryA(s_sys_bat_file, _countof(s_sys_bat_file));
+ PathAppendA(s_sys_bat_file, "test program.bat");
+ fclose(fopen(s_sys_bat_file, "wb"));
+ ok_int(PathFileExistsA(s_sys_bat_file), TRUE);
+
+ for (UINT iTest = 0; iTest < _countof(s_entries); ++iTest)
+ {
+ DoTestEntry(&s_entries[iTest]);
+ }
+
+ DeleteFileA(s_win_test_exe);
+ DeleteFileA(s_sys_test_exe);
+ DeleteFileA(s_win_bat_file);
+ DeleteFileA(s_sys_bat_file);
+}
diff --git a/modules/rostests/apitests/shell32/SHChangeNotify.cpp
b/modules/rostests/apitests/shell32/SHChangeNotify.cpp
index cd5b45c646c..377b9ce1cec 100644
--- a/modules/rostests/apitests/shell32/SHChangeNotify.cpp
+++ b/modules/rostests/apitests/shell32/SHChangeNotify.cpp
@@ -322,12 +322,12 @@ GetSubProgramPath(void)
{
GetModuleFileNameW(NULL, s_szSubProgram, _countof(s_szSubProgram));
PathRemoveFileSpecW(s_szSubProgram);
- PathAppendW(s_szSubProgram, L"shell-notify.exe");
+ PathAppendW(s_szSubProgram, L"shell32_apitest_sub.exe");
if (!PathFileExistsW(s_szSubProgram))
{
PathRemoveFileSpecW(s_szSubProgram);
- PathAppendW(s_szSubProgram, L"testdata\\shell-notify.exe");
+ PathAppendW(s_szSubProgram, L"testdata\\shell32_apitest_sub.exe");
if (!PathFileExistsW(s_szSubProgram))
{
@@ -356,7 +356,7 @@ JustDoIt(INT nMode)
HINSTANCE hinst = ShellExecuteW(NULL, NULL, s_szSubProgram, szParams, NULL,
SW_SHOWNORMAL);
if ((INT_PTR)hinst <= 32)
{
- skip("Unable to run shell-notify.exe.\n");
+ skip("Unable to run shell32_apitest_sub.exe.\n");
return;
}
@@ -421,7 +421,7 @@ START_TEST(SHChangeNotify)
{
if (!GetSubProgramPath())
{
- skip("shell-notify.exe not found\n");
+ skip("shell32_apitest_sub.exe not found\n");
}
JustDoIt(0);
diff --git a/modules/rostests/apitests/shell32/shell-notify.cpp
b/modules/rostests/apitests/shell32/shell32_apitest_sub.cpp
similarity index 99%
rename from modules/rostests/apitests/shell32/shell-notify.cpp
rename to modules/rostests/apitests/shell32/shell32_apitest_sub.cpp
index 367f43dc482..c0d3cc4d83e 100644
--- a/modules/rostests/apitests/shell32/shell-notify.cpp
+++ b/modules/rostests/apitests/shell32/shell32_apitest_sub.cpp
@@ -262,6 +262,9 @@ wWinMain(HINSTANCE hInstance,
LPWSTR lpCmdLine,
INT nCmdShow)
{
+ if (lstrcmpiW(lpCmdLine, L"") == 0)
+ return 0;
+
s_nMode = _wtoi(lpCmdLine);
WNDCLASSW wc;
diff --git a/modules/rostests/apitests/shell32/testlist.c
b/modules/rostests/apitests/shell32/testlist.c
index 9763afa4ea7..01219082ba3 100644
--- a/modules/rostests/apitests/shell32/testlist.c
+++ b/modules/rostests/apitests/shell32/testlist.c
@@ -14,6 +14,7 @@ extern void func_CShellLink(void);
extern void func_CUserNotification(void);
extern void func_DragDrop(void);
extern void func_ExtractIconEx(void);
+extern void func_FindExecutable(void);
extern void func_IShellFolderViewCB(void);
extern void func_menu(void);
extern void func_OpenAs_RunDLL(void);
@@ -43,6 +44,7 @@ const struct test winetest_testlist[] =
{ "CUserNotification", func_CUserNotification },
{ "DragDrop", func_DragDrop },
{ "ExtractIconEx", func_ExtractIconEx },
+ { "FindExecutable", func_FindExecutable },
{ "IShellFolderViewCB", func_IShellFolderViewCB },
{ "menu", func_menu },
{ "OpenAs_RunDLL", func_OpenAs_RunDLL },