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