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