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 * FtpGetFileSize
29 * FtpSetCurrentDirectory
30 */
31
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35
36 #include "windef.h"
37 #include "winbase.h"
38 #include "wininet.h"
39 #include "winsock2.h"
40
41 #include "wine/test.h"
42
43
44 static BOOL (WINAPI *pFtpCommandA)(HINTERNET,BOOL,DWORD,LPCSTR,DWORD_PTR,HINTERNET*);
45 static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackA)(HINTERNET,INTERNET_STATUS_CALLBACK);
46
47
test_getfile_no_open(void)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
test_connect(HINTERNET hInternet)61 static void test_connect(HINTERNET hInternet)
62 {
63 HINTERNET hFtp;
64
65 /* Try a few username/password combinations:
66 * anonymous : IEUser@
67 * NULL : IEUser@
68 * NULL : NULL
69 * "" : IEUser@
70 * "" : NULL
71 */
72
73 SetLastError(0xdeadbeef);
74 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
75 if (!hFtp)
76 {
77 skip("No ftp connection could be made to ftp.winehq.org %u\n", GetLastError());
78 return;
79 }
80 ok(GetLastError() == ERROR_SUCCESS,
81 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
82 InternetCloseHandle(hFtp);
83
84 SetLastError(0xdeadbeef);
85 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
86 ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
87 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
88 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
89
90 SetLastError(0xdeadbeef);
91 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "", "IEUser@",
92 INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
93 ok(!hFtp, "Expected InternetConnect to fail\n");
94 ok(GetLastError() == ERROR_INVALID_PARAMETER,
95 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
96
97 /* Using a NULL username and password will be interpreted as anonymous ftp. The username will be 'anonymous' the password
98 * is created via some simple heuristics (see dlls/wininet/ftp.c).
99 * On Wine this registry key is not set by default so (NULL, NULL) will result in anonymous ftp with an (most likely) not
100 * accepted password (the username).
101 * If the first call fails because we get an ERROR_INTERNET_LOGIN_FAILURE, we try again with a (more) correct password.
102 */
103
104 SetLastError(0xdeadbeef);
105 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
106 if (!hFtp && (GetLastError() == ERROR_INTERNET_LOGIN_FAILURE))
107 {
108 /* We are most likely running on a clean Wine install or a Windows install where the registry key is removed */
109 SetLastError(0xdeadbeef);
110 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
111 }
112 ros_skip_flaky
113 ok ( hFtp != NULL, "InternetConnect failed : %d\n", GetLastError());
114 ros_skip_flaky
115 ok ( GetLastError() == ERROR_SUCCESS,
116 "ERROR_SUCCESS, got %d\n", GetLastError());
117 InternetCloseHandle(hFtp);
118
119 SetLastError(0xdeadbeef);
120 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "", NULL,
121 INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
122 if (!hFtp)
123 {
124 ros_skip_flaky
125 ok(GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
126 "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
127 }
128 else
129 {
130 ros_skip_flaky
131 ok(GetLastError() == ERROR_SUCCESS,
132 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
133 InternetCloseHandle(hFtp);
134 }
135 }
136
test_createdir(HINTERNET hFtp,HINTERNET hConnect)137 static void test_createdir(HINTERNET hFtp, HINTERNET hConnect)
138 {
139 BOOL bRet;
140
141 /* Invalid internet handle, the other is a valid parameter */
142 SetLastError(0xdeadbeef);
143 bRet = FtpCreateDirectoryA(NULL, "new_directory_deadbeef");
144 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
145 ok ( GetLastError() == ERROR_INVALID_HANDLE,
146 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
147
148 /* No directory-name */
149 SetLastError(0xdeadbeef);
150 bRet = FtpCreateDirectoryA(hFtp, NULL);
151 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
152 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
153 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
154
155 /* Parameters are OK, but we shouldn't be allowed to create the directory */
156 SetLastError(0xdeadbeef);
157 bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
158 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
159 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
160 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
161
162 /* One small test to show that handle type is checked before parameters */
163 SetLastError(0xdeadbeef);
164 bRet = FtpCreateDirectoryA(hConnect, NULL);
165 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
166 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
167 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
168
169 SetLastError(0xdeadbeef);
170 bRet = FtpCreateDirectoryA(hConnect, "new_directory_deadbeef");
171 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
172 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
173 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
174 }
175
test_deletefile(HINTERNET hFtp,HINTERNET hConnect)176 static void test_deletefile(HINTERNET hFtp, HINTERNET hConnect)
177 {
178 BOOL bRet;
179
180 /* Invalid internet handle, the other is a valid parameter */
181 SetLastError(0xdeadbeef);
182 bRet = FtpDeleteFileA(NULL, "non_existent_file_deadbeef");
183 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
184 ok ( GetLastError() == ERROR_INVALID_HANDLE,
185 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
186
187 /* No filename */
188 SetLastError(0xdeadbeef);
189 bRet = FtpDeleteFileA(hFtp, NULL);
190 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
191 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
192 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
193
194 /* Parameters are OK but remote file should not be there */
195 SetLastError(0xdeadbeef);
196 bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
197 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
198 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
199 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
200
201 /* One small test to show that handle type is checked before parameters */
202 SetLastError(0xdeadbeef);
203 bRet = FtpDeleteFileA(hConnect, NULL);
204 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
205 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
206 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
207
208 SetLastError(0xdeadbeef);
209 bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
210 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
211 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
212 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
213 }
214
test_getfile(HINTERNET hFtp,HINTERNET hConnect)215 static void test_getfile(HINTERNET hFtp, HINTERNET hConnect)
216 {
217 BOOL bRet;
218 HANDLE hFile;
219
220 /* The order of checking is:
221 *
222 * All parameters except 'session handle' and 'condition flags'
223 * Session handle
224 * Session handle type
225 * Condition flags
226 */
227
228 /* Test to show the parameter checking order depends on the Windows version */
229 SetLastError(0xdeadbeef);
230 bRet = FtpGetFileA(NULL, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
231 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
232 ok ( GetLastError() == ERROR_INVALID_HANDLE ||
233 GetLastError() == ERROR_INVALID_PARAMETER,
234 "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
235
236 /* Test to show session handle is checked before 'condition flags' */
237 SetLastError(0xdeadbeef);
238 bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
239 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
240 ok ( GetLastError() == ERROR_INVALID_HANDLE,
241 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
242
243 /* Make sure we start clean */
244
245 DeleteFileA("should_be_non_existing_deadbeef");
246 DeleteFileA("should_also_be_non_existing_deadbeef");
247
248 /* No remote file */
249 SetLastError(0xdeadbeef);
250 bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
251 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
252 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
253 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
254 ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
255 "Local file should not have been created\n");
256 DeleteFileA("should_be_non_existing_deadbeef");
257
258 /* No local file */
259 SetLastError(0xdeadbeef);
260 bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
261 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
262 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
263 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
264
265 /* Zero attributes */
266 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
267 ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
268 ok (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES,
269 "Local file should have been created\n");
270 DeleteFileA("should_be_existing_non_deadbeef");
271
272 /* Illegal condition flags */
273 SetLastError(0xdeadbeef);
274 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 0xffffffff, 0);
275 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
276 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
277 "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
278 ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
279 "Local file should not have been created\n");
280 DeleteFileA("should_be_non_existing_deadbeef");
281
282 /* Remote file doesn't exist (and local doesn't exist as well) */
283 SetLastError(0xdeadbeef);
284 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
285 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
286 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
287 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
288 /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
289 ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
290 "Local file should not have been created\n");
291
292 DeleteFileA("should_also_be_non_existing_deadbeef");
293
294 /* Same call as the previous but now the local file does exists. Windows just removes the file if the call fails
295 * even if the local existed before!
296 */
297
298 /* Create a temporary local file */
299 SetLastError(0xdeadbeef);
300 hFile = CreateFileA("should_also_be_non_existing_deadbeef", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
301 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
302 CloseHandle(hFile);
303 SetLastError(0xdeadbeef);
304 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
305 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
306 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
307 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
308 /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
309 ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
310 "Local file should not have been created\n");
311
312 DeleteFileA("should_also_be_non_existing_deadbeef");
313
314 /* This one should succeed */
315 SetLastError(0xdeadbeef);
316 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
317 ok ( bRet == TRUE, "Expected FtpGetFileA to fail\n");
318 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
319
320 if (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES)
321 {
322 /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
323 SetLastError(0xdeadbeef);
324 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
325 ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
326 ok ( GetLastError() == ERROR_SUCCESS,
327 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
328
329 /* Should fail as fFailIfExists is set to TRUE */
330 SetLastError(0xdeadbeef);
331 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
332 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
333 ok ( GetLastError() == ERROR_FILE_EXISTS,
334 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
335
336 /* Prove that the existence of the local file is checked first (or at least reported last) */
337 SetLastError(0xdeadbeef);
338 bRet = FtpGetFileA(hFtp, "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_FILE_EXISTS,
341 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
342
343 DeleteFileA("should_be_existing_non_deadbeef");
344 }
345
346 /* Test to show the parameter checking order depends on the Windows version */
347 SetLastError(0xdeadbeef);
348 bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
349 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
350 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
351 GetLastError() == ERROR_INVALID_PARAMETER,
352 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
353
354 /* Test to show that 'session handle type' is checked before 'condition flags' */
355 SetLastError(0xdeadbeef);
356 bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
357 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
358 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
359 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
360
361 SetLastError(0xdeadbeef);
362 bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
363 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
364 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
365 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
366 }
367
trace_extended_error(DWORD error)368 static void trace_extended_error(DWORD error)
369 {
370 DWORD code, buflen = 0;
371
372 if (error != ERROR_INTERNET_EXTENDED_ERROR) return;
373 if (!InternetGetLastResponseInfoA(&code, NULL, &buflen) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
374 {
375 char *text = HeapAlloc(GetProcessHeap(), 0, ++buflen);
376 InternetGetLastResponseInfoA(&code, text, &buflen);
377 trace("%u %s\n", code, text);
378 HeapFree(GetProcessHeap(), 0, text);
379 }
380 }
381
test_openfile(HINTERNET hFtp,HINTERNET hConnect)382 static void test_openfile(HINTERNET hFtp, HINTERNET hConnect)
383 {
384 HINTERNET hOpenFile;
385
386 /* Invalid internet handle, the rest are valid parameters */
387 SetLastError(0xdeadbeef);
388 hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
389 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
390 ok ( GetLastError() == ERROR_INVALID_HANDLE,
391 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
392 InternetCloseHandle(hOpenFile); /* Just in case */
393
394 /* No filename */
395 SetLastError(0xdeadbeef);
396 hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
397 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
398 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
399 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
400 InternetCloseHandle(hOpenFile); /* Just in case */
401
402 /* Illegal access flags */
403 SetLastError(0xdeadbeef);
404 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
405 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
406 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
407 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
408 InternetCloseHandle(hOpenFile); /* Just in case */
409
410 /* Illegal combination of access flags */
411 SetLastError(0xdeadbeef);
412 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
413 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
414 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
415 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
416 InternetCloseHandle(hOpenFile); /* Just in case */
417
418 /* Illegal condition flags */
419 SetLastError(0xdeadbeef);
420 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 0xffffffff, 0);
421 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
422 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
423 "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
424 InternetCloseHandle(hOpenFile); /* Just in case */
425
426 SetLastError(0xdeadbeef);
427 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
428 ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
429 ok ( GetLastError() == ERROR_SUCCESS ||
430 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
431 "Expected ERROR_SUCCESS, got %u\n", GetLastError());
432
433 if (hOpenFile)
434 {
435 BOOL bRet;
436 DWORD error;
437 HINTERNET hOpenFile2;
438 HANDLE hFile;
439
440 /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
441 SetLastError(0xdeadbeef);
442 bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
443 error = GetLastError();
444 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
445 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR),
446 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
447 trace_extended_error(error);
448
449 SetLastError(0xdeadbeef);
450 bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
451 error = GetLastError();
452 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
453 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR),
454 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
455 trace_extended_error(error);
456
457 SetLastError(0xdeadbeef);
458 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
459 error = GetLastError();
460 ok ( bRet == FALSE || broken(bRet == TRUE), "Expected FtpGetFileA to fail\n");
461 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_SUCCESS),
462 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
463 DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
464
465 SetLastError(0xdeadbeef);
466 hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
467 error = GetLastError();
468 ok ( bRet == FALSE || broken(bRet == TRUE), "Expected FtpOpenFileA to fail\n");
469 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_SUCCESS),
470 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
471 InternetCloseHandle(hOpenFile2); /* Just in case */
472
473 /* Create a temporary local file */
474 SetLastError(0xdeadbeef);
475 hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
476 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
477 CloseHandle(hFile);
478 SetLastError(0xdeadbeef);
479 bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
480 error = GetLastError();
481 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
482 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR),
483 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
484 DeleteFileA("now_existing_local");
485
486 SetLastError(0xdeadbeef);
487 bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
488 error = GetLastError();
489 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
490 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR),
491 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
492
493 SetLastError(0xdeadbeef);
494 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
495 error = GetLastError();
496 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
497 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR),
498 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
499 }
500
501 InternetCloseHandle(hOpenFile);
502
503 /* One small test to show that handle type is checked before parameters */
504 SetLastError(0xdeadbeef);
505 hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
506 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
507 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
508 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
509 InternetCloseHandle(hOpenFile); /* Just in case */
510
511 SetLastError(0xdeadbeef);
512 hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
513 ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
514 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
515 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
516
517 InternetCloseHandle(hOpenFile); /* Just in case */
518 }
519
test_putfile(HINTERNET hFtp,HINTERNET hConnect)520 static void test_putfile(HINTERNET hFtp, HINTERNET hConnect)
521 {
522 BOOL bRet;
523 HANDLE hFile;
524
525 /* The order of checking is:
526 *
527 * All parameters except 'session handle' and 'condition flags'
528 * Session handle
529 * Session handle type
530 * Condition flags
531 */
532
533 /* Test to show the parameter checking order depends on the Windows version */
534 SetLastError(0xdeadbeef);
535 bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
536 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
537 ok ( GetLastError() == ERROR_INVALID_HANDLE ||
538 GetLastError() == ERROR_INVALID_PARAMETER,
539 "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
540
541 /* Test to show session handle is checked before 'condition flags' */
542 SetLastError(0xdeadbeef);
543 bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
544 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
545 ok ( GetLastError() == ERROR_INVALID_HANDLE,
546 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
547
548 /* Start clean */
549 DeleteFileA("non_existing_local");
550
551 /* No local file given */
552 SetLastError(0xdeadbeef);
553 bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
554 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
555 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
556 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
557
558 /* No remote file given */
559 SetLastError(0xdeadbeef);
560 bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
561 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
562 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
563 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
564
565 /* Illegal condition flags */
566 SetLastError(0xdeadbeef);
567 bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
568 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
569 ok ( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
570 "Expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
571
572 /* Parameters are OK but local file doesn't exist */
573 SetLastError(0xdeadbeef);
574 bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
575 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
576 ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
577 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
578
579 /* Create a temporary local file */
580 SetLastError(0xdeadbeef);
581 hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
582 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
583 CloseHandle(hFile);
584
585 /* Local file exists but we shouldn't be allowed to 'put' the file */
586 SetLastError(0xdeadbeef);
587 bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
588 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
589 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
590 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
591
592 DeleteFileA("now_existing_local");
593
594 /* Test to show the parameter checking order depends on the Windows version */
595 SetLastError(0xdeadbeef);
596 bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
597 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
598 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
599 GetLastError() == ERROR_INVALID_PARAMETER,
600 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
601
602 /* Test to show that 'session handle type' is checked before 'condition flags' */
603 SetLastError(0xdeadbeef);
604 bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
605 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
606 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
607 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
608
609 SetLastError(0xdeadbeef);
610 bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
611 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
612 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
613 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
614 }
615
test_removedir(HINTERNET hFtp,HINTERNET hConnect)616 static void test_removedir(HINTERNET hFtp, HINTERNET hConnect)
617 {
618 BOOL bRet;
619
620 /* Invalid internet handle, the other is a valid parameter */
621 SetLastError(0xdeadbeef);
622 bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
623 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
624 ok ( GetLastError() == ERROR_INVALID_HANDLE,
625 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
626
627 /* No remote directory given */
628 SetLastError(0xdeadbeef);
629 bRet = FtpRemoveDirectoryA(hFtp, NULL);
630 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
631 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
632 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
633
634 /* Remote directory doesn't exist */
635 SetLastError(0xdeadbeef);
636 bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
637 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
638 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
639 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
640
641 /* We shouldn't be allowed to remove that directory */
642 SetLastError(0xdeadbeef);
643 bRet = FtpRemoveDirectoryA(hFtp, "pub");
644 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
645 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
646 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
647
648 /* One small test to show that handle type is checked before parameters */
649 SetLastError(0xdeadbeef);
650 bRet = FtpRemoveDirectoryA(hConnect, NULL);
651 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
652 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
653 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
654
655 SetLastError(0xdeadbeef);
656 bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
657 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
658 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
659 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
660 }
661
test_renamefile(HINTERNET hFtp,HINTERNET hConnect)662 static void test_renamefile(HINTERNET hFtp, HINTERNET hConnect)
663 {
664 BOOL bRet;
665
666 /* Invalid internet handle, the rest are valid parameters */
667 SetLastError(0xdeadbeef);
668 bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
669 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
670 ok ( GetLastError() == ERROR_INVALID_HANDLE,
671 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
672
673 /* No 'existing' file */
674 SetLastError(0xdeadbeef);
675 bRet = FtpRenameFileA(hFtp , NULL, "new");
676 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
677 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
678 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
679
680 /* No new file */
681 SetLastError(0xdeadbeef);
682 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
683 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
684 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
685 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
686
687 /* Existing file shouldn't be there */
688 SetLastError(0xdeadbeef);
689 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
690 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
691 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
692 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
693
694 /* One small test to show that handle type is checked before parameters */
695 SetLastError(0xdeadbeef);
696 bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
697 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
698 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
699 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
700
701 SetLastError(0xdeadbeef);
702 bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
703 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
704 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
705 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
706 }
707
test_command(HINTERNET hFtp)708 static void test_command(HINTERNET hFtp)
709 {
710 BOOL ret;
711 DWORD error;
712 unsigned int i;
713 static const struct
714 {
715 BOOL ret;
716 DWORD error;
717 const char *cmd;
718 }
719 command_test[] =
720 {
721 { FALSE, ERROR_INVALID_PARAMETER, NULL },
722 { FALSE, ERROR_INVALID_PARAMETER, "" },
723 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "invalid" },
724 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "size" },
725 { TRUE, ERROR_SUCCESS, "type i" },
726 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "size " },
727 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, " size" },
728 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "size " },
729 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "size welcome.msg welcome.msg" },
730 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "size welcome.msg" },
731 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "size welcome.msg " },
732 { TRUE, ERROR_SUCCESS, "size welcome.msg" },
733 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "pwd welcome.msg" },
734 { TRUE, ERROR_SUCCESS, "pwd" }
735 };
736
737 if (!pFtpCommandA)
738 {
739 win_skip("FtpCommandA() is not available. Skipping the Ftp command tests\n");
740 return;
741 }
742
743 for (i = 0; i < ARRAY_SIZE(command_test); i++)
744 {
745 SetLastError(0xdeadbeef);
746 ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
747 error = GetLastError();
748
749 ok(ret == command_test[i].ret, "%d: expected FtpCommandA to %s\n", i, command_test[i].ret ? "succeed" : "fail");
750 ok(error == command_test[i].error, "%d: expected error %u, got %u\n", i, command_test[i].error, error);
751 }
752 }
753
test_find_first_file(HINTERNET hFtp,HINTERNET hConnect)754 static void test_find_first_file(HINTERNET hFtp, HINTERNET hConnect)
755 {
756 WIN32_FIND_DATAA findData;
757 HINTERNET hSearch;
758 HINTERNET hSearch2;
759 HINTERNET hOpenFile;
760 DWORD error;
761 BOOL success;
762
763 /* NULL as the search file ought to return the first file in the directory */
764 SetLastError(0xdeadbeef);
765 hSearch = FtpFindFirstFileA(hFtp, NULL, &findData, 0, 0);
766 ok ( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
767
768 /* This should fail as the previous handle wasn't closed */
769 SetLastError(0xdeadbeef);
770 hSearch2 = FtpFindFirstFileA(hFtp, "welcome.msg", &findData, 0, 0);
771 todo_wine ok ( hSearch2 == NULL, "Expected FtpFindFirstFileA to fail\n" );
772 todo_wine ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
773 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError() );
774 InternetCloseHandle(hSearch2); /* Just in case */
775
776 InternetCloseHandle(hSearch);
777
778 /* Try a valid filename in a subdirectory search */
779 SetLastError(0xdeadbeef);
780 hSearch = FtpFindFirstFileA(hFtp, "pub/wine", &findData, 0, 0);
781 ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
782 InternetCloseHandle(hSearch);
783
784 /* Try a valid filename in a subdirectory wildcard search */
785 SetLastError(0xdeadbeef);
786 hSearch = FtpFindFirstFileA(hFtp, "pub/w*", &findData, 0, 0);
787 ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
788 InternetCloseHandle(hSearch);
789
790 /* Try an invalid wildcard search */
791 SetLastError(0xdeadbeef);
792 hSearch = FtpFindFirstFileA(hFtp, "*/w*", &findData, 0, 0);
793 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
794 InternetCloseHandle(hSearch); /* Just in case */
795
796 /* change current directory, and repeat those tests - this shows
797 * that the search string is interpreted as relative directory. */
798 success = FtpSetCurrentDirectoryA(hFtp, "pub");
799 ok( success, "Expected FtpSetCurrentDirectory to succeed\n" );
800
801 SetLastError(0xdeadbeef);
802 hSearch = FtpFindFirstFileA(hFtp, "wine", &findData, 0, 0);
803 ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
804 InternetCloseHandle(hSearch);
805
806 SetLastError(0xdeadbeef);
807 hSearch = FtpFindFirstFileA(hFtp, "w*", &findData, 0, 0);
808 ok( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
809 InternetCloseHandle(hSearch);
810
811 success = FtpSetCurrentDirectoryA(hFtp, "..");
812 ok( success, "Expected FtpSetCurrentDirectory to succeed\n" );
813
814 /* Try FindFirstFile between FtpOpenFile and InternetCloseHandle */
815 SetLastError(0xdeadbeef);
816 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
817 ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n" );
818 ok ( GetLastError() == ERROR_SUCCESS ||
819 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
820 "Expected ERROR_SUCCESS, got %u\n", GetLastError() );
821
822 /* This should fail as the OpenFile handle wasn't closed */
823 SetLastError(0xdeadbeef);
824 hSearch = FtpFindFirstFileA(hFtp, "welcome.msg", &findData, 0, 0);
825 error = GetLastError();
826 ok ( hSearch == NULL || broken(hSearch != NULL), /* win2k */
827 "Expected FtpFindFirstFileA to fail\n" );
828 if (!hSearch)
829 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS || broken(error == ERROR_INTERNET_EXTENDED_ERROR),
830 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error );
831 else
832 {
833 ok( error == ERROR_SUCCESS, "wrong error %u on success\n", GetLastError() );
834 InternetCloseHandle(hSearch);
835 }
836
837 InternetCloseHandle(hOpenFile);
838
839 /* Test using a nonexistent filename */
840 SetLastError(0xdeadbeef);
841 hSearch = FtpFindFirstFileA(hFtp, "this_file_should_not_exist", &findData, 0, 0);
842 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
843 todo_wine ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
844 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError() );
845 InternetCloseHandle(hSearch); /* Just in case */
846
847 /* Test using a nonexistent filename and a wildcard */
848 SetLastError(0xdeadbeef);
849 hSearch = FtpFindFirstFileA(hFtp, "this_file_should_not_exist*", &findData, 0, 0);
850 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
851 todo_wine ok ( GetLastError() == ERROR_NO_MORE_FILES,
852 "Expected ERROR_NO_MORE_FILES, got %d\n", GetLastError() );
853 InternetCloseHandle(hSearch); /* Just in case */
854
855 /* Test using an invalid handle type */
856 SetLastError(0xdeadbeef);
857 hSearch = FtpFindFirstFileA(hConnect, "welcome.msg", &findData, 0, 0);
858 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
859 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
860 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError() );
861 InternetCloseHandle(hSearch); /* Just in case */
862 }
863
test_get_current_dir(HINTERNET hFtp,HINTERNET hConnect)864 static void test_get_current_dir(HINTERNET hFtp, HINTERNET hConnect)
865 {
866 BOOL bRet;
867 DWORD dwCurrentDirectoryLen = MAX_PATH;
868 CHAR lpszCurrentDirectory[MAX_PATH];
869
870 if (!pFtpCommandA)
871 {
872 win_skip("FtpCommandA() is not available. Skipping the Ftp get_current_dir tests\n");
873 return;
874 }
875
876 /* change directories to get a more interesting pwd */
877 bRet = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, "CWD pub/", 0, NULL);
878 if(bRet == FALSE)
879 {
880 skip("Failed to change directories in test_get_current_dir(HINTERNET hFtp).\n");
881 return;
882 }
883
884 /* test with all NULL arguments */
885 SetLastError(0xdeadbeef);
886 bRet = FtpGetCurrentDirectoryA( NULL, NULL, 0 );
887 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
888 ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
889
890 /* test with NULL parameters instead of expected LPSTR/LPDWORD */
891 SetLastError(0xdeadbeef);
892 bRet = FtpGetCurrentDirectoryA( hFtp, NULL, 0 );
893 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
894 ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
895
896 /* test with no valid handle and valid parameters */
897 SetLastError(0xdeadbeef);
898 bRet = FtpGetCurrentDirectoryA( NULL, lpszCurrentDirectory, &dwCurrentDirectoryLen );
899 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
900 ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
901
902 /* test with invalid dwCurrentDirectory and all other parameters correct */
903 SetLastError(0xdeadbeef);
904 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, 0 );
905 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
906 ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
907
908 /* test with invalid lpszCurrentDirectory and all other parameters correct */
909 SetLastError(0xdeadbeef);
910 bRet = FtpGetCurrentDirectoryA( hFtp, NULL, &dwCurrentDirectoryLen );
911 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
912 ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
913
914 /* test to show it checks the handle type */
915 SetLastError(0xdeadbeef);
916 bRet = FtpGetCurrentDirectoryA( hConnect, lpszCurrentDirectory, &dwCurrentDirectoryLen );
917 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
918 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
919 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got: %d\n", GetLastError());
920
921 /* test for the current directory with legitimate values */
922 SetLastError(0xdeadbeef);
923 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
924 ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n" );
925 ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
926 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
927
928 /* test for the current directory with a size only large enough to
929 * fit the string and not the null terminating character */
930 SetLastError(0xdeadbeef);
931 dwCurrentDirectoryLen = 4;
932 lpszCurrentDirectory[4] = 'a'; /* set position 4 of the array to something else to make sure a leftover \0 isn't fooling the test */
933 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
934 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n");
935 ok ( strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to not match \"/pub\"\n", lpszCurrentDirectory);
936 ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
937
938 /* test for the current directory with a size large enough to store
939 * the expected string as well as the null terminating character */
940 SetLastError(0xdeadbeef);
941 dwCurrentDirectoryLen = 5;
942 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
943 ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n");
944 ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
945 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
946 }
947
status_callback(HINTERNET handle,DWORD_PTR ctx,DWORD status,LPVOID info,DWORD info_len)948 static void WINAPI status_callback(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD info_len)
949 {
950 switch (status)
951 {
952 case INTERNET_STATUS_RESOLVING_NAME:
953 case INTERNET_STATUS_NAME_RESOLVED:
954 case INTERNET_STATUS_CONNECTING_TO_SERVER:
955 case INTERNET_STATUS_CONNECTED_TO_SERVER:
956 trace("%p %lx %u %s %u\n", handle, ctx, status, (char *)info, info_len);
957 break;
958 default:
959 break;
960 }
961 }
962
test_status_callbacks(HINTERNET hInternet)963 static void test_status_callbacks(HINTERNET hInternet)
964 {
965 INTERNET_STATUS_CALLBACK cb;
966 HINTERNET hFtp;
967 BOOL ret;
968
969 cb = pInternetSetStatusCallbackA(hInternet, status_callback);
970 ok(cb == NULL, "expected NULL got %p\n", cb);
971
972 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@",
973 INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 1);
974 if (!hFtp)
975 {
976 skip("No ftp connection could be made to ftp.winehq.org %u\n", GetLastError());
977 return;
978 }
979
980 ret = InternetCloseHandle(hFtp);
981 ok(ret, "InternetCloseHandle failed %u\n", GetLastError());
982
983 cb = pInternetSetStatusCallbackA(hInternet, NULL);
984 ok(cb == status_callback, "expected check_status got %p\n", cb);
985 }
986
START_TEST(ftp)987 START_TEST(ftp)
988 {
989 HMODULE hWininet;
990 HANDLE hInternet, hFtp, hHttp;
991
992 hWininet = GetModuleHandleA("wininet.dll");
993
994 if(!GetProcAddress(hWininet, "InternetGetCookieExW")) {
995 win_skip("Too old IE (older than 6.0)\n");
996 return;
997 }
998
999 pFtpCommandA = (void*)GetProcAddress(hWininet, "FtpCommandA");
1000 pInternetSetStatusCallbackA = (void*)GetProcAddress(hWininet, "InternetSetStatusCallbackA");
1001
1002 SetLastError(0xdeadbeef);
1003 hInternet = InternetOpenA("winetest", 0, NULL, NULL, 0);
1004 ok(hInternet != NULL, "InternetOpen failed: %u\n", GetLastError());
1005
1006 hFtp = InternetConnectA(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
1007 if (!hFtp)
1008 {
1009 InternetCloseHandle(hInternet);
1010 skip("No ftp connection could be made to ftp.winehq.org\n");
1011 return;
1012 }
1013 hHttp = InternetConnectA(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
1014 if (!hHttp)
1015 {
1016 InternetCloseHandle(hFtp);
1017 InternetCloseHandle(hInternet);
1018 skip("No http connection could be made to www.winehq.org\n");
1019 return;
1020 }
1021
1022 /* The first call should always be a proper InternetOpen, if not
1023 * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
1024 * all parameters are correct but no session handle is given. Whereas
1025 * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
1026 * is done before.
1027 * The following test will show that behaviour, where the tests inside
1028 * the other sub-tests will show the other situation.
1029 */
1030 test_getfile_no_open();
1031 test_connect(hInternet);
1032 test_createdir(hFtp, hHttp);
1033 test_deletefile(hFtp, hHttp);
1034 test_getfile(hFtp, hHttp);
1035 test_openfile(hFtp, hHttp);
1036 test_putfile(hFtp, hHttp);
1037 test_removedir(hFtp, hHttp);
1038 test_renamefile(hFtp, hHttp);
1039 test_command(hFtp);
1040 test_find_first_file(hFtp, hHttp);
1041 test_get_current_dir(hFtp, hHttp);
1042 test_status_callbacks(hInternet);
1043
1044 InternetCloseHandle(hHttp);
1045 InternetCloseHandle(hFtp);
1046 InternetCloseHandle(hInternet);
1047 }
1048