1 /*
2  * Copyright (C) 2005 Stefan Leichter
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 <stdarg.h>
20 #include <stdio.h>
21 
22 #include "wine/test.h"
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winver.h"
27 #include "shlobj.h"
28 
29 static void test_find_file(void)
30 {
31     DWORD ret;
32     UINT dwCur, dwOut ;
33     char tmp[MAX_PATH];
34     char appdir[MAX_PATH];
35     char curdir[MAX_PATH];
36     char filename[MAX_PATH];
37     char outBuf[MAX_PATH];
38     char windir[MAX_PATH];
39     static const char empty[]       = "",
40                       regedit[]     = "regedit",
41                       regedit_exe[] = "regedit.exe";
42 
43     memset(appdir, 0, MAX_PATH);
44     memset(windir, 0, MAX_PATH);
45 
46     dwCur=MAX_PATH;
47     dwOut=MAX_PATH;
48     memset(curdir, 0, MAX_PATH);
49     memset(outBuf, 0, MAX_PATH);
50     ret = VerFindFileA(0, regedit, empty, empty, curdir, &dwCur, outBuf, &dwOut);
51     switch(ret) {
52     case 0L:
53     ok(dwCur == 1, "Wrong length of buffer for current location: "
54        "got %d(%s) expected 1\n", dwCur, curdir);
55     ok(dwOut == 1, "Wrong length of buffer for the recommended installation location: "
56        "got %d(%s) expected 1\n", dwOut, outBuf);
57         break;
58     case VFF_BUFFTOOSMALL:
59         ok(dwCur == MAX_PATH, "Wrong length of buffer for current location: "
60            "got %d(%s) expected MAX_PATH\n", dwCur, curdir);
61         ok(dwOut == MAX_PATH, "Wrong length of buffer for the recommended installation location: "
62            "got %d(%s) expected MAX_PATH\n", dwOut, outBuf);
63         break;
64     default:
65         ok(0, "Got unexpected return value %x\n", ret);
66     }
67 
68     if(!GetWindowsDirectoryA(windir, MAX_PATH))
69         trace("GetWindowsDirectoryA failed\n");
70     else {
71         sprintf(appdir, "%s\\regedit.exe", windir);
72         if(INVALID_FILE_ATTRIBUTES == GetFileAttributesA(appdir))
73             trace("GetFileAttributesA(%s) failed\n", appdir);
74         else {
75             dwCur=MAX_PATH;
76             dwOut=MAX_PATH;
77             memset(curdir, 0, MAX_PATH);
78             memset(outBuf, 0, MAX_PATH);
79             ret = VerFindFileA(0, regedit_exe, empty, empty, curdir, &dwCur, outBuf, &dwOut);
80             switch(ret) {
81             case VFF_CURNEDEST:
82                 ok(dwCur == 1 + strlen(windir), "Wrong length of buffer for current location: "
83                "got %d(%s) expected %d\n", dwCur, curdir, lstrlenA(windir)+1);
84             ok(dwOut == 1, "Wrong length of buffer for the recommended installation location: "
85                "got %d(%s) expected 1\n", dwOut, outBuf);
86                 break;
87             case VFF_BUFFTOOSMALL:
88                 ok(dwCur == MAX_PATH, "Wrong length of buffer for current location: "
89                    "got %d(%s) expected MAX_PATH\n", dwCur, curdir);
90                 ok(dwOut == MAX_PATH, "Wrong length of buffer for the recommended installation location: "
91                    "got %d(%s) expected MAX_PATH\n", dwOut, outBuf);
92                 break;
93             default:
94                 ok(0, "Got unexpected return value %x\n", ret);
95             }
96 
97             dwCur=MAX_PATH;
98             dwOut=MAX_PATH;
99             memset(curdir, 0, MAX_PATH);
100             memset(outBuf, 0, MAX_PATH);
101             ret = VerFindFileA(0, regedit_exe, NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
102             switch(ret) {
103             case VFF_CURNEDEST:
104                 ok(dwCur == 1 + strlen(windir), "Wrong length of buffer for current location: "
105                "got %d(%s) expected %d\n", dwCur, curdir, lstrlenA(windir)+1);
106             ok(dwOut == 1, "Wrong length of buffer for the recommended installation location: "
107                "got %d(%s) expected 1\n", dwOut, outBuf);
108                 break;
109             case VFF_BUFFTOOSMALL:
110                 ok(dwCur == MAX_PATH, "Wrong length of buffer for current location: "
111                    "got %d(%s) expected MAX_PATH\n", dwCur, curdir);
112                 ok(dwOut == MAX_PATH, "Wrong length of buffer for the recommended installation location: "
113                    "got %d(%s) expected MAX_PATH\n", dwOut, outBuf);
114                 break;
115             default:
116                 ok(0, "Got unexpected return value %x\n", ret);
117             }
118         }
119     }
120     if(!GetSystemDirectoryA(windir, MAX_PATH) ||
121        !SHGetSpecialFolderPathA(0, appdir, CSIDL_PROGRAM_FILES, FALSE) ||
122        !GetTempPathA(MAX_PATH, tmp) ||
123        !GetTempFileNameA(tmp, "tes", 0, filename))
124         ok(0, "GetSystemDirectoryA, SHGetSpecialFolderPathA, GetTempPathA or GetTempFileNameA failed\n");
125     else {
126         char *p = strrchr(filename, '\\');
127         if(p) {
128             *(p++) ='\0';
129             SetCurrentDirectoryA(filename);
130             memmove(filename, p, 1 + strlen(p));
131         }
132 
133         dwCur=MAX_PATH;
134         dwOut=MAX_PATH;
135         memset(outBuf, 0, MAX_PATH);
136         memset(curdir, 0, MAX_PATH);
137         ret = VerFindFileA(0, filename, NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
138         switch(ret) {
139         case VFF_CURNEDEST:
140         ok(dwOut == 1, "Wrong length of buffer for the recommended installation location"
141            "got %d(%s) expected 1\n", dwOut, outBuf);
142             break;
143         case VFF_BUFFTOOSMALL:
144             ok(dwOut == MAX_PATH, "Wrong length of buffer for the recommended installation location"
145                "got %d(%s) expected MAX_PATH\n", dwOut, outBuf);
146             break;
147         default:
148             todo_wine ok(0, "Got unexpected return value %x\n", ret);
149         }
150 
151         dwCur=MAX_PATH;
152         dwOut=MAX_PATH;
153         memset(outBuf, 0, MAX_PATH);
154         memset(curdir, 0, MAX_PATH);
155         ret = VerFindFileA(VFFF_ISSHAREDFILE, filename, NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
156         ok(VFF_CURNEDEST == ret, "Wrong return value got %x expected VFF_CURNEDEST\n", ret);
157         ok(dwOut == 1 + strlen(windir), "Wrong length of buffer for current location: "
158            "got %d(%s) expected %d\n", dwOut, outBuf, lstrlenA(windir)+1);
159 
160         dwCur=MAX_PATH;
161         dwOut=MAX_PATH;
162         memset(outBuf, 0, MAX_PATH);
163         memset(curdir, 0, MAX_PATH);
164         ret = VerFindFileA(0, filename, NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
165         ok(VFF_CURNEDEST == ret, "Wrong return value got %x expected VFF_CURNEDEST\n", ret);
166         ok(dwOut == 1 + strlen(appdir), "Wrong length of buffer for current location: "
167            "got %d(%s) expected %d\n", dwOut, outBuf, lstrlenA(appdir)+1);
168 
169         /* search for filename */
170         dwCur=MAX_PATH;
171         dwOut=MAX_PATH;
172         ret = VerFindFileA(0, filename, NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
173         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
174 
175         dwCur=MAX_PATH;
176         dwOut=MAX_PATH;
177         ret = VerFindFileA(0, filename, NULL, empty, curdir, &dwCur, outBuf, &dwOut);
178         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
179 
180         dwCur=MAX_PATH;
181         dwOut=MAX_PATH;
182         ret = VerFindFileA(0, filename, NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
183         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
184 
185         dwCur=MAX_PATH;
186         dwOut=MAX_PATH;
187         ret = VerFindFileA(VFFF_ISSHAREDFILE, filename, NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
188         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
189 
190         dwCur=MAX_PATH;
191         dwOut=MAX_PATH;
192         ret = VerFindFileA(VFFF_ISSHAREDFILE, filename, NULL, empty, curdir, &dwCur, outBuf, &dwOut);
193         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
194 
195         dwCur=MAX_PATH;
196         dwOut=MAX_PATH;
197         ret = VerFindFileA(VFFF_ISSHAREDFILE, filename, NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
198         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
199 
200         /* search for regedit */
201         dwCur=MAX_PATH;
202         dwOut=MAX_PATH;
203         ret = VerFindFileA(0, "regedit", NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
204         ok(!ret, "Wrong return value got %x expected 0\n", ret);
205 
206         dwCur=MAX_PATH;
207         dwOut=MAX_PATH;
208         ret = VerFindFileA(0, "regedit", NULL, empty, curdir, &dwCur, outBuf, &dwOut);
209         ok(!ret, "Wrong return value got %x expected 0\n", ret);
210 
211         dwCur=MAX_PATH;
212         dwOut=MAX_PATH;
213         ret = VerFindFileA(0, "regedit", NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
214         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
215 
216         dwCur=MAX_PATH;
217         dwOut=MAX_PATH;
218         ret = VerFindFileA(VFFF_ISSHAREDFILE, "regedit", NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
219         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
220 
221         dwCur=MAX_PATH;
222         dwOut=MAX_PATH;
223         ret = VerFindFileA(VFFF_ISSHAREDFILE, "regedit", NULL, empty, curdir, &dwCur, outBuf, &dwOut);
224         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
225 
226         dwCur=MAX_PATH;
227         dwOut=MAX_PATH;
228         ret = VerFindFileA(VFFF_ISSHAREDFILE, "regedit", NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
229         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
230 
231         /* search for regedit.exe */
232         dwCur=MAX_PATH;
233         dwOut=MAX_PATH;
234         ret = VerFindFileA(0, "regedit.exe", NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
235         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
236 
237         dwCur=MAX_PATH;
238         dwOut=MAX_PATH;
239         ret = VerFindFileA(0, "regedit.exe", NULL, empty, curdir, &dwCur, outBuf, &dwOut);
240         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
241 
242         dwCur=MAX_PATH;
243         dwOut=MAX_PATH;
244         ret = VerFindFileA(0, "regedit.exe", NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
245         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
246 
247         dwCur=MAX_PATH;
248         dwOut=MAX_PATH;
249         ret = VerFindFileA(VFFF_ISSHAREDFILE, "regedit.exe", NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
250         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
251 
252         dwCur=MAX_PATH;
253         dwOut=MAX_PATH;
254         ret = VerFindFileA(VFFF_ISSHAREDFILE, "regedit.exe", NULL, empty, curdir, &dwCur, outBuf, &dwOut);
255         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
256 
257         dwCur=MAX_PATH;
258         dwOut=MAX_PATH;
259         ret = VerFindFileA(VFFF_ISSHAREDFILE, "regedit.exe", NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
260         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
261 
262         /* nonexistent filename */
263         dwCur=MAX_PATH;
264         dwOut=MAX_PATH;
265         ret = VerFindFileA(0, "doesnotexist.exe", NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
266         ok(!ret, "Wrong return value got %x expected 0\n", ret);
267 
268         dwCur=MAX_PATH;
269         dwOut=MAX_PATH;
270         ret = VerFindFileA(0, "doesnotexist.exe", NULL, empty, curdir, &dwCur, outBuf, &dwOut);
271         ok(!ret, "Wrong return value got %x expected 0\n", ret);
272 
273         dwCur=MAX_PATH;
274         dwOut=MAX_PATH;
275         ret = VerFindFileA(0, "doesnotexist.exe", NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
276         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
277 
278         dwCur=MAX_PATH;
279         dwOut=MAX_PATH;
280         ret = VerFindFileA(0, "doesnotexist.exe", NULL, "C:\\random_path_does_not_exist", curdir, &dwCur, outBuf, &dwOut);
281         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
282 
283         dwCur=MAX_PATH;
284         dwOut=MAX_PATH;
285         ret = VerFindFileA(VFFF_ISSHAREDFILE, "doesnotexist.exe", NULL, NULL, curdir, &dwCur, outBuf, &dwOut);
286         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
287 
288         dwCur=MAX_PATH;
289         dwOut=MAX_PATH;
290         ret = VerFindFileA(VFFF_ISSHAREDFILE, "doesnotexist.exe", NULL, empty, curdir, &dwCur, outBuf, &dwOut);
291         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
292 
293         dwCur=MAX_PATH;
294         dwOut=MAX_PATH;
295         ret = VerFindFileA(VFFF_ISSHAREDFILE, "doesnotexist.exe", NULL, appdir, curdir, &dwCur, outBuf, &dwOut);
296         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
297 
298         dwCur=MAX_PATH;
299         dwOut=MAX_PATH;
300         ret = VerFindFileA(VFFF_ISSHAREDFILE, "doesnotexist.exe", NULL, "C:\\random_path_does_not_exist", curdir, &dwCur, outBuf, &dwOut);
301         ok(ret & VFF_CURNEDEST, "Wrong return value got %x expected VFF_CURNEDEST set\n", ret);
302 
303         DeleteFileA(filename);
304     }
305 }
306 
307 static void test_install_file(void)
308 {
309     CHAR tmpname[MAX_PATH];
310     UINT size = MAX_PATH;
311     DWORD rc;
312     static const CHAR szSrcFileName[] = "nofile.txt";
313     static const CHAR szDestFileName[] = "nofile2.txt";
314     static const CHAR szSrcDir[] = "D:\\oes\\not\\exist";
315     static const CHAR szDestDir[] = "D:\\oes\\not\\exist\\either";
316     static const CHAR szCurDir[] = "C:\\";
317 
318     /* testing Invalid Parameters */
319     memset(tmpname,0,sizeof(tmpname));
320     rc = VerInstallFileA(0x0, NULL, NULL, NULL, NULL, NULL, tmpname, &size);
321     ok (rc == 0x10000 && tmpname[0]==0," expected return 0x10000 and no tempname, got %08x/\'%s\'\n",rc,tmpname);
322     memset(tmpname,0,sizeof(tmpname));
323     size = MAX_PATH;
324     rc = VerInstallFileA(0x0, szSrcFileName, NULL, NULL, NULL, NULL, tmpname, &size);
325     ok (rc == 0x10000 && tmpname[0]==0," expected return 0x10000 and no tempname, got %08x/\'%s\'\n",rc,tmpname);
326     memset(tmpname,0,sizeof(tmpname));
327     size = MAX_PATH;
328     rc = VerInstallFileA(0x0, szSrcFileName, szDestFileName, NULL, NULL, NULL, tmpname, &size);
329     ok (rc == 0x10000 && tmpname[0]==0," expected return 0x10000 and no tempname, got %08x/\'%s\'\n",rc,tmpname);
330     memset(tmpname,0,sizeof(tmpname));
331     size = MAX_PATH;
332     rc = VerInstallFileA(0x0, szSrcFileName, szDestFileName, szSrcDir, NULL, NULL, tmpname, &size);
333     ok (rc == 0x10000 && tmpname[0]==0," expected return 0x10000 and no tempname, got %08x/\'%s\'\n",rc,tmpname);
334 
335     /* Source file does not exist*/
336 
337     memset(tmpname,0,sizeof(tmpname));
338     size = MAX_PATH;
339     rc = VerInstallFileA(0x0, szSrcFileName, szDestFileName, szSrcDir, szDestDir, NULL, tmpname, &size);
340     ok (rc == 0x10000 && tmpname[0]==0," expected return 0x10000 and no tempname, got %08x/\'%s\'\n",rc,tmpname);
341     memset(tmpname,0,sizeof(tmpname));
342     size = MAX_PATH;
343     rc = VerInstallFileA(0x0, szSrcFileName, szDestFileName,  szSrcDir, szDestDir, szCurDir, tmpname, &size);
344     ok (rc == 0x10000 && tmpname[0]==0," expected return 0x10000 and no tempname, got %08x/\'%s\'\n",rc,tmpname);
345 }
346 
347 START_TEST(install)
348 {
349     test_find_file();
350     test_install_file();
351 }
352