wininet: Always return an error when a transfer is in progress.
[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_non_existing_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
305     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
306     todo_wine
307     {
308     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
309         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
310     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
311         "Local file should not have been created\n");
312     }
313     DeleteFileA("should_be_non_existing_deadbeef");
314
315     /* Illegal condition flags */
316     SetLastError(0xdeadbeef);
317     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 0xffffffff, 0);
318     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
319     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
320         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
321     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
322         "Local file should not have been created\n");
323     DeleteFileA("should_be_non_existing_deadbeef");
324
325     /* Remote file doesn't exist (and local doesn't exist as well) */
326     SetLastError(0xdeadbeef);
327     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
328     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
329     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
330         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
331     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
332     todo_wine
333     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
334         "Local file should not have been created\n");
335     DeleteFileA("should_also_be_non_existing_deadbeef");
336
337     /* Same call as the previous but now the local file does exists. Windows just removes the file if the call fails
338      * even if the local existed before!
339      */
340
341     /* Create a temporary local file */
342     SetLastError(0xdeadbeef);
343     hFile = CreateFileA("should_also_be_non_existing_deadbeef", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
344     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
345     CloseHandle(hFile);
346     SetLastError(0xdeadbeef);
347     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
348     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
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     todo_wine
353     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
354         "Local file should not have been created\n");
355     DeleteFileA("should_also_be_non_existing_deadbeef");
356
357     /* This one should fail */
358     SetLastError(0xdeadbeef);
359     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
360     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
361     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
362         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
363
364     if (GetFileAttributesA("should_be_non_existing_deadbeef") != INVALID_FILE_ATTRIBUTES)
365     {
366         /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
367         SetLastError(0xdeadbeef);
368         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
369         todo_wine
370         {
371         ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
372         ok ( GetLastError() == ERROR_SUCCESS,
373             "Expected ERROR_SUCCESS, got %d\n", GetLastError());
374         }
375
376         /* Should fail as fFailIfExists is set to TRUE */
377         SetLastError(0xdeadbeef);
378         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
379         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
380         ok ( GetLastError() == ERROR_FILE_EXISTS,
381             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
382
383         /* Prove that the existence of the local file is checked first (or at least reported last) */
384         SetLastError(0xdeadbeef);
385         bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
386         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
387         ok ( GetLastError() == ERROR_FILE_EXISTS,
388             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
389
390         DeleteFileA("should_be_non_existing_deadbeef");
391     }
392
393     InternetCloseHandle(hFtp);
394
395     /* Http handle-type for ftp connection */
396
397     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
398
399     /* Test to show the parameter checking order depends on the Windows version */
400     SetLastError(0xdeadbeef);
401     bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
402     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
403     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
404          GetLastError() == ERROR_INVALID_PARAMETER,
405         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
406
407     /* Test to show that 'session handle type' is checked before 'condition flags' */
408     SetLastError(0xdeadbeef);
409     bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
410     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
411     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
412         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
413
414     SetLastError(0xdeadbeef);
415     bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
416     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
417     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
418         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
419
420     InternetCloseHandle(hConnect);
421     InternetCloseHandle(hInternet);
422 }
423
424 static void test_openfile(void)
425 {
426     HINTERNET hOpenFile, hInternet, hFtp, hConnect;
427
428     /* Invalid internet handle, the rest are valid parameters */
429     SetLastError(0xdeadbeef);
430     hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
431     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
432     ok ( GetLastError() == ERROR_INVALID_HANDLE,
433         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
434     InternetCloseHandle(hOpenFile); /* Just in case */
435
436     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
437     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
438     if(!hFtp)
439     {
440         skip("No ftp connection could be made to ftp.winehq.org\n");
441         InternetCloseHandle(hInternet);
442         return;
443     }
444
445     /* We should have a ftp-connection (valid ftp session handle), try some opening */
446
447     /* No filename */
448     SetLastError(0xdeadbeef);
449     hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
450     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
451     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
452         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
453     InternetCloseHandle(hOpenFile); /* Just in case */
454
455     /* Illegal access flags */
456     SetLastError(0xdeadbeef);
457     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
458     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
459     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
460         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
461     InternetCloseHandle(hOpenFile); /* Just in case */
462
463     /* Illegal combination of access flags */
464     SetLastError(0xdeadbeef);
465     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
466     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
467     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
468         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
469     InternetCloseHandle(hOpenFile); /* Just in case */
470
471     /* Illegal condition flags */
472     SetLastError(0xdeadbeef);
473     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 0xffffffff, 0);
474     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
475     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
476         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
477     InternetCloseHandle(hOpenFile); /* Just in case */
478
479     SetLastError(0xdeadbeef);
480     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
481     todo_wine
482     {
483     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
484     /* For some strange/unknown reason, win98 returns ERROR_FILE_NOT_FOUND */
485     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_FILE_NOT_FOUND,
486         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_FILE_NOT_FOUND (win98), got %d\n", GetLastError());
487     }
488
489     if (hOpenFile)
490     {
491         BOOL bRet;
492         HINTERNET hOpenFile2;
493         HANDLE    hFile;
494
495         /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
496         SetLastError(0xdeadbeef);
497         bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
498         ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
499         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
500             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
501
502         SetLastError(0xdeadbeef);
503         bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
504         ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
505         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
506             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
507
508         SetLastError(0xdeadbeef);
509         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
510         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
511         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
512             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
513         DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
514
515         SetLastError(0xdeadbeef);
516         hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
517         ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n");
518         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
519             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
520         InternetCloseHandle(hOpenFile2); /* Just in case */
521
522         /* Create a temporary local file */
523         SetLastError(0xdeadbeef);
524         hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
525         ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
526         CloseHandle(hFile);
527         SetLastError(0xdeadbeef);
528         bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
529         ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
530         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
531             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
532         DeleteFileA("now_existing_local");
533
534         SetLastError(0xdeadbeef);
535         bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
536         ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
537         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
538             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
539
540         SetLastError(0xdeadbeef);
541         bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
542         ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
543         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
544             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
545     }
546
547     InternetCloseHandle(hOpenFile);
548     InternetCloseHandle(hFtp);
549
550     /* Http handle-type for ftp connection */
551
552     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
553
554     /* One small test to show that handle type is checked before parameters */
555     SetLastError(0xdeadbeef);
556     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
557     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
558     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
559         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
560     InternetCloseHandle(hOpenFile); /* Just in case */
561
562     SetLastError(0xdeadbeef);
563     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
564     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
565     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
566         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
567
568     InternetCloseHandle(hOpenFile); /* Just in case */
569     InternetCloseHandle(hConnect);
570     InternetCloseHandle(hInternet);
571 }
572
573 static void test_putfile(void)
574 {
575     BOOL      bRet;
576     HINTERNET hInternet, hFtp, hConnect;
577     HANDLE    hFile;
578
579     /* The order of checking is:
580      *
581      *   All parameters except 'session handle' and 'condition flags'
582      *   Session handle
583      *   Session handle type
584      *   Condition flags
585      */
586
587     /* Test to show the parameter checking order depends on the Windows version */
588     SetLastError(0xdeadbeef);
589     bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
590     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
591     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
592          GetLastError() == ERROR_INVALID_PARAMETER,
593         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
594
595     /* Test to show session handle is checked before 'condition flags' */
596     SetLastError(0xdeadbeef);
597     bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
598     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
599     ok ( GetLastError() == ERROR_INVALID_HANDLE,
600         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
601
602     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
603     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
604     if(!hFtp)
605     {
606         skip("No ftp connection could be made to ftp.winehq.org\n");
607         InternetCloseHandle(hInternet);
608         return;
609     }
610
611     /* Start clean */
612     DeleteFileA("non_existing_local");
613
614     /* We should have a ftp-connection, try some puts */
615
616     /* No local file given */
617     SetLastError(0xdeadbeef);
618     bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
619     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
620     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
621         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
622
623     /* No remote file given */
624     SetLastError(0xdeadbeef);
625     bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
626     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
627     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
628         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
629
630     /* Illegal condition flags */
631     SetLastError(0xdeadbeef);
632     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
633     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
634     ok ( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
635         "Expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
636
637     /* Parameters are OK but local file doesn't exist */
638     SetLastError(0xdeadbeef);
639     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
640     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
641     ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
642         "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
643
644     /* Create a temporary local file */
645     SetLastError(0xdeadbeef);
646     hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
647     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
648     CloseHandle(hFile);
649
650     /* Local file exists but we shouldn't be allowed to 'put' the file */
651     SetLastError(0xdeadbeef);
652     bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
653     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
654     todo_wine
655     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
656         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
657
658     DeleteFileA("now_existing_local");
659
660     InternetCloseHandle(hFtp);
661
662     /* Http handle-type for ftp connection */
663
664     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
665
666     /* Test to show the parameter checking order depends on the Windows version */
667     SetLastError(0xdeadbeef);
668     bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
669     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
670     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
671          GetLastError() == ERROR_INVALID_PARAMETER,
672         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
673
674     /* Test to show that 'session handle type' is checked before 'condition flags' */
675     SetLastError(0xdeadbeef);
676     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
677     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
678     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
679         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
680
681     SetLastError(0xdeadbeef);
682     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
683     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
684     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
685         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
686
687     InternetCloseHandle(hConnect);
688     InternetCloseHandle(hInternet);
689 }
690
691 static void test_removedir(void)
692 {
693     BOOL      bRet;
694     HINTERNET hInternet, hFtp, hConnect;
695
696     /* Invalid internet handle, the other is a valid parameter */
697     SetLastError(0xdeadbeef);
698     bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
699     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
700     ok ( GetLastError() == ERROR_INVALID_HANDLE,
701         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
702
703     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
704     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
705     if(!hFtp)
706     {
707         skip("No ftp connection could be made to ftp.winehq.org\n");
708         InternetCloseHandle(hInternet);
709         return;
710     }
711
712     /* We should have a ftp-connection, try some removing */
713
714     /* No remote directory given */
715     SetLastError(0xdeadbeef);
716     bRet = FtpRemoveDirectoryA(hFtp, NULL);
717     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
718     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
719         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
720
721     /* Remote directory doesn't exist */
722     SetLastError(0xdeadbeef);
723     bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
724     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
725     todo_wine
726     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
727         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
728
729     /* We shouldn't be allowed to remove that directory */
730     SetLastError(0xdeadbeef);
731     bRet = FtpRemoveDirectoryA(hFtp, "pub");
732     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
733     todo_wine
734     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
735         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
736
737     InternetCloseHandle(hFtp);
738
739     /* Http handle-type for ftp connection */
740
741     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
742
743     /* One small test to show that handle type is checked before parameters */
744     SetLastError(0xdeadbeef);
745     bRet = FtpRemoveDirectoryA(hConnect, NULL);
746     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
747     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
748         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
749
750     SetLastError(0xdeadbeef);
751     bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
752     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
753     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
754         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
755
756     InternetCloseHandle(hConnect);
757     InternetCloseHandle(hInternet);
758 }
759
760 static void test_renamefile(void)
761 {
762     BOOL      bRet;
763     HINTERNET hInternet, hFtp, hConnect;
764
765     /* Invalid internet handle, the rest are valid parameters */
766     SetLastError(0xdeadbeef);
767     bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
768     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
769     ok ( GetLastError() == ERROR_INVALID_HANDLE,
770         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
771
772     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
773     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
774     if(!hFtp)
775     {
776         skip("No ftp connection could be made to ftp.winehq.org\n");
777         InternetCloseHandle(hInternet);
778         return;
779     }
780
781     /* We should have a ftp-connection, try some renaming */
782
783     /* No 'existing' file */
784     SetLastError(0xdeadbeef);
785     bRet = FtpRenameFileA(hFtp , NULL, "new");
786     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
787     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
788         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
789
790     /* No new file */
791     SetLastError(0xdeadbeef);
792     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
793     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
794     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
795         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
796
797     /* Existing file shouldn't be there */
798     SetLastError(0xdeadbeef);
799     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
800     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
801     todo_wine
802     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
803         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
804
805     InternetCloseHandle(hFtp);
806
807     /* Http handle-type for ftp connection */
808
809     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);
810
811     /* One small test to show that handle type is checked before parameters */
812     SetLastError(0xdeadbeef);
813     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
814     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
815     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
816         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
817
818     SetLastError(0xdeadbeef);
819     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
820     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
821     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
822         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
823
824     InternetCloseHandle(hConnect);
825     InternetCloseHandle(hInternet);
826 }
827
828 static void test_multiple(void)
829 {
830     BOOL      bRet;
831     HINTERNET hInternet, hFtp, hOpenFile;
832
833     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
834     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
835     if(!hFtp)
836     {
837         skip("No ftp connection could be made to ftp.winehq.org\n");
838         InternetCloseHandle(hInternet);
839         return;
840     }
841
842     /* A correct call */
843     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
844     DeleteFileA("should_be_non_existing_deadbeef");
845
846     SetLastError(0xdeadbeef);
847     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
848     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
849     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_FILE_NOT_FOUND,
850         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_FILE_NOT_FOUND (win98), got %d\n", GetLastError());
851
852     InternetCloseHandle(hOpenFile);
853     InternetCloseHandle(hFtp);
854     InternetCloseHandle(hInternet);
855 }
856
857 START_TEST(ftp)
858 {
859     /* The first call should always be a proper InternetOpen, if not
860      * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
861      * all parameters are correct but no session handle is given. Whereas
862      * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
863      * is done before.
864      * The following test will show that behaviour, where the tests inside
865      * the other sub-tests will show the other situation.
866      */
867     test_getfile_no_open();
868     test_connect();
869     test_createdir();
870     test_deletefile();
871     test_getfile();
872     test_openfile();
873     test_putfile();
874     test_removedir();
875     test_renamefile();
876
877     /* A test that does two particular calls in one connection, this currently fails on Wine.
878      * The problem lies in FtpGetFile but is exposed in FtpOpenFile.
879      * Once this is fixed we should change the total test to setup and clear the connections
880      * only once. (and get rid of test_multiple).
881      */
882     test_multiple();
883 }