wininet/tests: Add a few more tests.
[wine] / dlls / wininet / tests / ftp.c
1 /*
2  * Wininet - ftp tests
3  *
4  * Copyright 2007 Paul Vriens
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /*
22  * FIXME:
23  *     Use InternetGetLastResponseInfo when the last error is set to ERROR_INTERNET_EXTENDED_ERROR.
24  * TODO:
25  *     Add W-function tests.
26  *     Add missing function tests:
27  *         FtpCommand
28  *         FtpFindFirstFile
29  *         FtpGetCurrentDirectory
30  *         FtpGetFileSize
31  *         FtpSetCurrentDirectory
32  */
33
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37
38 #include "windef.h"
39 #include "winbase.h"
40 #include "wininet.h"
41 #include "winsock.h"
42
43 #include "wine/test.h"
44
45 static void test_getfile_no_open(void)
46 {
47     BOOL      bRet;
48
49     /* Invalid internet handle, the others are valid parameters */
50     SetLastError(0xdeadbeef);
51     bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
52     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
53     ok ( GetLastError() == ERROR_INTERNET_NOT_INITIALIZED ||
54          GetLastError() == ERROR_INVALID_HANDLE,
55         "Expected ERROR_INTERNET_NOT_INITIALIZED or ERROR_INVALID_HANDLE (win98), got %d\n", GetLastError());
56 }
57
58 static void test_connect(void)
59 {
60     HINTERNET hInternet, hFtp;
61
62     SetLastError(0xdeadbeef);
63     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
64     ok(hInternet != NULL, "InternetOpen failed : %d\n", GetLastError());
65
66     if(!hInternet)
67     {
68         skip("No internet connection could be made\n");
69         return;
70     }
71
72     /* Try a few username/password combinations:
73      * anonymous : NULL
74      * NULL      : IEUser@
75      * NULL      : NULL
76      */
77
78     SetLastError(0xdeadbeef);
79     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, 0, 0);
80     ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
81     ok ( GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
82         "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
83
84     SetLastError(0xdeadbeef);
85     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
86     ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
87     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
88         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
89
90     /* Using a NULL username and password will be interpreted as anonymous ftp. The username will be 'anonymous' the password
91      * is created via some simple heuristics (see dlls/wininet/ftp.c).
92      * On Wine this registry key is not set by default so (NULL, NULL) will result in anonymous ftp with an (most likely) not
93      * accepted password (the username).
94      * If the first call fails because we get an ERROR_INTERNET_LOGIN_FAILURE, we try again with a (more) correct password.
95      */
96
97     SetLastError(0xdeadbeef);
98     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, 0, 0);
99     if (!hFtp && (GetLastError() == ERROR_INTERNET_LOGIN_FAILURE))
100     {
101         /* We are most likely running on a clean Wine install or a Windows install where the registry key is removed */
102         SetLastError(0xdeadbeef);
103         hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
104     }
105     ok ( hFtp != NULL, "InternetConnect failed : %d\n", GetLastError());
106     ok ( GetLastError() == ERROR_SUCCESS,
107         "ERROR_SUCCESS, got %d\n", GetLastError());
108
109     InternetCloseHandle(hFtp);
110     InternetCloseHandle(hInternet);
111 }
112
113 static void test_createdir(void)
114 {
115     BOOL      bRet;
116     HINTERNET hInternet, hFtp, hConnect;
117
118     /* Invalid internet handle, the other is a valid parameter */
119     SetLastError(0xdeadbeef);
120     bRet = FtpCreateDirectoryA(NULL, "new_directory_deadbeef");
121     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
122     ok ( GetLastError() == ERROR_INVALID_HANDLE,
123         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
124
125     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
126     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
127     if(!hFtp)
128     {
129         skip("No ftp connection could be made to ftp.winehq.org\n");
130         InternetCloseHandle(hInternet);
131         return;
132     }
133
134     /* We should have a ftp-connection (valid ftp session handle), try some creating */
135
136     /* No directory-name */
137     SetLastError(0xdeadbeef);
138     bRet = FtpCreateDirectoryA(hFtp, NULL);
139     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
140     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
141         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
142
143     /* Parameters are OK, but we shouldn't be allowed to create the directory */
144     SetLastError(0xdeadbeef);
145     bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
146     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
147     todo_wine
148     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
149         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
150
151     InternetCloseHandle(hFtp);
152
153     /* Http handle-type for ftp connection */
154
155     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
156
157     /* One small test to show that handle type is checked before parameters */
158     SetLastError(0xdeadbeef);
159     bRet = FtpCreateDirectoryA(hConnect, NULL);
160     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
161     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
162         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
163
164     SetLastError(0xdeadbeef);
165     bRet = FtpCreateDirectoryA(hConnect, "new_directory_deadbeef");
166     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
167     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
168         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
169
170     InternetCloseHandle(hConnect);
171     InternetCloseHandle(hInternet);
172 }
173
174 static void test_deletefile(void)
175 {
176     BOOL      bRet;
177     HINTERNET hInternet, hFtp, hConnect;
178
179     /* Invalid internet handle, the other is a valid parameter */
180     SetLastError(0xdeadbeef);
181     bRet = FtpDeleteFileA(NULL, "non_existent_file_deadbeef");
182     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
183     ok ( GetLastError() == ERROR_INVALID_HANDLE,
184         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
185
186     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
187     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
188     if(!hFtp)
189     {
190         skip("No ftp connection could be made to ftp.winehq.org\n");
191         InternetCloseHandle(hInternet);
192         return;
193     }
194
195     /* We should have a ftp-connection, try some deleting */
196
197     /* No filename */
198     SetLastError(0xdeadbeef);
199     bRet = FtpDeleteFileA(hFtp, NULL);
200     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
201     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
202         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
203
204     /* Parameters are OK but remote file should not be there */
205     SetLastError(0xdeadbeef);
206     bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
207     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
208     todo_wine
209     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
210         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
211
212     InternetCloseHandle(hFtp);
213
214     /* Http handle-type for ftp connection */
215
216     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
217
218     /* One small test to show that handle type is checked before parameters */
219     SetLastError(0xdeadbeef);
220     bRet = FtpDeleteFileA(hConnect, NULL);
221     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
222     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
223         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
224
225     SetLastError(0xdeadbeef);
226     bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
227     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
228     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
229         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
230
231     InternetCloseHandle(hConnect);
232     InternetCloseHandle(hInternet);
233 }
234
235 static void test_getfile(void)
236 {
237     BOOL      bRet;
238     HINTERNET hInternet, hFtp, hConnect;
239
240     /* The order of checking is:
241      *
242      *   All parameters except 'session handle' and 'condition flags'
243      *   Session handle
244      *   Session handle type
245      *   Condition flags
246      */
247
248     /* Test to show the parameter checking order depends on the Windows version */
249     SetLastError(0xdeadbeef);
250     bRet = FtpGetFileA(NULL, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
251     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
252     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
253          GetLastError() == ERROR_INVALID_PARAMETER,
254         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
255
256     /* Test to show session handle is checked before 'condition flags' */
257     SetLastError(0xdeadbeef);
258     bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
259     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
260     ok ( GetLastError() == ERROR_INVALID_HANDLE,
261         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
262
263     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
264     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
265     if(!hFtp)
266     {
267         skip("No ftp connection could be made to ftp.winehq.org\n");
268         InternetCloseHandle(hInternet);
269         return;
270     }
271
272     /* Make sure we start clean */
273
274     DeleteFileA("should_be_non_existing_deadbeef");
275     DeleteFileA("should_also_be_non_existing_deadbeef");
276
277     /* We should have a ftp-connection, try some getting */
278
279     /* No remote file */
280     SetLastError(0xdeadbeef);
281     bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
282     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
283     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
284         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
285     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
286         "Local file should not have been created\n");
287     DeleteFileA("should_be_non_existing_deadbeef");
288
289     /* No local file */
290     SetLastError(0xdeadbeef);
291     bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
292     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
293     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
294         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
295
296     /* Zero attributes, but call succeeds (as would CreateFile with zero attributes) */
297     SetLastError(0xdeadbeef);
298     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
299     todo_wine
300     {
301     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
302     ok ( GetLastError() == ERROR_SUCCESS,
303         "Expected ERROR_SUCCESS, got %d\n", GetLastError());
304     }
305     /* Wine passes this test but for the wrong reason */
306     ok (GetFileAttributesA("should_be_non_existing_deadbeef") != INVALID_FILE_ATTRIBUTES,
307         "Local file should have been created\n");
308     DeleteFileA("should_be_non_existing_deadbeef");
309
310     /* Illegal condition flags */
311     SetLastError(0xdeadbeef);
312     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
313     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
314     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
315         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
316     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
317         "Local file should not have been created\n");
318     DeleteFileA("should_be_non_existing_deadbeef");
319
320     /* Remote file doesn't exist */
321     SetLastError(0xdeadbeef);
322     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
323     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
324     todo_wine
325     {
326     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
327         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
328     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
329     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
330         "Local file should not have been created\n");
331     }
332     DeleteFileA("should_also_be_non_existing_deadbeef");
333
334     /* This one should succeed and give us a copy of the 'welcome.msg' file */
335     SetLastError(0xdeadbeef);
336     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
337     todo_wine
338     {
339     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
340     ok ( GetLastError() == ERROR_SUCCESS,
341         "Expected ERROR_SUCCESS, got %d\n", GetLastError());
342     }
343
344     if (GetFileAttributesA("should_be_non_existing_deadbeef") != INVALID_FILE_ATTRIBUTES)
345     {
346         /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
347         SetLastError(0xdeadbeef);
348         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
349         todo_wine
350         {
351         ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
352         ok ( GetLastError() == ERROR_SUCCESS,
353             "Expected ERROR_SUCCESS, got %d\n", GetLastError());
354         }
355
356         /* Should fail as fFailIfExists is set to TRUE */
357         SetLastError(0xdeadbeef);
358         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
359         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
360         todo_wine
361         ok ( GetLastError() == ERROR_FILE_EXISTS,
362             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
363
364         /* Prove that the existence of the local file is checked first (or at least reported last) */
365         SetLastError(0xdeadbeef);
366         bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
367         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
368         todo_wine
369         ok ( GetLastError() == ERROR_FILE_EXISTS,
370             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
371
372         DeleteFileA("should_be_non_existing_deadbeef");
373     }
374
375     InternetCloseHandle(hFtp);
376
377     /* Http handle-type for ftp connection */
378
379     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
380
381     /* Test to show the parameter checking order depends on the Windows version */
382     SetLastError(0xdeadbeef);
383     bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
384     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
385     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
386          GetLastError() == ERROR_INVALID_PARAMETER,
387         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
388
389     /* Test to show that 'session handle type' is checked before 'condition flags' */
390     SetLastError(0xdeadbeef);
391     bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
392     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
393     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
394         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
395
396     SetLastError(0xdeadbeef);
397     bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
398     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
399     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
400         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
401
402     InternetCloseHandle(hConnect);
403     InternetCloseHandle(hInternet);
404 }
405
406 static void test_openfile(void)
407 {
408     HINTERNET hOpenFile, hInternet, hFtp, hConnect;
409
410     /* Invalid internet handle, the rest are valid parameters */
411     SetLastError(0xdeadbeef);
412     hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
413     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
414     ok ( GetLastError() == ERROR_INVALID_HANDLE,
415         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
416     InternetCloseHandle(hOpenFile); /* Just in case */
417
418     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
419     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
420     if(!hFtp)
421     {
422         skip("No ftp connection could be made to ftp.winehq.org\n");
423         InternetCloseHandle(hInternet);
424         return;
425     }
426
427     /* We should have a ftp-connection (valid ftp session handle), try some opening */
428
429     /* No filename */
430     SetLastError(0xdeadbeef);
431     hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
432     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
433     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
434         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
435     InternetCloseHandle(hOpenFile); /* Just in case */
436
437     /* Illegal access flags */
438     SetLastError(0xdeadbeef);
439     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
440     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
441     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
442         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
443     InternetCloseHandle(hOpenFile); /* Just in case */
444
445     /* Illegal combination of access flags */
446     SetLastError(0xdeadbeef);
447     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
448     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
449     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
450         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
451     InternetCloseHandle(hOpenFile); /* Just in case */
452
453     /* Illegal condition flags */
454     SetLastError(0xdeadbeef);
455     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 5, 0);
456     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
457     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
458         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
459     InternetCloseHandle(hOpenFile); /* Just in case */
460
461     /* All OK */
462     SetLastError(0xdeadbeef);
463     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
464     ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
465     /* For some strange/unknown reason, win98 returns ERROR_FILE_NOT_FOUND */
466     ok ( GetLastError() == ERROR_SUCCESS || GetLastError() == ERROR_FILE_NOT_FOUND,
467         "Expected ERROR_SUCCESS or ERROR_FILE_NOT_FOUND (win98), got %d\n", GetLastError());
468
469     if (hOpenFile)
470     {
471         BOOL bRet;
472         HINTERNET hOpenFile2;
473         HANDLE    hFile;
474
475         /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
476         SetLastError(0xdeadbeef);
477         bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
478         ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
479         todo_wine
480         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
481             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
482
483         SetLastError(0xdeadbeef);
484         bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
485         ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
486         todo_wine
487         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
488             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
489
490         SetLastError(0xdeadbeef);
491         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
492         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
493         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
494             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
495         DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
496
497         SetLastError(0xdeadbeef);
498         hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
499         ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n");
500         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
501             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
502         InternetCloseHandle(hOpenFile2); /* Just in case */
503
504         /* Create a temporary local file */
505         SetLastError(0xdeadbeef);
506         hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
507         ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
508         CloseHandle(hFile);
509         SetLastError(0xdeadbeef);
510         bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
511         ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
512         todo_wine
513         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
514             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
515         DeleteFileA("now_existing_local");
516
517         SetLastError(0xdeadbeef);
518         bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
519         ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
520         todo_wine
521         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
522             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
523
524         SetLastError(0xdeadbeef);
525         bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
526         ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
527         todo_wine
528         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
529             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
530     }
531
532     InternetCloseHandle(hOpenFile);
533     InternetCloseHandle(hFtp);
534
535     /* Http handle-type for ftp connection */
536
537     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
538
539     /* One small test to show that handle type is checked before parameters */
540     SetLastError(0xdeadbeef);
541     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
542     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
543     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
544         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
545     InternetCloseHandle(hOpenFile); /* Just in case */
546
547     SetLastError(0xdeadbeef);
548     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
549     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
550     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
551         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
552
553     InternetCloseHandle(hOpenFile); /* Just in case */
554     InternetCloseHandle(hConnect);
555     InternetCloseHandle(hInternet);
556 }
557
558 static void test_putfile(void)
559 {
560     BOOL      bRet;
561     HINTERNET hInternet, hFtp, hConnect;
562     HANDLE    hFile;
563
564     /* The order of checking is:
565      *
566      *   All parameters except 'session handle' and 'condition flags'
567      *   Session handle
568      *   Session handle type
569      *   Condition flags
570      */
571
572     /* Test to show the parameter checking order depends on the Windows version */
573     SetLastError(0xdeadbeef);
574     bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
575     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
576     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
577          GetLastError() == ERROR_INVALID_PARAMETER,
578         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
579
580     /* Test to show session handle is checked before 'condition flags' */
581     SetLastError(0xdeadbeef);
582     bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
583     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
584     ok ( GetLastError() == ERROR_INVALID_HANDLE,
585         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
586
587     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
588     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
589     if(!hFtp)
590     {
591         skip("No ftp connection could be made to ftp.winehq.org\n");
592         InternetCloseHandle(hInternet);
593         return;
594     }
595
596     /* We should have a ftp-connection, try some puts */
597
598     /* No local file given */
599     SetLastError(0xdeadbeef);
600     bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
601     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
602     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
603         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
604
605     /* No remote file given */
606     SetLastError(0xdeadbeef);
607     bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
608     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
609     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
610         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
611
612     /* Illegal condition flags */
613     SetLastError(0xdeadbeef);
614     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
615     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
616     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
617         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
618
619     /* Parameters are OK but local file doesn't exist */
620     SetLastError(0xdeadbeef);
621     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
622     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
623     ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
624         "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
625
626     /* Create a temporary local file */
627     SetLastError(0xdeadbeef);
628     hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
629     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
630     CloseHandle(hFile);
631
632     /* Local file exists but we shouldn't be allowed to 'put' the file */
633     SetLastError(0xdeadbeef);
634     bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
635     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
636     todo_wine
637     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
638         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
639
640     DeleteFileA("now_existing_local");
641
642     InternetCloseHandle(hFtp);
643
644     /* Http handle-type for ftp connection */
645
646     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
647
648     /* Test to show the parameter checking order depends on the Windows version */
649     SetLastError(0xdeadbeef);
650     bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
651     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
652     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
653          GetLastError() == ERROR_INVALID_PARAMETER,
654         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
655
656     /* Test to show that 'session handle type' is checked before 'condition flags' */
657     SetLastError(0xdeadbeef);
658     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
659     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
660     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
661         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
662
663     SetLastError(0xdeadbeef);
664     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
665     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
666     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
667         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
668
669     InternetCloseHandle(hConnect);
670     InternetCloseHandle(hInternet);
671 }
672
673 static void test_removedir(void)
674 {
675     BOOL      bRet;
676     HINTERNET hInternet, hFtp, hConnect;
677
678     /* Invalid internet handle, the other is a valid parameter */
679     SetLastError(0xdeadbeef);
680     bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
681     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
682     ok ( GetLastError() == ERROR_INVALID_HANDLE,
683         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
684
685     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
686     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
687     if(!hFtp)
688     {
689         skip("No ftp connection could be made to ftp.winehq.org\n");
690         InternetCloseHandle(hInternet);
691         return;
692     }
693
694     /* We should have a ftp-connection, try some removing */
695
696     /* No remote directory given */
697     SetLastError(0xdeadbeef);
698     bRet = FtpRemoveDirectoryA(hFtp, NULL);
699     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
700     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
701         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
702
703     /* Remote directory doesn't exist */
704     SetLastError(0xdeadbeef);
705     bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
706     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
707     todo_wine
708     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
709         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
710
711     /* We shouldn't be allowed to remove that directory */
712     SetLastError(0xdeadbeef);
713     bRet = FtpRemoveDirectoryA(hFtp, "pub");
714     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
715     todo_wine
716     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
717         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
718
719     InternetCloseHandle(hFtp);
720
721     /* Http handle-type for ftp connection */
722
723     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
724
725     /* One small test to show that handle type is checked before parameters */
726     SetLastError(0xdeadbeef);
727     bRet = FtpRemoveDirectoryA(hConnect, NULL);
728     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
729     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
730         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
731
732     SetLastError(0xdeadbeef);
733     bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
734     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
735     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
736         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
737
738     InternetCloseHandle(hConnect);
739     InternetCloseHandle(hInternet);
740 }
741
742 static void test_renamefile(void)
743 {
744     BOOL      bRet;
745     HINTERNET hInternet, hFtp, hConnect;
746
747     /* Invalid internet handle, the rest are valid parameters */
748     SetLastError(0xdeadbeef);
749     bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
750     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
751     ok ( GetLastError() == ERROR_INVALID_HANDLE,
752         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
753
754     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
755     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
756     if(!hFtp)
757     {
758         skip("No ftp connection could be made to ftp.winehq.org\n");
759         InternetCloseHandle(hInternet);
760         return;
761     }
762
763     /* We should have a ftp-connection, try some renaming */
764
765     /* No 'existing' file */
766     SetLastError(0xdeadbeef);
767     bRet = FtpRenameFileA(hFtp , NULL, "new");
768     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
769     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
770         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
771
772     /* No new file */
773     SetLastError(0xdeadbeef);
774     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
775     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
776     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
777         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
778
779     /* Existing file shouldn't be there */
780     SetLastError(0xdeadbeef);
781     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
782     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
783     todo_wine
784     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
785         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
786
787     InternetCloseHandle(hFtp);
788
789     /* Http handle-type for ftp connection */
790
791     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
792
793     /* One small test to show that handle type is checked before parameters */
794     SetLastError(0xdeadbeef);
795     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
796     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
797     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
798         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
799
800     SetLastError(0xdeadbeef);
801     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
802     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
803     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
804         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
805
806     InternetCloseHandle(hConnect);
807     InternetCloseHandle(hInternet);
808 }
809
810 START_TEST(ftp)
811 {
812     /* The first call should always be a proper InternetOpen, if not
813      * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
814      * all parameters are correct but no session handle is given. Whereas
815      * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
816      * is done before.
817      * The following test will show that behaviour, where the tests inside
818      * the other sub-tests will show the other situation.
819      */
820     test_getfile_no_open();
821     test_connect();
822     test_createdir();
823     test_deletefile();
824     test_getfile();
825     test_openfile();
826     test_putfile();
827     test_removedir();
828     test_renamefile();
829 }