wininet/ftp.c: Fix some returned error codes.
[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_connect(void)
46 {
47     HINTERNET hInternet, hFtp;
48
49     SetLastError(0xdeadbeef);
50     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
51     ok(hInternet != NULL, "InternetOpen failed : %d\n", GetLastError());
52
53     if(!hInternet)
54     {
55         skip("No internet connection could be made\n");
56         return;
57     }
58
59     /* Try a few username/password combinations:
60      * anonymous : NULL
61      * NULL      : IEUser@
62      * NULL      : NULL
63      */
64
65     SetLastError(0xdeadbeef);
66     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, 0, 0);
67     ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
68     ok ( GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
69         "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
70
71     SetLastError(0xdeadbeef);
72     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
73     ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
74     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
75         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
76
77     /* Using a NULL username and password will be interpreted as anonymous ftp. The username will be 'anonymous' the password
78      * is created via some simple heuristics (see dlls/wininet/ftp.c).
79      * On Wine this registry key is not set by default so (NULL, NULL) will result in anonymous ftp with an (most likely) not
80      * accepted password (the username).
81      * If the first call fails because we get an ERROR_INTERNET_LOGIN_FAILURE, we try again with a (more) correct password.
82      */
83
84     SetLastError(0xdeadbeef);
85     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, 0, 0);
86     if (!hFtp && (GetLastError() == ERROR_INTERNET_LOGIN_FAILURE))
87     {
88         /* We are most likely running on a clean Wine install or a Windows install where the registry key is removed */
89         SetLastError(0xdeadbeef);
90         hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
91     }
92     ok ( hFtp != NULL, "InternetConnect failed : %d\n", GetLastError());
93     ok ( GetLastError() == ERROR_SUCCESS,
94         "ERROR_SUCCESS, got %d\n", GetLastError());
95
96     InternetCloseHandle(hFtp);
97     InternetCloseHandle(hInternet);
98 }
99
100 static void test_createdir(void)
101 {
102     BOOL      bRet;
103     HINTERNET hInternet, hFtp, hConnect;
104
105     /* Invalid internet handle, the other is a valid parameter */
106     SetLastError(0xdeadbeef);
107     bRet = FtpCreateDirectoryA(NULL, "new_directory_deadbeef");
108     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
109     ok ( GetLastError() == ERROR_INVALID_HANDLE,
110         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
111
112     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
113     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
114     if(!hFtp)
115     {
116         skip("No ftp connection could be made\n");
117         InternetCloseHandle(hInternet);
118         return;
119     }
120
121     /* We should have a ftp-connection (valid ftp session handle), try some creating */
122
123     /* No directory-name */
124     SetLastError(0xdeadbeef);
125     bRet = FtpCreateDirectoryA(hFtp, NULL);
126     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
127     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
128         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
129
130     /* Parameters are OK, but we shouldn't be allowed to create the directory */
131     SetLastError(0xdeadbeef);
132     bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
133     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
134     todo_wine
135     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
136         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
137
138     InternetCloseHandle(hFtp);
139
140     /* Http handle-type for ftp connection */
141
142     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
143
144     /* One small test to show that handle type is checked before parameters */
145     SetLastError(0xdeadbeef);
146     bRet = FtpCreateDirectoryA(hConnect, NULL);
147     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
148     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
149         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
150
151     SetLastError(0xdeadbeef);
152     bRet = FtpCreateDirectoryA(hConnect, "new_directory_deadbeef");
153     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
154     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
155         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
156
157     InternetCloseHandle(hConnect);
158     InternetCloseHandle(hInternet);
159 }
160
161 static void test_deletefile(void)
162 {
163     BOOL      bRet;
164     HINTERNET hInternet, hFtp, hConnect;
165
166     /* Invalid internet handle, the other is a valid parameter */
167     SetLastError(0xdeadbeef);
168     bRet = FtpDeleteFileA(NULL, "non_existent_file_deadbeef");
169     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
170     ok ( GetLastError() == ERROR_INVALID_HANDLE,
171         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
172
173     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
174     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
175     if(!hFtp)
176     {
177         skip("No ftp connection could be made\n");
178         InternetCloseHandle(hInternet);
179         return;
180     }
181
182     /* We should have a ftp-connection, try some deleting */
183
184     /* No filename */
185     SetLastError(0xdeadbeef);
186     bRet = FtpDeleteFileA(hFtp, NULL);
187     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
188     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
189         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
190
191     /* Parameters are OK but remote file should not be there */
192     SetLastError(0xdeadbeef);
193     bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
194     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
195     todo_wine
196     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
197         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
198
199     InternetCloseHandle(hFtp);
200
201     /* Http handle-type for ftp connection */
202
203     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
204
205     /* One small test to show that handle type is checked before parameters */
206     SetLastError(0xdeadbeef);
207     bRet = FtpDeleteFileA(hConnect, NULL);
208     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
209     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
210         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
211
212     SetLastError(0xdeadbeef);
213     bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
214     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
215     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
216         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
217
218     InternetCloseHandle(hConnect);
219     InternetCloseHandle(hInternet);
220 }
221
222 static void test_getfile(void)
223 {
224     BOOL      bRet;
225     HINTERNET hInternet, hFtp, hConnect;
226
227     /* Invalid internet handle, the other is a valid parameter */
228     SetLastError(0xdeadbeef);
229     bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
230     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
231     todo_wine
232     ok ( GetLastError() == ERROR_INVALID_HANDLE,
233         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
234
235     /* Test to show that FtpGetFileA checks the parameters before the handle */
236     SetLastError(0xdeadbeef);
237     bRet = FtpGetFileA(NULL, NULL, NULL, FALSE, 0, 5, 0);
238     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
239     todo_wine
240     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
241         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
242
243     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
244     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
245     if(!hFtp)
246     {
247         skip("No ftp connection could be made\n");
248         InternetCloseHandle(hInternet);
249         return;
250     }
251
252     /* Make sure we start clean */
253
254     DeleteFileA("should_be_non_existing_deadbeef");
255     DeleteFileA("should_also_be_non_existing_deadbeef");
256
257     /* We should have a ftp-connection, try some getting */
258
259     /* No remote file */
260     SetLastError(0xdeadbeef);
261     bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
262     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
263     todo_wine
264     {
265     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
266         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
267     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
268     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
269         "Local file should not have been created\n");
270     }
271     DeleteFileA("should_be_non_existing_deadbeef");
272
273     /* No local file */
274     SetLastError(0xdeadbeef);
275     bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
276     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
277     todo_wine
278     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
279         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
280
281     /* Zero attributes, but call succeeds (as would CreateFile with zero attributes) */
282     SetLastError(0xdeadbeef);
283     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
284     todo_wine
285     {
286     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
287     ok ( GetLastError() == ERROR_SUCCESS,
288         "Expected ERROR_SUCCESS, got %d\n", GetLastError());
289     }
290     /* Wine passes this test but for the wrong reason */
291     ok (GetFileAttributesA("should_be_non_existing_deadbeef") != INVALID_FILE_ATTRIBUTES,
292         "Local file should have been created\n");
293     DeleteFileA("should_be_non_existing_deadbeef");
294
295     /* Illegal condition flags */
296     SetLastError(0xdeadbeef);
297     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
298     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
299     todo_wine
300     {
301     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
302         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
303     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
304         "Local file should not have been created\n");
305     }
306     DeleteFileA("should_be_non_existing_deadbeef");
307
308     /* Remote file doesn't exist */
309     SetLastError(0xdeadbeef);
310     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
311     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
312     todo_wine
313     {
314     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
315         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
316     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
317         "Local file should not have been created\n");
318     }
319     DeleteFileA("should_also_be_non_existing_deadbeef");
320
321     /* This one should succeed and give us a copy of the 'welcome.msg' file */
322     SetLastError(0xdeadbeef);
323     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
324     todo_wine
325     {
326     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
327     ok ( GetLastError() == ERROR_SUCCESS,
328         "Expected ERROR_SUCCESS, got %d\n", GetLastError());
329     }
330
331     if (GetFileAttributesA("should_be_non_existing_deadbeef") != INVALID_FILE_ATTRIBUTES)
332     {
333         /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
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         /* Should fail as fFailIfExists is set to TRUE */
344         SetLastError(0xdeadbeef);
345         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
346         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
347         todo_wine
348         ok ( GetLastError() == ERROR_FILE_EXISTS,
349             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
350
351         /* Prove that the existence of the local file is checked first (or at least reported last) */
352         SetLastError(0xdeadbeef);
353         bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
354         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
355         todo_wine
356         ok ( GetLastError() == ERROR_FILE_EXISTS,
357             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
358
359         DeleteFileA("should_be_non_existing_deadbeef");
360     }
361
362     InternetCloseHandle(hFtp);
363
364     /* Http handle-type for ftp connection */
365
366     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
367
368     /* One small test to show that handle type is checked before parameters */
369     SetLastError(0xdeadbeef);
370     bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
371     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
372     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
373         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
374
375     SetLastError(0xdeadbeef);
376     bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
377     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
378     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
379         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
380
381     InternetCloseHandle(hConnect);
382     InternetCloseHandle(hInternet);
383 }
384
385 static void test_openfile(void)
386 {
387     HINTERNET hOpenFile, hInternet, hFtp, hConnect;
388
389     /* Invalid internet handle, the rest are valid parameters */
390     SetLastError(0xdeadbeef);
391     hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
392     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
393     todo_wine
394     ok ( GetLastError() == ERROR_INVALID_HANDLE,
395         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
396     InternetCloseHandle(hOpenFile); /* Just in case */
397
398     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
399     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
400     if(!hFtp)
401     {
402         skip("No ftp connection could be made\n");
403         InternetCloseHandle(hInternet);
404         return;
405     }
406
407     /* We should have a ftp-connection (valid ftp session handle), try some opening */
408
409     /* No filename */
410     SetLastError(0xdeadbeef);
411     hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
412     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
413     todo_wine
414     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
415         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
416     InternetCloseHandle(hOpenFile); /* Just in case */
417
418     /* Illegal access flags */
419     SetLastError(0xdeadbeef);
420     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
421     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
422     todo_wine
423     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
424         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
425     InternetCloseHandle(hOpenFile); /* Just in case */
426
427     /* Illegal combination of access flags */
428     SetLastError(0xdeadbeef);
429     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
430     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
431     todo_wine
432     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
433         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
434     InternetCloseHandle(hOpenFile); /* Just in case */
435
436     /* Illegal condition flags */
437     SetLastError(0xdeadbeef);
438     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 5, 0);
439     todo_wine
440     {
441     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
442     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
443         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
444     }
445     InternetCloseHandle(hOpenFile); /* Just in case */
446
447     /* All OK */
448     SetLastError(0xdeadbeef);
449     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
450     todo_wine
451     {
452     ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
453     /* For some strange/unknown reason, win98 returns ERROR_FILE_NOT_FOUND */
454     ok ( GetLastError() == ERROR_SUCCESS || GetLastError() == ERROR_FILE_NOT_FOUND,
455         "Expected ERROR_SUCCESS or ERROR_FILE_NOT_FOUND (win98), got %d\n", GetLastError());
456     }
457
458     if (hOpenFile)
459     {
460         BOOL bRet;
461
462         /* We have a handle so all ftp calls should fail (TODO: Put more ftp-calls in here) */
463         SetLastError(0xdeadbeef);
464         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
465         ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
466         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
467             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
468         DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
469     }
470
471     InternetCloseHandle(hOpenFile);
472     InternetCloseHandle(hFtp);
473
474     /* Http handle-type for ftp connection */
475
476     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
477
478     /* One small test to show that handle type is checked before parameters */
479     SetLastError(0xdeadbeef);
480     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
481     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
482     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
483         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
484     InternetCloseHandle(hOpenFile); /* Just in case */
485
486     SetLastError(0xdeadbeef);
487     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
488     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
489     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
490         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
491
492     InternetCloseHandle(hOpenFile); /* Just in case */
493     InternetCloseHandle(hConnect);
494     InternetCloseHandle(hInternet);
495 }
496
497 static void test_putfile(void)
498 {
499     BOOL      bRet;
500     HINTERNET hInternet, hFtp, hConnect;
501     HANDLE    hFile;
502
503     /* Invalid internet handle, the rest are valid parameters */
504     SetLastError(0xdeadbeef);
505     bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
506     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
507     todo_wine
508     ok ( GetLastError() == ERROR_INVALID_HANDLE,
509         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
510
511     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
512     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
513     if(!hFtp)
514     {
515         skip("No ftp connection could be made\n");
516         InternetCloseHandle(hInternet);
517         return;
518     }
519
520     /* We should have a ftp-connection, try some puts */
521
522     /* No local file given */
523     SetLastError(0xdeadbeef);
524     bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
525     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
526     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
527         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
528
529     /* No remote file given */
530     SetLastError(0xdeadbeef);
531     bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
532     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
533     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
534         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
535
536     /* Illegal condition flags */
537     SetLastError(0xdeadbeef);
538     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
539     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
540     todo_wine
541     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
542         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
543
544     /* Parameters are OK but local file doesn't exist */
545     SetLastError(0xdeadbeef);
546     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
547     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
548     todo_wine
549     ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
550         "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
551
552     /* Create a temporary local file */
553     SetLastError(0xdeadbeef);
554     hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
555     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
556     CloseHandle(hFile);
557
558     /* Local file exists but we shouldn't be allowed to 'put' the file */
559     SetLastError(0xdeadbeef);
560     bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
561     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
562     todo_wine
563     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
564         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
565
566     DeleteFileA("now_existing_local");
567
568     InternetCloseHandle(hFtp);
569
570     /* Http handle-type for ftp connection */
571
572     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
573
574     /* One small test to show that handle type is checked before parameters */
575     SetLastError(0xdeadbeef);
576     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
577     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
578     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
579         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
580
581     SetLastError(0xdeadbeef);
582     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
583     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
584     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
585         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
586
587     InternetCloseHandle(hConnect);
588     InternetCloseHandle(hInternet);
589 }
590
591 static void test_removedir(void)
592 {
593     BOOL      bRet;
594     HINTERNET hInternet, hFtp, hConnect;
595
596     /* Invalid internet handle, the other is a valid parameter */
597     SetLastError(0xdeadbeef);
598     bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
599     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
600     ok ( GetLastError() == ERROR_INVALID_HANDLE,
601         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
602
603     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
604     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
605     if(!hFtp)
606     {
607         skip("No ftp connection could be made\n");
608         InternetCloseHandle(hInternet);
609         return;
610     }
611
612     /* We should have a ftp-connection, try some removing */
613
614     /* No remote directory given */
615     SetLastError(0xdeadbeef);
616     bRet = FtpRemoveDirectoryA(hFtp, NULL);
617     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
618     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
619         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
620
621     /* Remote directory doesn't exist */
622     SetLastError(0xdeadbeef);
623     bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
624     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
625     todo_wine
626     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
627         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
628
629     /* We shouldn't be allowed to remove that directory */
630     SetLastError(0xdeadbeef);
631     bRet = FtpRemoveDirectoryA(hFtp, "pub");
632     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
633     todo_wine
634     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
635         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
636
637     InternetCloseHandle(hFtp);
638
639     /* Http handle-type for ftp connection */
640
641     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
642
643     /* One small test to show that handle type is checked before parameters */
644     SetLastError(0xdeadbeef);
645     bRet = FtpRemoveDirectoryA(hConnect, NULL);
646     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
647     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
648         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
649
650     SetLastError(0xdeadbeef);
651     bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
652     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
653     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
654         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
655
656     InternetCloseHandle(hConnect);
657     InternetCloseHandle(hInternet);
658 }
659
660 static void test_renamefile(void)
661 {
662     BOOL      bRet;
663     HINTERNET hInternet, hFtp, hConnect;
664
665     /* Invalid internet handle, the rest are valid parameters */
666     SetLastError(0xdeadbeef);
667     bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
668     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
669     ok ( GetLastError() == ERROR_INVALID_HANDLE,
670         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
671
672     hInternet = InternetOpen(NULL, 0, NULL, NULL, 0);
673     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, 0, 0);
674     if(!hFtp)
675     {
676         skip("No ftp connection could be made\n");
677         InternetCloseHandle(hInternet);
678         return;
679     }
680
681     /* We should have a ftp-connection, try some renaming */
682
683     /* No 'existing' file */
684     SetLastError(0xdeadbeef);
685     bRet = FtpRenameFileA(hFtp , NULL, "new");
686     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
687     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
688         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
689
690     /* No new file */
691     SetLastError(0xdeadbeef);
692     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
693     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
694     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
695         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
696
697     /* Existing file shouldn't be there */
698     SetLastError(0xdeadbeef);
699     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
700     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
701     todo_wine
702     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
703         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
704
705     InternetCloseHandle(hFtp);
706
707     /* Http handle-type for ftp connection */
708
709     hConnect = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
710
711     /* One small test to show that handle type is checked before parameters */
712     SetLastError(0xdeadbeef);
713     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
714     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
715     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
716         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
717
718     SetLastError(0xdeadbeef);
719     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
720     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
721     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
722         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
723
724     InternetCloseHandle(hConnect);
725     InternetCloseHandle(hInternet);
726 }
727
728 START_TEST(ftp)
729 {
730     test_connect();
731     test_createdir();
732     test_deletefile();
733     test_getfile();
734     test_openfile();
735     test_putfile();
736     test_removedir();
737     test_renamefile();
738 }