wininet: Avoid a crash with traces on.
[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     todo_wine
263     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
264         "Local file should not have been created\n");
265
266     DeleteFileA("should_also_be_non_existing_deadbeef");
267
268     /* Same call as the previous but now the local file does exists. Windows just removes the file if the call fails
269      * even if the local existed before!
270      */
271
272     /* Create a temporary local file */
273     SetLastError(0xdeadbeef);
274     hFile = CreateFileA("should_also_be_non_existing_deadbeef", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
275     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
276     CloseHandle(hFile);
277     SetLastError(0xdeadbeef);
278     bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
279     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
280     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
281         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
282     /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
283     todo_wine
284     ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
285         "Local file should not have been created\n");
286
287     DeleteFileA("should_also_be_non_existing_deadbeef");
288
289     /* This one should succeed */
290     SetLastError(0xdeadbeef);
291     bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
292     ok ( bRet == TRUE, "Expected FtpGetFileA to fail\n");
293     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
294
295     if (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES)
296     {
297         /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
298         SetLastError(0xdeadbeef);
299         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
300         ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
301         ok ( GetLastError() == ERROR_SUCCESS,
302             "Expected ERROR_SUCCESS, got %d\n", GetLastError());
303
304         /* Should fail as fFailIfExists is set to TRUE */
305         SetLastError(0xdeadbeef);
306         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
307         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
308         ok ( GetLastError() == ERROR_FILE_EXISTS,
309             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
310
311         /* Prove that the existence of the local file is checked first (or at least reported last) */
312         SetLastError(0xdeadbeef);
313         bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
314         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
315         ok ( GetLastError() == ERROR_FILE_EXISTS,
316             "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
317
318         DeleteFileA("should_be_existing_non_deadbeef");
319     }
320
321     /* Test to show the parameter checking order depends on the Windows version */
322     SetLastError(0xdeadbeef);
323     bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
324     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
325     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
326          GetLastError() == ERROR_INVALID_PARAMETER,
327         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
328
329     /* Test to show that 'session handle type' is checked before 'condition flags' */
330     SetLastError(0xdeadbeef);
331     bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
332     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
333     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
334         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
335
336     SetLastError(0xdeadbeef);
337     bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
338     ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
339     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
340         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
341 }
342
343 static void test_openfile(HINTERNET hFtp, HINTERNET hConnect)
344 {
345     HINTERNET hOpenFile;
346
347     /* Invalid internet handle, the rest are valid parameters */
348     SetLastError(0xdeadbeef);
349     hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
350     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
351     ok ( GetLastError() == ERROR_INVALID_HANDLE,
352         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
353     InternetCloseHandle(hOpenFile); /* Just in case */
354
355     /* No filename */
356     SetLastError(0xdeadbeef);
357     hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
358     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
359     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
360         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
361     InternetCloseHandle(hOpenFile); /* Just in case */
362
363     /* Illegal access flags */
364     SetLastError(0xdeadbeef);
365     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
366     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
367     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
368         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
369     InternetCloseHandle(hOpenFile); /* Just in case */
370
371     /* Illegal combination of access flags */
372     SetLastError(0xdeadbeef);
373     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
374     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
375     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
376         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
377     InternetCloseHandle(hOpenFile); /* Just in case */
378
379     /* Illegal condition flags */
380     SetLastError(0xdeadbeef);
381     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 0xffffffff, 0);
382     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
383     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
384         "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
385     InternetCloseHandle(hOpenFile); /* Just in case */
386
387     SetLastError(0xdeadbeef);
388     hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
389     ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
390     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", GetLastError());
391
392     if (hOpenFile)
393     {
394         BOOL bRet;
395         HINTERNET hOpenFile2;
396         HANDLE    hFile;
397
398         /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
399         SetLastError(0xdeadbeef);
400         bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
401         ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
402         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
403             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
404
405         SetLastError(0xdeadbeef);
406         bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
407         ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
408         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
409             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
410
411         SetLastError(0xdeadbeef);
412         bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
413         ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
414         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
415             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
416         DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
417
418         SetLastError(0xdeadbeef);
419         hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
420         ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n");
421         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
422             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
423         InternetCloseHandle(hOpenFile2); /* Just in case */
424
425         /* Create a temporary local file */
426         SetLastError(0xdeadbeef);
427         hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
428         ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
429         CloseHandle(hFile);
430         SetLastError(0xdeadbeef);
431         bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
432         ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
433         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
434             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
435         DeleteFileA("now_existing_local");
436
437         SetLastError(0xdeadbeef);
438         bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
439         ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
440         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
441             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
442
443         SetLastError(0xdeadbeef);
444         bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
445         ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
446         ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
447             "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
448     }
449
450     InternetCloseHandle(hOpenFile);
451
452     /* One small test to show that handle type is checked before parameters */
453     SetLastError(0xdeadbeef);
454     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
455     ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
456     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
457         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
458     InternetCloseHandle(hOpenFile); /* Just in case */
459
460     SetLastError(0xdeadbeef);
461     hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
462     ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
463     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
464         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
465
466     InternetCloseHandle(hOpenFile); /* Just in case */
467 }
468
469 static void test_putfile(HINTERNET hFtp, HINTERNET hConnect)
470 {
471     BOOL      bRet;
472     HANDLE    hFile;
473
474     /* The order of checking is:
475      *
476      *   All parameters except 'session handle' and 'condition flags'
477      *   Session handle
478      *   Session handle type
479      *   Condition flags
480      */
481
482     /* Test to show the parameter checking order depends on the Windows version */
483     SetLastError(0xdeadbeef);
484     bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
485     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
486     ok ( GetLastError() == ERROR_INVALID_HANDLE ||
487          GetLastError() == ERROR_INVALID_PARAMETER,
488         "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
489
490     /* Test to show session handle is checked before 'condition flags' */
491     SetLastError(0xdeadbeef);
492     bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
493     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
494     ok ( GetLastError() == ERROR_INVALID_HANDLE,
495         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
496
497     /* Start clean */
498     DeleteFileA("non_existing_local");
499
500     /* No local file given */
501     SetLastError(0xdeadbeef);
502     bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
503     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
504     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
505         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
506
507     /* No remote file given */
508     SetLastError(0xdeadbeef);
509     bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
510     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
511     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
512         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
513
514     /* Illegal condition flags */
515     SetLastError(0xdeadbeef);
516     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
517     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
518     ok ( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
519         "Expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
520
521     /* Parameters are OK but local file doesn't exist */
522     SetLastError(0xdeadbeef);
523     bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
524     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
525     ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
526         "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
527
528     /* Create a temporary local file */
529     SetLastError(0xdeadbeef);
530     hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
531     ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
532     CloseHandle(hFile);
533
534     /* Local file exists but we shouldn't be allowed to 'put' the file */
535     SetLastError(0xdeadbeef);
536     bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
537     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
538     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
539         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
540
541     DeleteFileA("now_existing_local");
542
543     /* Test to show the parameter checking order depends on the Windows version */
544     SetLastError(0xdeadbeef);
545     bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
546     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
547     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
548          GetLastError() == ERROR_INVALID_PARAMETER,
549         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
550
551     /* Test to show that 'session handle type' is checked before 'condition flags' */
552     SetLastError(0xdeadbeef);
553     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
554     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
555     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
556         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
557
558     SetLastError(0xdeadbeef);
559     bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
560     ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
561     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
562         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
563 }
564
565 static void test_removedir(HINTERNET hFtp, HINTERNET hConnect)
566 {
567     BOOL      bRet;
568
569     /* Invalid internet handle, the other is a valid parameter */
570     SetLastError(0xdeadbeef);
571     bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
572     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
573     ok ( GetLastError() == ERROR_INVALID_HANDLE,
574         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
575
576     /* No remote directory given */
577     SetLastError(0xdeadbeef);
578     bRet = FtpRemoveDirectoryA(hFtp, NULL);
579     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
580     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
581         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
582
583     /* Remote directory doesn't exist */
584     SetLastError(0xdeadbeef);
585     bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
586     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
587     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
588         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
589
590     /* We shouldn't be allowed to remove that directory */
591     SetLastError(0xdeadbeef);
592     bRet = FtpRemoveDirectoryA(hFtp, "pub");
593     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
594     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
595         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
596
597     /* One small test to show that handle type is checked before parameters */
598     SetLastError(0xdeadbeef);
599     bRet = FtpRemoveDirectoryA(hConnect, NULL);
600     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
601     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
602         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
603
604     SetLastError(0xdeadbeef);
605     bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
606     ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
607     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
608         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
609 }
610
611 static void test_renamefile(HINTERNET hFtp, HINTERNET hConnect)
612 {
613     BOOL      bRet;
614
615     /* Invalid internet handle, the rest are valid parameters */
616     SetLastError(0xdeadbeef);
617     bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
618     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
619     ok ( GetLastError() == ERROR_INVALID_HANDLE,
620         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
621
622     /* No 'existing' file */
623     SetLastError(0xdeadbeef);
624     bRet = FtpRenameFileA(hFtp , NULL, "new");
625     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
626     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
627         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
628
629     /* No new file */
630     SetLastError(0xdeadbeef);
631     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
632     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
633     ok ( GetLastError() == ERROR_INVALID_PARAMETER,
634         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
635
636     /* Existing file shouldn't be there */
637     SetLastError(0xdeadbeef);
638     bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
639     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
640     ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
641         "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
642
643     /* One small test to show that handle type is checked before parameters */
644     SetLastError(0xdeadbeef);
645     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
646     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
647     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
648         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
649
650     SetLastError(0xdeadbeef);
651     bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
652     ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
653     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
654         "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
655 }
656
657 static void test_command(HINTERNET hFtp, HINTERNET hConnect)
658 {
659     BOOL ret;
660     DWORD error;
661     unsigned int i;
662     static const struct
663     {
664         BOOL  ret;
665         DWORD error;
666         const char *cmd;
667     }
668     command_test[] =
669     {
670         { FALSE, ERROR_INVALID_PARAMETER,       NULL },
671         { FALSE, ERROR_INVALID_PARAMETER,       "" },
672         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "HELO" },
673         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
674         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, " SIZE" },
675         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
676         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg /welcome.msg" },
677         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE  /welcome.msg" },
678         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg " },
679         { TRUE,  ERROR_SUCCESS,                 "SIZE\t/welcome.msg" },
680         { TRUE,  ERROR_SUCCESS,                 "SIZE /welcome.msg" },
681         { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "PWD /welcome.msg" },
682         { TRUE,  ERROR_SUCCESS,                 "PWD" },
683         { TRUE,  ERROR_SUCCESS,                 "PWD\r\n" }
684     };
685
686     if (!pFtpCommandA)
687     {
688         skip("FtpCommandA() is not available. Skipping the Ftp command tests\n");
689         return;
690     }
691
692     for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
693     {
694         SetLastError(0xdeadbeef);
695         ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
696         error = GetLastError();
697
698         ok(ret == command_test[i].ret, "%d: expected FtpCommandA to %s\n", i, command_test[i].ret ? "succeed" : "fail");
699         ok(error == command_test[i].error, "%d: expected error %u, got %u\n", i, command_test[i].error, error);
700     }
701 }
702
703 static void test_get_current_dir(HINTERNET hFtp, HINTERNET hConnect)
704 {
705     BOOL    bRet;
706     DWORD   dwCurrentDirectoryLen = MAX_PATH;
707     CHAR    lpszCurrentDirectory[MAX_PATH];
708
709     if (!pFtpCommandA)
710     {
711         skip("FtpCommandA() is not available. Skipping the Ftp get_current_dir tests\n");
712         return;
713     }
714
715     /* change directories to get a more interesting pwd */
716     bRet = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, "CWD pub/", 0, NULL);
717     if(bRet == FALSE)
718     {
719         skip("Failed to change directories in test_get_current_dir(HINTERNET hFtp).\n");
720         return;
721     }
722
723     /* test with all NULL arguments */
724     SetLastError(0xdeadbeef);
725     bRet = FtpGetCurrentDirectoryA( NULL, NULL, 0 );
726     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
727     ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
728
729     /* test with NULL parameters instead of expected LPSTR/LPDWORD */
730     SetLastError(0xdeadbeef);
731     bRet = FtpGetCurrentDirectoryA( hFtp, NULL, 0 );
732     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
733     ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
734
735     /* test with no valid handle and valid parameters */
736     SetLastError(0xdeadbeef);
737     bRet = FtpGetCurrentDirectoryA( NULL, lpszCurrentDirectory, &dwCurrentDirectoryLen );
738     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
739     ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
740
741     /* test with invalid dwCurrentDirectory and all other parameters correct */
742     SetLastError(0xdeadbeef);
743     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, 0 );
744     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
745     ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
746
747     /* test with invalid lpszCurrentDirectory and all other parameters correct */
748     SetLastError(0xdeadbeef);
749     bRet = FtpGetCurrentDirectoryA( hFtp, NULL, &dwCurrentDirectoryLen );
750     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
751     ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
752
753     /* test to show it checks the handle type */
754     SetLastError(0xdeadbeef);
755     bRet = FtpGetCurrentDirectoryA( hConnect, lpszCurrentDirectory, &dwCurrentDirectoryLen );
756     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
757     ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
758     "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got: %d\n", GetLastError());
759
760     /* test for the current directory with legitimate values */
761     SetLastError(0xdeadbeef);
762     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
763     ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n" );
764     ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
765     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
766
767     /* test for the current directory with a size only large enough to
768      * fit the string and not the null terminating character */
769     SetLastError(0xdeadbeef);
770     dwCurrentDirectoryLen = 4;
771     lpszCurrentDirectory[4] = 'a'; /* set position 4 of the array to something else to make sure a leftover \0 isn't fooling the test */
772     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
773     ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n");
774     ok ( strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to not match \"/pub\"\n", lpszCurrentDirectory);
775     ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
776
777     /* test for the current directory with a size large enough to store
778      * the expected string as well as the null terminating character */
779     SetLastError(0xdeadbeef);
780     dwCurrentDirectoryLen = 5;
781     bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
782     ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n");
783     ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
784     ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
785 }
786
787 START_TEST(ftp)
788 {
789     HMODULE hWininet;
790     HANDLE hInternet, hFtp, hHttp;
791
792     hWininet = GetModuleHandleA("wininet.dll");
793     pFtpCommandA = (void*)GetProcAddress(hWininet, "FtpCommandA");
794
795     SetLastError(0xdeadbeef);
796     hInternet = InternetOpen("winetest", 0, NULL, NULL, 0);
797     ok(hInternet != NULL, "InternetOpen failed: %u\n", GetLastError());
798
799     hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
800     if (!hFtp)
801     {
802         InternetCloseHandle(hInternet);
803         skip("No ftp connection could be made to ftp.winehq.org\n");
804         return;
805     }
806     hHttp = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
807     if (!hHttp)
808     {
809         InternetCloseHandle(hFtp);
810         InternetCloseHandle(hInternet);
811         skip("No http connection could be made to www.winehq.org\n");
812         return;
813     }
814
815     /* The first call should always be a proper InternetOpen, if not
816      * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
817      * all parameters are correct but no session handle is given. Whereas
818      * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
819      * is done before.
820      * The following test will show that behaviour, where the tests inside
821      * the other sub-tests will show the other situation.
822      */
823     test_getfile_no_open();
824     test_connect(hInternet);
825     test_createdir(hFtp, hHttp);
826     test_deletefile(hFtp, hHttp);
827     test_getfile(hFtp, hHttp);
828     test_openfile(hFtp, hHttp);
829     test_putfile(hFtp, hHttp);
830     test_removedir(hFtp, hHttp);
831     test_renamefile(hFtp, hHttp);
832     test_command(hFtp, hHttp);
833     test_get_current_dir(hFtp, hHttp);
834
835     InternetCloseHandle(hHttp);
836     InternetCloseHandle(hFtp);
837     InternetCloseHandle(hInternet);
838 }