4 * Copyright 2007 Paul Vriens
5 * Copyright 2007 Hans Leidekker
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.
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.
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
24 * Use InternetGetLastResponseInfo when the last error is set to ERROR_INTERNET_EXTENDED_ERROR.
26 * Add W-function tests.
27 * Add missing function tests:
30 * FtpSetCurrentDirectory
42 #include "wine/test.h"
45 static BOOL (WINAPI *pFtpCommandA)(HINTERNET,BOOL,DWORD,LPCSTR,DWORD_PTR,HINTERNET*);
48 static void test_getfile_no_open(void)
52 /* Invalid internet handle, the others are valid parameters */
53 SetLastError(0xdeadbeef);
54 bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
55 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
56 ok ( GetLastError() == ERROR_INTERNET_NOT_INITIALIZED ||
57 GetLastError() == ERROR_INVALID_HANDLE,
58 "Expected ERROR_INTERNET_NOT_INITIALIZED or ERROR_INVALID_HANDLE (win98), got %d\n", GetLastError());
61 static void test_connect(HINTERNET hInternet)
65 /* Try a few username/password combinations:
71 SetLastError(0xdeadbeef);
72 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
73 if (hFtp) /* some servers accept an empty password */
75 ok ( GetLastError() == ERROR_SUCCESS, "ERROR_SUCCESS, got %d\n", GetLastError());
76 InternetCloseHandle(hFtp);
79 ok ( GetLastError() == ERROR_INTERNET_LOGIN_FAILURE,
80 "Expected ERROR_INTERNET_LOGIN_FAILURE, got %d\n", GetLastError());
82 SetLastError(0xdeadbeef);
83 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
84 ok ( hFtp == NULL, "Expected InternetConnect to fail\n");
85 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
86 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
88 /* Using a NULL username and password will be interpreted as anonymous ftp. The username will be 'anonymous' the password
89 * is created via some simple heuristics (see dlls/wininet/ftp.c).
90 * On Wine this registry key is not set by default so (NULL, NULL) will result in anonymous ftp with an (most likely) not
91 * accepted password (the username).
92 * If the first call fails because we get an ERROR_INTERNET_LOGIN_FAILURE, we try again with a (more) correct password.
95 SetLastError(0xdeadbeef);
96 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
97 if (!hFtp && (GetLastError() == ERROR_INTERNET_LOGIN_FAILURE))
99 /* We are most likely running on a clean Wine install or a Windows install where the registry key is removed */
100 SetLastError(0xdeadbeef);
101 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", "IEUser@", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
103 ok ( hFtp != NULL, "InternetConnect failed : %d\n", GetLastError());
104 ok ( GetLastError() == ERROR_SUCCESS,
105 "ERROR_SUCCESS, got %d\n", GetLastError());
108 static void test_createdir(HINTERNET hFtp, HINTERNET hConnect)
112 /* Invalid internet handle, the other is a valid parameter */
113 SetLastError(0xdeadbeef);
114 bRet = FtpCreateDirectoryA(NULL, "new_directory_deadbeef");
115 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
116 ok ( GetLastError() == ERROR_INVALID_HANDLE,
117 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
119 /* No directory-name */
120 SetLastError(0xdeadbeef);
121 bRet = FtpCreateDirectoryA(hFtp, NULL);
122 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
123 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
124 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
126 /* Parameters are OK, but we shouldn't be allowed to create the directory */
127 SetLastError(0xdeadbeef);
128 bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
129 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
130 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
131 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
133 /* One small test to show that handle type is checked before parameters */
134 SetLastError(0xdeadbeef);
135 bRet = FtpCreateDirectoryA(hConnect, NULL);
136 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
137 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
138 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
140 SetLastError(0xdeadbeef);
141 bRet = FtpCreateDirectoryA(hConnect, "new_directory_deadbeef");
142 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
143 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
144 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
147 static void test_deletefile(HINTERNET hFtp, HINTERNET hConnect)
151 /* Invalid internet handle, the other is a valid parameter */
152 SetLastError(0xdeadbeef);
153 bRet = FtpDeleteFileA(NULL, "non_existent_file_deadbeef");
154 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
155 ok ( GetLastError() == ERROR_INVALID_HANDLE,
156 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
159 SetLastError(0xdeadbeef);
160 bRet = FtpDeleteFileA(hFtp, NULL);
161 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
162 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
163 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
165 /* Parameters are OK but remote file should not be there */
166 SetLastError(0xdeadbeef);
167 bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
168 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
169 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
170 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
172 /* One small test to show that handle type is checked before parameters */
173 SetLastError(0xdeadbeef);
174 bRet = FtpDeleteFileA(hConnect, NULL);
175 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
176 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
177 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
179 SetLastError(0xdeadbeef);
180 bRet = FtpDeleteFileA(hConnect, "non_existent_file_deadbeef");
181 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
182 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
183 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
186 static void test_getfile(HINTERNET hFtp, HINTERNET hConnect)
191 /* The order of checking is:
193 * All parameters except 'session handle' and 'condition flags'
195 * Session handle type
199 /* Test to show the parameter checking order depends on the Windows version */
200 SetLastError(0xdeadbeef);
201 bRet = FtpGetFileA(NULL, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
202 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
203 ok ( GetLastError() == ERROR_INVALID_HANDLE ||
204 GetLastError() == ERROR_INVALID_PARAMETER,
205 "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
207 /* Test to show session handle is checked before 'condition flags' */
208 SetLastError(0xdeadbeef);
209 bRet = FtpGetFileA(NULL, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
210 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
211 ok ( GetLastError() == ERROR_INVALID_HANDLE,
212 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
214 /* Make sure we start clean */
216 DeleteFileA("should_be_non_existing_deadbeef");
217 DeleteFileA("should_also_be_non_existing_deadbeef");
220 SetLastError(0xdeadbeef);
221 bRet = FtpGetFileA(hFtp, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
222 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
223 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
224 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
225 ok (GetFileAttributesA("should_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
226 "Local file should not have been created\n");
227 DeleteFileA("should_be_non_existing_deadbeef");
230 SetLastError(0xdeadbeef);
231 bRet = FtpGetFileA(hFtp, "welcome.msg", NULL, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
232 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
233 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
234 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
236 /* Zero attributes */
237 SetLastError(0xdeadbeef);
238 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, 0, FTP_TRANSFER_TYPE_UNKNOWN, 0);
239 ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
240 ok (GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
241 ok (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES,
242 "Local file should have been created\n");
243 DeleteFileA("should_be_existing_non_deadbeef");
245 /* Illegal condition flags */
246 SetLastError(0xdeadbeef);
247 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 0xffffffff, 0);
248 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
249 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
250 "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), 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");
255 /* Remote file doesn't exist (and local doesn't exist as well) */
256 SetLastError(0xdeadbeef);
257 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
258 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
259 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
260 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
261 /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
263 ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
264 "Local file should not have been created\n");
266 DeleteFileA("should_also_be_non_existing_deadbeef");
268 /* Same call as the previous but now the local file does exists. Windows just removes the file if the call fails
269 * even if the local existed before!
272 /* Create a temporary local file */
273 SetLastError(0xdeadbeef);
274 hFile = CreateFileA("should_also_be_non_existing_deadbeef", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
275 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
277 SetLastError(0xdeadbeef);
278 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_also_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
279 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
280 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
281 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
282 /* Currently Wine always creates the local file (even on failure) which is not correct, hence the test */
284 ok (GetFileAttributesA("should_also_be_non_existing_deadbeef") == INVALID_FILE_ATTRIBUTES,
285 "Local file should not have been created\n");
287 DeleteFileA("should_also_be_non_existing_deadbeef");
289 /* This one should succeed */
290 SetLastError(0xdeadbeef);
291 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_existing_non_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
292 ok ( bRet == TRUE, "Expected FtpGetFileA to fail\n");
293 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
295 if (GetFileAttributesA("should_be_existing_non_deadbeef") != INVALID_FILE_ATTRIBUTES)
297 /* Should succeed as fFailIfExists is set to FALSE (meaning don't fail if local file exists) */
298 SetLastError(0xdeadbeef);
299 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
300 ok ( bRet == TRUE, "Expected FtpGetFileA to succeed\n");
301 ok ( GetLastError() == ERROR_SUCCESS,
302 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
304 /* Should fail as fFailIfExists is set to TRUE */
305 SetLastError(0xdeadbeef);
306 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
307 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
308 ok ( GetLastError() == ERROR_FILE_EXISTS,
309 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
311 /* Prove that the existence of the local file is checked first (or at least reported last) */
312 SetLastError(0xdeadbeef);
313 bRet = FtpGetFileA(hFtp, "should_be_non_existing_deadbeef", "should_be_non_existing_deadbeef", TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
314 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
315 ok ( GetLastError() == ERROR_FILE_EXISTS,
316 "Expected ERROR_FILE_EXISTS, got %d\n", GetLastError());
318 DeleteFileA("should_be_existing_non_deadbeef");
321 /* Test to show the parameter checking order depends on the Windows version */
322 SetLastError(0xdeadbeef);
323 bRet = FtpGetFileA(hConnect, NULL, "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
324 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
325 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
326 GetLastError() == ERROR_INVALID_PARAMETER,
327 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
329 /* Test to show that 'session handle type' is checked before 'condition flags' */
330 SetLastError(0xdeadbeef);
331 bRet = FtpGetFileA(hConnect, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, 5, 0);
332 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
333 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
334 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
336 SetLastError(0xdeadbeef);
337 bRet = FtpGetFileA(hConnect, "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_INTERNET_INCORRECT_HANDLE_TYPE,
340 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
343 static void test_openfile(HINTERNET hFtp, HINTERNET hConnect)
347 /* Invalid internet handle, the rest are valid parameters */
348 SetLastError(0xdeadbeef);
349 hOpenFile = FtpOpenFileA(NULL, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
350 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
351 ok ( GetLastError() == ERROR_INVALID_HANDLE,
352 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
353 InternetCloseHandle(hOpenFile); /* Just in case */
356 SetLastError(0xdeadbeef);
357 hOpenFile = FtpOpenFileA(hFtp, NULL, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
358 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
359 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
360 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
361 InternetCloseHandle(hOpenFile); /* Just in case */
363 /* Illegal access flags */
364 SetLastError(0xdeadbeef);
365 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", 0, FTP_TRANSFER_TYPE_ASCII, 0);
366 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
367 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
368 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
369 InternetCloseHandle(hOpenFile); /* Just in case */
371 /* Illegal combination of access flags */
372 SetLastError(0xdeadbeef);
373 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ|GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII, 0);
374 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
375 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
376 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
377 InternetCloseHandle(hOpenFile); /* Just in case */
379 /* Illegal condition flags */
380 SetLastError(0xdeadbeef);
381 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, 0xffffffff, 0);
382 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
383 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR || GetLastError() == ERROR_INVALID_PARAMETER,
384 "Expected ERROR_INTERNET_EXTENDED_ERROR or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
385 InternetCloseHandle(hOpenFile); /* Just in case */
387 SetLastError(0xdeadbeef);
388 hOpenFile = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
389 ok ( hOpenFile != NULL, "Expected FtpOpenFileA to succeed\n");
390 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", GetLastError());
395 HINTERNET hOpenFile2;
398 /* We have a handle so all ftp calls should fail (TODO: Put all ftp-calls in here) */
399 SetLastError(0xdeadbeef);
400 bRet = FtpCreateDirectoryA(hFtp, "new_directory_deadbeef");
401 ok ( bRet == FALSE, "Expected FtpCreateDirectoryA to fail\n");
402 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
403 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
405 SetLastError(0xdeadbeef);
406 bRet = FtpDeleteFileA(hFtp, "non_existent_file_deadbeef");
407 ok ( bRet == FALSE, "Expected FtpDeleteFileA to fail\n");
408 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
409 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
411 SetLastError(0xdeadbeef);
412 bRet = FtpGetFileA(hFtp, "welcome.msg", "should_be_non_existing_deadbeef", FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
413 ok ( bRet == FALSE, "Expected FtpGetFileA to fail\n");
414 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
415 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
416 DeleteFileA("should_be_non_existing_deadbeef"); /* Just in case */
418 SetLastError(0xdeadbeef);
419 hOpenFile2 = FtpOpenFileA(hFtp, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
420 ok ( bRet == FALSE, "Expected FtpOpenFileA to fail\n");
421 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
422 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
423 InternetCloseHandle(hOpenFile2); /* Just in case */
425 /* Create a temporary local file */
426 SetLastError(0xdeadbeef);
427 hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
428 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
430 SetLastError(0xdeadbeef);
431 bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
432 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
433 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
434 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
435 DeleteFileA("now_existing_local");
437 SetLastError(0xdeadbeef);
438 bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
439 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
440 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
441 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
443 SetLastError(0xdeadbeef);
444 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
445 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
446 ok ( GetLastError() == ERROR_FTP_TRANSFER_IN_PROGRESS,
447 "Expected ERROR_FTP_TRANSFER_IN_PROGRESS, got %d\n", GetLastError());
450 InternetCloseHandle(hOpenFile);
452 /* One small test to show that handle type is checked before parameters */
453 SetLastError(0xdeadbeef);
454 hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, 5, 0);
455 ok ( !hOpenFile, "Expected FtpOpenFileA to fail\n");
456 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
457 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
458 InternetCloseHandle(hOpenFile); /* Just in case */
460 SetLastError(0xdeadbeef);
461 hOpenFile = FtpOpenFileA(hConnect, "welcome.msg", GENERIC_READ, FTP_TRANSFER_TYPE_ASCII, 0);
462 ok ( hOpenFile == NULL, "Expected FtpOpenFileA to fail\n");
463 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
464 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
466 InternetCloseHandle(hOpenFile); /* Just in case */
469 static void test_putfile(HINTERNET hFtp, HINTERNET hConnect)
474 /* The order of checking is:
476 * All parameters except 'session handle' and 'condition flags'
478 * Session handle type
482 /* Test to show the parameter checking order depends on the Windows version */
483 SetLastError(0xdeadbeef);
484 bRet = FtpPutFileA(NULL, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
485 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
486 ok ( GetLastError() == ERROR_INVALID_HANDLE ||
487 GetLastError() == ERROR_INVALID_PARAMETER,
488 "Expected ERROR_INVALID_HANDLE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
490 /* Test to show session handle is checked before 'condition flags' */
491 SetLastError(0xdeadbeef);
492 bRet = FtpPutFileA(NULL, "non_existing_local", "non_existing_remote", 5, 0);
493 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
494 ok ( GetLastError() == ERROR_INVALID_HANDLE,
495 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
498 DeleteFileA("non_existing_local");
500 /* No local file given */
501 SetLastError(0xdeadbeef);
502 bRet = FtpPutFileA(hFtp, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
503 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
504 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
505 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
507 /* No remote file given */
508 SetLastError(0xdeadbeef);
509 bRet = FtpPutFileA(hFtp, "non_existing_local", NULL, FTP_TRANSFER_TYPE_UNKNOWN, 0);
510 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
511 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
512 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
514 /* Illegal condition flags */
515 SetLastError(0xdeadbeef);
516 bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", 5, 0);
517 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
518 ok ( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
519 "Expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER (win98), got %d\n", GetLastError());
521 /* Parameters are OK but local file doesn't exist */
522 SetLastError(0xdeadbeef);
523 bRet = FtpPutFileA(hFtp, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
524 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
525 ok ( GetLastError() == ERROR_FILE_NOT_FOUND,
526 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
528 /* Create a temporary local file */
529 SetLastError(0xdeadbeef);
530 hFile = CreateFileA("now_existing_local", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
531 ok ( hFile != NULL, "Error creating a local file : %d\n", GetLastError());
534 /* Local file exists but we shouldn't be allowed to 'put' the file */
535 SetLastError(0xdeadbeef);
536 bRet = FtpPutFileA(hFtp, "now_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
537 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
538 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
539 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
541 DeleteFileA("now_existing_local");
543 /* Test to show the parameter checking order depends on the Windows version */
544 SetLastError(0xdeadbeef);
545 bRet = FtpPutFileA(hConnect, NULL, "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
546 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
547 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE ||
548 GetLastError() == ERROR_INVALID_PARAMETER,
549 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE (win98) or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
551 /* Test to show that 'session handle type' is checked before 'condition flags' */
552 SetLastError(0xdeadbeef);
553 bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", 5, 0);
554 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
555 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
556 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
558 SetLastError(0xdeadbeef);
559 bRet = FtpPutFileA(hConnect, "non_existing_local", "non_existing_remote", FTP_TRANSFER_TYPE_UNKNOWN, 0);
560 ok ( bRet == FALSE, "Expected FtpPutFileA to fail\n");
561 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
562 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
565 static void test_removedir(HINTERNET hFtp, HINTERNET hConnect)
569 /* Invalid internet handle, the other is a valid parameter */
570 SetLastError(0xdeadbeef);
571 bRet = FtpRemoveDirectoryA(NULL, "should_be_non_existing_deadbeef_dir");
572 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
573 ok ( GetLastError() == ERROR_INVALID_HANDLE,
574 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
576 /* No remote directory given */
577 SetLastError(0xdeadbeef);
578 bRet = FtpRemoveDirectoryA(hFtp, NULL);
579 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
580 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
581 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
583 /* Remote directory doesn't exist */
584 SetLastError(0xdeadbeef);
585 bRet = FtpRemoveDirectoryA(hFtp, "should_be_non_existing_deadbeef_dir");
586 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
587 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
588 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
590 /* We shouldn't be allowed to remove that directory */
591 SetLastError(0xdeadbeef);
592 bRet = FtpRemoveDirectoryA(hFtp, "pub");
593 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
594 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
595 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
597 /* One small test to show that handle type is checked before parameters */
598 SetLastError(0xdeadbeef);
599 bRet = FtpRemoveDirectoryA(hConnect, NULL);
600 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
601 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
602 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
604 SetLastError(0xdeadbeef);
605 bRet = FtpRemoveDirectoryA(hConnect, "should_be_non_existing_deadbeef_dir");
606 ok ( bRet == FALSE, "Expected FtpRemoveDirectoryA to fail\n");
607 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
608 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
611 static void test_renamefile(HINTERNET hFtp, HINTERNET hConnect)
615 /* Invalid internet handle, the rest are valid parameters */
616 SetLastError(0xdeadbeef);
617 bRet = FtpRenameFileA(NULL , "should_be_non_existing_deadbeef", "new");
618 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
619 ok ( GetLastError() == ERROR_INVALID_HANDLE,
620 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
622 /* No 'existing' file */
623 SetLastError(0xdeadbeef);
624 bRet = FtpRenameFileA(hFtp , NULL, "new");
625 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
626 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
627 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
630 SetLastError(0xdeadbeef);
631 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", NULL);
632 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
633 ok ( GetLastError() == ERROR_INVALID_PARAMETER,
634 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
636 /* Existing file shouldn't be there */
637 SetLastError(0xdeadbeef);
638 bRet = FtpRenameFileA(hFtp , "should_be_non_existing_deadbeef", "new");
639 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
640 ok ( GetLastError() == ERROR_INTERNET_EXTENDED_ERROR,
641 "Expected ERROR_INTERNET_EXTENDED_ERROR, got %d\n", GetLastError());
643 /* One small test to show that handle type is checked before parameters */
644 SetLastError(0xdeadbeef);
645 bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", NULL);
646 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
647 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
648 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
650 SetLastError(0xdeadbeef);
651 bRet = FtpRenameFileA(hConnect , "should_be_non_existing_deadbeef", "new");
652 ok ( bRet == FALSE, "Expected FtpRenameFileA to fail\n");
653 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
654 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
657 static void test_command(HINTERNET hFtp, HINTERNET hConnect)
670 { FALSE, ERROR_INVALID_PARAMETER, NULL },
671 { FALSE, ERROR_INVALID_PARAMETER, "" },
672 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "HELO" },
673 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
674 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, " SIZE" },
675 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
676 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg /welcome.msg" },
677 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg" },
678 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg " },
679 { TRUE, ERROR_SUCCESS, "SIZE\t/welcome.msg" },
680 { TRUE, ERROR_SUCCESS, "SIZE /welcome.msg" },
681 { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "PWD /welcome.msg" },
682 { TRUE, ERROR_SUCCESS, "PWD" },
683 { TRUE, ERROR_SUCCESS, "PWD\r\n" }
688 skip("FtpCommandA() is not available. Skipping the Ftp command tests\n");
692 for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
694 SetLastError(0xdeadbeef);
695 ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
696 error = GetLastError();
698 ok(ret == command_test[i].ret, "%d: expected FtpCommandA to %s\n", i, command_test[i].ret ? "succeed" : "fail");
699 ok(error == command_test[i].error, "%d: expected error %u, got %u\n", i, command_test[i].error, error);
703 static void test_get_current_dir(HINTERNET hFtp, HINTERNET hConnect)
706 DWORD dwCurrentDirectoryLen = MAX_PATH;
707 CHAR lpszCurrentDirectory[MAX_PATH];
711 skip("FtpCommandA() is not available. Skipping the Ftp get_current_dir tests\n");
715 /* change directories to get a more interesting pwd */
716 bRet = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, "CWD pub/", 0, NULL);
719 skip("Failed to change directories in test_get_current_dir(HINTERNET hFtp).\n");
723 /* test with all NULL arguments */
724 SetLastError(0xdeadbeef);
725 bRet = FtpGetCurrentDirectoryA( NULL, NULL, 0 );
726 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
727 ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
729 /* test with NULL parameters instead of expected LPSTR/LPDWORD */
730 SetLastError(0xdeadbeef);
731 bRet = FtpGetCurrentDirectoryA( hFtp, NULL, 0 );
732 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
733 ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
735 /* test with no valid handle and valid parameters */
736 SetLastError(0xdeadbeef);
737 bRet = FtpGetCurrentDirectoryA( NULL, lpszCurrentDirectory, &dwCurrentDirectoryLen );
738 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
739 ok ( GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got: %d\n", GetLastError());
741 /* test with invalid dwCurrentDirectory and all other parameters correct */
742 SetLastError(0xdeadbeef);
743 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, 0 );
744 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
745 ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got: %d\n", GetLastError());
747 /* test with invalid lpszCurrentDirectory and all other parameters correct */
748 SetLastError(0xdeadbeef);
749 bRet = FtpGetCurrentDirectoryA( hFtp, NULL, &dwCurrentDirectoryLen );
750 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
751 ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
753 /* test to show it checks the handle type */
754 SetLastError(0xdeadbeef);
755 bRet = FtpGetCurrentDirectoryA( hConnect, lpszCurrentDirectory, &dwCurrentDirectoryLen );
756 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n" );
757 ok ( GetLastError() == ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
758 "Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got: %d\n", GetLastError());
760 /* test for the current directory with legitimate values */
761 SetLastError(0xdeadbeef);
762 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
763 ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n" );
764 ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
765 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
767 /* test for the current directory with a size only large enough to
768 * fit the string and not the null terminating character */
769 SetLastError(0xdeadbeef);
770 dwCurrentDirectoryLen = 4;
771 lpszCurrentDirectory[4] = 'a'; /* set position 4 of the array to something else to make sure a leftover \0 isn't fooling the test */
772 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
773 ok ( bRet == FALSE, "Expected FtpGetCurrentDirectoryA to fail\n");
774 ok ( strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to not match \"/pub\"\n", lpszCurrentDirectory);
775 ok ( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got: %d\n", GetLastError());
777 /* test for the current directory with a size large enough to store
778 * the expected string as well as the null terminating character */
779 SetLastError(0xdeadbeef);
780 dwCurrentDirectoryLen = 5;
781 bRet = FtpGetCurrentDirectoryA( hFtp, lpszCurrentDirectory, &dwCurrentDirectoryLen );
782 ok ( bRet == TRUE, "Expected FtpGetCurrentDirectoryA to pass\n");
783 ok ( !strcmp(lpszCurrentDirectory, "/pub"), "Expected returned value \"%s\" to match \"/pub\"\n", lpszCurrentDirectory);
784 ok ( GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got: %d\n", GetLastError());
790 HANDLE hInternet, hFtp, hHttp;
792 hWininet = GetModuleHandleA("wininet.dll");
793 pFtpCommandA = (void*)GetProcAddress(hWininet, "FtpCommandA");
795 SetLastError(0xdeadbeef);
796 hInternet = InternetOpen("winetest", 0, NULL, NULL, 0);
797 ok(hInternet != NULL, "InternetOpen failed: %u\n", GetLastError());
799 hFtp = InternetConnect(hInternet, "ftp.winehq.org", INTERNET_DEFAULT_FTP_PORT, "anonymous", NULL, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
802 InternetCloseHandle(hInternet);
803 skip("No ftp connection could be made to ftp.winehq.org\n");
806 hHttp = InternetConnect(hInternet, "www.winehq.org", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
809 InternetCloseHandle(hFtp);
810 InternetCloseHandle(hInternet);
811 skip("No http connection could be made to www.winehq.org\n");
815 /* The first call should always be a proper InternetOpen, if not
816 * several calls will return ERROR_INTERNET_NOT_INITIALIZED when
817 * all parameters are correct but no session handle is given. Whereas
818 * the same call will return ERROR_INVALID_HANDLE if an InternetOpen
820 * The following test will show that behaviour, where the tests inside
821 * the other sub-tests will show the other situation.
823 test_getfile_no_open();
824 test_connect(hInternet);
825 test_createdir(hFtp, hHttp);
826 test_deletefile(hFtp, hHttp);
827 test_getfile(hFtp, hHttp);
828 test_openfile(hFtp, hHttp);
829 test_putfile(hFtp, hHttp);
830 test_removedir(hFtp, hHttp);
831 test_renamefile(hFtp, hHttp);
832 test_command(hFtp, hHttp);
833 test_get_current_dir(hFtp, hHttp);
835 InternetCloseHandle(hHttp);
836 InternetCloseHandle(hFtp);
837 InternetCloseHandle(hInternet);