wined3d: Default to GLSL. This is safe because we now have proper ps2.0/vs2.0 detection.
[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, INTERNET_FLAG_PASSIVE, 0);
80     if (hFtp)  /* some servers accept an empty password */
81     {
82         ok ( GetLastError() == ERROR_SUCCESS, "ERROR_SUCCESS, got %d\n", GetLastError());
83         InternetCloseHandle(hFtp);
84     }
85     else
86         ok ( GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
87              "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
88
89     SetLastError(0xdeadbeef);
90     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
91     ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
92     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
93         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
94
95     /* Using a NULL username and password will be interpreted as anonymous ftp. The username will be 'anonymous' the password
96      * is created via some simple heuristics (see dlls/wininet/ftp.c).
97      * On Wine this registry key is not set by default so (NULL, NULL) will result in anonymous ftp with an (most likely) not
98      * accepted password (the username).
99      * If the first call fails because we get an ERROR_INTERNET_LOGIN_FAILURE, we try again with a (more) correct password.
100      */
101
102     SetLastError(0xdeadbeef);
103     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
104     if (!hFtp && (GetLastError() == ERROR_INTERNET_LOGIN_FAILURE))
105     {
106         /* We are most likely running on a clean Wine install or a Windows install where the registry key is removed */
107         SetLastError(0xdeadbeef);
108         hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
109     }
110     ok ( hFtp != NULL, "InternetConnect failed : %d\n", GetLastError());
111     ok ( GetLastError() == ERROR_SUCCESS,
112         "ERROR_SUCCESS, got %d\n", GetLastError());
113
114     InternetCloseHandle(hFtp);
115     InternetCloseHandle(hInternet);
116 }
117
118 static void test_createdir(void)
119 {
120     BOOL      bRet;
121     HINTERNET hInternet, hFtp, hConnect;
122
123     /* Invalid internet handle, the other is a valid parameter */
124     SetLastError(0xdeadbeef);
125     bRet = FtpCreateDirectoryA(NULL, "new_directory_deadbeef");
126     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
127     ok ( GetLastError() == ERROR_INVALID_HANDLE,
128         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
129
130     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
131     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
132     if(!hFtp)
133     {
134         skip("No ftp connection could be made to ftp.winehq.org\n");
135         InternetCloseHandle(hInternet);
136         return;
137     }
138
139     /* We should have a ftp-connection (valid ftp session handle), try some creating */
140
141     /* No directory-name */
142     SetLastError(0xdeadbeef);
143     bRet = FtpCreateDirectoryA(hFtp, NULL);
144     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
145     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
146         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
147
148     /* Parameters are OK, but we shouldn't be allowed to create the directory */
149     SetLastError(0xdeadbeef);
150     bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
151     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
152     todo_wine
153     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
154         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
155
156     InternetCloseHandle(hFtp);
157
158     /* Http handle-type for ftp connection */
159
160     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
161
162     /* One small test to show that handle type is checked before parameters */
163     SetLastError(0xdeadbeef);
164     bRet = FtpCreateDirectoryA(hConnect, NULL);
165     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
166     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
167         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
168
169     SetLastError(0xdeadbeef);
170     bRet = FtpCreateDirectoryA(hConnect, "new_directory_deadbeef");
171     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
172     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
173         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
174
175     InternetCloseHandle(hConnect);
176     InternetCloseHandle(hInternet);
177 }
178
179 static void test_deletefile(void)
180 {
181     BOOL      bRet;
182     HINTERNET hInternet, hFtp, hConnect;
183
184     /* Invalid internet handle, the other is a valid parameter */
185     SetLastError(0xdeadbeef);
186     bRet = FtpDeleteFileA(NULL, "non_existent_file_deadbeef");
187     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
188     ok ( GetLastError() == ERROR_INVALID_HANDLE,
189         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
190
191     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
192     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
193     if(!hFtp)
194     {
195         skip("No ftp connection could be made to ftp.winehq.org\n");
196         InternetCloseHandle(hInternet);
197         return;
198     }
199
200     /* We should have a ftp-connection, try some deleting */
201
202     /* No filename */
203     SetLastError(0xdeadbeef);
204     bRet = FtpDeleteFileA(hFtp, NULL);
205     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
206     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
207         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
208
209     /* Parameters are OK but remote file should not be there */
210     SetLastError(0xdeadbeef);
211     bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
212     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
213     todo_wine
214     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
215         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
216
217     InternetCloseHandle(hFtp);
218
219     /* Http handle-type for ftp connection */
220
221     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
222
223     /* One small test to show that handle type is checked before parameters */
224     SetLastError(0xdeadbeef);
225     bRet = FtpDeleteFileA(hConnect, NULL);
226     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
227     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
228         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
229
230     SetLastError(0xdeadbeef);
231     bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
232     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
233     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
234         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
235
236     InternetCloseHandle(hConnect);
237     InternetCloseHandle(hInternet);
238 }
239
240 static void test_getfile(void)
241 {
242     BOOL      bRet;
243     HINTERNET hInternet, hFtp, hConnect;
244     HANDLE    hFile;
245
246     /* The order of checking is:
247      *
248      *   All parameters except 'session handle' and 'condition flags'
249      *   Session handle
250      *   Session handle type
251      *   Condition flags
252      */
253
254     /* Test to show the parameter checking order depends on the Windows version */
255     SetLastError(0xdeadbeef);
256     bRet = FtpGetFileA(NULL, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
257     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
258     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
259          GetLastError() == ERROR_INVALID_PARAMETER,
260         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
261
262     /* Test to show session handle is checked before 'condition flags' */
263     SetLastError(0xdeadbeef);
264     bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
265     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
266     ok ( GetLastError() == ERROR_INVALID_HANDLE,
267         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
268
269     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
270     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
271     if(!hFtp)
272     {
273         skip("No ftp connection could be made to ftp.winehq.org\n");
274         InternetCloseHandle(hInternet);
275         return;
276     }
277
278     /* Make sure we start clean */
279
280     DeleteFileA("should_be_non_existing_deadbeef");
281     DeleteFileA("should_also_be_non_existing_deadbeef");
282
283     /* We should have a ftp-connection, try some getting */
284
285     /* No remote file */
286     SetLastError(0xdeadbeef);
287     bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
288     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
289     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
290         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
291     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
292         "Local file should not have been created\n");
293     DeleteFileA("should_be_non_existing_deadbeef");
294
295     /* No local file */
296     SetLastError(0xdeadbeef);
297     bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
298     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
299     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
300         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
301
302     /* Zero attributes */
303     SetLastError(0xdeadbeef);
304     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
305     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
306     ok (GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
307     ok (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES,
308         "Local file should have been created\n");
309     DeleteFileA("should_be_existing_non_deadbeef");
310
311     /* Illegal condition flags */
312     SetLastError(0xdeadbeef);
313     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 0xffffffff, 0);
314     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
315     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
316         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
317     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
318         "Local file should not have been created\n");
319     DeleteFileA("should_be_non_existing_deadbeef");
320
321     /* Remote file doesn't exist (and local doesn't exist as well) */
322     SetLastError(0xdeadbeef);
323     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
324     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
325     todo_wine
326     {
327     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
328         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
329     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
330     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
331         "Local file should not have been created\n");
332     }
333     DeleteFileA("should_also_be_non_existing_deadbeef");
334
335     /* Same call as the previous but now the local file does exists. Windows just removes the file if the call fails
336      * even if the local existed before!
337      */
338
339     /* Create a temporary local file */
340     SetLastError(0xdeadbeef);
341     hFile = CreateFileA("should_also_be_non_existing_deadbeef", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
342     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
343     CloseHandle(hFile);
344     SetLastError(0xdeadbeef);
345     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
346     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
347     todo_wine
348     {
349     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
350         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
351     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
352     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
353         "Local file should not have been created\n");
354     }
355     DeleteFileA("should_also_be_non_existing_deadbeef");
356
357     /* This one should succeed */
358     SetLastError(0xdeadbeef);
359     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
360     ok ( bRet == TRUE, "Expected FtpGetFileA to fail\n");
361     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
362
363     if (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES)
364     {
365         /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
366         SetLastError(0xdeadbeef);
367         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
368         ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
369         ok ( GetLastError() == ERROR_SUCCESS,
370             "Expected ERROR_SUCCESS, got %d\n", GetLastError());
371
372         /* Should fail as fFailIfExists is set to TRUE */
373         SetLastError(0xdeadbeef);
374         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
375         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
376         ok ( GetLastError() == ERROR_FILE_EXISTS,
377             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
378
379         /* Prove that the existence of the local file is checked first (or at least reported last) */
380         SetLastError(0xdeadbeef);
381         bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
382         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
383         ok ( GetLastError() == ERROR_FILE_EXISTS,
384             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
385
386         DeleteFileA("should_be_existing_non_deadbeef");
387     }
388
389     InternetCloseHandle(hFtp);
390
391     /* Http handle-type for ftp connection */
392
393     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
394
395     /* Test to show the parameter checking order depends on the Windows version */
396     SetLastError(0xdeadbeef);
397     bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, 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          GetLastError() == ERROR_INVALID_PARAMETER,
401         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
402
403     /* Test to show that 'session handle type' is checked before 'condition flags' */
404     SetLastError(0xdeadbeef);
405     bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
406     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
407     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
408         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
409
410     SetLastError(0xdeadbeef);
411     bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
412     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
413     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
414         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
415
416     InternetCloseHandle(hConnect);
417     InternetCloseHandle(hInternet);
418 }
419
420 static void test_openfile(void)
421 {
422     HINTERNET hOpenFile, hInternet, hFtp, hConnect;
423
424     /* Invalid internet handle, the rest are valid parameters */
425     SetLastError(0xdeadbeef);
426     hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
427     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
428     ok ( GetLastError() == ERROR_INVALID_HANDLE,
429         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
430     InternetCloseHandle(hOpenFile); /* Just in case */
431
432     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
433     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
434     if(!hFtp)
435     {
436         skip("No ftp connection could be made to ftp.winehq.org\n");
437         InternetCloseHandle(hInternet);
438         return;
439     }
440
441     /* We should have a ftp-connection (valid ftp session handle), try some opening */
442
443     /* No filename */
444     SetLastError(0xdeadbeef);
445     hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
446     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
447     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
448         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
449     InternetCloseHandle(hOpenFile); /* Just in case */
450
451     /* Illegal access flags */
452     SetLastError(0xdeadbeef);
453     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
454     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
455     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
456         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
457     InternetCloseHandle(hOpenFile); /* Just in case */
458
459     /* Illegal combination of access flags */
460     SetLastError(0xdeadbeef);
461     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
462     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
463     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
464         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
465     InternetCloseHandle(hOpenFile); /* Just in case */
466
467     /* Illegal condition flags */
468     SetLastError(0xdeadbeef);
469     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 0xffffffff, 0);
470     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
471     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
472         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
473     InternetCloseHandle(hOpenFile); /* Just in case */
474
475     SetLastError(0xdeadbeef);
476     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
477     ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
478     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", GetLastError());
479
480     if (hOpenFile)
481     {
482         BOOL bRet;
483         HINTERNET hOpenFile2;
484         HANDLE    hFile;
485
486         /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
487         SetLastError(0xdeadbeef);
488         bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
489         ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
490         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
491             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
492
493         SetLastError(0xdeadbeef);
494         bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
495         ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
496         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
497             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
498
499         SetLastError(0xdeadbeef);
500         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
501         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
502         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
503             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
504         DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
505
506         SetLastError(0xdeadbeef);
507         hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
508         ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n");
509         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
510             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
511         InternetCloseHandle(hOpenFile2); /* Just in case */
512
513         /* Create a temporary local file */
514         SetLastError(0xdeadbeef);
515         hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
516         ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
517         CloseHandle(hFile);
518         SetLastError(0xdeadbeef);
519         bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
520         ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
521         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
522             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
523         DeleteFileA("now_existing_local");
524
525         SetLastError(0xdeadbeef);
526         bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
527         ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
528         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
529             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
530
531         SetLastError(0xdeadbeef);
532         bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
533         ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
534         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
535             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
536     }
537
538     InternetCloseHandle(hOpenFile);
539     InternetCloseHandle(hFtp);
540
541     /* Http handle-type for ftp connection */
542
543     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
544
545     /* One small test to show that handle type is checked before parameters */
546     SetLastError(0xdeadbeef);
547     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
548     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
549     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
550         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
551     InternetCloseHandle(hOpenFile); /* Just in case */
552
553     SetLastError(0xdeadbeef);
554     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
555     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
556     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
557         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
558
559     InternetCloseHandle(hOpenFile); /* Just in case */
560     InternetCloseHandle(hConnect);
561     InternetCloseHandle(hInternet);
562 }
563
564 static void test_putfile(void)
565 {
566     BOOL      bRet;
567     HINTERNET hInternet, hFtp, hConnect;
568     HANDLE    hFile;
569
570     /* The order of checking is:
571      *
572      *   All parameters except 'session handle' and 'condition flags'
573      *   Session handle
574      *   Session handle type
575      *   Condition flags
576      */
577
578     /* Test to show the parameter checking order depends on the Windows version */
579     SetLastError(0xdeadbeef);
580     bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
581     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
582     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
583          GetLastError() == ERROR_INVALID_PARAMETER,
584         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
585
586     /* Test to show session handle is checked before 'condition flags' */
587     SetLastError(0xdeadbeef);
588     bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
589     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
590     ok ( GetLastError() == ERROR_INVALID_HANDLE,
591         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
592
593     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
594     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
595     if(!hFtp)
596     {
597         skip("No ftp connection could be made to ftp.winehq.org\n");
598         InternetCloseHandle(hInternet);
599         return;
600     }
601
602     /* Start clean */
603     DeleteFileA("non_existing_local");
604
605     /* We should have a ftp-connection, try some puts */
606
607     /* No local file given */
608     SetLastError(0xdeadbeef);
609     bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
610     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
611     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
612         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
613
614     /* No remote file given */
615     SetLastError(0xdeadbeef);
616     bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
617     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
618     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
619         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
620
621     /* Illegal condition flags */
622     SetLastError(0xdeadbeef);
623     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
624     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
625     ok ( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
626         "Expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
627
628     /* Parameters are OK but local file doesn't exist */
629     SetLastError(0xdeadbeef);
630     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
631     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
632     ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
633         "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
634
635     /* Create a temporary local file */
636     SetLastError(0xdeadbeef);
637     hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
638     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
639     CloseHandle(hFile);
640
641     /* Local file exists but we shouldn't be allowed to 'put' the file */
642     SetLastError(0xdeadbeef);
643     bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
644     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
645     todo_wine
646     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
647         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
648
649     DeleteFileA("now_existing_local");
650
651     InternetCloseHandle(hFtp);
652
653     /* Http handle-type for ftp connection */
654
655     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
656
657     /* Test to show the parameter checking order depends on the Windows version */
658     SetLastError(0xdeadbeef);
659     bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
660     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
661     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
662          GetLastError() == ERROR_INVALID_PARAMETER,
663         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
664
665     /* Test to show that 'session handle type' is checked before 'condition flags' */
666     SetLastError(0xdeadbeef);
667     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
668     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
669     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
670         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
671
672     SetLastError(0xdeadbeef);
673     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
674     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
675     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
676         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
677
678     InternetCloseHandle(hConnect);
679     InternetCloseHandle(hInternet);
680 }
681
682 static void test_removedir(void)
683 {
684     BOOL      bRet;
685     HINTERNET hInternet, hFtp, hConnect;
686
687     /* Invalid internet handle, the other is a valid parameter */
688     SetLastError(0xdeadbeef);
689     bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
690     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
691     ok ( GetLastError() == ERROR_INVALID_HANDLE,
692         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
693
694     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
695     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
696     if(!hFtp)
697     {
698         skip("No ftp connection could be made to ftp.winehq.org\n");
699         InternetCloseHandle(hInternet);
700         return;
701     }
702
703     /* We should have a ftp-connection, try some removing */
704
705     /* No remote directory given */
706     SetLastError(0xdeadbeef);
707     bRet = FtpRemoveDirectoryA(hFtp, NULL);
708     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
709     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
710         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
711
712     /* Remote directory doesn't exist */
713     SetLastError(0xdeadbeef);
714     bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
715     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
716     todo_wine
717     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
718         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
719
720     /* We shouldn't be allowed to remove that directory */
721     SetLastError(0xdeadbeef);
722     bRet = FtpRemoveDirectoryA(hFtp, "pub");
723     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
724     todo_wine
725     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
726         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
727
728     InternetCloseHandle(hFtp);
729
730     /* Http handle-type for ftp connection */
731
732     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
733
734     /* One small test to show that handle type is checked before parameters */
735     SetLastError(0xdeadbeef);
736     bRet = FtpRemoveDirectoryA(hConnect, NULL);
737     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
738     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
739         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
740
741     SetLastError(0xdeadbeef);
742     bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
743     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
744     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
745         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
746
747     InternetCloseHandle(hConnect);
748     InternetCloseHandle(hInternet);
749 }
750
751 static void test_renamefile(void)
752 {
753     BOOL      bRet;
754     HINTERNET hInternet, hFtp, hConnect;
755
756     /* Invalid internet handle, the rest are valid parameters */
757     SetLastError(0xdeadbeef);
758     bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
759     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
760     ok ( GetLastError() == ERROR_INVALID_HANDLE,
761         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
762
763     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
764     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
765     if(!hFtp)
766     {
767         skip("No ftp connection could be made to ftp.winehq.org\n");
768         InternetCloseHandle(hInternet);
769         return;
770     }
771
772     /* We should have a ftp-connection, try some renaming */
773
774     /* No 'existing' file */
775     SetLastError(0xdeadbeef);
776     bRet = FtpRenameFileA(hFtp , NULL, "new");
777     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
778     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
779         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
780
781     /* No new file */
782     SetLastError(0xdeadbeef);
783     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
784     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
785     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
786         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
787
788     /* Existing file shouldn't be there */
789     SetLastError(0xdeadbeef);
790     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
791     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
792     todo_wine
793     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
794         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
795
796     InternetCloseHandle(hFtp);
797
798     /* Http handle-type for ftp connection */
799
800     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
801
802     /* One small test to show that handle type is checked before parameters */
803     SetLastError(0xdeadbeef);
804     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
805     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
806     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
807         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
808
809     SetLastError(0xdeadbeef);
810     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
811     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
812     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
813         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
814
815     InternetCloseHandle(hConnect);
816     InternetCloseHandle(hInternet);
817 }
818
819 static void test_multiple(void)
820 {
821     BOOL      bRet;
822     HINTERNET hInternet, hFtp, hOpenFile;
823
824     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
825     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
826     if(!hFtp)
827     {
828         skip("No ftp connection could be made to ftp.winehq.org\n");
829         InternetCloseHandle(hInternet);
830         return;
831     }
832
833     /* A correct call */
834     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
835     ok(bRet, "Expected FtpGetFileA to succeed\n");
836     DeleteFileA("should_be_existing_non_deadbeef");
837
838     SetLastError(0xdeadbeef);
839     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
840     ok(hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
841     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", GetLastError());
842
843     InternetCloseHandle(hOpenFile);
844     InternetCloseHandle(hFtp);
845     InternetCloseHandle(hInternet);
846 }
847
848 START_TEST(ftp)
849 {
850     /* The first call should always be a proper InternetOpen, if not
851      * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
852      * all parameters are correct but no session handle is given. Whereas
853      * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
854      * is done before.
855      * The following test will show that behaviour, where the tests inside
856      * the other sub-tests will show the other situation.
857      */
858     test_getfile_no_open();
859     test_connect();
860     test_createdir();
861     test_deletefile();
862     test_getfile();
863     test_openfile();
864     test_putfile();
865     test_removedir();
866     test_renamefile();
867
868     /* A test that does two particular calls in one connection, this currently fails on Wine.
869      * The problem lies in FtpGetFile but is exposed in FtpOpenFile.
870      * Once this is fixed we should change the total test to setup and clear the connections
871      * only once. (and get rid of test_multiple).
872      */
873     test_multiple();
874 }