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