1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Tests for PathResolve
5  * PROGRAMMER:      Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 
8 #include "shelltest.h"
9 
10 #include <stdio.h>
11 #include <assert.h>
12 
13 /*
14  * NOTE: "App Paths" registry key and PATHEXT environment variable
15  *       have no effect for PathResolve.
16  */
17 
18 /* PathResolve */
19 typedef int (WINAPI *PATHRESOLVE)(LPWSTR, LPWSTR*, UINT);
20 
21 /* IsLFNDriveW */
22 typedef BOOL (WINAPI *ISLFNDRIVEW)(LPCWSTR);
23 
24 static HINSTANCE    s_hShell32 = NULL;
25 static PATHRESOLVE  s_pPathResolve = NULL;
26 static ISLFNDRIVEW  s_pIsLFNDriveW = NULL;
27 static WCHAR        s_TestDir[MAX_PATH];
28 static WCHAR        s_TestDirWithBackslash[MAX_PATH];
29 static WCHAR        s_ShortcutLongName[MAX_PATH];
30 static WCHAR        s_LinkTarget[MAX_PATH];
31 static WCHAR        s_LinkTargetWithBackslash[MAX_PATH];
32 static WCHAR        s_LinkTargetDoubleBackslash[MAX_PATH];
33 static LPWSTR       s_Dirs[2] = { s_TestDir, NULL };
34 static LPWSTR       s_DirsWithBackslash[2] = { s_TestDirWithBackslash, NULL };
35 
36 /* PathResolve flags */
37 #ifndef PRF_VERIFYEXISTS
38     #define PRF_VERIFYEXISTS         0x01
39     #define PRF_EXECUTABLE           0x02
40     #define PRF_TRYPROGRAMEXTENSIONS (PRF_EXECUTABLE | PRF_VERIFYEXISTS)
41     #define PRF_FIRSTDIRDEF          0x04
42     #define PRF_DONTFINDLNK          0x08
43 #endif
44 #ifndef PRF_REQUIREABSOLUTE
45     #define PRF_REQUIREABSOLUTE      0x10
46 #endif
47 
48 /* Abstraction of PathResolve flags to manage the test entries */
49 #define FLAGS0      0
50 #define FLAGS1      PRF_VERIFYEXISTS
51 #define FLAGS2      PRF_EXECUTABLE
52 #define FLAGS3      PRF_TRYPROGRAMEXTENSIONS
53 #define FLAGS4      (PRF_FIRSTDIRDEF | PRF_VERIFYEXISTS)
54 #define FLAGS5      (PRF_FIRSTDIRDEF | PRF_EXECUTABLE)
55 #define FLAGS6      (PRF_FIRSTDIRDEF | PRF_TRYPROGRAMEXTENSIONS)
56 #define FLAGS7      (PRF_REQUIREABSOLUTE | PRF_VERIFYEXISTS)
57 #define FLAGS8      (PRF_REQUIREABSOLUTE | PRF_EXECUTABLE)
58 #define FLAGS9      (PRF_REQUIREABSOLUTE | PRF_TRYPROGRAMEXTENSIONS)
59 #define FLAGS10     (PRF_REQUIREABSOLUTE | PRF_FIRSTDIRDEF | PRF_VERIFYEXISTS)
60 #define FLAGS11     (PRF_REQUIREABSOLUTE | PRF_FIRSTDIRDEF | PRF_EXECUTABLE)
61 #define FLAGS12     (PRF_REQUIREABSOLUTE | PRF_FIRSTDIRDEF | PRF_TRYPROGRAMEXTENSIONS)
62 #define FLAGS13     0xFFFFFFFF
63 
64 /* The test entry structure */
65 typedef struct tagTEST_ENTRY
66 {
67     INT         LineNumber;    /* # */
68     INT         Ret;
69     DWORD       Error;
70     UINT        EF_;
71     LPCWSTR     NameBefore;
72     LPCWSTR     NameExpected;
73     UINT        Flags;
74     LPWSTR     *Dirs;
75 } TEST_ENTRY, *PTEST_ENTRY;
76 
77 /* Flags for TEST_ENTRY */
78 #define EF_FULLPATH     0x01
79 #define EF_TESTDATA     0x02
80 #define EF_TYPE_MASK    0x0F
81 #define EF_NAME_ONLY    0x10
82 #define EF_APP_PATH     0x20
83 
84 /* Special error codes */
85 #define ERR_NO_CHANGE 0xBEEF      /* Error Code 48879 */
86 #define ERR_DEAD      0xDEAD      /* Error Code 57005 */
87 #define ERR_IGNORE    0x7F7F7F7F  /* Ignore Error Code */
88 #define RAISED        9999        /* exception raised */
89 
90 /* The test entries for long file name (LFN) */
91 static const TEST_ENTRY s_LFNEntries[] =
92 {
93     /* null path */
94     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS0 },
95     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS1 },
96     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS2 },
97     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS3 },
98     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS4 },
99     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS5 },
100     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS6 },
101     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS7 },
102     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS8 },
103     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS9 },
104     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS10 },
105     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS11 },
106     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS12 },
107     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, NULL, NULL, FLAGS13 },
108     /* empty path */
109     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"", NULL, FLAGS0 },
110     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS1 },
111     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS2 },
112     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS3 },
113     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS4 },
114     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS5 },
115     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS6 },
116     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS7 },
117     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS8 },
118     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS9 },
119     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS10 },
120     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS11 },
121     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS12 },
122     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"", NULL, FLAGS13 },
123     /* invalid name */
124     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS0 },
125     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS1 },
126     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS2 },
127     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS3 },
128     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS4 },
129     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS5 },
130     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS6 },
131     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS7 },
132     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS8 },
133     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS9 },
134     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS10 },
135     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS11 },
136     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS12 },
137     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"invalid name", L"invalid name", FLAGS13 },
138     /* testdir/2PRONG (path) */
139     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS0 },
140     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS1 },
141     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS2 },
142     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS3 },
143     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS4 },
144     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS5 },
145     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS6 },
146     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS7 },
147     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS8 },
148     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS9 },
149     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS10 },
150     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS11 },
151     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS12 },
152     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG", L"2PRONG", FLAGS13 },
153     /* testdir/2PRONG (name only) */
154     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS0 },
155     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS1 },
156     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS2 },
157     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS3 },
158     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS4 },
159     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS5 },
160     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS6 },
161     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS7 },
162     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS8 },
163     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS9 },
164     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS10 },
165     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS11 },
166     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS12 },
167     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS13 },
168     /* testdir/2PRONG with dirs (name only) */
169     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS0, s_Dirs },
170     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS1, s_Dirs },
171     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS2, s_Dirs },
172     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS3, s_Dirs },
173     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS4, s_Dirs },
174     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS5, s_Dirs },
175     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS6, s_Dirs },
176     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS7, s_Dirs },
177     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS8, s_Dirs },
178     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS9, s_Dirs },
179     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS10, s_Dirs },
180     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS11, s_Dirs },
181     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS12, s_Dirs },
182     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG", NULL, FLAGS13, s_Dirs },
183     /* testdir/2PRONG (name only, app path) */
184     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS0 },
185     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS1 },
186     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS2 },
187     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS3 },
188     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS4 },
189     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS5 },
190     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS6 },
191     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS7 },
192     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS8 },
193     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS9 },
194     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS10 },
195     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS11 },
196     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS12 },
197     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"2PRONG", L"2PRONG", FLAGS13 },
198     /* 2PRONG.txt */
199     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS0 },
200     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS1 },
201     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS2 },
202     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS3 },
203     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS4 },
204     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS5 },
205     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS6 },
206     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS7 },
207     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS8 },
208     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS9 },
209     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS10 },
210     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS11 },
211     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS12 },
212     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS13 },
213     /* 2PRONG.txt with dirs */
214     { __LINE__, 1, ERR_IGNORE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS0, s_Dirs },
215     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS1, s_Dirs },
216     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS2, s_Dirs },
217     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS3, s_Dirs },
218     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS4, s_Dirs },
219     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS5, s_Dirs },
220     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS6, s_Dirs },
221     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS7, s_Dirs },
222     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS8, s_Dirs },
223     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS9, s_Dirs },
224     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS10, s_Dirs },
225     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS11, s_Dirs },
226     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS12, s_Dirs },
227     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"2PRONG.txt", L"2PRONG.txt", FLAGS13, s_Dirs },
228     /* 2PRONG.txt with dirs (path) */
229     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS0, s_Dirs },
230     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS1, s_Dirs },
231     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS2, s_Dirs },
232     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS3, s_Dirs },
233     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS4, s_Dirs },
234     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS5, s_Dirs },
235     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS6, s_Dirs },
236     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS7, s_Dirs },
237     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS8, s_Dirs },
238     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS9, s_Dirs },
239     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS10, s_Dirs },
240     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS11, s_Dirs },
241     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS12, s_Dirs },
242     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS13, s_Dirs },
243     /* 2PRONG.txt (with a trailing backslash) */
244     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS0 },
245     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS1 },
246     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS2 },
247     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS3 },
248     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetWithBackslash, NULL, FLAGS4 },
249     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetWithBackslash, NULL, FLAGS5 },
250     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetWithBackslash, NULL, FLAGS6 },
251     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS7 },
252     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS8 },
253     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS9 },
254     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetWithBackslash, NULL, FLAGS10 },
255     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetWithBackslash, NULL, FLAGS11 },
256     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetWithBackslash, NULL, FLAGS12 },
257     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetWithBackslash, NULL, FLAGS13 },
258     /* 2PRONG.txt with dirs (with a trailing backslash) */
259     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS0, s_Dirs },
260     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS1, s_Dirs },
261     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS2, s_Dirs },
262     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS3, s_Dirs },
263     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS4, s_Dirs },
264     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS5, s_Dirs },
265     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS6, s_Dirs },
266     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS7, s_Dirs },
267     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS8, s_Dirs },
268     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS9, s_Dirs },
269     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS10, s_Dirs },
270     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS11, s_Dirs },
271     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS12, s_Dirs },
272     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS13, s_Dirs },
273     /* 2PRONG.txt with dirs (with a trailing backslash) */
274     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS0, s_Dirs },
275     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS1, s_Dirs },
276     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS2, s_Dirs },
277     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS3, s_Dirs },
278     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS4, s_Dirs },
279     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS5, s_Dirs },
280     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS6, s_Dirs },
281     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS7, s_Dirs },
282     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS8, s_Dirs },
283     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS9, s_Dirs },
284     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS10, s_Dirs },
285     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS11, s_Dirs },
286     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS12, s_Dirs },
287     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, L"2PRONG.txt", s_LinkTarget, FLAGS13, s_Dirs },
288     /* 2PRONG.txt with dirs (with a trailing backslash) (s_DirsWithBackslash) */
289     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS0, s_DirsWithBackslash },
290     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS1, s_DirsWithBackslash },
291     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS2, s_DirsWithBackslash },
292     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS3, s_DirsWithBackslash },
293     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS4, s_DirsWithBackslash },
294     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS5, s_DirsWithBackslash },
295     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS6, s_DirsWithBackslash },
296     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS7, s_DirsWithBackslash },
297     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS8, s_DirsWithBackslash },
298     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS9, s_DirsWithBackslash },
299     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS10, s_DirsWithBackslash },
300     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS11, s_DirsWithBackslash },
301     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS12, s_DirsWithBackslash },
302     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetWithBackslash, s_LinkTarget, FLAGS13, s_DirsWithBackslash },
303     /* 2PRONG.txt (double backslash) */
304     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS0 },
305     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS1 },
306     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS2 },
307     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS3 },
308     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetDoubleBackslash, NULL, FLAGS4 },
309     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetDoubleBackslash, NULL, FLAGS5 },
310     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetDoubleBackslash, NULL, FLAGS6 },
311     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS7 },
312     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS8 },
313     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS9 },
314     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetDoubleBackslash, NULL, FLAGS10 },
315     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetDoubleBackslash, NULL, FLAGS11 },
316     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetDoubleBackslash, NULL, FLAGS12 },
317     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_LinkTargetDoubleBackslash, NULL, FLAGS13 },
318     /* 2PRONG.txt with dirs (double backslash) */
319     { __LINE__, 1, ERR_IGNORE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS0, s_Dirs },
320     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS1, s_Dirs },
321     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS2, s_Dirs },
322     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS3, s_Dirs },
323     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS4, s_Dirs },
324     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS5, s_Dirs },
325     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS6, s_Dirs },
326     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS7, s_Dirs },
327     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS8, s_Dirs },
328     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS9, s_Dirs },
329     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS10, s_Dirs },
330     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS11, s_Dirs },
331     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS12, s_Dirs },
332     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_LinkTargetDoubleBackslash, s_LinkTarget, FLAGS13, s_Dirs },
333     /* 2PRONG.txt (name only) */
334     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS0 },
335     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS1 },
336     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS2 },
337     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS3 },
338     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS4 },
339     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS5 },
340     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS6 },
341     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS7 },
342     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS8 },
343     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS9 },
344     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS10 },
345     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS11 },
346     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS12 },
347     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", NULL, FLAGS13 },
348     /* 2PRONG.txt with dirs (name only) */
349     { __LINE__, 1, ERR_IGNORE, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS0, s_Dirs },
350     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS1, s_Dirs },
351     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS2, s_Dirs },
352     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS3, s_Dirs },
353     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS4, s_Dirs },
354     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS5, s_Dirs },
355     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS6, s_Dirs },
356     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS7, s_Dirs },
357     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS8, s_Dirs },
358     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS9, s_Dirs },
359     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS10, s_Dirs },
360     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS11, s_Dirs },
361     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS12, s_Dirs },
362     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"2PRONG.txt", L"2PRONG.txt", FLAGS13, s_Dirs },
363     /* testdir/CmdLineUtils (path) */
364     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS0 },
365     { __LINE__, 1, ERR_IGNORE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS1 },
366     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS2 },
367     { __LINE__, 1, ERR_IGNORE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS3 },
368     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS4 },
369     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS5 },
370     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS6 },
371     { __LINE__, 1, ERR_IGNORE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS7 },
372     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS8 },
373     { __LINE__, 1, ERR_IGNORE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils.lnk", FLAGS9 },
374     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS10 },
375     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS11 },
376     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS12 },
377     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS13 },
378     /* testdir/CmdLineUtils with PRF_DONTFINDLNK (path) */
379     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS0 | PRF_DONTFINDLNK },
380     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS1 | PRF_DONTFINDLNK },
381     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS2 | PRF_DONTFINDLNK },
382     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS3 | PRF_DONTFINDLNK },
383     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS4 | PRF_DONTFINDLNK },
384     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS5 | PRF_DONTFINDLNK },
385     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS6 | PRF_DONTFINDLNK },
386     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS7 | PRF_DONTFINDLNK },
387     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS8 | PRF_DONTFINDLNK },
388     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS9 | PRF_DONTFINDLNK },
389     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS10 | PRF_DONTFINDLNK },
390     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS11 | PRF_DONTFINDLNK },
391     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS12 | PRF_DONTFINDLNK },
392     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils", L"CmdLineUtils", FLAGS13 | PRF_DONTFINDLNK },
393     /* testdir/CmdLineUtils (name only) */
394     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS0 },
395     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS1 },
396     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS2 },
397     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS3 },
398     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS4 },
399     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS5 },
400     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS6 },
401     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS7 },
402     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS8 },
403     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS9 },
404     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS10 },
405     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS11 },
406     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS12 },
407     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils", NULL, FLAGS13 },
408     /* testdir/CmdLineUtils.exe (path) */
409     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS0 },
410     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS1 },
411     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS2 },
412     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS3 },
413     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS4 },
414     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS5 },
415     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS6 },
416     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS7 },
417     { __LINE__, 1, ERR_NO_CHANGE, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS8 },
418     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS9 },
419     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS10 },
420     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS11 },
421     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS12 },
422     { __LINE__, RAISED, ERR_DEAD, EF_TESTDATA, L"CmdLineUtils.exe", L"CmdLineUtils.exe", FLAGS13 },
423     /* testdir/CmdLineUtils.exe (name only) */
424     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS0 },
425     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS1 },
426     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS2 },
427     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS3 },
428     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS4 },
429     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS5 },
430     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS6 },
431     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS7 },
432     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS8 },
433     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS9 },
434     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS10 },
435     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS11 },
436     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS12 },
437     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS13 },
438     /* testdir/CmdLineUtils.exe with dirs (name only) */
439     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS0, s_Dirs },
440     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS1, s_Dirs },
441     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS2, s_Dirs },
442     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS3, s_Dirs },
443     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS4, s_Dirs },
444     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS5, s_Dirs },
445     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS6, s_Dirs },
446     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS7, s_Dirs },
447     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS8, s_Dirs },
448     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS9, s_Dirs },
449     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS10, s_Dirs },
450     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS11, s_Dirs },
451     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS12, s_Dirs },
452     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS13, s_Dirs },
453     /* testdir/CmdLineUtils.exe with dirs (name only) */
454     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS0, s_Dirs },
455     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS1, s_Dirs },
456     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS2, s_Dirs },
457     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS3, s_Dirs },
458     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS4, s_Dirs },
459     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS5, s_Dirs },
460     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS6, s_Dirs },
461     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS7, s_Dirs },
462     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS8, s_Dirs },
463     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS9, s_Dirs },
464     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS10, s_Dirs },
465     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS11, s_Dirs },
466     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS12, s_Dirs },
467     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY, L"CmdLineUtils.exe", NULL, FLAGS13, s_Dirs },
468     /* GhostProgram.exe -> testdir/CmdLineUtils.exe (name only, app path) */
469     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS0 },
470     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS1 },
471     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS2 },
472     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS3 },
473     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS4 },
474     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS5 },
475     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS6 },
476     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS7 },
477     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS8 },
478     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS9 },
479     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS10 },
480     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS11 },
481     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS12 },
482     { __LINE__, 0, ERROR_FILE_NOT_FOUND, EF_TESTDATA | EF_NAME_ONLY | EF_APP_PATH, L"GhostProgram.exe", L"CmdLineUtils.exe", FLAGS13 },
483     /* CmdLineUtils.lnk */
484     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS0 },
485     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS1 },
486     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_ShortcutLongName, NULL, FLAGS2 },
487     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS3 },
488     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS4 },
489     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS5 },
490     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS6 },
491     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS7 },
492     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS8 },
493     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS9 },
494     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS10 },
495     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS11 },
496     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS12 },
497     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS13 },
498     /* CmdLineUtils.lnk (with PRF_DONTFINDLNK) */
499     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS0 | PRF_DONTFINDLNK },
500     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS1 | PRF_DONTFINDLNK },
501     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_ShortcutLongName, NULL, FLAGS2 | PRF_DONTFINDLNK },
502     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS3 | PRF_DONTFINDLNK },
503     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS4 | PRF_DONTFINDLNK },
504     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS5 | PRF_DONTFINDLNK },
505     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS6 | PRF_DONTFINDLNK },
506     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS7 | PRF_DONTFINDLNK },
507     { __LINE__, 1, ERR_NO_CHANGE, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS8 | PRF_DONTFINDLNK },
508     { __LINE__, 1, ERROR_FILE_NOT_FOUND, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS9 | PRF_DONTFINDLNK },
509     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS10 | PRF_DONTFINDLNK },
510     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS11 | PRF_DONTFINDLNK },
511     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS12 | PRF_DONTFINDLNK },
512     { __LINE__, RAISED, ERR_DEAD, EF_FULLPATH, s_ShortcutLongName, s_ShortcutLongName, FLAGS13 | PRF_DONTFINDLNK },
513 };
514 
515 static BOOL
516 CreateShortcut(LPCWSTR pszLnkFileName,
517                LPCWSTR pszTargetPathName)
518 {
519     IPersistFile *ppf;
520     IShellLinkW* psl;
521     HRESULT hres;
522 
523     hres = CoInitialize(NULL);
524     if (SUCCEEDED(hres))
525     {
526         hres = CoCreateInstance(CLSID_ShellLink, NULL,
527             CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);
528         if (SUCCEEDED(hres))
529         {
530             psl->SetPath(pszTargetPathName);
531             hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
532             if (SUCCEEDED(hres))
533             {
534                 hres = ppf->Save(pszLnkFileName, TRUE);
535                 ppf->Release();
536             }
537             psl->Release();
538         }
539         CoUninitialize();
540     }
541     SetLastError(hres);
542 
543     return SUCCEEDED(hres);
544 }
545 
546 static BOOL
547 CreateRegAppPath(INT SectionNumber, INT LineNumber, const WCHAR* Name, const WCHAR* Value)
548 {
549     HKEY RegistryKey;
550     LONG Result;
551     WCHAR Buffer[1024];
552     DWORD Disposition;
553 
554     wcscpy(Buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
555     wcscat(Buffer, Name);
556     Result = RegCreateKeyExW(HKEY_LOCAL_MACHINE, Buffer, 0, NULL,
557         0, KEY_WRITE, NULL, &RegistryKey, &Disposition);
558     if (Result != ERROR_SUCCESS)
559     {
560         trace("Section %d, Line %d: Could not create test key. Status: %lu\n",
561               SectionNumber, LineNumber, Result);
562         return FALSE;
563     }
564     Result = RegSetValueW(RegistryKey, NULL, REG_SZ, Value, 0);
565     if (Result != ERROR_SUCCESS)
566     {
567         trace("Section %d, Line %d: Could not set value of the test key. Status: %lu\n",
568               SectionNumber, LineNumber, Result);
569         RegCloseKey(RegistryKey);
570         return FALSE;
571     }
572     RegCloseKey(RegistryKey);
573     return TRUE;
574 }
575 
576 static BOOL
577 DeleteRegAppPath(INT SectionNumber, INT LineNumber, const WCHAR* Name)
578 {
579     LONG Result;
580     WCHAR Buffer[1024];
581     wcscpy(Buffer, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
582     wcscat(Buffer, Name);
583     Result = RegDeleteKeyW(HKEY_LOCAL_MACHINE, Buffer);
584     if (Result != ERROR_SUCCESS)
585     {
586         trace("Section %d, Line %d: Could not remove the test key. Status: %lu\n",
587               SectionNumber, LineNumber, Result);
588         return FALSE;
589     }
590     return TRUE;
591 }
592 
593 static void DoEntry(INT SectionNumber, INT LineNumber, const TEST_ENTRY *pEntry)
594 {
595     WCHAR Path[MAX_PATH], PathExpected[MAX_PATH];
596     INT Ret;
597     DWORD Error;
598 
599     if (pEntry->NameBefore == NULL)
600     {
601         assert(pEntry->NameExpected == NULL);
602     }
603 
604     switch (pEntry->EF_ & EF_TYPE_MASK)
605     {
606         case EF_FULLPATH:
607             if (pEntry->NameBefore)
608             {
609                 lstrcpyW(Path, pEntry->NameBefore);
610             }
611             if (pEntry->NameExpected)
612             {
613                 lstrcpyW(PathExpected, pEntry->NameExpected);
614             }
615             break;
616 
617         case EF_TESTDATA:
618             if (pEntry->EF_ & EF_NAME_ONLY)
619             {
620                 lstrcpyW(Path, pEntry->NameBefore);
621             }
622             else
623             {
624                 lstrcpyW(Path, s_TestDir);
625                 lstrcatW(Path, L"\\");
626                 lstrcatW(Path, pEntry->NameBefore);
627             }
628 
629             if (pEntry->NameExpected)
630             {
631                 lstrcpyW(PathExpected, s_TestDir);
632                 lstrcatW(PathExpected, L"\\");
633                 lstrcatW(PathExpected, pEntry->NameExpected);
634             }
635             break;
636 
637         default:
638             assert(0);
639             break;
640     }
641 
642     if (pEntry->EF_ & EF_APP_PATH)
643     {
644         if (!CreateRegAppPath(SectionNumber, LineNumber, pEntry->NameBefore, PathExpected))
645         {
646             skip("Section %d, Line %d: CreateRegAppPath failure\n", SectionNumber, LineNumber);
647             return;
648         }
649     }
650 
651     _SEH2_TRY
652     {
653         SetLastError(ERR_NO_CHANGE);
654         if (pEntry->NameBefore)
655         {
656             Ret = (*s_pPathResolve)(Path, pEntry->Dirs, pEntry->Flags);
657         }
658         else
659         {
660             Ret = (*s_pPathResolve)(NULL, pEntry->Dirs, pEntry->Flags);
661         }
662         Error = GetLastError();
663     }
664     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
665     {
666         Ret = RAISED;
667         Error = ERR_DEAD;
668     }
669     _SEH2_END;
670 
671     if (pEntry->EF_ & EF_APP_PATH)
672     {
673         ok(DeleteRegAppPath(SectionNumber, LineNumber, pEntry->NameBefore),
674            "Section %d, Line %d: DeleteRegAppPath failed\n", SectionNumber, LineNumber);
675     }
676 
677     ok(Ret == pEntry->Ret, "Section %d, Line %d: Ret expected %d, was %d.\n",
678        SectionNumber, LineNumber, pEntry->Ret, Ret);
679     if (pEntry->Error != ERR_IGNORE)
680     {
681         ok(Error == pEntry->Error, "Section %d, Line %d: last error expected %ld, was %ld.\n",
682            SectionNumber, LineNumber, pEntry->Error, Error);
683     }
684 
685     if (pEntry->NameExpected && !(pEntry->EF_ & EF_APP_PATH))
686     {
687         ok(lstrcmpW(Path, PathExpected) == 0, "Section %d, Line %d: Path expected %s, was %s.\n",
688            SectionNumber, LineNumber, wine_dbgstr_w(PathExpected), wine_dbgstr_w(Path));
689     }
690 }
691 
692 static void TestMain_PathResolve(void)
693 {
694     UINT i, cEntries;
695     const TEST_ENTRY *pEntries;
696     WCHAR Saved[128], *pPathExtSaved;
697 
698     pEntries = s_LFNEntries;
699     cEntries = _countof(s_LFNEntries);
700 
701     /* save PATHEXT */
702     if (GetEnvironmentVariableW(L"PATHEXT", Saved, _countof(Saved)))
703         pPathExtSaved = Saved;
704     else
705         pPathExtSaved = NULL;
706 
707     /* Section 1 */
708     for (i = 0; i < cEntries; ++i)
709     {
710         DoEntry(1, pEntries[i].LineNumber, &pEntries[i]);
711     }
712 
713     /* Section 2: reset PATHEXT */
714     if (SetEnvironmentVariableW(L"PATHEXT", NULL))
715     {
716         for (i = 0; i < cEntries; ++i)
717         {
718             DoEntry(2, pEntries[i].LineNumber, &pEntries[i]);
719         }
720     }
721     else
722     {
723         skip("SetEnvironmentVariableW failed\n");
724     }
725 
726     /* Section 3: set PATHEXT to ".COM;.EXE;.BAT" */
727     if (SetEnvironmentVariableW(L"PATHEXT", L".COM;.EXE;.BAT"))
728     {
729         for (i = 0; i < cEntries; ++i)
730         {
731             DoEntry(3, pEntries[i].LineNumber, &pEntries[i]);
732         }
733     }
734     else
735     {
736         skip("SetEnvironmentVariableW failed\n");
737     }
738 
739     /* Section 4: set PATHEXT to ".TXT" */
740     if (SetEnvironmentVariableW(L"PATHEXT", L".TXT"))
741     {
742         for (i = 0; i < cEntries; ++i)
743         {
744             DoEntry(4, pEntries[i].LineNumber, &pEntries[i]);
745         }
746     }
747     else
748     {
749         skip("SetEnvironmentVariableW failed\n");
750     }
751 
752     /* restore PATHEXT */
753     SetEnvironmentVariableW(L"PATHEXT", pPathExtSaved);
754 }
755 
756 START_TEST(PathResolve)
757 {
758     LPWSTR pch;
759     WCHAR szRoot[MAX_PATH];
760 
761     /* Get this program's path */
762     GetModuleFileNameW(NULL, s_TestDir, _countof(s_TestDir));
763 
764     /* Add '\testdir' to the path */
765     pch = wcsrchr(s_TestDir, L'\\');
766     if (pch == NULL)
767     {
768         skip("GetModuleFileName and/or wcsrchr are insane.\n");
769         return;
770     }
771     lstrcpyW(pch, L"\\testdir");
772 
773     /* Create the testdir directory */
774     CreateDirectoryW(s_TestDir, NULL);
775     if (GetFileAttributesW(s_TestDir) == INVALID_FILE_ATTRIBUTES)
776     {
777         skip("testdir is not found.\n");
778         return;
779     }
780 
781     /* Build s_TestDirWithBackslash path */
782     lstrcpyW(s_TestDirWithBackslash, s_TestDir);
783     lstrcatW(s_TestDirWithBackslash, L"\\");
784 
785     /* Build s_LinkTarget path */
786     lstrcpyW(s_LinkTarget, s_TestDir);
787     lstrcatW(s_LinkTarget, L"\\");
788     lstrcatW(s_LinkTarget, L"2PRONG.txt");
789 
790     /* Create the file */
791     fclose(_wfopen(s_LinkTarget, L"wb"));
792     ok(GetFileAttributesW(s_LinkTarget) != INVALID_FILE_ATTRIBUTES, "s_LinkTarget not found\n");
793 
794     /* Build s_LinkTargetWithBackslash path */
795     lstrcpyW(s_LinkTargetWithBackslash, s_TestDir);
796     lstrcatW(s_LinkTargetWithBackslash, L"\\");
797     lstrcatW(s_LinkTargetWithBackslash, L"2PRONG.txt");
798     lstrcatW(s_LinkTargetWithBackslash, L"\\");
799 
800     /* Build s_LinkTargetDoubleBackslash path */
801     lstrcpyW(s_LinkTargetDoubleBackslash, s_TestDir);
802     lstrcatW(s_LinkTargetDoubleBackslash, L"\\\\");
803     lstrcatW(s_LinkTargetDoubleBackslash, L"2PRONG.txt");
804 
805     /* Build s_ShortcutLongName path */
806     lstrcpyW(s_ShortcutLongName, s_TestDir);
807     lstrcatW(s_ShortcutLongName, L"\\");
808     lstrcatW(s_ShortcutLongName, L"CmdLineUtils.lnk"); /* in Long File Name */
809 
810     /* Create s_ShortcutLongName shortcut file */
811     ok(CreateShortcut(s_ShortcutLongName, s_LinkTarget),
812        "CreateShortcut(%s, %s) failed.\n",
813        wine_dbgstr_w(s_ShortcutLongName), wine_dbgstr_w(s_LinkTarget));
814 
815     /* Load shell32.dll */
816     s_hShell32 = LoadLibraryA("shell32");
817     if (s_hShell32 == NULL)
818     {
819         skip("Unable to load shell32.\n");
820         goto Cleanup;
821     }
822 
823     /* Get PathResolve procedure */
824     s_pPathResolve = (PATHRESOLVE)GetProcAddress(s_hShell32, "PathResolve");
825     if (s_pPathResolve == NULL)
826     {
827         skip("Unable to get PathResolve address.\n");
828         goto Cleanup;
829     }
830 
831     /* Get IsLFNDriveW procedure */
832     s_pIsLFNDriveW = (ISLFNDRIVEW)GetProcAddress(s_hShell32, (LPCSTR)(INT_PTR)42);
833     if (s_pIsLFNDriveW == NULL)
834     {
835         skip("Unable to get IsLFNDriveW address.\n");
836         goto Cleanup;
837     }
838 
839     /* Is LFN supported? */
840     lstrcpyW(szRoot, s_TestDir);
841     PathStripToRootW(szRoot);
842     if (!s_pIsLFNDriveW(szRoot))
843     {
844         skip("LFN is not supported in this drive %s.\n", wine_dbgstr_w(szRoot));
845         goto Cleanup;
846     }
847 
848     /* Do tests */
849     TestMain_PathResolve();
850 
851     /* Clean up */
852 Cleanup:
853     DeleteFileW(s_LinkTarget);
854     DeleteFileW(s_ShortcutLongName);
855     RemoveDirectoryW(s_TestDir);
856     FreeLibrary(s_hShell32);
857 }
858