ReactOS  0.4.15-dev-3451-gf606fec
FindExecutable.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4  * PURPOSE: Test for FindExecutable
5  * COPYRIGHT: Copyright 2021 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6  */
7 
8 #include "shelltest.h"
9 #include <stdio.h>
10 #include <shlwapi.h>
11 
12 static char s_sub_program[MAX_PATH];
13 
14 static BOOL
16 {
19  PathAppendA(s_sub_program, "shell32_apitest_sub.exe");
20 
22  {
24  PathAppendA(s_sub_program, "testdata\\shell32_apitest_sub.exe");
25 
27  {
28  return FALSE;
29  }
30  }
31 
32  return TRUE;
33 }
34 
35 typedef struct TEST_ENTRY
36 {
37  INT lineno;
38  BOOL ret;
42 } TEST_ENTRY;
43 
44 static char s_win_dir[MAX_PATH];
45 static char s_win_notepad[MAX_PATH];
46 static char s_sys_notepad[MAX_PATH];
47 static char s_win_test_exe[MAX_PATH];
48 static char s_sys_test_exe[MAX_PATH];
49 static char s_win_bat_file[MAX_PATH];
50 static char s_sys_bat_file[MAX_PATH];
51 static char s_win_txt_file[MAX_PATH];
52 static char s_sys_txt_file[MAX_PATH];
53 
54 #define DIR_0 NULL
55 #define DIR_1 "."
56 #define DIR_2 ".."
57 #define DIR_3 s_win_dir
58 #define DIR_4 "(invalid)"
59 
60 static const TEST_ENTRY s_entries[] =
61 {
62  { __LINE__, TRUE, "notepad", DIR_0, s_sys_notepad },
63  { __LINE__, TRUE, "notepad", DIR_1, s_sys_notepad },
64  { __LINE__, TRUE, "notepad", DIR_2, s_sys_notepad },
65  { __LINE__, TRUE, "notepad", DIR_3, s_win_notepad },
66  { __LINE__, TRUE, "notepad", DIR_4, s_sys_notepad },
67  { __LINE__, FALSE, " notepad", DIR_0, "" },
68  { __LINE__, FALSE, " notepad", DIR_1, "" },
69  { __LINE__, FALSE, " notepad", DIR_2, "" },
70  { __LINE__, FALSE, " notepad", DIR_3, "" },
71  { __LINE__, FALSE, " notepad", DIR_4, "" },
72  { __LINE__, FALSE, "notepad ", DIR_0, "" },
73  { __LINE__, FALSE, "notepad ", DIR_1, "" },
74  { __LINE__, FALSE, "notepad ", DIR_2, "" },
75  { __LINE__, FALSE, "notepad ", DIR_3, "" },
76  { __LINE__, FALSE, "notepad ", DIR_4, "" },
77  { __LINE__, TRUE, "\"notepad\"", DIR_0, s_sys_notepad },
78  { __LINE__, TRUE, "\"notepad\"", DIR_1, s_sys_notepad },
79  { __LINE__, TRUE, "\"notepad\"", DIR_2, s_sys_notepad },
80  { __LINE__, TRUE, "\"notepad\"", DIR_3, s_win_notepad },
81  { __LINE__, TRUE, "\"notepad\"", DIR_4, s_sys_notepad },
82  { __LINE__, TRUE, "notepad.exe", DIR_0, s_sys_notepad },
83  { __LINE__, TRUE, "notepad.exe", DIR_1, s_sys_notepad },
84  { __LINE__, TRUE, "notepad.exe", DIR_2, s_sys_notepad },
85  { __LINE__, TRUE, "notepad.exe", DIR_3, s_win_notepad },
86  { __LINE__, TRUE, "notepad.exe", DIR_4, s_sys_notepad },
87  { __LINE__, FALSE, "notepad.bat", DIR_0, "" },
88  { __LINE__, FALSE, "notepad.bat", DIR_1, "" },
89  { __LINE__, FALSE, "notepad.bat", DIR_2, "" },
90  { __LINE__, FALSE, "notepad.bat", DIR_3, "" },
91  { __LINE__, FALSE, "notepad.bat", DIR_4, "" },
92  { __LINE__, FALSE, "C:\\notepad.exe", DIR_0, "" },
93  { __LINE__, FALSE, "C:\\notepad.exe", DIR_1, "" },
94  { __LINE__, FALSE, "C:\\notepad.exe", DIR_2, "" },
95  { __LINE__, FALSE, "C:\\notepad.exe", DIR_3, "" },
96  { __LINE__, FALSE, "C:\\notepad.exe", DIR_4, "" },
97  { __LINE__, FALSE, "..\\notepad.exe", DIR_0, "" },
98  { __LINE__, FALSE, "..\\notepad.exe", DIR_1, "" },
99  { __LINE__, FALSE, "..\\notepad.exe", DIR_2, "" },
100  { __LINE__, FALSE, "..\\notepad.exe", DIR_3, "" },
101  { __LINE__, FALSE, "..\\notepad.exe", DIR_4, "" },
102  { __LINE__, FALSE, ".\\notepad.exe", DIR_0, "" },
103  { __LINE__, FALSE, ".\\notepad.exe", DIR_1, "" },
104  { __LINE__, FALSE, ".\\notepad.exe", DIR_2, "" },
105  { __LINE__, TRUE, ".\\notepad.exe", DIR_3, s_win_notepad },
106  { __LINE__, FALSE, ".\\notepad.exe", DIR_4, "" },
107  { __LINE__, FALSE, "system32\\notepad.exe", DIR_0, "" },
108  { __LINE__, FALSE, "system32\\notepad.exe", DIR_1, "" },
109  { __LINE__, FALSE, "system32\\notepad.exe", DIR_2, "" },
110  { __LINE__, TRUE, "system32\\notepad.exe", DIR_3, s_sys_notepad },
111  { __LINE__, FALSE, "system32\\notepad.exe", DIR_4, "" },
112  { __LINE__, TRUE, s_win_notepad, DIR_0, s_win_notepad },
113  { __LINE__, TRUE, s_win_notepad, DIR_1, s_win_notepad },
114  { __LINE__, TRUE, s_win_notepad, DIR_2, s_win_notepad },
115  { __LINE__, TRUE, s_win_notepad, DIR_3, s_win_notepad },
116  { __LINE__, TRUE, s_win_notepad, DIR_4, s_win_notepad },
117  { __LINE__, TRUE, "test program", DIR_0, s_sys_test_exe },
118  { __LINE__, TRUE, "test program", DIR_1, s_sys_test_exe },
119  { __LINE__, TRUE, "test program", DIR_2, s_sys_test_exe },
120  { __LINE__, TRUE, "test program", DIR_3, s_win_test_exe },
121  { __LINE__, TRUE, "test program", DIR_4, s_sys_test_exe },
122  { __LINE__, FALSE, " test program", DIR_0, "" },
123  { __LINE__, FALSE, " test program", DIR_1, "" },
124  { __LINE__, FALSE, " test program", DIR_2, "" },
125  { __LINE__, FALSE, " test program", DIR_3, "" },
126  { __LINE__, FALSE, " test program", DIR_4, "" },
127  { __LINE__, FALSE, "test program ", DIR_0, "" },
128  { __LINE__, FALSE, "test program ", DIR_1, "" },
129  { __LINE__, FALSE, "test program ", DIR_2, "" },
130  { __LINE__, FALSE, "test program ", DIR_3, "" },
131  { __LINE__, FALSE, "test program ", DIR_4, "" },
132  { __LINE__, TRUE, "\"test program\"", DIR_0, s_sys_test_exe },
133  { __LINE__, TRUE, "\"test program\"", DIR_1, s_sys_test_exe },
134  { __LINE__, TRUE, "\"test program\"", DIR_2, s_sys_test_exe },
135  { __LINE__, TRUE, "\"test program\"", DIR_3, s_win_test_exe },
136  { __LINE__, TRUE, "\"test program\"", DIR_4, s_sys_test_exe },
137  { __LINE__, TRUE, "test program.exe", DIR_0, s_sys_test_exe },
138  { __LINE__, TRUE, "test program.exe", DIR_1, s_sys_test_exe },
139  { __LINE__, TRUE, "test program.exe", DIR_2, s_sys_test_exe },
140  { __LINE__, TRUE, "test program.exe", DIR_3, s_win_test_exe },
141  { __LINE__, TRUE, "test program.exe", DIR_4, s_sys_test_exe },
142  { __LINE__, TRUE, "\"test program.exe\"", DIR_0, s_sys_test_exe },
143  { __LINE__, TRUE, "\"test program.exe\"", DIR_1, s_sys_test_exe },
144  { __LINE__, TRUE, "\"test program.exe\"", DIR_2, s_sys_test_exe },
145  { __LINE__, TRUE, "\"test program.exe\"", DIR_3, s_win_test_exe },
146  { __LINE__, TRUE, "\"test program.exe\"", DIR_4, s_sys_test_exe },
147  { __LINE__, FALSE, "\"test program.exe \"", DIR_0, "" },
148  { __LINE__, FALSE, "\"test program.exe \"", DIR_1, "" },
149  { __LINE__, FALSE, "\"test program.exe \"", DIR_2, "" },
150  { __LINE__, FALSE, "\"test program.exe \"", DIR_3, "" },
151  { __LINE__, FALSE, "\"test program.exe \"", DIR_4, "" },
152  { __LINE__, FALSE, "\" test program.exe\"", DIR_0, "" },
153  { __LINE__, FALSE, "\" test program.exe\"", DIR_1, "" },
154  { __LINE__, FALSE, "\" test program.exe\"", DIR_2, "" },
155  { __LINE__, FALSE, "\" test program.exe\"", DIR_3, "" },
156  { __LINE__, FALSE, "\" test program.exe\"", DIR_4, "" },
157  { __LINE__, TRUE, "test program.bat", DIR_0, s_sys_bat_file },
158  { __LINE__, TRUE, "test program.bat", DIR_1, s_sys_bat_file },
159  { __LINE__, TRUE, "test program.bat", DIR_2, s_sys_bat_file },
160  { __LINE__, TRUE, "test program.bat", DIR_3, s_win_bat_file },
161  { __LINE__, TRUE, "test program.bat", DIR_4, s_sys_bat_file },
162  { __LINE__, FALSE, " test program.bat ", DIR_0, "" },
163  { __LINE__, FALSE, " test program.bat ", DIR_1, "" },
164  { __LINE__, FALSE, " test program.bat ", DIR_2, "" },
165  { __LINE__, FALSE, " test program.bat ", DIR_3, "" },
166  { __LINE__, FALSE, " test program.bat ", DIR_4, "" },
167  { __LINE__, TRUE, "\"test program.bat\"", DIR_0, s_sys_bat_file },
168  { __LINE__, TRUE, "\"test program.bat\"", DIR_1, s_sys_bat_file },
169  { __LINE__, TRUE, "\"test program.bat\"", DIR_2, s_sys_bat_file },
170  { __LINE__, TRUE, "\"test program.bat\"", DIR_3, s_win_bat_file },
171  { __LINE__, TRUE, "\"test program.bat\"", DIR_4, s_sys_bat_file },
172  { __LINE__, TRUE, "shell32_apitest_sub.exe", DIR_0, s_sub_program },
173  { __LINE__, TRUE, "shell32_apitest_sub.exe", DIR_1, "shell32_apitest_sub.exe" },
174  { __LINE__, FALSE, "shell32_apitest_sub.exe", DIR_2, "" },
175  { __LINE__, FALSE, "shell32_apitest_sub.exe", DIR_3, "" },
176  { __LINE__, FALSE, "shell32_apitest_sub.exe", DIR_4, "" },
177  { __LINE__, TRUE, "test file.txt", DIR_0, s_sys_notepad },
178  { __LINE__, TRUE, "test file.txt", DIR_1, s_sys_notepad },
179  { __LINE__, TRUE, "test file.txt", DIR_2, s_sys_notepad },
180  { __LINE__, TRUE, "test file.txt", DIR_3, s_sys_notepad },
181  { __LINE__, TRUE, "test file.txt", DIR_4, s_sys_notepad },
182  { __LINE__, FALSE, "invalid file.txt", DIR_0, "" },
183  { __LINE__, FALSE, "invalid file.txt", DIR_1, "" },
184  { __LINE__, FALSE, "invalid file.txt", DIR_2, "" },
185  { __LINE__, FALSE, "invalid file.txt", DIR_3, "" },
186  { __LINE__, FALSE, "invalid file.txt", DIR_4, "" },
187 };
188 
189 static void DoTestEntry(const TEST_ENTRY *pEntry)
190 {
191  char result[MAX_PATH];
192  result[0] = 0;
193  BOOL ret = ((INT_PTR)FindExecutableA(pEntry->file, pEntry->dir, result) > 32);
194  ok(ret == pEntry->ret, "Line %u: ret expected %d, got %d\n", pEntry->lineno, pEntry->ret, ret);
195 
197 
198  ok(lstrcmpiA(result, pEntry->result) == 0,
199  "Line %u: result expected '%s', got '%s'\n",
200  pEntry->lineno, pEntry->result, result);
201 }
202 
204 {
205  if (!GetSubProgramPath())
206  {
207  skip("shell32_apitest_sub.exe not found\n");
208  return;
209  }
210 
211  char cur_dir[MAX_PATH];
212  GetCurrentDirectoryA(_countof(cur_dir), cur_dir);
213  if (PathIsRootA(cur_dir))
214  {
215  skip("Don't use this program at root directory\n");
216  return;
217  }
218 
220 
222  PathAppendA(s_win_notepad, "notepad.exe");
223 
225  PathAppendA(s_sys_notepad, "notepad.exe");
226 
228  PathAppendA(s_win_test_exe, "test program.exe");
230  if (!ret)
231  {
232  skip("Please retry with admin rights\n");
233  return;
234  }
235 
237  PathAppendA(s_sys_test_exe, "test program.exe");
239 
241  PathAppendA(s_win_bat_file, "test program.bat");
242  fclose(fopen(s_win_bat_file, "wb"));
244 
246  PathAppendA(s_sys_bat_file, "test program.bat");
247  fclose(fopen(s_sys_bat_file, "wb"));
249 
251  PathAppendA(s_win_txt_file, "test file.txt");
252  fclose(fopen(s_win_txt_file, "wb"));
254 
256  PathAppendA(s_sys_txt_file, "test file.txt");
257  fclose(fopen(s_sys_txt_file, "wb"));
259 
260  for (UINT iTest = 0; iTest < _countof(s_entries); ++iTest)
261  {
262  DoTestEntry(&s_entries[iTest]);
263  }
264 
271 }
static char s_sys_bat_file[MAX_PATH]
static char s_win_bat_file[MAX_PATH]
LPCSTR dir
#define DIR_3
static const TEST_ENTRY s_entries[]
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
GLuint64EXT * result
Definition: glext.h:11304
#define DIR_1
#define TRUE
Definition: types.h:120
#define DIR_0
BOOL WINAPI PathAppendA(LPSTR lpszPath, LPCSTR lpszAppend)
Definition: path.c:106
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2282
BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
Definition: path.c:1754
BOOL WINAPI CopyFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:404
static void DoTestEntry(const TEST_ENTRY *pEntry)
static char s_win_notepad[MAX_PATH]
int32_t INT_PTR
Definition: typedefs.h:64
static char s_sys_txt_file[MAX_PATH]
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
Definition: path.c:586
#define FindExecutable
Definition: shellapi.h:688
static char s_sub_program[MAX_PATH]
DWORD WINAPI GetLongPathNameA(IN LPCSTR lpszShortPath, OUT LPSTR lpszLongPath, IN DWORD cchBuffer)
Definition: path.c:1670
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
static char s_win_txt_file[MAX_PATH]
#define ok_int(expression, result)
Definition: atltest.h:134
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
INT lineno
Definition: fc.c:16
const char * LPCSTR
Definition: xmlstorage.h:183
static BOOL GetSubProgramPath(void)
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
HINSTANCE WINAPI FindExecutableA(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
Definition: shlexec.cpp:1223
int ret
static char s_win_test_exe[MAX_PATH]
Definition: cmd.c:12
static char s_sys_test_exe[MAX_PATH]
LPCSTR result
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
Definition: path.c:1601
struct TEST_ENTRY TEST_ENTRY
static char s_sys_notepad[MAX_PATH]
#define ok(value,...)
Definition: atltest.h:57
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
LPCSTR file
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2336
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define DIR_4
#define skip(...)
Definition: atltest.h:64
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
INT ret
Definition: fc.c:17
START_TEST(FindExecutable)
static char s_win_dir[MAX_PATH]
#define DIR_2