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