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