push 149f0a5527ac85057a8ef03858d34d91c36f97e8
[wine/hacks.git] / dlls / wininet / tests / ftp.c
blob37c71dafd5748b6cebec12f1060719c6fff683df
1 /*
2 * Wininet - ftp tests
4 * Copyright 2007 Paul Vriens
5 * Copyright 2007 Hans Leidekker
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.
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.
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
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
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <stdlib.h>
36 #include "windef.h"
37 #include "winbase.h"
38 #include "wininet.h"
39 #include "winsock.h"
41 #include "wine/test.h"
44 static BOOL (WINAPI *pFtpCommandA)(HINTERNET,BOOL,DWORD,LPCSTR,DWORD_PTR,HINTERNET*);
45 static INTERNET_STATUS_CALLBACK (WINAPI *pInternetSetStatusCallbackA)(HINTERNET,INTERNET_STATUS_CALLBACK);
48 static void test_getfile_no_open(void)
50 BOOL bRet;
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());
61 static void test_connect(HINTERNET hInternet)
63 HINTERNET hFtp;
65 /* Try a few username/password combinations:
66 * anonymous : NULL
67 * NULL : IEUser@
68 * NULL : NULL
69 * "" : IEUser@
70 * "" : NULL
73 SetLastError(0xdeadbeef);
74 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
75 if (hFtp) /* some servers accept an empty password */
77 ok ( GetLastError() == ERROR_SUCCESS, "ERROR_SUCCESS, got %d\n", GetLastError());
78 InternetCloseHandle(hFtp);
80 else
81 ok ( GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
82 "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
84 SetLastError(0xdeadbeef);
85 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
86 ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
87 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
88 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
90 SetLastError(0xdeadbeef);
91 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "", "IEUser@",
92 INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
93 ok(!hFtp, "Expected InternetConnect to fail\n");
94 ok(GetLastError() == ERROR_INVALID_PARAMETER,
95 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
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.
104 SetLastError(0xdeadbeef);
105 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
106 if (!hFtp && (GetLastError() == ERROR_INTERNET_LOGIN_FAILURE))
108 /* We are most likely running on a clean Wine install or a Windows install where the registry key is removed */
109 SetLastError(0xdeadbeef);
110 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
112 ok ( hFtp != NULL, "InternetConnect failed : %d\n", GetLastError());
113 ok ( GetLastError() == ERROR_SUCCESS,
114 "ERROR_SUCCESS, got %d\n", GetLastError());
116 SetLastError(0xdeadbeef);
117 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "", NULL,
118 INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
119 if (!hFtp)
121 ok(GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
122 "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
124 else
126 ok(GetLastError() == ERROR_SUCCESS,
127 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
131 static void test_createdir(HINTERNET hFtp, HINTERNET hConnect)
133 BOOL bRet;
135 /* Invalid internet handle, the other is a valid parameter */
136 SetLastError(0xdeadbeef);
137 bRet = FtpCreateDirectoryA(NULL, "new_directory_deadbeef");
138 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
139 ok ( GetLastError() == ERROR_INVALID_HANDLE,
140 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
142 /* No directory-name */
143 SetLastError(0xdeadbeef);
144 bRet = FtpCreateDirectoryA(hFtp, NULL);
145 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
146 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
147 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
149 /* Parameters are OK, but we shouldn't be allowed to create the directory */
150 SetLastError(0xdeadbeef);
151 bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
152 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
153 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
154 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
156 /* One small test to show that handle type is checked before parameters */
157 SetLastError(0xdeadbeef);
158 bRet = FtpCreateDirectoryA(hConnect, NULL);
159 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
160 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
161 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
163 SetLastError(0xdeadbeef);
164 bRet = FtpCreateDirectoryA(hConnect, "new_directory_deadbeef");
165 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
166 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
167 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
170 static void test_deletefile(HINTERNET hFtp, HINTERNET hConnect)
172 BOOL bRet;
174 /* Invalid internet handle, the other is a valid parameter */
175 SetLastError(0xdeadbeef);
176 bRet = FtpDeleteFileA(NULL, "non_existent_file_deadbeef");
177 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
178 ok ( GetLastError() == ERROR_INVALID_HANDLE,
179 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
181 /* No filename */
182 SetLastError(0xdeadbeef);
183 bRet = FtpDeleteFileA(hFtp, NULL);
184 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
185 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
186 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
188 /* Parameters are OK but remote file should not be there */
189 SetLastError(0xdeadbeef);
190 bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
191 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
192 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
193 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
195 /* One small test to show that handle type is checked before parameters */
196 SetLastError(0xdeadbeef);
197 bRet = FtpDeleteFileA(hConnect, NULL);
198 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
199 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
200 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
202 SetLastError(0xdeadbeef);
203 bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
204 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
205 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
206 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
209 static void test_getfile(HINTERNET hFtp, HINTERNET hConnect)
211 BOOL bRet;
212 HANDLE hFile;
214 /* The order of checking is:
216 * All parameters except 'session handle' and 'condition flags'
217 * Session handle
218 * Session handle type
219 * Condition flags
222 /* Test to show the parameter checking order depends on the Windows version */
223 SetLastError(0xdeadbeef);
224 bRet = FtpGetFileA(NULL, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
225 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
226 ok ( GetLastError() == ERROR_INVALID_HANDLE ||
227 GetLastError() == ERROR_INVALID_PARAMETER,
228 "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
230 /* Test to show session handle is checked before 'condition flags' */
231 SetLastError(0xdeadbeef);
232 bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
233 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
234 ok ( GetLastError() == ERROR_INVALID_HANDLE,
235 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
237 /* Make sure we start clean */
239 DeleteFileA("should_be_non_existing_deadbeef");
240 DeleteFileA("should_also_be_non_existing_deadbeef");
242 /* No remote file */
243 SetLastError(0xdeadbeef);
244 bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
245 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
246 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
247 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
248 ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
249 "Local file should not have been created\n");
250 DeleteFileA("should_be_non_existing_deadbeef");
252 /* No local file */
253 SetLastError(0xdeadbeef);
254 bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
255 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
256 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
257 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
259 /* Zero attributes */
260 SetLastError(0xdeadbeef);
261 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
262 ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
263 ok (GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
264 ok (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES,
265 "Local file should have been created\n");
266 DeleteFileA("should_be_existing_non_deadbeef");
268 /* Illegal condition flags */
269 SetLastError(0xdeadbeef);
270 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 0xffffffff, 0);
271 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
272 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
273 "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
274 ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
275 "Local file should not have been created\n");
276 DeleteFileA("should_be_non_existing_deadbeef");
278 /* Remote file doesn't exist (and local doesn't exist as well) */
279 SetLastError(0xdeadbeef);
280 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
281 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
282 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
283 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
284 /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
285 ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
286 "Local file should not have been created\n");
288 DeleteFileA("should_also_be_non_existing_deadbeef");
290 /* Same call as the previous but now the local file does exists. Windows just removes the file if the call fails
291 * even if the local existed before!
294 /* Create a temporary local file */
295 SetLastError(0xdeadbeef);
296 hFile = CreateFileA("should_also_be_non_existing_deadbeef", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
297 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
298 CloseHandle(hFile);
299 SetLastError(0xdeadbeef);
300 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
301 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
302 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
303 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
304 /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
305 ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
306 "Local file should not have been created\n");
308 DeleteFileA("should_also_be_non_existing_deadbeef");
310 /* This one should succeed */
311 SetLastError(0xdeadbeef);
312 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
313 ok ( bRet == TRUE, "Expected FtpGetFileA to fail\n");
314 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
316 if (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES)
318 /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
319 SetLastError(0xdeadbeef);
320 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
321 ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
322 ok ( GetLastError() == ERROR_SUCCESS,
323 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
325 /* Should fail as fFailIfExists is set to TRUE */
326 SetLastError(0xdeadbeef);
327 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
328 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
329 ok ( GetLastError() == ERROR_FILE_EXISTS,
330 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
332 /* Prove that the existence of the local file is checked first (or at least reported last) */
333 SetLastError(0xdeadbeef);
334 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
335 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
336 ok ( GetLastError() == ERROR_FILE_EXISTS,
337 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
339 DeleteFileA("should_be_existing_non_deadbeef");
342 /* Test to show the parameter checking order depends on the Windows version */
343 SetLastError(0xdeadbeef);
344 bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
345 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
346 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
347 GetLastError() == ERROR_INVALID_PARAMETER,
348 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
350 /* Test to show that 'session handle type' is checked before 'condition flags' */
351 SetLastError(0xdeadbeef);
352 bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
353 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
354 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
355 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
357 SetLastError(0xdeadbeef);
358 bRet = FtpGetFileA(hConnect, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
359 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
360 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
361 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
364 static void trace_extended_error(DWORD error)
366 DWORD code, buflen = 0;
368 if (error != ERROR_INTERNET_EXTENDED_ERROR) return;
369 if (!InternetGetLastResponseInfoA(&code, NULL, &buflen) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
371 char *text = HeapAlloc(GetProcessHeap(), 0, ++buflen);
372 InternetGetLastResponseInfoA(&code, text, &buflen);
373 trace("%u %s\n", code, text);
374 HeapFree(GetProcessHeap(), 0, text);
378 static void test_openfile(HINTERNET hFtp, HINTERNET hConnect)
380 HINTERNET hOpenFile;
382 /* Invalid internet handle, the rest are valid parameters */
383 SetLastError(0xdeadbeef);
384 hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
385 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
386 ok ( GetLastError() == ERROR_INVALID_HANDLE,
387 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
388 InternetCloseHandle(hOpenFile); /* Just in case */
390 /* No filename */
391 SetLastError(0xdeadbeef);
392 hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
393 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
394 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
395 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
396 InternetCloseHandle(hOpenFile); /* Just in case */
398 /* Illegal access flags */
399 SetLastError(0xdeadbeef);
400 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
401 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
402 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
403 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
404 InternetCloseHandle(hOpenFile); /* Just in case */
406 /* Illegal combination of access flags */
407 SetLastError(0xdeadbeef);
408 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
409 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
410 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
411 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
412 InternetCloseHandle(hOpenFile); /* Just in case */
414 /* Illegal condition flags */
415 SetLastError(0xdeadbeef);
416 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 0xffffffff, 0);
417 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
418 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
419 "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
420 InternetCloseHandle(hOpenFile); /* Just in case */
422 SetLastError(0xdeadbeef);
423 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
424 ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
425 ok ( GetLastError() == ERROR_SUCCESS ||
426 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
427 "Expected ERROR_SUCCESS, got %u\n", GetLastError());
429 if (hOpenFile)
431 BOOL bRet;
432 DWORD error;
433 HINTERNET hOpenFile2;
434 HANDLE hFile;
436 /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
437 SetLastError(0xdeadbeef);
438 bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
439 error = GetLastError();
440 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
441 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS,
442 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
443 trace_extended_error(error);
445 SetLastError(0xdeadbeef);
446 bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
447 error = GetLastError();
448 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
449 ok ( error == ERROR_FTP_TRANSFER_IN_PROGRESS,
450 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", error);
451 trace_extended_error(error);
453 SetLastError(0xdeadbeef);
454 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
455 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
456 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
457 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
458 DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
460 SetLastError(0xdeadbeef);
461 hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
462 ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n");
463 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
464 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
465 InternetCloseHandle(hOpenFile2); /* Just in case */
467 /* Create a temporary local file */
468 SetLastError(0xdeadbeef);
469 hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
470 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
471 CloseHandle(hFile);
472 SetLastError(0xdeadbeef);
473 bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
474 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
475 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
476 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
477 DeleteFileA("now_existing_local");
479 SetLastError(0xdeadbeef);
480 bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
481 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
482 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
483 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
485 SetLastError(0xdeadbeef);
486 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
487 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
488 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
489 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
492 InternetCloseHandle(hOpenFile);
494 /* One small test to show that handle type is checked before parameters */
495 SetLastError(0xdeadbeef);
496 hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
497 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
498 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
499 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
500 InternetCloseHandle(hOpenFile); /* Just in case */
502 SetLastError(0xdeadbeef);
503 hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
504 ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
505 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
506 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
508 InternetCloseHandle(hOpenFile); /* Just in case */
511 static void test_putfile(HINTERNET hFtp, HINTERNET hConnect)
513 BOOL bRet;
514 HANDLE hFile;
516 /* The order of checking is:
518 * All parameters except 'session handle' and 'condition flags'
519 * Session handle
520 * Session handle type
521 * Condition flags
524 /* Test to show the parameter checking order depends on the Windows version */
525 SetLastError(0xdeadbeef);
526 bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
527 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
528 ok ( GetLastError() == ERROR_INVALID_HANDLE ||
529 GetLastError() == ERROR_INVALID_PARAMETER,
530 "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
532 /* Test to show session handle is checked before 'condition flags' */
533 SetLastError(0xdeadbeef);
534 bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
535 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
536 ok ( GetLastError() == ERROR_INVALID_HANDLE,
537 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
539 /* Start clean */
540 DeleteFileA("non_existing_local");
542 /* No local file given */
543 SetLastError(0xdeadbeef);
544 bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
545 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
546 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
547 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
549 /* No remote file given */
550 SetLastError(0xdeadbeef);
551 bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
552 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
553 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
554 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
556 /* Illegal condition flags */
557 SetLastError(0xdeadbeef);
558 bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
559 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
560 ok ( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
561 "Expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
563 /* Parameters are OK but local file doesn't exist */
564 SetLastError(0xdeadbeef);
565 bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
566 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
567 ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
568 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
570 /* Create a temporary local file */
571 SetLastError(0xdeadbeef);
572 hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
573 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
574 CloseHandle(hFile);
576 /* Local file exists but we shouldn't be allowed to 'put' the file */
577 SetLastError(0xdeadbeef);
578 bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
579 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
580 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
581 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
583 DeleteFileA("now_existing_local");
585 /* Test to show the parameter checking order depends on the Windows version */
586 SetLastError(0xdeadbeef);
587 bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
588 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
589 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
590 GetLastError() == ERROR_INVALID_PARAMETER,
591 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
593 /* Test to show that 'session handle type' is checked before 'condition flags' */
594 SetLastError(0xdeadbeef);
595 bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
596 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
597 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
598 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
600 SetLastError(0xdeadbeef);
601 bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
602 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
603 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
604 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
607 static void test_removedir(HINTERNET hFtp, HINTERNET hConnect)
609 BOOL bRet;
611 /* Invalid internet handle, the other is a valid parameter */
612 SetLastError(0xdeadbeef);
613 bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
614 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
615 ok ( GetLastError() == ERROR_INVALID_HANDLE,
616 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
618 /* No remote directory given */
619 SetLastError(0xdeadbeef);
620 bRet = FtpRemoveDirectoryA(hFtp, NULL);
621 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
622 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
623 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
625 /* Remote directory doesn't exist */
626 SetLastError(0xdeadbeef);
627 bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
628 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
629 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
630 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
632 /* We shouldn't be allowed to remove that directory */
633 SetLastError(0xdeadbeef);
634 bRet = FtpRemoveDirectoryA(hFtp, "pub");
635 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
636 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
637 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
639 /* One small test to show that handle type is checked before parameters */
640 SetLastError(0xdeadbeef);
641 bRet = FtpRemoveDirectoryA(hConnect, NULL);
642 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
643 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
644 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
646 SetLastError(0xdeadbeef);
647 bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
648 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
649 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
650 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
653 static void test_renamefile(HINTERNET hFtp, HINTERNET hConnect)
655 BOOL bRet;
657 /* Invalid internet handle, the rest are valid parameters */
658 SetLastError(0xdeadbeef);
659 bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
660 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
661 ok ( GetLastError() == ERROR_INVALID_HANDLE,
662 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
664 /* No 'existing' file */
665 SetLastError(0xdeadbeef);
666 bRet = FtpRenameFileA(hFtp , NULL, "new");
667 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
668 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
669 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
671 /* No new file */
672 SetLastError(0xdeadbeef);
673 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
674 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
675 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
676 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
678 /* Existing file shouldn't be there */
679 SetLastError(0xdeadbeef);
680 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
681 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
682 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
683 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
685 /* One small test to show that handle type is checked before parameters */
686 SetLastError(0xdeadbeef);
687 bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
688 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
689 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
690 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
692 SetLastError(0xdeadbeef);
693 bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
694 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
695 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
696 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
699 static void test_command(HINTERNET hFtp, HINTERNET hConnect)
701 BOOL ret;
702 DWORD error;
703 unsigned int i;
704 static const struct
706 BOOL ret;
707 DWORD error;
708 const char *cmd;
710 command_test[] =
712 { FALSE, ERROR_INVALID_PARAMETER, NULL },
713 { FALSE, ERROR_INVALID_PARAMETER, "" },
714 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "HELO" },
715 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
716 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, " SIZE" },
717 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
718 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg /welcome.msg" },
719 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg" },
720 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg " },
721 { TRUE, ERROR_SUCCESS, "SIZE\t/welcome.msg" },
722 { TRUE, ERROR_SUCCESS, "SIZE /welcome.msg" },
723 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "PWD /welcome.msg" },
724 { TRUE, ERROR_SUCCESS, "PWD" },
725 { TRUE, ERROR_SUCCESS, "PWD\r\n" }
728 if (!pFtpCommandA)
730 win_skip("FtpCommandA() is not available. Skipping the Ftp command tests\n");
731 return;
734 for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
736 SetLastError(0xdeadbeef);
737 ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
738 error = GetLastError();
740 ok(ret == command_test[i].ret, "%d: expected FtpCommandA to %s\n", i, command_test[i].ret ? "succeed" : "fail");
741 ok(error == command_test[i].error, "%d: expected error %u, got %u\n", i, command_test[i].error, error);
745 static void test_find_first_file(HINTERNET hFtp, HINTERNET hConnect)
747 WIN32_FIND_DATA findData;
748 HINTERNET hSearch;
749 HINTERNET hSearch2;
750 HINTERNET hOpenFile;
752 /* NULL as the search file ought to return the first file in the directory */
753 SetLastError(0xdeadbeef);
754 hSearch = FtpFindFirstFileA(hFtp, NULL, &findData, 0, 0);
755 ok ( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
757 /* This should fail as the previous handle wasn't closed */
758 SetLastError(0xdeadbeef);
759 hSearch2 = FtpFindFirstFileA(hFtp, "welcome.msg", &findData, 0, 0);
760 todo_wine ok ( hSearch2 == NULL, "Expected FtpFindFirstFileA to fail\n" );
761 todo_wine ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
762 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError() );
763 InternetCloseHandle(hSearch2); /* Just in case */
765 InternetCloseHandle(hSearch);
767 /* Try a valid filename in a subdirectory search */
768 SetLastError(0xdeadbeef);
769 hSearch = FtpFindFirstFileA(hFtp, "pub/wine", &findData, 0, 0);
770 todo_wine ok ( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
771 InternetCloseHandle(hSearch);
773 /* Try a valid filename in a subdirectory wildcard search */
774 SetLastError(0xdeadbeef);
775 hSearch = FtpFindFirstFileA(hFtp, "pub/w*", &findData, 0, 0);
776 todo_wine ok ( hSearch != NULL, "Expected FtpFindFirstFileA to pass\n" );
777 InternetCloseHandle(hSearch);
779 /* Try an invalid wildcard search */
780 SetLastError(0xdeadbeef);
781 hSearch = FtpFindFirstFileA(hFtp, "*/w*", &findData, 0, 0);
782 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
783 InternetCloseHandle(hSearch); /* Just in case */
785 /* Try FindFirstFile between FtpOpenFile and InternetCloseHandle */
786 SetLastError(0xdeadbeef);
787 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
788 ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n" );
789 ok ( GetLastError() == ERROR_SUCCESS ||
790 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
791 "Expected ERROR_SUCCESS, got %u\n", GetLastError() );
793 /* This should fail as the OpenFile handle wasn't closed */
794 SetLastError(0xdeadbeef);
795 hSearch = FtpFindFirstFileA(hFtp, "welcome.msg", &findData, 0, 0);
796 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
797 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
798 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError() );
799 InternetCloseHandle(hSearch); /* Just in case */
801 InternetCloseHandle(hOpenFile);
803 /* Test using a nonexistent filename */
804 SetLastError(0xdeadbeef);
805 hSearch = FtpFindFirstFileA(hFtp, "this_file_should_not_exist", &findData, 0, 0);
806 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
807 todo_wine ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
808 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError() );
809 InternetCloseHandle(hSearch); /* Just in case */
811 /* Test using a nonexistent filename and a wildcard */
812 SetLastError(0xdeadbeef);
813 hSearch = FtpFindFirstFileA(hFtp, "this_file_should_not_exist*", &findData, 0, 0);
814 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
815 todo_wine ok ( GetLastError() == ERROR_NO_MORE_FILES,
816 "Expected ERROR_NO_MORE_FILES, got %d\n", GetLastError() );
817 InternetCloseHandle(hSearch); /* Just in case */
819 /* Test using an invalid handle type */
820 SetLastError(0xdeadbeef);
821 hSearch = FtpFindFirstFileA(hConnect, "welcome.msg", &findData, 0, 0);
822 ok ( hSearch == NULL, "Expected FtpFindFirstFileA to fail\n" );
823 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
824 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError() );
825 InternetCloseHandle(hSearch); /* Just in case */
828 static void test_get_current_dir(HINTERNET hFtp, HINTERNET hConnect)
830 BOOL bRet;
831 DWORD dwCurrentDirectoryLen = MAX_PATH;
832 CHAR lpszCurrentDirectory[MAX_PATH];
834 if (!pFtpCommandA)
836 win_skip("FtpCommandA() is not available. Skipping the Ftp get_current_dir tests\n");
837 return;
840 /* change directories to get a more interesting pwd */
841 bRet = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, "CWD pub/", 0, NULL);
842 if(bRet == FALSE)
844 skip("Failed to change directories in test_get_current_dir(HINTERNET hFtp).\n");
845 return;
848 /* test with all NULL arguments */
849 SetLastError(0xdeadbeef);
850 bRet = FtpGetCurrentDirectoryA( NULL, NULL, 0 );
851 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
852 ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
854 /* test with NULL parameters instead of expected LPSTR/LPDWORD */
855 SetLastError(0xdeadbeef);
856 bRet = FtpGetCurrentDirectoryA( hFtp, NULL, 0 );
857 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
858 ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
860 /* test with no valid handle and valid parameters */
861 SetLastError(0xdeadbeef);
862 bRet = FtpGetCurrentDirectoryA( NULL, lpszCurrentDirectory, &dwCurrentDirectoryLen );
863 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
864 ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
866 /* test with invalid dwCurrentDirectory and all other parameters correct */
867 SetLastError(0xdeadbeef);
868 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, 0 );
869 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
870 ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
872 /* test with invalid lpszCurrentDirectory and all other parameters correct */
873 SetLastError(0xdeadbeef);
874 bRet = FtpGetCurrentDirectoryA( hFtp, NULL, &dwCurrentDirectoryLen );
875 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
876 ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
878 /* test to show it checks the handle type */
879 SetLastError(0xdeadbeef);
880 bRet = FtpGetCurrentDirectoryA( hConnect, lpszCurrentDirectory, &dwCurrentDirectoryLen );
881 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
882 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
883 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got: %d\n", GetLastError());
885 /* test for the current directory with legitimate values */
886 SetLastError(0xdeadbeef);
887 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
888 ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n" );
889 ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
890 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
892 /* test for the current directory with a size only large enough to
893 * fit the string and not the null terminating character */
894 SetLastError(0xdeadbeef);
895 dwCurrentDirectoryLen = 4;
896 lpszCurrentDirectory[4] = 'a'; /* set position 4 of the array to something else to make sure a leftover \0 isn't fooling the test */
897 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
898 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n");
899 ok ( strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to not match \"/pub\"\n", lpszCurrentDirectory);
900 ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
902 /* test for the current directory with a size large enough to store
903 * the expected string as well as the null terminating character */
904 SetLastError(0xdeadbeef);
905 dwCurrentDirectoryLen = 5;
906 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
907 ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n");
908 ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
909 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
912 static void WINAPI status_callback(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID info, DWORD info_len)
914 switch (status)
916 case INTERNET_STATUS_RESOLVING_NAME:
917 case INTERNET_STATUS_NAME_RESOLVED:
918 case INTERNET_STATUS_CONNECTING_TO_SERVER:
919 case INTERNET_STATUS_CONNECTED_TO_SERVER:
920 trace("%p %lx %u %s %u\n", handle, ctx, status, (char *)info, info_len);
921 break;
922 default:
923 break;
927 static void test_status_callbacks(HINTERNET hInternet)
929 INTERNET_STATUS_CALLBACK cb;
930 HINTERNET hFtp;
931 BOOL ret;
933 if (!pInternetSetStatusCallbackA)
935 win_skip("InternetSetStatusCallbackA() is not available, skipping test\n");
936 return;
939 cb = pInternetSetStatusCallbackA(hInternet, status_callback);
940 ok(cb == NULL, "expected NULL got %p\n", cb);
942 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL,
943 INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 1);
944 if (!hFtp)
946 skip("No ftp connection could be made to ftp.winehq.org %u\n", GetLastError());
947 return;
950 ret = InternetCloseHandle(hFtp);
951 ok(ret, "InternetCloseHandle failed %u\n", GetLastError());
953 cb = pInternetSetStatusCallbackA(hInternet, NULL);
954 ok(cb == status_callback, "expected check_status got %p\n", cb);
957 START_TEST(ftp)
959 HMODULE hWininet;
960 HANDLE hInternet, hFtp, hHttp;
962 hWininet = GetModuleHandleA("wininet.dll");
963 pFtpCommandA = (void*)GetProcAddress(hWininet, "FtpCommandA");
964 pInternetSetStatusCallbackA = (void*)GetProcAddress(hWininet, "InternetSetStatusCallbackA");
966 SetLastError(0xdeadbeef);
967 hInternet = InternetOpen("winetest", 0, NULL, NULL, 0);
968 ok(hInternet != NULL, "InternetOpen failed: %u\n", GetLastError());
970 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
971 if (!hFtp)
973 InternetCloseHandle(hInternet);
974 skip("No ftp connection could be made to ftp.winehq.org\n");
975 return;
977 hHttp = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
978 if (!hHttp)
980 InternetCloseHandle(hFtp);
981 InternetCloseHandle(hInternet);
982 skip("No http connection could be made to www.winehq.org\n");
983 return;
986 /* The first call should always be a proper InternetOpen, if not
987 * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
988 * all parameters are correct but no session handle is given. Whereas
989 * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
990 * is done before.
991 * The following test will show that behaviour, where the tests inside
992 * the other sub-tests will show the other situation.
994 test_getfile_no_open();
995 test_connect(hInternet);
996 test_createdir(hFtp, hHttp);
997 test_deletefile(hFtp, hHttp);
998 test_getfile(hFtp, hHttp);
999 test_openfile(hFtp, hHttp);
1000 test_putfile(hFtp, hHttp);
1001 test_removedir(hFtp, hHttp);
1002 test_renamefile(hFtp, hHttp);
1003 test_command(hFtp, hHttp);
1004 test_find_first_file(hFtp, hHttp);
1005 test_get_current_dir(hFtp, hHttp);
1006 test_status_callbacks(hInternet);
1008 InternetCloseHandle(hHttp);
1009 InternetCloseHandle(hFtp);
1010 InternetCloseHandle(hInternet);