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