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