comctl32/tests: Destroy the window after the tests.
[wine] / dlls / wininet / tests / ftp.c
1 /*
2  * Wininet - ftp tests
3  *
4  * Copyright 2007 Paul Vriens
5  * Copyright 2007 Hans Leidekker
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 /*
23  * FIXME:
24  *     Use InternetGetLastResponseInfo when the last error is set to ERROR_INTERNET_EXTENDED_ERROR.
25  * TODO:
26  *     Add W-function tests.
27  *     Add missing function tests:
28  *         FtpFindFirstFile
29  *         FtpGetFileSize
30  *         FtpSetCurrentDirectory
31  */
32
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #include "windef.h"
38 #include "winbase.h"
39 #include "wininet.h"
40 #include "winsock.h"
41
42 #include "wine/test.h"
43
44
45 static BOOL (WINAPI *pFtpCommandA)(HINTERNET,BOOL,DWORD,LPCSTR,DWORD_PTR,HINTERNET*);
46
47
48 static void test_getfile_no_open(void)
49 {
50     BOOL      bRet;
51
52     /* Invalid internet handle, the others are valid parameters */
53     SetLastError(0xdeadbeef);
54     bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
55     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
56     ok ( GetLastError() == ERROR_INTERNET_NOT_INITIALIZED ||
57          GetLastError() == ERROR_INVALID_HANDLE,
58         "Expected ERROR_INTERNET_NOT_INITIALIZED or ERROR_INVALID_HANDLE (win98), got %d\n", GetLastError());
59 }
60
61 static void test_connect(HINTERNET hInternet)
62 {
63     HINTERNET hFtp;
64
65     /* Try a few username/password combinations:
66      * anonymous : NULL
67      * NULL      : IEUser@
68      * NULL      : NULL
69      * ""        : IEUser@
70      * ""        : NULL
71      */
72
73     SetLastError(0xdeadbeef);
74     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
75     if (hFtp)  /* some servers accept an empty password */
76     {
77         ok ( GetLastError() == ERROR_SUCCESS, "ERROR_SUCCESS, got %d\n", GetLastError());
78         InternetCloseHandle(hFtp);
79     }
80     else
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, INTERNET_FLAG_PASSIVE, 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     SetLastError(0xdeadbeef);
91     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "", "IEUser@",
92             INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
93     ok(!hFtp, "Expected InternetConnect to fail\n");
94     ok(GetLastError() == ERROR_INVALID_PARAMETER,
95         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
96
97     /* Using a NULL username and password will be interpreted as anonymous ftp. The username will be 'anonymous' the password
98      * is created via some simple heuristics (see dlls/wininet/ftp.c).
99      * On Wine this registry key is not set by default so (NULL, NULL) will result in anonymous ftp with an (most likely) not
100      * accepted password (the username).
101      * If the first call fails because we get an ERROR_INTERNET_LOGIN_FAILURE, we try again with a (more) correct password.
102      */
103
104     SetLastError(0xdeadbeef);
105     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
106     if (!hFtp && (GetLastError() == ERROR_INTERNET_LOGIN_FAILURE))
107     {
108         /* We are most likely running on a clean Wine install or a Windows install where the registry key is removed */
109         SetLastError(0xdeadbeef);
110         hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
111     }
112     ok ( hFtp != NULL, "InternetConnect failed : %d\n", GetLastError());
113     ok ( GetLastError() == ERROR_SUCCESS,
114         "ERROR_SUCCESS, got %d\n", GetLastError());
115
116     SetLastError(0xdeadbeef);
117     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "", NULL,
118             INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
119     if (!hFtp)
120     {
121         ok(GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
122                 "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
123     }
124     else
125     {
126         ok(GetLastError() == ERROR_SUCCESS,
127                 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
128     }
129 }
130
131 static void test_createdir(HINTERNET hFtp, HINTERNET hConnect)
132 {
133     BOOL      bRet;
134
135     /* Invalid internet handle, the other is a valid parameter */
136     SetLastError(0xdeadbeef);
137     bRet = FtpCreateDirectoryA(NULL, "new_directory_deadbeef");
138     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
139     ok ( GetLastError() == ERROR_INVALID_HANDLE,
140         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
141
142     /* No directory-name */
143     SetLastError(0xdeadbeef);
144     bRet = FtpCreateDirectoryA(hFtp, NULL);
145     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
146     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
147         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
148
149     /* Parameters are OK, but we shouldn't be allowed to create the directory */
150     SetLastError(0xdeadbeef);
151     bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
152     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
153     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
154         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
155
156     /* One small test to show that handle type is checked before parameters */
157     SetLastError(0xdeadbeef);
158     bRet = FtpCreateDirectoryA(hConnect, NULL);
159     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
160     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
161         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
162
163     SetLastError(0xdeadbeef);
164     bRet = FtpCreateDirectoryA(hConnect, "new_directory_deadbeef");
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
170 static void test_deletefile(HINTERNET hFtp, HINTERNET hConnect)
171 {
172     BOOL      bRet;
173
174     /* Invalid internet handle, the other is a valid parameter */
175     SetLastError(0xdeadbeef);
176     bRet = FtpDeleteFileA(NULL, "non_existent_file_deadbeef");
177     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
178     ok ( GetLastError() == ERROR_INVALID_HANDLE,
179         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
180
181     /* No filename */
182     SetLastError(0xdeadbeef);
183     bRet = FtpDeleteFileA(hFtp, NULL);
184     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
185     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
186         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
187
188     /* Parameters are OK but remote file should not be there */
189     SetLastError(0xdeadbeef);
190     bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
191     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
192     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
193         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
194
195     /* One small test to show that handle type is checked before parameters */
196     SetLastError(0xdeadbeef);
197     bRet = FtpDeleteFileA(hConnect, NULL);
198     ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
199     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
200         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
201
202     SetLastError(0xdeadbeef);
203     bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
204     ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
205     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
206         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
207 }
208
209 static void test_getfile(HINTERNET hFtp, HINTERNET hConnect)
210 {
211     BOOL      bRet;
212     HANDLE    hFile;
213
214     /* The order of checking is:
215      *
216      *   All parameters except 'session handle' and 'condition flags'
217      *   Session handle
218      *   Session handle type
219      *   Condition flags
220      */
221
222     /* Test to show the parameter checking order depends on the Windows version */
223     SetLastError(0xdeadbeef);
224     bRet = FtpGetFileA(NULL, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
225     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
226     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
227          GetLastError() == ERROR_INVALID_PARAMETER,
228         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
229
230     /* Test to show session handle is checked before 'condition flags' */
231     SetLastError(0xdeadbeef);
232     bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
233     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
234     ok ( GetLastError() == ERROR_INVALID_HANDLE,
235         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
236
237     /* Make sure we start clean */
238
239     DeleteFileA("should_be_non_existing_deadbeef");
240     DeleteFileA("should_also_be_non_existing_deadbeef");
241
242     /* No remote file */
243     SetLastError(0xdeadbeef);
244     bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
245     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
246     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
247         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
248     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
249         "Local file should not have been created\n");
250     DeleteFileA("should_be_non_existing_deadbeef");
251
252     /* No local file */
253     SetLastError(0xdeadbeef);
254     bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
255     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
256     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
257         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
258
259     /* Zero attributes */
260     SetLastError(0xdeadbeef);
261     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
262     ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
263     ok (GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
264     ok (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES,
265         "Local file should have been created\n");
266     DeleteFileA("should_be_existing_non_deadbeef");
267
268     /* Illegal condition flags */
269     SetLastError(0xdeadbeef);
270     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 0xffffffff, 0);
271     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
272     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
273         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
274     ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
275         "Local file should not have been created\n");
276     DeleteFileA("should_be_non_existing_deadbeef");
277
278     /* Remote file doesn't exist (and local doesn't exist as well) */
279     SetLastError(0xdeadbeef);
280     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_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_INTERNET_EXTENDED_ERROR,
283         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
284     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
285     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
286         "Local file should not have been created\n");
287
288     DeleteFileA("should_also_be_non_existing_deadbeef");
289
290     /* Same call as the previous but now the local file does exists. Windows just removes the file if the call fails
291      * even if the local existed before!
292      */
293
294     /* Create a temporary local file */
295     SetLastError(0xdeadbeef);
296     hFile = CreateFileA("should_also_be_non_existing_deadbeef", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
297     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
298     CloseHandle(hFile);
299     SetLastError(0xdeadbeef);
300     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
301     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
302     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
303         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
304     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
305     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
306         "Local file should not have been created\n");
307
308     DeleteFileA("should_also_be_non_existing_deadbeef");
309
310     /* This one should succeed */
311     SetLastError(0xdeadbeef);
312     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
313     ok ( bRet == TRUE, "Expected FtpGetFileA to fail\n");
314     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
315
316     if (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES)
317     {
318         /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
319         SetLastError(0xdeadbeef);
320         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
321         ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
322         ok ( GetLastError() == ERROR_SUCCESS,
323             "Expected ERROR_SUCCESS, got %d\n", GetLastError());
324
325         /* Should fail as fFailIfExists is set to TRUE */
326         SetLastError(0xdeadbeef);
327         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
328         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
329         ok ( GetLastError() == ERROR_FILE_EXISTS,
330             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
331
332         /* Prove that the existence of the local file is checked first (or at least reported last) */
333         SetLastError(0xdeadbeef);
334         bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
335         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
336         ok ( GetLastError() == ERROR_FILE_EXISTS,
337             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
338
339         DeleteFileA("should_be_existing_non_deadbeef");
340     }
341
342     /* Test to show the parameter checking order depends on the Windows version */
343     SetLastError(0xdeadbeef);
344     bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
345     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
346     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
347          GetLastError() == ERROR_INVALID_PARAMETER,
348         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
349
350     /* Test to show that 'session handle type' is checked before 'condition flags' */
351     SetLastError(0xdeadbeef);
352     bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
353     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
354     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
355         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
356
357     SetLastError(0xdeadbeef);
358     bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
359     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
360     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
361         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
362 }
363
364 static void test_openfile(HINTERNET hFtp, HINTERNET hConnect)
365 {
366     HINTERNET hOpenFile;
367
368     /* Invalid internet handle, the rest are valid parameters */
369     SetLastError(0xdeadbeef);
370     hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
371     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
372     ok ( GetLastError() == ERROR_INVALID_HANDLE,
373         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
374     InternetCloseHandle(hOpenFile); /* Just in case */
375
376     /* No filename */
377     SetLastError(0xdeadbeef);
378     hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
379     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
380     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
381         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
382     InternetCloseHandle(hOpenFile); /* Just in case */
383
384     /* Illegal access flags */
385     SetLastError(0xdeadbeef);
386     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
387     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
388     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
389         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
390     InternetCloseHandle(hOpenFile); /* Just in case */
391
392     /* Illegal combination of access flags */
393     SetLastError(0xdeadbeef);
394     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
395     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
396     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
397         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
398     InternetCloseHandle(hOpenFile); /* Just in case */
399
400     /* Illegal condition flags */
401     SetLastError(0xdeadbeef);
402     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 0xffffffff, 0);
403     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
404     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
405         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
406     InternetCloseHandle(hOpenFile); /* Just in case */
407
408     SetLastError(0xdeadbeef);
409     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
410     ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
411     ok ( GetLastError() == ERROR_SUCCESS ||
412         broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
413         "Expected ERROR_SUCCESS, got %u\n", GetLastError());
414
415     if (hOpenFile)
416     {
417         BOOL bRet;
418         HINTERNET hOpenFile2;
419         HANDLE    hFile;
420
421         /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
422         SetLastError(0xdeadbeef);
423         bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
424         ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
425         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
426             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
427
428         SetLastError(0xdeadbeef);
429         bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
430         ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
431         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
432             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
433
434         SetLastError(0xdeadbeef);
435         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
436         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
437         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
438             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
439         DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
440
441         SetLastError(0xdeadbeef);
442         hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
443         ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n");
444         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
445             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
446         InternetCloseHandle(hOpenFile2); /* Just in case */
447
448         /* Create a temporary local file */
449         SetLastError(0xdeadbeef);
450         hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
451         ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
452         CloseHandle(hFile);
453         SetLastError(0xdeadbeef);
454         bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
455         ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
456         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
457             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
458         DeleteFileA("now_existing_local");
459
460         SetLastError(0xdeadbeef);
461         bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
462         ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
463         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
464             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
465
466         SetLastError(0xdeadbeef);
467         bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
468         ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
469         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
470             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
471     }
472
473     InternetCloseHandle(hOpenFile);
474
475     /* One small test to show that handle type is checked before parameters */
476     SetLastError(0xdeadbeef);
477     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
478     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
479     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
480         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
481     InternetCloseHandle(hOpenFile); /* Just in case */
482
483     SetLastError(0xdeadbeef);
484     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
485     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
486     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
487         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
488
489     InternetCloseHandle(hOpenFile); /* Just in case */
490 }
491
492 static void test_putfile(HINTERNET hFtp, HINTERNET hConnect)
493 {
494     BOOL      bRet;
495     HANDLE    hFile;
496
497     /* The order of checking is:
498      *
499      *   All parameters except 'session handle' and 'condition flags'
500      *   Session handle
501      *   Session handle type
502      *   Condition flags
503      */
504
505     /* Test to show the parameter checking order depends on the Windows version */
506     SetLastError(0xdeadbeef);
507     bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
508     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
509     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
510          GetLastError() == ERROR_INVALID_PARAMETER,
511         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
512
513     /* Test to show session handle is checked before 'condition flags' */
514     SetLastError(0xdeadbeef);
515     bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
516     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
517     ok ( GetLastError() == ERROR_INVALID_HANDLE,
518         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
519
520     /* Start clean */
521     DeleteFileA("non_existing_local");
522
523     /* No local file given */
524     SetLastError(0xdeadbeef);
525     bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
526     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
527     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
528         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
529
530     /* No remote file given */
531     SetLastError(0xdeadbeef);
532     bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
533     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
534     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
535         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
536
537     /* Illegal condition flags */
538     SetLastError(0xdeadbeef);
539     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
540     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
541     ok ( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
542         "Expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER (win98), 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     ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
549         "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
550
551     /* Create a temporary local file */
552     SetLastError(0xdeadbeef);
553     hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
554     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
555     CloseHandle(hFile);
556
557     /* Local file exists but we shouldn't be allowed to 'put' the file */
558     SetLastError(0xdeadbeef);
559     bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
560     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
561     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
562         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
563
564     DeleteFileA("now_existing_local");
565
566     /* Test to show the parameter checking order depends on the Windows version */
567     SetLastError(0xdeadbeef);
568     bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
569     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
570     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
571          GetLastError() == ERROR_INVALID_PARAMETER,
572         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
573
574     /* Test to show that 'session handle type' is checked before 'condition flags' */
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
588 static void test_removedir(HINTERNET hFtp, HINTERNET hConnect)
589 {
590     BOOL      bRet;
591
592     /* Invalid internet handle, the other is a valid parameter */
593     SetLastError(0xdeadbeef);
594     bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
595     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
596     ok ( GetLastError() == ERROR_INVALID_HANDLE,
597         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
598
599     /* No remote directory given */
600     SetLastError(0xdeadbeef);
601     bRet = FtpRemoveDirectoryA(hFtp, NULL);
602     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
603     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
604         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
605
606     /* Remote directory doesn't exist */
607     SetLastError(0xdeadbeef);
608     bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
609     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
610     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
611         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
612
613     /* We shouldn't be allowed to remove that directory */
614     SetLastError(0xdeadbeef);
615     bRet = FtpRemoveDirectoryA(hFtp, "pub");
616     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
617     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
618         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
619
620     /* One small test to show that handle type is checked before parameters */
621     SetLastError(0xdeadbeef);
622     bRet = FtpRemoveDirectoryA(hConnect, NULL);
623     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
624     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
625         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
626
627     SetLastError(0xdeadbeef);
628     bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
629     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
630     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
631         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
632 }
633
634 static void test_renamefile(HINTERNET hFtp, HINTERNET hConnect)
635 {
636     BOOL      bRet;
637
638     /* Invalid internet handle, the rest are valid parameters */
639     SetLastError(0xdeadbeef);
640     bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
641     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
642     ok ( GetLastError() == ERROR_INVALID_HANDLE,
643         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
644
645     /* No 'existing' file */
646     SetLastError(0xdeadbeef);
647     bRet = FtpRenameFileA(hFtp , NULL, "new");
648     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
649     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
650         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
651
652     /* No new file */
653     SetLastError(0xdeadbeef);
654     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
655     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
656     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
657         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
658
659     /* Existing file shouldn't be there */
660     SetLastError(0xdeadbeef);
661     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
662     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
663     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
664         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
665
666     /* One small test to show that handle type is checked before parameters */
667     SetLastError(0xdeadbeef);
668     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
669     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
670     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
671         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
672
673     SetLastError(0xdeadbeef);
674     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
675     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
676     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
677         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
678 }
679
680 static void test_command(HINTERNET hFtp, HINTERNET hConnect)
681 {
682     BOOL ret;
683     DWORD error;
684     unsigned int i;
685     static const struct
686     {
687         BOOL  ret;
688         DWORD error;
689         const char *cmd;
690     }
691     command_test[] =
692     {
693         { FALSE, ERROR_INVALID_PARAMETER,       NULL },
694         { FALSE, ERROR_INVALID_PARAMETER,       "" },
695         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "HELO" },
696         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
697         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, " SIZE" },
698         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
699         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg /welcome.msg" },
700         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE  /welcome.msg" },
701         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg " },
702         { TRUE,  ERROR_SUCCESS,                 "SIZE\t/welcome.msg" },
703         { TRUE,  ERROR_SUCCESS,                 "SIZE /welcome.msg" },
704         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "PWD /welcome.msg" },
705         { TRUE,  ERROR_SUCCESS,                 "PWD" },
706         { TRUE,  ERROR_SUCCESS,                 "PWD\r\n" }
707     };
708
709     if (!pFtpCommandA)
710     {
711         skip("FtpCommandA() is not available. Skipping the Ftp command tests\n");
712         return;
713     }
714
715     for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
716     {
717         SetLastError(0xdeadbeef);
718         ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
719         error = GetLastError();
720
721         ok(ret == command_test[i].ret, "%d: expected FtpCommandA to %s\n", i, command_test[i].ret ? "succeed" : "fail");
722         ok(error == command_test[i].error, "%d: expected error %u, got %u\n", i, command_test[i].error, error);
723     }
724 }
725
726 static void test_get_current_dir(HINTERNET hFtp, HINTERNET hConnect)
727 {
728     BOOL    bRet;
729     DWORD   dwCurrentDirectoryLen = MAX_PATH;
730     CHAR    lpszCurrentDirectory[MAX_PATH];
731
732     if (!pFtpCommandA)
733     {
734         skip("FtpCommandA() is not available. Skipping the Ftp get_current_dir tests\n");
735         return;
736     }
737
738     /* change directories to get a more interesting pwd */
739     bRet = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, "CWD pub/", 0, NULL);
740     if(bRet == FALSE)
741     {
742         skip("Failed to change directories in test_get_current_dir(HINTERNET hFtp).\n");
743         return;
744     }
745
746     /* test with all NULL arguments */
747     SetLastError(0xdeadbeef);
748     bRet = FtpGetCurrentDirectoryA( NULL, NULL, 0 );
749     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
750     ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
751
752     /* test with NULL parameters instead of expected LPSTR/LPDWORD */
753     SetLastError(0xdeadbeef);
754     bRet = FtpGetCurrentDirectoryA( hFtp, NULL, 0 );
755     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
756     ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
757
758     /* test with no valid handle and valid parameters */
759     SetLastError(0xdeadbeef);
760     bRet = FtpGetCurrentDirectoryA( NULL, lpszCurrentDirectory, &dwCurrentDirectoryLen );
761     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
762     ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
763
764     /* test with invalid dwCurrentDirectory and all other parameters correct */
765     SetLastError(0xdeadbeef);
766     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, 0 );
767     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
768     ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
769
770     /* test with invalid lpszCurrentDirectory and all other parameters correct */
771     SetLastError(0xdeadbeef);
772     bRet = FtpGetCurrentDirectoryA( hFtp, NULL, &dwCurrentDirectoryLen );
773     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
774     ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
775
776     /* test to show it checks the handle type */
777     SetLastError(0xdeadbeef);
778     bRet = FtpGetCurrentDirectoryA( hConnect, lpszCurrentDirectory, &dwCurrentDirectoryLen );
779     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
780     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
781     "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got: %d\n", GetLastError());
782
783     /* test for the current directory with legitimate values */
784     SetLastError(0xdeadbeef);
785     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
786     ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n" );
787     ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
788     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
789
790     /* test for the current directory with a size only large enough to
791      * fit the string and not the null terminating character */
792     SetLastError(0xdeadbeef);
793     dwCurrentDirectoryLen = 4;
794     lpszCurrentDirectory[4] = 'a'; /* set position 4 of the array to something else to make sure a leftover \0 isn't fooling the test */
795     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
796     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n");
797     ok ( strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to not match \"/pub\"\n", lpszCurrentDirectory);
798     ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
799
800     /* test for the current directory with a size large enough to store
801      * the expected string as well as the null terminating character */
802     SetLastError(0xdeadbeef);
803     dwCurrentDirectoryLen = 5;
804     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
805     ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n");
806     ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
807     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
808 }
809
810 START_TEST(ftp)
811 {
812     HMODULE hWininet;
813     HANDLE hInternet, hFtp, hHttp;
814
815     hWininet = GetModuleHandleA("wininet.dll");
816     pFtpCommandA = (void*)GetProcAddress(hWininet, "FtpCommandA");
817
818     SetLastError(0xdeadbeef);
819     hInternet = InternetOpen("winetest", 0, NULL, NULL, 0);
820     ok(hInternet != NULL, "InternetOpen failed: %u\n", GetLastError());
821
822     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
823     if (!hFtp)
824     {
825         InternetCloseHandle(hInternet);
826         skip("No ftp connection could be made to ftp.winehq.org\n");
827         return;
828     }
829     hHttp = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
830     if (!hHttp)
831     {
832         InternetCloseHandle(hFtp);
833         InternetCloseHandle(hInternet);
834         skip("No http connection could be made to www.winehq.org\n");
835         return;
836     }
837
838     /* The first call should always be a proper InternetOpen, if not
839      * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
840      * all parameters are correct but no session handle is given. Whereas
841      * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
842      * is done before.
843      * The following test will show that behaviour, where the tests inside
844      * the other sub-tests will show the other situation.
845      */
846     test_getfile_no_open();
847     test_connect(hInternet);
848     test_createdir(hFtp, hHttp);
849     test_deletefile(hFtp, hHttp);
850     test_getfile(hFtp, hHttp);
851     test_openfile(hFtp, hHttp);
852     test_putfile(hFtp, hHttp);
853     test_removedir(hFtp, hHttp);
854     test_renamefile(hFtp, hHttp);
855     test_command(hFtp, hHttp);
856     test_get_current_dir(hFtp, hHttp);
857
858     InternetCloseHandle(hHttp);
859     InternetCloseHandle(hFtp);
860     InternetCloseHandle(hInternet);
861 }