ReactOS 0.4.16-dev-197-g92996da
PathFindOnPath.c
Go to the documentation of this file.
1/*
2 * Copyright 2017 Katayama Hirofumi MZ
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <apitest.h>
20#include <shlwapi.h>
21#include <assert.h>
22
23#include <pseh/pseh2.h>
24
25#define EF_FULLPATH 1
26#define EF_TESTDATA 2
27#define EF_WIN_DIR 4
28#define EF_SYS_DIR 8
29#define EF_TYPE_MASK 0xF
30
31#define EF_NAME_ONLY 16
32
33typedef struct ENTRY
34{
44
45#define BEEF 0xBEEF /* Error Code 48879 */
46#define DEAD 0xDEAD /* Error Code 57005 */
47#define IGNORE_ERR 0x7F7F7F7F /* Ignore Error Code */
48#define RAISED 9999 /* exception raised */
49
51static LPWSTR s_Dirs[2];
56
57static const ENTRY s_Entries[] =
58{
59 /* NULL or empty path */
60 { 0, 0, BEEF, EF_FULLPATH, NULL, NULL },
61 { 1, 1, BEEF, EF_FULLPATH, L"", s_SysDir },
62 /* path without dirs in Windows */
63 { 2, 0, BEEF, EF_WIN_DIR, L"", L"" },
64 { 3, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts" },
65 { 4, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad" },
66 { 5, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe" },
67 { 6, 0, BEEF, EF_WIN_DIR, L"system32", L"system32" },
68 { 7, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name" },
69 /* path with dirs in Windows */
70 { 8, 0, BEEF, EF_WIN_DIR, L"", L"", NULL, s_Dirs },
71 { 9, 0, BEEF, EF_WIN_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
72 { 10, 0, BEEF, EF_WIN_DIR, L"notepad", L"notepad", NULL, s_Dirs },
73 { 11, 0, BEEF, EF_WIN_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
74 { 12, 0, BEEF, EF_WIN_DIR, L"system32", L"system32", NULL, s_Dirs },
75 { 13, 0, BEEF, EF_WIN_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
76 /* name only without dirs in Windows */
77 { 14, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"", L"system32" },
78 { 15, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts" },
79 { 16, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad" },
80 { 17, 1, BEEF, EF_WIN_DIR | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
81 { 18, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32" },
82 { 19, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
83 /* name only with dirs in Windows */
85 { 21, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"Fonts", L"Fonts", NULL, s_Dirs },
86 { 22, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
88 { 24, 1, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"system32", L"system32", NULL, s_Dirs },
89 { 25, 0, ERROR_FILE_NOT_FOUND, EF_WIN_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
90 /* path without dirs in system32 */
91 { 26, 0, BEEF, EF_SYS_DIR, L"", L"" },
92 { 27, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts" },
93 { 28, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad" },
94 { 29, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe" },
95 { 30, 0, BEEF, EF_SYS_DIR, L"system32", L"system32" },
96 { 31, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name" },
97 /* path with dirs in system32 */
98 { 32, 0, BEEF, EF_SYS_DIR, L"", L"", NULL, s_Dirs },
99 { 33, 0, BEEF, EF_SYS_DIR, L"Fonts", L"Fonts", NULL, s_Dirs },
100 { 34, 0, BEEF, EF_SYS_DIR, L"notepad", L"notepad", NULL, s_Dirs },
101 { 35, 0, BEEF, EF_SYS_DIR, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
102 { 36, 0, BEEF, EF_SYS_DIR, L"system32", L"system32", NULL, s_Dirs },
103 { 37, 0, BEEF, EF_SYS_DIR, L"invalid name", L"invalid name", NULL, s_Dirs },
104 /* name only without dirs in system32 */
105 { 38, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"", NULL, s_SysDir },
107 { 40, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
108 { 41, 1, BEEF, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe" },
109 { 42, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
110 { 43, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
111 /* name only with dirs in system32 */
114 { 46, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
115 { 47, 1, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
117 { 49, 0, ERROR_FILE_NOT_FOUND, EF_SYS_DIR | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
118 /* path without dirs in testdata dir */
119 { 50, 0, BEEF, EF_TESTDATA, L"", L"" },
120 { 51, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts" },
121 { 52, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad" },
122 { 53, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe" },
123 { 54, 0, BEEF, EF_TESTDATA, L"system32", L"system32" },
124 { 55, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name" },
125 { 56, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt" },
126 { 57, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils" },
127 { 58, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe" },
128 /* path with dirs in testdata dir */
129 { 59, 0, BEEF, EF_TESTDATA, L"", L"", NULL, s_Dirs },
130 { 60, 0, BEEF, EF_TESTDATA, L"Fonts", L"Fonts", NULL, s_Dirs },
131 { 61, 0, BEEF, EF_TESTDATA, L"notepad", L"notepad", NULL, s_Dirs },
132 { 62, 0, BEEF, EF_TESTDATA, L"notepad.exe", L"notepad.exe", NULL, s_Dirs },
133 { 63, 0, BEEF, EF_TESTDATA, L"system32", L"system32", NULL, s_Dirs },
134 { 64, 0, BEEF, EF_TESTDATA, L"invalid name", L"invalid name", NULL, s_Dirs },
135 { 65, 0, BEEF, EF_TESTDATA, L"README.txt", L"README.txt", NULL, s_Dirs },
136 { 66, 0, BEEF, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", NULL, s_Dirs },
137 { 67, 0, BEEF, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", NULL, s_Dirs },
138 /* name only without dirs in testdata dir */
139 { 68, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"", NULL, s_SysDir },
141 { 70, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad" },
142 { 71, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"notepad.exe", NULL, s_NotepadPath },
143 { 72, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"system32", NULL, s_SysDir },
144 { 73, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name" },
145 { 74, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
146 { 75, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
147 { 76, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
148 /* name only with dirs in testdata dir */
151 { 79, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"notepad", NULL, L"notepad", s_Dirs },
154 { 82, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"invalid name", NULL, L"invalid name", s_Dirs },
155 { 83, 1, BEEF, EF_TESTDATA | EF_NAME_ONLY, L"README.txt", L"README.txt", NULL, s_Dirs },
156 { 84, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, L"CmdLineUtils", s_Dirs },
157 { 85, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, L"CmdLineUtils.exe", s_Dirs },
158};
159
160static void DoEntry(INT EntryNumber, const ENTRY *pEntry, const WCHAR *PathVar)
161{
162 WCHAR Path[MAX_PATH], PathExpected[MAX_PATH], OldPathVar[256];
163 INT Ret;
164 DWORD Error;
165
166 if (pEntry->NameBefore == NULL)
167 {
168 assert(pEntry->NameExpected == NULL);
169 assert(pEntry->PathExpected == NULL);
170 }
171
172 switch (pEntry->EF_ & EF_TYPE_MASK)
173 {
174 case EF_FULLPATH:
175 if (pEntry->NameBefore)
176 {
177 lstrcpyW(Path, pEntry->NameBefore);
178 }
179 if (pEntry->NameExpected)
180 {
181 lstrcpyW(PathExpected, pEntry->NameExpected);
182 }
183 break;
184
185 case EF_TESTDATA:
186 if (pEntry->EF_ & EF_NAME_ONLY)
187 {
188 lstrcpyW(Path, pEntry->NameBefore);
189 }
190 else
191 {
193 lstrcatW(Path, L"\\");
194 lstrcatW(Path, pEntry->NameBefore);
195 }
196
197 if (pEntry->NameExpected)
198 {
199 lstrcpyW(PathExpected, s_TestDataPath);
200 lstrcatW(PathExpected, L"\\");
201 lstrcatW(PathExpected, pEntry->NameExpected);
202 }
203 break;
204
205 case EF_WIN_DIR:
206 if (pEntry->EF_ & EF_NAME_ONLY)
207 {
208 lstrcpyW(Path, pEntry->NameBefore);
209 }
210 else
211 {
213 lstrcatW(Path, L"\\");
214 lstrcatW(Path, pEntry->NameBefore);
215 }
216
217 if (pEntry->NameExpected)
218 {
219 GetWindowsDirectoryW(PathExpected, _countof(PathExpected));
220 lstrcatW(PathExpected, L"\\");
221 lstrcatW(PathExpected, pEntry->NameExpected);
222 }
223 break;
224
225 case EF_SYS_DIR:
226 if (pEntry->EF_ & EF_NAME_ONLY)
227 {
228 lstrcpyW(Path, pEntry->NameBefore);
229 }
230 else
231 {
233 lstrcatW(Path, L"\\");
234 lstrcatW(Path, pEntry->NameBefore);
235 }
236
237 if (pEntry->NameExpected)
238 {
239 GetSystemDirectoryW(PathExpected, _countof(PathExpected));
240 lstrcatW(PathExpected, L"\\");
241 lstrcatW(PathExpected, pEntry->NameExpected);
242 }
243 break;
244 }
245
246 if (PathVar)
247 {
248 if (!GetEnvironmentVariableW(L"PATH", OldPathVar, _countof(OldPathVar)))
249 {
250 skip("#%d: GetEnvironmentVariableW failed\n", EntryNumber);
251 return;
252 }
253 if (!SetEnvironmentVariableW(L"PATH", PathVar))
254 {
255 skip("#%d: SetEnvironmentVariableW failed\n", EntryNumber);
256 return;
257 }
258 }
259
261 {
263 if (pEntry->NameBefore)
264 {
265 Ret = PathFindOnPathW(Path, (LPCWSTR *)pEntry->Dirs);
266 }
267 else
268 {
269 Ret = PathFindOnPathW(NULL, (LPCWSTR *)pEntry->Dirs);
270 }
272 }
274 {
275 Ret = RAISED;
276 Error = DEAD;
277 }
278 _SEH2_END;
279
280 if (PathVar)
281 {
282 ok(SetEnvironmentVariableW(L"PATH", OldPathVar),
283 "#%d: SetEnvironmentVariableW failed\n", EntryNumber);
284 }
285
286 ok(Ret == pEntry->Ret, "#%d: Ret expected %d, was %d.\n",
287 EntryNumber, pEntry->Ret, Ret);
288
289 if (pEntry->Error != IGNORE_ERR)
290 {
291 ok(Error == pEntry->Error, "#%d: last error expected %ld, was %ld.\n",
292 EntryNumber, pEntry->Error, Error);
293 }
294
295 if (pEntry->PathExpected)
296 {
297 ok(lstrcmpiW(Path, pEntry->PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
298 EntryNumber, wine_dbgstr_w(pEntry->PathExpected), wine_dbgstr_w(Path));
299 }
300 else if (pEntry->NameExpected)
301 {
302 ok(lstrcmpiW(Path, PathExpected) == 0, "#%d: Path expected %s, was %s.\n",
303 EntryNumber, wine_dbgstr_w(PathExpected), wine_dbgstr_w(Path));
304 }
305}
306
307static void Test_PathFindOnPathW(void)
308{
309 UINT i;
310
311 for (i = 0; i < _countof(s_Entries); ++i)
312 {
313 DoEntry(s_Entries[i].EntryNumber, &s_Entries[i], NULL);
314 }
315}
316
318{
319 LPWSTR pch;
320
323
325 lstrcatW(s_FontsDir, L"\\Fonts");
326
328 lstrcatW(s_NotepadPath, L"\\notepad.exe");
329
331 pch = wcsrchr(s_TestDataPath, L'\\');
332 if (pch == NULL)
334 if (pch == NULL)
335 {
336 skip("GetModuleFileName and/or wcsrchr are insane.\n");
337 return;
338 }
339 lstrcpyW(pch, L"\\testdata");
341 {
342 skip("testdata is not found.\n");
343 return;
344 }
345
347 s_Dirs[1] = NULL;
348
350}
#define EF_FULLPATH
static WCHAR s_NotepadPath[MAX_PATH]
#define BEEF
#define EF_WIN_DIR
#define DEAD
static WCHAR s_FontsDir[MAX_PATH]
#define IGNORE_ERR
#define EF_NAME_ONLY
#define EF_TYPE_MASK
#define EF_SYS_DIR
static WCHAR s_SysDir[MAX_PATH]
static const ENTRY s_Entries[]
static WCHAR s_TestDataPath[MAX_PATH]
static WCHAR s_WinDir[MAX_PATH]
static void DoEntry(INT EntryNumber, const ENTRY *pEntry, const WCHAR *PathVar)
static void Test_PathFindOnPathW(void)
#define RAISED
static LPWSTR s_Dirs[2]
#define EF_TESTDATA
PRTL_UNICODE_STRING_BUFFER Path
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
BOOL Error
Definition: chkdsk.c:66
#define NULL
Definition: types.h:112
#define wcsrchr
Definition: compat.h:16
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define SetLastError(x)
Definition: compat.h:752
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:1403
#define assert(x)
Definition: debug.h:53
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned long DWORD
Definition: ntddk_ex.h:95
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define wine_dbgstr_w
Definition: kernel32.h:34
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define pch(ap)
Definition: match.c:418
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define PathFindOnPath
Definition: shlwapi.h:945
#define _countof(array)
Definition: sndvol32.h:70
Definition: DelNode.c:62
INT EntryNumber
LPCWSTR NameExpected
LPCWSTR PathExpected
UINT EF_
LPWSTR * Dirs
LPCWSTR NameBefore
int32_t INT
Definition: typedefs.h:58
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185