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