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