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