wininet: Skip empty accept type strings in HttpOpenRequest.
[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     todo_wine
54     ok ( GetLastError() == ERROR_INTERNET_NOT_INITIALIZED,
55         "Expected ERROR_INVALID_HANDLE, 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\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\n");
191         InternetCloseHandle(hInternet);
192         return;
193     }
194
195     /* We should have a ftp-connection, try some deleting */
196
197     /* No filename */
198     SetLastError(0xdeadbeef);
199     bRet = FtpDeleteFileA(hFtp, NULL);
200     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
201     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
202         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
203
204     /* Parameters are OK but remote file should not be there */
205     SetLastError(0xdeadbeef);
206     bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
207     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
208     todo_wine
209     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
210         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
211
212     InternetCloseHandle(hFtp);
213
214     /* Http handle-type for ftp connection */
215
216     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
217
218     /* One small test to show that handle type is checked before parameters */
219     SetLastError(0xdeadbeef);
220     bRet = FtpDeleteFileA(hConnect, NULL);
221     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
222     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
223         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
224
225     SetLastError(0xdeadbeef);
226     bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
227     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
228     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
229         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
230
231     InternetCloseHandle(hConnect);
232     InternetCloseHandle(hInternet);
233 }
234
235 static void test_getfile(void)
236 {
237     BOOL      bRet;
238     HINTERNET hInternet, hFtp, hConnect;
239
240     /* The order of checking is:
241      *
242      *   All parameters except 'session handle' and 'condition flags'
243      *   Session handle
244      *   Session handle type
245      *   Condition flags
246      */
247
248     /* Test to show existence of local file is tested first (together with 'remote file') */
249     SetLastError(0xdeadbeef);
250     bRet = FtpGetFileA(NULL, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
251     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
252     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
253         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
254
255     /* Test to show session handle is checked before 'condition flags' */
256     SetLastError(0xdeadbeef);
257     bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
258     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
259     ok ( GetLastError() == ERROR_INVALID_HANDLE,
260         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
261
262     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
263     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
264     if(!hFtp)
265     {
266         skip("No ftp connection could be made\n");
267         InternetCloseHandle(hInternet);
268         return;
269     }
270
271     /* Make sure we start clean */
272
273     DeleteFileA("should_be_non_existing_deadbeef");
274     DeleteFileA("should_also_be_non_existing_deadbeef");
275
276     /* We should have a ftp-connection, try some getting */
277
278     /* No remote file */
279     SetLastError(0xdeadbeef);
280     bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
281     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
282     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
283         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
284     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
285         "Local file should not have been created\n");
286     DeleteFileA("should_be_non_existing_deadbeef");
287
288     /* No local file */
289     SetLastError(0xdeadbeef);
290     bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
291     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
292     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
293         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
294
295     /* Zero attributes, but call succeeds (as would CreateFile with zero attributes) */
296     SetLastError(0xdeadbeef);
297     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
298     todo_wine
299     {
300     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
301     ok ( GetLastError() == ERROR_SUCCESS,
302         "Expected ERROR_SUCCESS, got %d\n", GetLastError());
303     }
304     /* Wine passes this test but for the wrong reason */
305     ok (GetFileAttributesA("should_be_non_existing_deadbeef") != INVALID_FILE_ATTRIBUTES,
306         "Local file should have been created\n");
307     DeleteFileA("should_be_non_existing_deadbeef");
308
309     /* Illegal condition flags */
310     SetLastError(0xdeadbeef);
311     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
312     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
313     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
314         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
315     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
316         "Local file should not have been created\n");
317     DeleteFileA("should_be_non_existing_deadbeef");
318
319     /* Remote file doesn't exist */
320     SetLastError(0xdeadbeef);
321     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
322     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
323     todo_wine
324     {
325     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
326         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
327     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
328     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
329         "Local file should not have been created\n");
330     }
331     DeleteFileA("should_also_be_non_existing_deadbeef");
332
333     /* This one should succeed and give us a copy of the 'welcome.msg' file */
334     SetLastError(0xdeadbeef);
335     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
336     todo_wine
337     {
338     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
339     ok ( GetLastError() == ERROR_SUCCESS,
340         "Expected ERROR_SUCCESS, got %d\n", GetLastError());
341     }
342
343     if (GetFileAttributesA("should_be_non_existing_deadbeef") != INVALID_FILE_ATTRIBUTES)
344     {
345         /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
346         SetLastError(0xdeadbeef);
347         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
348         todo_wine
349         {
350         ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
351         ok ( GetLastError() == ERROR_SUCCESS,
352             "Expected ERROR_SUCCESS, got %d\n", GetLastError());
353         }
354
355         /* Should fail as fFailIfExists is set to TRUE */
356         SetLastError(0xdeadbeef);
357         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
358         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
359         todo_wine
360         ok ( GetLastError() == ERROR_FILE_EXISTS,
361             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
362
363         /* Prove that the existence of the local file is checked first (or at least reported last) */
364         SetLastError(0xdeadbeef);
365         bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
366         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
367         todo_wine
368         ok ( GetLastError() == ERROR_FILE_EXISTS,
369             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
370
371         DeleteFileA("should_be_non_existing_deadbeef");
372     }
373
374     InternetCloseHandle(hFtp);
375
376     /* Http handle-type for ftp connection */
377
378     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
379
380     /* Test to show existence of local file is tested before 'session handle type' */
381     SetLastError(0xdeadbeef);
382     bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
383     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
384     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
385         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
386
387     /* Test to show that 'session handle type' is checked before 'condition flags' */
388     SetLastError(0xdeadbeef);
389     bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
390     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
391     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
392         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
393
394     SetLastError(0xdeadbeef);
395     bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
396     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
397     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
398         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
399
400     InternetCloseHandle(hConnect);
401     InternetCloseHandle(hInternet);
402 }
403
404 static void test_openfile(void)
405 {
406     HINTERNET hOpenFile, hInternet, hFtp, hConnect;
407
408     /* Invalid internet handle, the rest are valid parameters */
409     SetLastError(0xdeadbeef);
410     hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
411     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
412     todo_wine
413     ok ( GetLastError() == ERROR_INVALID_HANDLE,
414         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
415     InternetCloseHandle(hOpenFile); /* Just in case */
416
417     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
418     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
419     if(!hFtp)
420     {
421         skip("No ftp connection could be made\n");
422         InternetCloseHandle(hInternet);
423         return;
424     }
425
426     /* We should have a ftp-connection (valid ftp session handle), try some opening */
427
428     /* No filename */
429     SetLastError(0xdeadbeef);
430     hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
431     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
432     todo_wine
433     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
434         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
435     InternetCloseHandle(hOpenFile); /* Just in case */
436
437     /* Illegal access flags */
438     SetLastError(0xdeadbeef);
439     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
440     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
441     todo_wine
442     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
443         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
444     InternetCloseHandle(hOpenFile); /* Just in case */
445
446     /* Illegal combination of access flags */
447     SetLastError(0xdeadbeef);
448     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
449     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
450     todo_wine
451     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
452         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
453     InternetCloseHandle(hOpenFile); /* Just in case */
454
455     /* Illegal condition flags */
456     SetLastError(0xdeadbeef);
457     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 5, 0);
458     todo_wine
459     {
460     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
461     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
462         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
463     }
464     InternetCloseHandle(hOpenFile); /* Just in case */
465
466     /* All OK */
467     SetLastError(0xdeadbeef);
468     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
469     todo_wine
470     {
471     ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
472     /* For some strange/unknown reason, win98 returns ERROR_FILE_NOT_FOUND */
473     ok ( GetLastError() == ERROR_SUCCESS || GetLastError() == ERROR_FILE_NOT_FOUND,
474         "Expected ERROR_SUCCESS or ERROR_FILE_NOT_FOUND (win98), got %d\n", GetLastError());
475     }
476
477     if (hOpenFile)
478     {
479         BOOL bRet;
480
481         /* We have a handle so all ftp calls should fail (TODO: Put more ftp-calls in here) */
482         SetLastError(0xdeadbeef);
483         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
484         ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
485         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
486             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
487         DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
488     }
489
490     InternetCloseHandle(hOpenFile);
491     InternetCloseHandle(hFtp);
492
493     /* Http handle-type for ftp connection */
494
495     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
496
497     /* One small test to show that handle type is checked before parameters */
498     SetLastError(0xdeadbeef);
499     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
500     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
501     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
502         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
503     InternetCloseHandle(hOpenFile); /* Just in case */
504
505     SetLastError(0xdeadbeef);
506     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
507     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
508     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
509         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
510
511     InternetCloseHandle(hOpenFile); /* Just in case */
512     InternetCloseHandle(hConnect);
513     InternetCloseHandle(hInternet);
514 }
515
516 static void test_putfile(void)
517 {
518     BOOL      bRet;
519     HINTERNET hInternet, hFtp, hConnect;
520     HANDLE    hFile;
521
522     /* Invalid internet handle, the rest are valid parameters */
523     SetLastError(0xdeadbeef);
524     bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
525     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
526     todo_wine
527     ok ( GetLastError() == ERROR_INVALID_HANDLE,
528         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
529
530     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
531     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
532     if(!hFtp)
533     {
534         skip("No ftp connection could be made\n");
535         InternetCloseHandle(hInternet);
536         return;
537     }
538
539     /* We should have a ftp-connection, try some puts */
540
541     /* No local file given */
542     SetLastError(0xdeadbeef);
543     bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
544     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
545     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
546         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
547
548     /* No remote file given */
549     SetLastError(0xdeadbeef);
550     bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
551     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
552     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
553         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
554
555     /* Illegal condition flags */
556     SetLastError(0xdeadbeef);
557     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
558     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
559     todo_wine
560     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
561         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
562
563     /* Parameters are OK but local file doesn't exist */
564     SetLastError(0xdeadbeef);
565     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
566     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
567     todo_wine
568     ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
569         "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
570
571     /* Create a temporary local file */
572     SetLastError(0xdeadbeef);
573     hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
574     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
575     CloseHandle(hFile);
576
577     /* Local file exists but we shouldn't be allowed to 'put' the file */
578     SetLastError(0xdeadbeef);
579     bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
580     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
581     todo_wine
582     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
583         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
584
585     DeleteFileA("now_existing_local");
586
587     InternetCloseHandle(hFtp);
588
589     /* Http handle-type for ftp connection */
590
591     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
592
593     /* One small test to show that handle type is checked before parameters */
594     SetLastError(0xdeadbeef);
595     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
596     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
597     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
598         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
599
600     SetLastError(0xdeadbeef);
601     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
602     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
603     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
604         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
605
606     InternetCloseHandle(hConnect);
607     InternetCloseHandle(hInternet);
608 }
609
610 static void test_removedir(void)
611 {
612     BOOL      bRet;
613     HINTERNET hInternet, hFtp, hConnect;
614
615     /* Invalid internet handle, the other is a valid parameter */
616     SetLastError(0xdeadbeef);
617     bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
618     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
619     ok ( GetLastError() == ERROR_INVALID_HANDLE,
620         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
621
622     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
623     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
624     if(!hFtp)
625     {
626         skip("No ftp connection could be made\n");
627         InternetCloseHandle(hInternet);
628         return;
629     }
630
631     /* We should have a ftp-connection, try some removing */
632
633     /* No remote directory given */
634     SetLastError(0xdeadbeef);
635     bRet = FtpRemoveDirectoryA(hFtp, NULL);
636     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
637     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
638         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
639
640     /* Remote directory doesn't exist */
641     SetLastError(0xdeadbeef);
642     bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
643     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
644     todo_wine
645     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
646         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
647
648     /* We shouldn't be allowed to remove that directory */
649     SetLastError(0xdeadbeef);
650     bRet = FtpRemoveDirectoryA(hFtp, "pub");
651     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
652     todo_wine
653     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
654         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
655
656     InternetCloseHandle(hFtp);
657
658     /* Http handle-type for ftp connection */
659
660     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
661
662     /* One small test to show that handle type is checked before parameters */
663     SetLastError(0xdeadbeef);
664     bRet = FtpRemoveDirectoryA(hConnect, NULL);
665     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
666     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
667         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
668
669     SetLastError(0xdeadbeef);
670     bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
671     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
672     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
673         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
674
675     InternetCloseHandle(hConnect);
676     InternetCloseHandle(hInternet);
677 }
678
679 static void test_renamefile(void)
680 {
681     BOOL      bRet;
682     HINTERNET hInternet, hFtp, hConnect;
683
684     /* Invalid internet handle, the rest are valid parameters */
685     SetLastError(0xdeadbeef);
686     bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
687     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
688     ok ( GetLastError() == ERROR_INVALID_HANDLE,
689         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
690
691     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
692     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
693     if(!hFtp)
694     {
695         skip("No ftp connection could be made\n");
696         InternetCloseHandle(hInternet);
697         return;
698     }
699
700     /* We should have a ftp-connection, try some renaming */
701
702     /* No 'existing' file */
703     SetLastError(0xdeadbeef);
704     bRet = FtpRenameFileA(hFtp , NULL, "new");
705     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
706     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
707         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
708
709     /* No new file */
710     SetLastError(0xdeadbeef);
711     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
712     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
713     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
714         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
715
716     /* Existing file shouldn't be there */
717     SetLastError(0xdeadbeef);
718     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
719     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
720     todo_wine
721     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
722         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
723
724     InternetCloseHandle(hFtp);
725
726     /* Http handle-type for ftp connection */
727
728     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
729
730     /* One small test to show that handle type is checked before parameters */
731     SetLastError(0xdeadbeef);
732     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
733     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
734     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
735         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
736
737     SetLastError(0xdeadbeef);
738     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
739     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
740     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
741         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
742
743     InternetCloseHandle(hConnect);
744     InternetCloseHandle(hInternet);
745 }
746
747 START_TEST(ftp)
748 {
749     /* The first call should always be a proper InternetOpen, if not
750      * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
751      * all parameters are correct but no session handle is given. Whereas
752      * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
753      * is done before.
754      * The following test will show that behaviour, where the tests inside
755      * the other sub-tests will show the other situation.
756      */
757     test_getfile_no_open();
758     test_connect();
759     test_createdir();
760     test_deletefile();
761     test_getfile();
762     test_openfile();
763     test_putfile();
764     test_removedir();
765     test_renamefile();
766 }