ReactOS  0.4.15-dev-2947-g59e1b78
ftp.c
Go to the documentation of this file.
1 #ifdef __REACTOS__
2 #include "precomp.h"
3 #else
4 /*
5  * WININET - Ftp implementation
6  *
7  * Copyright 1999 Corel Corporation
8  * Copyright 2004 Mike McCormack for CodeWeavers
9  * Copyright 2004 Kevin Koltzau
10  * Copyright 2007 Hans Leidekker
11  *
12  * Ulrich Czekalla
13  * Noureddine Jemmali
14  *
15  * Copyright 2000 Andreas Mohr
16  * Copyright 2002 Jaco Greeff
17  *
18  * This library is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU Lesser General Public
20  * License as published by the Free Software Foundation; either
21  * version 2.1 of the License, or (at your option) any later version.
22  *
23  * This library is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26  * Lesser General Public License for more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public
29  * License along with this library; if not, write to the Free Software
30  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31  */
32 
33 #include "ws2tcpip.h"
34 
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <time.h>
40 #include <assert.h>
41 
42 #include "windef.h"
43 #include "winbase.h"
44 #include "wingdi.h"
45 #include "winuser.h"
46 #include "wininet.h"
47 #include "winnls.h"
48 #include "winerror.h"
49 #include "winreg.h"
50 #include "winternl.h"
51 #include "shlwapi.h"
52 
53 #include "wine/debug.h"
54 #include "internet.h"
55 #endif /* defined(__REACTOS__) */
56 
58 
59 #define RESPONSE_TIMEOUT 30
60 
62 
63 typedef struct
64 {
71 } ftp_file_t;
72 
74 {
77  int sndSocket;
79  int pasvSocket; /* data socket connected by us in case of passive FTP */
87 };
88 
89 typedef struct
90 {
95  unsigned short permissions;
97 
98 typedef struct
99 {
106 
107 #define DATA_PACKET_SIZE 0x2000
108 #define szCRLF "\r\n"
109 #define MAX_BACKLOG 5
110 
111 /* Testing shows that Windows only accepts dwFlags where the last
112  * 3 (yes 3) bits define FTP_TRANSFER_TYPE_UNKNOWN, FTP_TRANSFER_TYPE_ASCII or FTP_TRANSFER_TYPE_BINARY.
113  */
114 #define FTP_CONDITION_MASK 0x0007
115 
116 typedef enum {
117  /* FTP commands with arguments. */
132 
133  /* FTP commands without arguments. */
140 } FTP_COMMAND;
141 
142 static const CHAR *const szFtpCommands[] = {
143  "ACCT",
144  "CWD",
145  "DELE",
146  "MKD",
147  "PASS",
148  "PORT",
149  "RETR",
150  "RMD",
151  "RNFR",
152  "RNTO",
153  "STOR",
154  "TYPE",
155  "USER",
156  "SIZE",
157  "ABOR",
158  "LIST",
159  "NLST",
160  "PASV",
161  "PWD",
162  "QUIT",
163 };
164 
165 static const CHAR szMonths[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
166 
167 static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam,
168  INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext);
169 static BOOL FTP_SendStore(ftp_session_t*, LPCWSTR lpszRemoteFile, DWORD dwType);
170 static BOOL FTP_GetDataSocket(ftp_session_t*, LPINT nDataSocket);
171 static BOOL FTP_SendData(ftp_session_t*, INT nDataSocket, HANDLE hFile);
172 static INT FTP_ReceiveResponse(ftp_session_t*, DWORD_PTR dwContext);
173 static BOOL FTP_SendRetrieve(ftp_session_t*, LPCWSTR lpszRemoteFile, DWORD dwType);
174 static BOOL FTP_RetrieveFileData(ftp_session_t*, INT nDataSocket, HANDLE hFile);
179 static BOOL FTP_SendType(ftp_session_t*, DWORD dwType);
183 static BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESW lpfp);
184 static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW fileprop);
185 static BOOL FTP_ParseDirectory(ftp_session_t*, INT nSocket, LPCWSTR lpszSearchFile,
186  LPFILEPROPERTIESW *lpafp, LPDWORD dwfp);
187 static HINTERNET FTP_ReceiveFileList(ftp_session_t*, INT nSocket, LPCWSTR lpszSearchFile,
188  LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext);
189 static DWORD FTP_SetResponseError(DWORD dwResponse);
190 static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData);
191 static BOOL FTP_FtpPutFileW(ftp_session_t*, LPCWSTR lpszLocalFile,
192  LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext);
193 static BOOL FTP_FtpSetCurrentDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory);
194 static BOOL FTP_FtpCreateDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory);
196  LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext);
197 static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t*, LPWSTR lpszCurrentDirectory,
198  LPDWORD lpdwCurrentDirectory);
200 static BOOL FTP_FtpRemoveDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory);
201 static BOOL FTP_FtpDeleteFileW(ftp_session_t*, LPCWSTR lpszFileName);
202 static BOOL FTP_FtpGetFileW(ftp_session_t*, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
203  BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
204  DWORD_PTR dwContext);
205 
206 /* A temporary helper until we get rid of INTERNET_GetLastError calls */
208 {
209  if(res != ERROR_SUCCESS)
211  return res == ERROR_SUCCESS;
212 }
213 
214 /***********************************************************************
215  * FtpPutFileA (WININET.@)
216  *
217  * Uploads a file to the FTP server
218  *
219  * RETURNS
220  * TRUE on success
221  * FALSE on failure
222  *
223  */
224 BOOL WINAPI FtpPutFileA(HINTERNET hConnect, LPCSTR lpszLocalFile,
225  LPCSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
226 {
227  LPWSTR lpwzLocalFile;
228  LPWSTR lpwzNewRemoteFile;
229  BOOL ret;
230 
231  lpwzLocalFile = heap_strdupAtoW(lpszLocalFile);
232  lpwzNewRemoteFile = heap_strdupAtoW(lpszNewRemoteFile);
233  ret = FtpPutFileW(hConnect, lpwzLocalFile, lpwzNewRemoteFile,
234  dwFlags, dwContext);
235  heap_free(lpwzLocalFile);
236  heap_free(lpwzNewRemoteFile);
237  return ret;
238 }
239 
240 typedef struct {
247 
249 {
252 
253  TRACE("%p\n", session);
254 
256  task->flags, task->context);
257 
258  heap_free(task->local_file);
259  heap_free(task->remote_file);
260 }
261 
262 /***********************************************************************
263  * FtpPutFileW (WININET.@)
264  *
265  * Uploads a file to the FTP server
266  *
267  * RETURNS
268  * TRUE on success
269  * FALSE on failure
270  *
271  */
272 BOOL WINAPI FtpPutFileW(HINTERNET hConnect, LPCWSTR lpszLocalFile,
273  LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
274 {
275  ftp_session_t *lpwfs;
276  appinfo_t *hIC = NULL;
277  BOOL r = FALSE;
278 
279  if (!lpszLocalFile || !lpszNewRemoteFile)
280  {
282  return FALSE;
283  }
284 
285  lpwfs = (ftp_session_t*) get_handle_object( hConnect );
286  if (!lpwfs)
287  {
289  return FALSE;
290  }
291 
292  if (WH_HFTPSESSION != lpwfs->hdr.htype)
293  {
295  goto lend;
296  }
297 
298  if (lpwfs->download_in_progress != NULL)
299  {
301  goto lend;
302  }
303 
305  {
307  goto lend;
308  }
309 
310  hIC = lpwfs->lpAppInfo;
311  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
312  {
313  put_file_task_t *task = alloc_async_task(&lpwfs->hdr, AsyncFtpPutFileProc, sizeof(*task));
314 
315  task->local_file = heap_strdupW(lpszLocalFile);
316  task->remote_file = heap_strdupW(lpszNewRemoteFile);
317  task->flags = dwFlags;
318  task->context = dwContext;
319 
320  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
321  }
322  else
323  {
324  r = FTP_FtpPutFileW(lpwfs, lpszLocalFile,
325  lpszNewRemoteFile, dwFlags, dwContext);
326  }
327 
328 lend:
329  WININET_Release( &lpwfs->hdr );
330 
331  return r;
332 }
333 
334 /***********************************************************************
335  * FTP_FtpPutFileW (Internal)
336  *
337  * Uploads a file to the FTP server
338  *
339  * RETURNS
340  * TRUE on success
341  * FALSE on failure
342  *
343  */
344 static BOOL FTP_FtpPutFileW(ftp_session_t *lpwfs, LPCWSTR lpszLocalFile,
345  LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
346 {
347  HANDLE hFile;
348  BOOL bSuccess = FALSE;
349  appinfo_t *hIC = NULL;
350  INT nResCode;
351 
352  TRACE(" lpszLocalFile(%s) lpszNewRemoteFile(%s)\n", debugstr_w(lpszLocalFile), debugstr_w(lpszNewRemoteFile));
353 
354  /* Clear any error information */
356 
357  /* Open file to be uploaded */
358  if (INVALID_HANDLE_VALUE ==
359  (hFile = CreateFileW(lpszLocalFile, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)))
360  /* Let CreateFile set the appropriate error */
361  return FALSE;
362 
363  hIC = lpwfs->lpAppInfo;
364 
366 
367  if (FTP_SendStore(lpwfs, lpszNewRemoteFile, dwFlags))
368  {
369  INT nDataSocket;
370 
371  /* Get data socket to server */
372  if (FTP_GetDataSocket(lpwfs, &nDataSocket))
373  {
374  FTP_SendData(lpwfs, nDataSocket, hFile);
375  closesocket(nDataSocket);
376  nResCode = FTP_ReceiveResponse(lpwfs, dwContext);
377  if (nResCode)
378  {
379  if (nResCode == 226)
380  bSuccess = TRUE;
381  else
382  FTP_SetResponseError(nResCode);
383  }
384  }
385  }
386 
387  if (lpwfs->lstnSocket != -1)
388  {
389  closesocket(lpwfs->lstnSocket);
390  lpwfs->lstnSocket = -1;
391  }
392 
393  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
394  {
396 
397  iar.dwResult = (DWORD)bSuccess;
400  &iar, sizeof(INTERNET_ASYNC_RESULT));
401  }
402 
404 
405  return bSuccess;
406 }
407 
408 
409 /***********************************************************************
410  * FtpSetCurrentDirectoryA (WININET.@)
411  *
412  * Change the working directory on the FTP server
413  *
414  * RETURNS
415  * TRUE on success
416  * FALSE on failure
417  *
418  */
420 {
421  LPWSTR lpwzDirectory;
422  BOOL ret;
423 
424  lpwzDirectory = heap_strdupAtoW(lpszDirectory);
425  ret = FtpSetCurrentDirectoryW(hConnect, lpwzDirectory);
426  heap_free(lpwzDirectory);
427  return ret;
428 }
429 
430 typedef struct {
434 
436 {
439 
440  TRACE("%p\n", session);
441 
443  heap_free(task->directory);
444 }
445 
446 /***********************************************************************
447  * FtpSetCurrentDirectoryW (WININET.@)
448  *
449  * Change the working directory on the FTP server
450  *
451  * RETURNS
452  * TRUE on success
453  * FALSE on failure
454  *
455  */
457 {
458  ftp_session_t *lpwfs = NULL;
459  appinfo_t *hIC = NULL;
460  BOOL r = FALSE;
461 
462  if (!lpszDirectory)
463  {
465  goto lend;
466  }
467 
468  lpwfs = (ftp_session_t*) get_handle_object( hConnect );
469  if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
470  {
472  goto lend;
473  }
474 
475  if (lpwfs->download_in_progress != NULL)
476  {
478  goto lend;
479  }
480 
481  TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory));
482 
483  hIC = lpwfs->lpAppInfo;
484  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
485  {
486  directory_task_t *task;
487 
488  task = alloc_async_task(&lpwfs->hdr, AsyncFtpSetCurrentDirectoryProc, sizeof(*task));
489  task->directory = heap_strdupW(lpszDirectory);
490 
491  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
492  }
493  else
494  {
495  r = FTP_FtpSetCurrentDirectoryW(lpwfs, lpszDirectory);
496  }
497 
498 lend:
499  if( lpwfs )
500  WININET_Release( &lpwfs->hdr );
501 
502  return r;
503 }
504 
505 
506 /***********************************************************************
507  * FTP_FtpSetCurrentDirectoryW (Internal)
508  *
509  * Change the working directory on the FTP server
510  *
511  * RETURNS
512  * TRUE on success
513  * FALSE on failure
514  *
515  */
517 {
518  INT nResCode;
519  appinfo_t *hIC = NULL;
520  BOOL bSuccess = FALSE;
521 
522  TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory));
523 
524  /* Clear any error information */
526 
527  hIC = lpwfs->lpAppInfo;
528  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_CWD, lpszDirectory,
529  lpwfs->hdr.lpfnStatusCB, &lpwfs->hdr, lpwfs->hdr.dwContext))
530  goto lend;
531 
532  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
533 
534  if (nResCode)
535  {
536  if (nResCode == 250)
537  bSuccess = TRUE;
538  else
539  FTP_SetResponseError(nResCode);
540  }
541 
542 lend:
543  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
544  {
546 
547  iar.dwResult = bSuccess;
550  &iar, sizeof(INTERNET_ASYNC_RESULT));
551  }
552  return bSuccess;
553 }
554 
555 
556 /***********************************************************************
557  * FtpCreateDirectoryA (WININET.@)
558  *
559  * Create new directory on the FTP server
560  *
561  * RETURNS
562  * TRUE on success
563  * FALSE on failure
564  *
565  */
567 {
568  LPWSTR lpwzDirectory;
569  BOOL ret;
570 
571  lpwzDirectory = heap_strdupAtoW(lpszDirectory);
572  ret = FtpCreateDirectoryW(hConnect, lpwzDirectory);
573  heap_free(lpwzDirectory);
574  return ret;
575 }
576 
577 
579 {
582 
583  TRACE(" %p\n", session);
584 
586  heap_free(task->directory);
587 }
588 
589 /***********************************************************************
590  * FtpCreateDirectoryW (WININET.@)
591  *
592  * Create new directory on the FTP server
593  *
594  * RETURNS
595  * TRUE on success
596  * FALSE on failure
597  *
598  */
600 {
601  ftp_session_t *lpwfs;
602  appinfo_t *hIC = NULL;
603  BOOL r = FALSE;
604 
605  lpwfs = (ftp_session_t*) get_handle_object( hConnect );
606  if (!lpwfs)
607  {
609  return FALSE;
610  }
611 
612  if (WH_HFTPSESSION != lpwfs->hdr.htype)
613  {
615  goto lend;
616  }
617 
618  if (lpwfs->download_in_progress != NULL)
619  {
621  goto lend;
622  }
623 
624  if (!lpszDirectory)
625  {
627  goto lend;
628  }
629 
630  hIC = lpwfs->lpAppInfo;
631  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
632  {
633  directory_task_t *task;
634 
635  task = alloc_async_task(&lpwfs->hdr, AsyncFtpCreateDirectoryProc, sizeof(*task));
636  task->directory = heap_strdupW(lpszDirectory);
637 
638  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
639  }
640  else
641  {
642  r = FTP_FtpCreateDirectoryW(lpwfs, lpszDirectory);
643  }
644 lend:
645  WININET_Release( &lpwfs->hdr );
646 
647  return r;
648 }
649 
650 
651 /***********************************************************************
652  * FTP_FtpCreateDirectoryW (Internal)
653  *
654  * Create new directory on the FTP server
655  *
656  * RETURNS
657  * TRUE on success
658  * FALSE on failure
659  *
660  */
661 static BOOL FTP_FtpCreateDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirectory)
662 {
663  INT nResCode;
664  BOOL bSuccess = FALSE;
665  appinfo_t *hIC = NULL;
666 
667  TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory));
668 
669  /* Clear any error information */
671 
672  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_MKD, lpszDirectory, 0, 0, 0))
673  goto lend;
674 
675  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
676  if (nResCode)
677  {
678  if (nResCode == 257)
679  bSuccess = TRUE;
680  else
681  FTP_SetResponseError(nResCode);
682  }
683 
684 lend:
685  hIC = lpwfs->lpAppInfo;
686  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
687  {
689 
690  iar.dwResult = (DWORD)bSuccess;
693  &iar, sizeof(INTERNET_ASYNC_RESULT));
694  }
695 
696  return bSuccess;
697 }
698 
699 /***********************************************************************
700  * FtpFindFirstFileA (WININET.@)
701  *
702  * Search the specified directory
703  *
704  * RETURNS
705  * HINTERNET on success
706  * NULL on failure
707  *
708  */
710  LPCSTR lpszSearchFile, LPWIN32_FIND_DATAA lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
711 {
712  LPWSTR lpwzSearchFile;
713  WIN32_FIND_DATAW wfd;
714  LPWIN32_FIND_DATAW lpFindFileDataW;
715  HINTERNET ret;
716 
717  lpwzSearchFile = heap_strdupAtoW(lpszSearchFile);
718  lpFindFileDataW = lpFindFileData?&wfd:NULL;
719  ret = FtpFindFirstFileW(hConnect, lpwzSearchFile, lpFindFileDataW, dwFlags, dwContext);
720  heap_free(lpwzSearchFile);
721 
722  if (ret && lpFindFileData)
723  WININET_find_data_WtoA(lpFindFileDataW, lpFindFileData);
724 
725  return ret;
726 }
727 
728 typedef struct {
735 
737 {
740 
741  TRACE("%p\n", session);
742 
744  heap_free(task->search_file);
745 }
746 
747 /***********************************************************************
748  * FtpFindFirstFileW (WININET.@)
749  *
750  * Search the specified directory
751  *
752  * RETURNS
753  * HINTERNET on success
754  * NULL on failure
755  *
756  */
758  LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
759 {
760  ftp_session_t *lpwfs;
761  appinfo_t *hIC = NULL;
762  HINTERNET r = NULL;
763 
764  lpwfs = (ftp_session_t*) get_handle_object( hConnect );
765  if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
766  {
768  goto lend;
769  }
770 
771  if (lpwfs->download_in_progress != NULL)
772  {
774  goto lend;
775  }
776 
777  hIC = lpwfs->lpAppInfo;
778  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
779  {
781 
782  task = alloc_async_task(&lpwfs->hdr, AsyncFtpFindFirstFileProc, sizeof(*task));
783  task->search_file = heap_strdupW(lpszSearchFile);
784  task->find_file_data = lpFindFileData;
785  task->flags = dwFlags;
786  task->context = dwContext;
787 
788  INTERNET_AsyncCall(&task->hdr);
789  r = NULL;
790  }
791  else
792  {
793  r = FTP_FtpFindFirstFileW(lpwfs, lpszSearchFile, lpFindFileData,
794  dwFlags, dwContext);
795  }
796 lend:
797  if( lpwfs )
798  WININET_Release( &lpwfs->hdr );
799 
800  return r;
801 }
802 
803 
804 /***********************************************************************
805  * FTP_FtpFindFirstFileW (Internal)
806  *
807  * Search the specified directory
808  *
809  * RETURNS
810  * HINTERNET on success
811  * NULL on failure
812  *
813  */
815  LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
816 {
817  INT nResCode;
818  appinfo_t *hIC = NULL;
819  HINTERNET hFindNext = NULL;
820  LPWSTR lpszSearchPath = NULL;
821 
822  TRACE("\n");
823 
824  /* Clear any error information */
826 
827  if (!FTP_InitListenSocket(lpwfs))
828  goto lend;
829 
831  goto lend;
832 
833  if (!FTP_SendPortOrPasv(lpwfs))
834  goto lend;
835 
836  /* split search path into file and path */
837  if (lpszSearchFile)
838  {
839  LPCWSTR name = lpszSearchFile, p;
840  if ((p = wcsrchr( name, '\\' ))) name = p + 1;
841  if ((p = wcsrchr( name, '/' ))) name = p + 1;
842  if (name != lpszSearchFile)
843  {
844  lpszSearchPath = heap_strndupW(lpszSearchFile, name - lpszSearchFile);
845  lpszSearchFile = name;
846  }
847  }
848 
849  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_LIST, lpszSearchPath,
850  lpwfs->hdr.lpfnStatusCB, &lpwfs->hdr, lpwfs->hdr.dwContext))
851  goto lend;
852 
853  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
854  if (nResCode)
855  {
856  if (nResCode == 125 || nResCode == 150)
857  {
858  INT nDataSocket;
859 
860  /* Get data socket to server */
861  if (FTP_GetDataSocket(lpwfs, &nDataSocket))
862  {
863  hFindNext = FTP_ReceiveFileList(lpwfs, nDataSocket, lpszSearchFile, lpFindFileData, dwContext);
864  closesocket(nDataSocket);
865  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
866  if (nResCode != 226 && nResCode != 250)
868  }
869  }
870  else
871  FTP_SetResponseError(nResCode);
872  }
873 
874 lend:
875  heap_free(lpszSearchPath);
876 
877  if (lpwfs->lstnSocket != -1)
878  {
879  closesocket(lpwfs->lstnSocket);
880  lpwfs->lstnSocket = -1;
881  }
882 
883  hIC = lpwfs->lpAppInfo;
884  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
885  {
887 
888  if (hFindNext)
889  {
890  iar.dwResult = (DWORD_PTR)hFindNext;
891  iar.dwError = ERROR_SUCCESS;
893  &iar, sizeof(INTERNET_ASYNC_RESULT));
894  }
895 
896  iar.dwResult = (DWORD_PTR)hFindNext;
897  iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError();
899  &iar, sizeof(INTERNET_ASYNC_RESULT));
900  }
901 
902  return hFindNext;
903 }
904 
905 
906 /***********************************************************************
907  * FtpGetCurrentDirectoryA (WININET.@)
908  *
909  * Retrieves the current directory
910  *
911  * RETURNS
912  * TRUE on success
913  * FALSE on failure
914  *
915  */
916 BOOL WINAPI FtpGetCurrentDirectoryA(HINTERNET hFtpSession, LPSTR lpszCurrentDirectory,
917  LPDWORD lpdwCurrentDirectory)
918 {
919  WCHAR *dir = NULL;
920  DWORD len;
921  BOOL ret;
922 
923  if(lpdwCurrentDirectory) {
924  len = *lpdwCurrentDirectory;
925  if(lpszCurrentDirectory)
926  {
927  dir = heap_alloc(len * sizeof(WCHAR));
928  if (NULL == dir)
929  {
931  return FALSE;
932  }
933  }
934  }
935  ret = FtpGetCurrentDirectoryW(hFtpSession, lpszCurrentDirectory?dir:NULL, lpdwCurrentDirectory?&len:NULL);
936 
937  if (ret && lpszCurrentDirectory)
938  WideCharToMultiByte(CP_ACP, 0, dir, -1, lpszCurrentDirectory, len, NULL, NULL);
939 
940  if (lpdwCurrentDirectory) *lpdwCurrentDirectory = len;
941  heap_free(dir);
942  return ret;
943 }
944 
945 typedef struct {
950 
952 {
955 
956  TRACE("%p\n", session);
957 
959 }
960 
961 /***********************************************************************
962  * FtpGetCurrentDirectoryW (WININET.@)
963  *
964  * Retrieves the current directory
965  *
966  * RETURNS
967  * TRUE on success
968  * FALSE on failure
969  *
970  */
971 BOOL WINAPI FtpGetCurrentDirectoryW(HINTERNET hFtpSession, LPWSTR lpszCurrentDirectory,
972  LPDWORD lpdwCurrentDirectory)
973 {
974  ftp_session_t *lpwfs;
975  appinfo_t *hIC = NULL;
976  BOOL r = FALSE;
977 
978  TRACE("%p %p %p\n", hFtpSession, lpszCurrentDirectory, lpdwCurrentDirectory);
979 
980  lpwfs = (ftp_session_t*) get_handle_object( hFtpSession );
981  if (NULL == lpwfs)
982  {
984  goto lend;
985  }
986 
987  if (WH_HFTPSESSION != lpwfs->hdr.htype)
988  {
990  goto lend;
991  }
992 
993  if (!lpdwCurrentDirectory)
994  {
996  goto lend;
997  }
998 
999  if (lpszCurrentDirectory == NULL)
1000  {
1002  goto lend;
1003  }
1004 
1005  if (lpwfs->download_in_progress != NULL)
1006  {
1008  goto lend;
1009  }
1010 
1011  hIC = lpwfs->lpAppInfo;
1012  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1013  {
1014  get_current_dir_task_t *task;
1015 
1016  task = alloc_async_task(&lpwfs->hdr, AsyncFtpGetCurrentDirectoryProc, sizeof(*task));
1017  task->directory = lpszCurrentDirectory;
1018  task->directory_len = lpdwCurrentDirectory;
1019 
1020  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
1021  }
1022  else
1023  {
1024  r = FTP_FtpGetCurrentDirectoryW(lpwfs, lpszCurrentDirectory,
1025  lpdwCurrentDirectory);
1026  }
1027 
1028 lend:
1029  if( lpwfs )
1030  WININET_Release( &lpwfs->hdr );
1031 
1032  return r;
1033 }
1034 
1035 
1036 /***********************************************************************
1037  * FTP_FtpGetCurrentDirectoryW (Internal)
1038  *
1039  * Retrieves the current directory
1040  *
1041  * RETURNS
1042  * TRUE on success
1043  * FALSE on failure
1044  *
1045  */
1046 static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t *lpwfs, LPWSTR lpszCurrentDirectory,
1047  LPDWORD lpdwCurrentDirectory)
1048 {
1049  INT nResCode;
1050  appinfo_t *hIC = NULL;
1051  BOOL bSuccess = FALSE;
1052 
1053  /* Clear any error information */
1055 
1056  hIC = lpwfs->lpAppInfo;
1057  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PWD, NULL,
1058  lpwfs->hdr.lpfnStatusCB, &lpwfs->hdr, lpwfs->hdr.dwContext))
1059  goto lend;
1060 
1061  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
1062  if (nResCode)
1063  {
1064  if (nResCode == 257) /* Extract directory name */
1065  {
1066  DWORD firstpos, lastpos, len;
1067  LPWSTR lpszResponseBuffer = heap_strdupAtoW(INTERNET_GetResponseBuffer());
1068 
1069  for (firstpos = 0, lastpos = 0; lpszResponseBuffer[lastpos]; lastpos++)
1070  {
1071  if ('"' == lpszResponseBuffer[lastpos])
1072  {
1073  if (!firstpos)
1074  firstpos = lastpos;
1075  else
1076  break;
1077  }
1078  }
1079  len = lastpos - firstpos;
1080  if (*lpdwCurrentDirectory >= len)
1081  {
1082  memcpy(lpszCurrentDirectory, &lpszResponseBuffer[firstpos + 1], len * sizeof(WCHAR));
1083  lpszCurrentDirectory[len - 1] = 0;
1084  *lpdwCurrentDirectory = len;
1085  bSuccess = TRUE;
1086  }
1088 
1089  heap_free(lpszResponseBuffer);
1090  }
1091  else
1092  FTP_SetResponseError(nResCode);
1093  }
1094 
1095 lend:
1096  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1097  {
1099 
1100  iar.dwResult = bSuccess;
1103  &iar, sizeof(INTERNET_ASYNC_RESULT));
1104  }
1105 
1106  return bSuccess;
1107 }
1108 
1109 
1110 /***********************************************************************
1111  * FTPFILE_Destroy(internal)
1112  *
1113  * Closes the file transfer handle. This also 'cleans' the data queue of
1114  * the 'transfer complete' message (this is a bit of a hack though :-/ )
1115  *
1116  */
1118 {
1119  ftp_file_t *lpwh = (ftp_file_t*) hdr;
1120  ftp_session_t *lpwfs = lpwh->lpFtpSession;
1121  INT nResCode;
1122 
1123  TRACE("\n");
1124 
1127 
1128  heap_free(lpwh->cache_file);
1129 
1130  if (!lpwh->session_deleted)
1131  lpwfs->download_in_progress = NULL;
1132 
1133  if (lpwh->nDataSocket != -1)
1134  closesocket(lpwh->nDataSocket);
1135 
1136  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
1137  if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n");
1138 
1139  WININET_Release(&lpwh->lpFtpSession->hdr);
1140 }
1141 
1143 {
1144  switch(option) {
1146  TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
1147 
1148  if (*size < sizeof(ULONG))
1150 
1151  *size = sizeof(DWORD);
1153  return ERROR_SUCCESS;
1155  {
1156  DWORD required;
1157  ftp_file_t *file = (ftp_file_t *)hdr;
1158 
1159  TRACE("INTERNET_OPTION_DATAFILE_NAME\n");
1160 
1161  if (!file->cache_file)
1162  {
1163  *size = 0;
1165  }
1166  if (unicode)
1167  {
1168  required = (lstrlenW(file->cache_file) + 1) * sizeof(WCHAR);
1169  if (*size < required)
1171 
1172  *size = required;
1173  memcpy(buffer, file->cache_file, *size);
1174  return ERROR_SUCCESS;
1175  }
1176  else
1177  {
1178  required = WideCharToMultiByte(CP_ACP, 0, file->cache_file, -1, NULL, 0, NULL, NULL);
1179  if (required > *size)
1181 
1182  *size = WideCharToMultiByte(CP_ACP, 0, file->cache_file, -1, buffer, *size, NULL, NULL);
1183  return ERROR_SUCCESS;
1184  }
1185  }
1186  }
1187  return INET_QueryOption(hdr, option, buffer, size, unicode);
1188 }
1189 
1192 {
1194  int res;
1195  DWORD error;
1196 
1197  if (file->nDataSocket == -1)
1199 
1200  /* FIXME: FTP should use NETCON_ stuff */
1201  res = sock_recv(file->nDataSocket, buffer, size, MSG_WAITALL);
1202  *read = res>0 ? res : 0;
1203 
1204  error = res >= 0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME */
1205  if (error == ERROR_SUCCESS && file->cache_file)
1206  {
1207  DWORD bytes_written;
1208 
1209  if (!WriteFile(file->cache_file_handle, buffer, *read, &bytes_written, NULL))
1210  WARN("WriteFile failed: %u\n", GetLastError());
1211  }
1212  return error;
1213 }
1214 
1216 {
1217  ftp_file_t *lpwh = (ftp_file_t*) hdr;
1218  int res;
1219 
1220  res = sock_send(lpwh->nDataSocket, buffer, size, 0);
1221 
1222  *written = res>0 ? res : 0;
1223  return res >= 0 ? ERROR_SUCCESS : WSAGetLastError();
1224 }
1225 
1226 static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif)
1227 {
1229  BYTE buffer[4096];
1230  int available;
1231 
1232  TRACE("%p\n", file);
1233 
1234  available = sock_recv(file->nDataSocket, buffer, sizeof(buffer), MSG_PEEK);
1235 
1236  if(available != -1) {
1237  iar.dwResult = (DWORD_PTR)file->hdr.hInternet;
1238  iar.dwError = first_notif ? 0 : available;
1239  }else {
1240  iar.dwResult = 0;
1242  }
1243 
1244  INTERNET_SendCallback(&file->hdr, file->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar,
1245  sizeof(INTERNET_ASYNC_RESULT));
1246 }
1247 
1249 {
1250  ftp_file_t *file = (ftp_file_t*)task->hdr;
1251 
1253 }
1254 
1256 {
1257  ftp_file_t *file = (ftp_file_t*) hdr;
1258  ULONG unread = 0;
1259  int retval;
1260 
1261  TRACE("(%p %p %x %lx)\n", file, available, flags, ctx);
1262 
1263  retval = ioctlsocket(file->nDataSocket, FIONREAD, &unread);
1264  if (!retval)
1265  TRACE("%d bytes of queued, but unread data\n", unread);
1266 
1267  *available = unread;
1268 
1269  if(!unread) {
1270  BYTE byte;
1271 
1272  *available = 0;
1273 
1274  retval = sock_recv(file->nDataSocket, &byte, 1, MSG_PEEK);
1275  if(retval > 0) {
1276  task_header_t *task;
1277 
1278  task = alloc_async_task(&file->hdr, FTPFILE_AsyncQueryDataAvailableProc, sizeof(*task));
1279  INTERNET_AsyncCall(task);
1280 
1281  return ERROR_IO_PENDING;
1282  }
1283  }
1284 
1285  return ERROR_SUCCESS;
1286 }
1287 
1289 {
1291  FIXME("%p\n", file);
1292  return ERROR_NOT_SUPPORTED;
1293 }
1294 
1295 static const object_vtbl_t FTPFILEVtbl = {
1297  NULL,
1303  NULL,
1305 };
1306 
1307 /***********************************************************************
1308  * FTP_FtpOpenFileW (Internal)
1309  *
1310  * Open a remote file for writing or reading
1311  *
1312  * RETURNS
1313  * HINTERNET handle on success
1314  * NULL on failure
1315  *
1316  */
1318  LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
1319  DWORD_PTR dwContext)
1320 {
1321  INT nDataSocket;
1322  BOOL bSuccess = FALSE;
1323  ftp_file_t *lpwh = NULL;
1324  appinfo_t *hIC = NULL;
1325 
1326  TRACE("\n");
1327 
1328  /* Clear any error information */
1330 
1331  if (GENERIC_READ == fdwAccess)
1332  {
1333  /* Set up socket to retrieve data */
1334  bSuccess = FTP_SendRetrieve(lpwfs, lpszFileName, dwFlags);
1335  }
1336  else if (GENERIC_WRITE == fdwAccess)
1337  {
1338  /* Set up socket to send data */
1339  bSuccess = FTP_SendStore(lpwfs, lpszFileName, dwFlags);
1340  }
1341 
1342  /* Get data socket to server */
1343  if (bSuccess && FTP_GetDataSocket(lpwfs, &nDataSocket))
1344  {
1345  lpwh = alloc_object(&lpwfs->hdr, &FTPFILEVtbl, sizeof(ftp_file_t));
1346  lpwh->hdr.htype = WH_HFILE;
1347  lpwh->hdr.dwFlags = dwFlags;
1348  lpwh->hdr.dwContext = dwContext;
1349  lpwh->nDataSocket = nDataSocket;
1350  lpwh->cache_file = NULL;
1352  lpwh->session_deleted = FALSE;
1353 
1354  WININET_AddRef( &lpwfs->hdr );
1355  lpwh->lpFtpSession = lpwfs;
1356  list_add_head( &lpwfs->hdr.children, &lpwh->hdr.entry );
1357 
1358  /* Indicate that a download is currently in progress */
1359  lpwfs->download_in_progress = lpwh;
1360  }
1361 
1362  if (lpwfs->lstnSocket != -1)
1363  {
1364  closesocket(lpwfs->lstnSocket);
1365  lpwfs->lstnSocket = -1;
1366  }
1367 
1368  if (bSuccess && fdwAccess == GENERIC_READ)
1369  {
1370  WCHAR filename[MAX_PATH + 1];
1371  URL_COMPONENTSW uc;
1372  DWORD len;
1373 
1374  memset(&uc, 0, sizeof(uc));
1375  uc.dwStructSize = sizeof(uc);
1377  uc.lpszHostName = lpwfs->servername;
1378  uc.nPort = lpwfs->serverport;
1379  uc.lpszUserName = lpwfs->lpszUserName;
1380  uc.lpszUrlPath = heap_strdupW(lpszFileName);
1381 
1383  {
1384  WCHAR *url = heap_alloc(len * sizeof(WCHAR));
1385 
1386  if (url && InternetCreateUrlW(&uc, 0, url, &len) && CreateUrlCacheEntryW(url, 0, NULL, filename, 0))
1387  {
1388  lpwh->cache_file = heap_strdupW(filename);
1392  {
1393  WARN("Could not create cache file: %u\n", GetLastError());
1394  heap_free(lpwh->cache_file);
1395  lpwh->cache_file = NULL;
1396  }
1397  }
1398  heap_free(url);
1399  }
1400  heap_free(uc.lpszUrlPath);
1401  }
1402 
1403  hIC = lpwfs->lpAppInfo;
1404  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1405  {
1407 
1408  if (lpwh)
1409  {
1410  iar.dwResult = (DWORD_PTR)lpwh->hdr.hInternet;
1411  iar.dwError = ERROR_SUCCESS;
1413  &iar, sizeof(INTERNET_ASYNC_RESULT));
1414  }
1415 
1416  if(bSuccess) {
1418  }else {
1419  iar.dwResult = 0;
1422  &iar, sizeof(INTERNET_ASYNC_RESULT));
1423  }
1424  }
1425 
1426  if(!bSuccess)
1427  return FALSE;
1428 
1429  return lpwh->hdr.hInternet;
1430 }
1431 
1432 
1433 /***********************************************************************
1434  * FtpOpenFileA (WININET.@)
1435  *
1436  * Open a remote file for writing or reading
1437  *
1438  * RETURNS
1439  * HINTERNET handle on success
1440  * NULL on failure
1441  *
1442  */
1444  LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
1445  DWORD_PTR dwContext)
1446 {
1447  LPWSTR lpwzFileName;
1448  HINTERNET ret;
1449 
1450  lpwzFileName = heap_strdupAtoW(lpszFileName);
1451  ret = FtpOpenFileW(hFtpSession, lpwzFileName, fdwAccess, dwFlags, dwContext);
1452  heap_free(lpwzFileName);
1453  return ret;
1454 }
1455 
1456 typedef struct {
1463 
1465 {
1468 
1469  TRACE("%p\n", session);
1470 
1471  FTP_FtpOpenFileW(session, task->file_name, task->access, task->flags, task->context);
1472  heap_free(task->file_name);
1473 }
1474 
1475 /***********************************************************************
1476  * FtpOpenFileW (WININET.@)
1477  *
1478  * Open a remote file for writing or reading
1479  *
1480  * RETURNS
1481  * HINTERNET handle on success
1482  * NULL on failure
1483  *
1484  */
1486  LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
1487  DWORD_PTR dwContext)
1488 {
1489  ftp_session_t *lpwfs;
1490  appinfo_t *hIC = NULL;
1491  HINTERNET r = NULL;
1492 
1493  TRACE("(%p,%s,0x%08x,0x%08x,0x%08lx)\n", hFtpSession,
1494  debugstr_w(lpszFileName), fdwAccess, dwFlags, dwContext);
1495 
1496  lpwfs = (ftp_session_t*) get_handle_object( hFtpSession );
1497  if (!lpwfs)
1498  {
1500  return FALSE;
1501  }
1502 
1503  if (WH_HFTPSESSION != lpwfs->hdr.htype)
1504  {
1506  goto lend;
1507  }
1508 
1509  if ((!lpszFileName) ||
1510  ((fdwAccess != GENERIC_READ) && (fdwAccess != GENERIC_WRITE)) ||
1512  {
1514  goto lend;
1515  }
1516 
1517  if (lpwfs->download_in_progress != NULL)
1518  {
1520  goto lend;
1521  }
1522 
1523  hIC = lpwfs->lpAppInfo;
1524  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1525  {
1526  open_file_task_t *task;
1527 
1528  task = alloc_async_task(&lpwfs->hdr, AsyncFtpOpenFileProc, sizeof(*task));
1529  task->file_name = heap_strdupW(lpszFileName);
1530  task->access = fdwAccess;
1531  task->flags = dwFlags;
1532  task->context = dwContext;
1533 
1534  INTERNET_AsyncCall(&task->hdr);
1535  r = NULL;
1536  }
1537  else
1538  {
1539  r = FTP_FtpOpenFileW(lpwfs, lpszFileName, fdwAccess, dwFlags, dwContext);
1540  }
1541 
1542 lend:
1543  WININET_Release( &lpwfs->hdr );
1544 
1545  return r;
1546 }
1547 
1548 
1549 /***********************************************************************
1550  * FtpGetFileA (WININET.@)
1551  *
1552  * Retrieve file from the FTP server
1553  *
1554  * RETURNS
1555  * TRUE on success
1556  * FALSE on failure
1557  *
1558  */
1559 BOOL WINAPI FtpGetFileA(HINTERNET hInternet, LPCSTR lpszRemoteFile, LPCSTR lpszNewFile,
1560  BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
1561  DWORD_PTR dwContext)
1562 {
1563  LPWSTR lpwzRemoteFile;
1564  LPWSTR lpwzNewFile;
1565  BOOL ret;
1566 
1567  lpwzRemoteFile = heap_strdupAtoW(lpszRemoteFile);
1568  lpwzNewFile = heap_strdupAtoW(lpszNewFile);
1569  ret = FtpGetFileW(hInternet, lpwzRemoteFile, lpwzNewFile, fFailIfExists,
1570  dwLocalFlagsAttribute, dwInternetFlags, dwContext);
1571  heap_free(lpwzRemoteFile);
1572  heap_free(lpwzNewFile);
1573  return ret;
1574 }
1575 
1576 typedef struct {
1584 } get_file_task_t;
1585 
1587 {
1590 
1591  TRACE("%p\n", session);
1592 
1594  task->local_attr, task->flags, task->context);
1595  heap_free(task->remote_file);
1596  heap_free(task->new_file);
1597 }
1598 
1599 
1600 /***********************************************************************
1601  * FtpGetFileW (WININET.@)
1602  *
1603  * Retrieve file from the FTP server
1604  *
1605  * RETURNS
1606  * TRUE on success
1607  * FALSE on failure
1608  *
1609  */
1610 BOOL WINAPI FtpGetFileW(HINTERNET hInternet, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
1611  BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
1612  DWORD_PTR dwContext)
1613 {
1614  ftp_session_t *lpwfs;
1615  appinfo_t *hIC = NULL;
1616  BOOL r = FALSE;
1617 
1618  if (!lpszRemoteFile || !lpszNewFile)
1619  {
1621  return FALSE;
1622  }
1623 
1624  lpwfs = (ftp_session_t*) get_handle_object( hInternet );
1625  if (!lpwfs)
1626  {
1628  return FALSE;
1629  }
1630 
1631  if (WH_HFTPSESSION != lpwfs->hdr.htype)
1632  {
1634  goto lend;
1635  }
1636 
1637  if ((dwInternetFlags & FTP_CONDITION_MASK) > FTP_TRANSFER_TYPE_BINARY)
1638  {
1640  goto lend;
1641  }
1642 
1643  if (lpwfs->download_in_progress != NULL)
1644  {
1646  goto lend;
1647  }
1648 
1649  hIC = lpwfs->lpAppInfo;
1650  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1651  {
1652  get_file_task_t *task;
1653 
1654  task = alloc_async_task(&lpwfs->hdr, AsyncFtpGetFileProc, sizeof(*task));
1655  task->remote_file = heap_strdupW(lpszRemoteFile);
1656  task->new_file = heap_strdupW(lpszNewFile);
1657  task->local_attr = dwLocalFlagsAttribute;
1658  task->fail_if_exists = fFailIfExists;
1659  task->flags = dwInternetFlags;
1660  task->context = dwContext;
1661 
1662  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
1663  }
1664  else
1665  {
1666  r = FTP_FtpGetFileW(lpwfs, lpszRemoteFile, lpszNewFile,
1667  fFailIfExists, dwLocalFlagsAttribute, dwInternetFlags, dwContext);
1668  }
1669 
1670 lend:
1671  WININET_Release( &lpwfs->hdr );
1672 
1673  return r;
1674 }
1675 
1676 
1677 /***********************************************************************
1678  * FTP_FtpGetFileW (Internal)
1679  *
1680  * Retrieve file from the FTP server
1681  *
1682  * RETURNS
1683  * TRUE on success
1684  * FALSE on failure
1685  *
1686  */
1687 static BOOL FTP_FtpGetFileW(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
1688  BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
1689  DWORD_PTR dwContext)
1690 {
1691  BOOL bSuccess = FALSE;
1692  HANDLE hFile;
1693  appinfo_t *hIC = NULL;
1694 
1695  TRACE("lpszRemoteFile(%s) lpszNewFile(%s)\n", debugstr_w(lpszRemoteFile), debugstr_w(lpszNewFile));
1696 
1697  /* Clear any error information */
1699 
1700  /* Ensure we can write to lpszNewfile by opening it */
1701  hFile = CreateFileW(lpszNewFile, GENERIC_WRITE, 0, 0, fFailIfExists ?
1702  CREATE_NEW : CREATE_ALWAYS, dwLocalFlagsAttribute, 0);
1703  if (INVALID_HANDLE_VALUE == hFile)
1704  return FALSE;
1705 
1706  /* Set up socket to retrieve data */
1707  if (FTP_SendRetrieve(lpwfs, lpszRemoteFile, dwInternetFlags))
1708  {
1709  INT nDataSocket;
1710 
1711  /* Get data socket to server */
1712  if (FTP_GetDataSocket(lpwfs, &nDataSocket))
1713  {
1714  INT nResCode;
1715 
1716  /* Receive data */
1717  FTP_RetrieveFileData(lpwfs, nDataSocket, hFile);
1718  closesocket(nDataSocket);
1719 
1720  nResCode = FTP_ReceiveResponse(lpwfs, dwContext);
1721  if (nResCode)
1722  {
1723  if (nResCode == 226)
1724  bSuccess = TRUE;
1725  else
1726  FTP_SetResponseError(nResCode);
1727  }
1728  }
1729  }
1730 
1731  if (lpwfs->lstnSocket != -1)
1732  {
1733  closesocket(lpwfs->lstnSocket);
1734  lpwfs->lstnSocket = -1;
1735  }
1736 
1737  CloseHandle(hFile);
1738 
1739  hIC = lpwfs->lpAppInfo;
1740  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1741  {
1743 
1744  iar.dwResult = (DWORD)bSuccess;
1747  &iar, sizeof(INTERNET_ASYNC_RESULT));
1748  }
1749 
1750  if (!bSuccess) DeleteFileW(lpszNewFile);
1751  return bSuccess;
1752 }
1753 
1754 /***********************************************************************
1755  * FtpGetFileSize (WININET.@)
1756  */
1758 {
1759  FIXME("(%p, %p)\n", hFile, lpdwFileSizeHigh);
1760 
1761  if (lpdwFileSizeHigh)
1762  *lpdwFileSizeHigh = 0;
1763 
1764  return 0;
1765 }
1766 
1767 /***********************************************************************
1768  * FtpDeleteFileA (WININET.@)
1769  *
1770  * Delete a file on the ftp server
1771  *
1772  * RETURNS
1773  * TRUE on success
1774  * FALSE on failure
1775  *
1776  */
1777 BOOL WINAPI FtpDeleteFileA(HINTERNET hFtpSession, LPCSTR lpszFileName)
1778 {
1779  LPWSTR lpwzFileName;
1780  BOOL ret;
1781 
1782  lpwzFileName = heap_strdupAtoW(lpszFileName);
1783  ret = FtpDeleteFileW(hFtpSession, lpwzFileName);
1784  heap_free(lpwzFileName);
1785  return ret;
1786 }
1787 
1788 typedef struct {
1792 
1794 {
1797 
1798  TRACE("%p\n", session);
1799 
1801  heap_free(task->file_name);
1802 }
1803 
1804 /***********************************************************************
1805  * FtpDeleteFileW (WININET.@)
1806  *
1807  * Delete a file on the ftp server
1808  *
1809  * RETURNS
1810  * TRUE on success
1811  * FALSE on failure
1812  *
1813  */
1814 BOOL WINAPI FtpDeleteFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName)
1815 {
1816  ftp_session_t *lpwfs;
1817  appinfo_t *hIC = NULL;
1818  BOOL r = FALSE;
1819 
1820  lpwfs = (ftp_session_t*) get_handle_object( hFtpSession );
1821  if (!lpwfs)
1822  {
1824  return FALSE;
1825  }
1826 
1827  if (WH_HFTPSESSION != lpwfs->hdr.htype)
1828  {
1830  goto lend;
1831  }
1832 
1833  if (lpwfs->download_in_progress != NULL)
1834  {
1836  goto lend;
1837  }
1838 
1839  if (!lpszFileName)
1840  {
1842  goto lend;
1843  }
1844 
1845  hIC = lpwfs->lpAppInfo;
1846  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1847  {
1848  delete_file_task_t *task;
1849 
1850  task = alloc_async_task(&lpwfs->hdr, AsyncFtpDeleteFileProc, sizeof(*task));
1851  task->file_name = heap_strdupW(lpszFileName);
1852 
1853  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
1854  }
1855  else
1856  {
1857  r = FTP_FtpDeleteFileW(lpwfs, lpszFileName);
1858  }
1859 
1860 lend:
1861  WININET_Release( &lpwfs->hdr );
1862 
1863  return r;
1864 }
1865 
1866 /***********************************************************************
1867  * FTP_FtpDeleteFileW (Internal)
1868  *
1869  * Delete a file on the ftp server
1870  *
1871  * RETURNS
1872  * TRUE on success
1873  * FALSE on failure
1874  *
1875  */
1877 {
1878  INT nResCode;
1879  BOOL bSuccess = FALSE;
1880  appinfo_t *hIC = NULL;
1881 
1882  TRACE("%p\n", lpwfs);
1883 
1884  /* Clear any error information */
1886 
1887  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_DELE, lpszFileName, 0, 0, 0))
1888  goto lend;
1889 
1890  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
1891  if (nResCode)
1892  {
1893  if (nResCode == 250)
1894  bSuccess = TRUE;
1895  else
1896  FTP_SetResponseError(nResCode);
1897  }
1898 lend:
1899  hIC = lpwfs->lpAppInfo;
1900  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1901  {
1903 
1904  iar.dwResult = (DWORD)bSuccess;
1907  &iar, sizeof(INTERNET_ASYNC_RESULT));
1908  }
1909 
1910  return bSuccess;
1911 }
1912 
1913 
1914 /***********************************************************************
1915  * FtpRemoveDirectoryA (WININET.@)
1916  *
1917  * Remove a directory on the ftp server
1918  *
1919  * RETURNS
1920  * TRUE on success
1921  * FALSE on failure
1922  *
1923  */
1924 BOOL WINAPI FtpRemoveDirectoryA(HINTERNET hFtpSession, LPCSTR lpszDirectory)
1925 {
1926  LPWSTR lpwzDirectory;
1927  BOOL ret;
1928 
1929  lpwzDirectory = heap_strdupAtoW(lpszDirectory);
1930  ret = FtpRemoveDirectoryW(hFtpSession, lpwzDirectory);
1931  heap_free(lpwzDirectory);
1932  return ret;
1933 }
1934 
1936 {
1939 
1940  TRACE("%p\n", session);
1941 
1943  heap_free(task->directory);
1944 }
1945 
1946 /***********************************************************************
1947  * FtpRemoveDirectoryW (WININET.@)
1948  *
1949  * Remove a directory on the ftp server
1950  *
1951  * RETURNS
1952  * TRUE on success
1953  * FALSE on failure
1954  *
1955  */
1956 BOOL WINAPI FtpRemoveDirectoryW(HINTERNET hFtpSession, LPCWSTR lpszDirectory)
1957 {
1958  ftp_session_t *lpwfs;
1959  appinfo_t *hIC = NULL;
1960  BOOL r = FALSE;
1961 
1962  lpwfs = (ftp_session_t*) get_handle_object( hFtpSession );
1963  if (!lpwfs)
1964  {
1966  return FALSE;
1967  }
1968 
1969  if (WH_HFTPSESSION != lpwfs->hdr.htype)
1970  {
1972  goto lend;
1973  }
1974 
1975  if (lpwfs->download_in_progress != NULL)
1976  {
1978  goto lend;
1979  }
1980 
1981  if (!lpszDirectory)
1982  {
1984  goto lend;
1985  }
1986 
1987  hIC = lpwfs->lpAppInfo;
1988  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
1989  {
1990  directory_task_t *task;
1991 
1992  task = alloc_async_task(&lpwfs->hdr, AsyncFtpRemoveDirectoryProc, sizeof(*task));
1993  task->directory = heap_strdupW(lpszDirectory);
1994 
1995  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
1996  }
1997  else
1998  {
1999  r = FTP_FtpRemoveDirectoryW(lpwfs, lpszDirectory);
2000  }
2001 
2002 lend:
2003  WININET_Release( &lpwfs->hdr );
2004 
2005  return r;
2006 }
2007 
2008 /***********************************************************************
2009  * FTP_FtpRemoveDirectoryW (Internal)
2010  *
2011  * Remove a directory on the ftp server
2012  *
2013  * RETURNS
2014  * TRUE on success
2015  * FALSE on failure
2016  *
2017  */
2019 {
2020  INT nResCode;
2021  BOOL bSuccess = FALSE;
2022  appinfo_t *hIC = NULL;
2023 
2024  TRACE("\n");
2025 
2026  /* Clear any error information */
2028 
2029  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RMD, lpszDirectory, 0, 0, 0))
2030  goto lend;
2031 
2032  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2033  if (nResCode)
2034  {
2035  if (nResCode == 250)
2036  bSuccess = TRUE;
2037  else
2038  FTP_SetResponseError(nResCode);
2039  }
2040 
2041 lend:
2042  hIC = lpwfs->lpAppInfo;
2043  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
2044  {
2046 
2047  iar.dwResult = (DWORD)bSuccess;
2050  &iar, sizeof(INTERNET_ASYNC_RESULT));
2051  }
2052 
2053  return bSuccess;
2054 }
2055 
2056 
2057 /***********************************************************************
2058  * FtpRenameFileA (WININET.@)
2059  *
2060  * Rename a file on the ftp server
2061  *
2062  * RETURNS
2063  * TRUE on success
2064  * FALSE on failure
2065  *
2066  */
2068 {
2069  LPWSTR lpwzSrc;
2070  LPWSTR lpwzDest;
2071  BOOL ret;
2072 
2073  lpwzSrc = heap_strdupAtoW(lpszSrc);
2074  lpwzDest = heap_strdupAtoW(lpszDest);
2075  ret = FtpRenameFileW(hFtpSession, lpwzSrc, lpwzDest);
2076  heap_free(lpwzSrc);
2077  heap_free(lpwzDest);
2078  return ret;
2079 }
2080 
2081 typedef struct {
2086 
2088 {
2091 
2092  TRACE("%p\n", session);
2093 
2095  heap_free(task->src_file);
2096  heap_free(task->dst_file);
2097 }
2098 
2099 /***********************************************************************
2100  * FtpRenameFileW (WININET.@)
2101  *
2102  * Rename a file on the ftp server
2103  *
2104  * RETURNS
2105  * TRUE on success
2106  * FALSE on failure
2107  *
2108  */
2110 {
2111  ftp_session_t *lpwfs;
2112  appinfo_t *hIC = NULL;
2113  BOOL r = FALSE;
2114 
2115  lpwfs = (ftp_session_t*) get_handle_object( hFtpSession );
2116  if (!lpwfs)
2117  {
2119  return FALSE;
2120  }
2121 
2122  if (WH_HFTPSESSION != lpwfs->hdr.htype)
2123  {
2125  goto lend;
2126  }
2127 
2128  if (lpwfs->download_in_progress != NULL)
2129  {
2131  goto lend;
2132  }
2133 
2134  if (!lpszSrc || !lpszDest)
2135  {
2137  goto lend;
2138  }
2139 
2140  hIC = lpwfs->lpAppInfo;
2141  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
2142  {
2143  rename_file_task_t *task;
2144 
2145  task = alloc_async_task(&lpwfs->hdr, AsyncFtpRenameFileProc, sizeof(*task));
2146  task->src_file = heap_strdupW(lpszSrc);
2147  task->dst_file = heap_strdupW(lpszDest);
2148 
2149  r = res_to_le(INTERNET_AsyncCall(&task->hdr));
2150  }
2151  else
2152  {
2153  r = FTP_FtpRenameFileW(lpwfs, lpszSrc, lpszDest);
2154  }
2155 
2156 lend:
2157  WININET_Release( &lpwfs->hdr );
2158 
2159  return r;
2160 }
2161 
2162 /***********************************************************************
2163  * FTP_FtpRenameFileW (Internal)
2164  *
2165  * Rename a file on the ftp server
2166  *
2167  * RETURNS
2168  * TRUE on success
2169  * FALSE on failure
2170  *
2171  */
2173 {
2174  INT nResCode;
2175  BOOL bSuccess = FALSE;
2176  appinfo_t *hIC = NULL;
2177 
2178  TRACE("\n");
2179 
2180  /* Clear any error information */
2182 
2183  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RNFR, lpszSrc, 0, 0, 0))
2184  goto lend;
2185 
2186  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2187  if (nResCode == 350)
2188  {
2189  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RNTO, lpszDest, 0, 0, 0))
2190  goto lend;
2191 
2192  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2193  }
2194 
2195  if (nResCode == 250)
2196  bSuccess = TRUE;
2197  else
2198  FTP_SetResponseError(nResCode);
2199 
2200 lend:
2201  hIC = lpwfs->lpAppInfo;
2202  if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
2203  {
2205 
2206  iar.dwResult = (DWORD)bSuccess;
2209  &iar, sizeof(INTERNET_ASYNC_RESULT));
2210  }
2211 
2212  return bSuccess;
2213 }
2214 
2215 /***********************************************************************
2216  * FtpCommandA (WININET.@)
2217  */
2218 BOOL WINAPI FtpCommandA( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags,
2219  LPCSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand )
2220 {
2221  BOOL r;
2222  WCHAR *cmdW;
2223 
2224  TRACE("%p %d 0x%08x %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
2225  debugstr_a(lpszCommand), dwContext, phFtpCommand);
2226 
2227  if (fExpectResponse)
2228  {
2229  FIXME("data connection not supported\n");
2230  return FALSE;
2231  }
2232 
2233  if (!lpszCommand || !lpszCommand[0])
2234  {
2236  return FALSE;
2237  }
2238 
2239  if (!(cmdW = heap_strdupAtoW(lpszCommand)))
2240  {
2242  return FALSE;
2243  }
2244 
2245  r = FtpCommandW(hConnect, fExpectResponse, dwFlags, cmdW, dwContext, phFtpCommand);
2246 
2247  heap_free(cmdW);
2248  return r;
2249 }
2250 
2251 /***********************************************************************
2252  * FtpCommandW (WININET.@)
2253  */
2254 BOOL WINAPI FtpCommandW( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags,
2255  LPCWSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand )
2256 {
2257  BOOL r = FALSE;
2258  ftp_session_t *lpwfs;
2259  LPSTR cmd = NULL;
2260  DWORD len, nBytesSent= 0;
2261  INT nResCode, nRC = 0;
2262 
2263  TRACE("%p %d 0x%08x %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
2264  debugstr_w(lpszCommand), dwContext, phFtpCommand);
2265 
2266  if (!lpszCommand || !lpszCommand[0])
2267  {
2269  return FALSE;
2270  }
2271 
2272  if (fExpectResponse)
2273  {
2274  FIXME("data connection not supported\n");
2275  return FALSE;
2276  }
2277 
2278  lpwfs = (ftp_session_t*) get_handle_object( hConnect );
2279  if (!lpwfs)
2280  {
2282  return FALSE;
2283  }
2284 
2285  if (WH_HFTPSESSION != lpwfs->hdr.htype)
2286  {
2288  goto lend;
2289  }
2290 
2291  if (lpwfs->download_in_progress != NULL)
2292  {
2294  goto lend;
2295  }
2296 
2297  len = WideCharToMultiByte(CP_ACP, 0, lpszCommand, -1, NULL, 0, NULL, NULL) + strlen(szCRLF);
2298  if ((cmd = heap_alloc(len)))
2299  WideCharToMultiByte(CP_ACP, 0, lpszCommand, -1, cmd, len, NULL, NULL);
2300  else
2301  {
2303  goto lend;
2304  }
2305 
2306  strcat(cmd, szCRLF);
2307  len--;
2308 
2309  TRACE("Sending (%s) len(%d)\n", debugstr_a(cmd), len);
2310  while ((nBytesSent < len) && (nRC != -1))
2311  {
2312  nRC = sock_send(lpwfs->sndSocket, cmd + nBytesSent, len - nBytesSent, 0);
2313  if (nRC != -1)
2314  {
2315  nBytesSent += nRC;
2316  TRACE("Sent %d bytes\n", nRC);
2317  }
2318  }
2319 
2320  if (nBytesSent)
2321  {
2322  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2323  if (nResCode > 0 && nResCode < 400)
2324  r = TRUE;
2325  else
2326  FTP_SetResponseError(nResCode);
2327  }
2328 
2329 lend:
2330  WININET_Release( &lpwfs->hdr );
2331  heap_free( cmd );
2332  return r;
2333 }
2334 
2335 
2336 /***********************************************************************
2337  * FTPSESSION_Destroy (internal)
2338  *
2339  * Deallocate session handle
2340  */
2342 {
2343  ftp_session_t *lpwfs = (ftp_session_t*) hdr;
2344 
2345  TRACE("\n");
2346 
2347  WININET_Release(&lpwfs->lpAppInfo->hdr);
2348 
2349  heap_free(lpwfs->lpszPassword);
2350  heap_free(lpwfs->lpszUserName);
2351  heap_free(lpwfs->servername);
2352 }
2353 
2355 {
2356  ftp_session_t *lpwfs = (ftp_session_t*) hdr;
2357 
2358  TRACE("\n");
2359 
2360  INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
2362 
2363  if (lpwfs->download_in_progress != NULL)
2365 
2366  if (lpwfs->sndSocket != -1)
2367  closesocket(lpwfs->sndSocket);
2368 
2369  if (lpwfs->lstnSocket != -1)
2370  closesocket(lpwfs->lstnSocket);
2371 
2372  if (lpwfs->pasvSocket != -1)
2373  closesocket(lpwfs->pasvSocket);
2374 
2375  INTERNET_SendCallback(&lpwfs->hdr, lpwfs->hdr.dwContext,
2377 }
2378 
2380 {
2381  switch(option) {
2383  TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
2384 
2385  if (*size < sizeof(ULONG))
2387 
2388  *size = sizeof(DWORD);
2390  return ERROR_SUCCESS;
2391  }
2392 
2393  return INET_QueryOption(hdr, option, buffer, size, unicode);
2394 }
2395 
2401  NULL,
2402  NULL,
2403  NULL,
2404  NULL
2405 };
2406 
2407 
2408 /***********************************************************************
2409  * FTP_Connect (internal)
2410  *
2411  * Connect to a ftp server
2412  *
2413  * RETURNS
2414  * HINTERNET a session handle on success
2415  * NULL on failure
2416  *
2417  * NOTES:
2418  *
2419  * Windows uses 'anonymous' as the username, when given a NULL username
2420  * and a NULL password. The password is first looked up in:
2421  *
2422  * HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\EmailName
2423  *
2424  * If this entry is not present it uses the current username as the password.
2425  *
2426  */
2427 
2429  INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
2431  DWORD dwInternalFlags)
2432 {
2433  struct sockaddr_in socketAddr;
2434  INT nsocket = -1;
2435  socklen_t sock_namelen;
2436  BOOL bSuccess = FALSE;
2437  ftp_session_t *lpwfs = NULL;
2438  char szaddr[INET6_ADDRSTRLEN];
2439 
2440  TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n",
2441  hIC, debugstr_w(lpszServerName),
2442  nServerPort, debugstr_w(lpszUserName), debugstr_w(lpszPassword));
2443 
2444  assert( hIC->hdr.htype == WH_HINIT );
2445 
2446  if ((!lpszUserName || !*lpszUserName) && lpszPassword && *lpszPassword)
2447  {
2449  return NULL;
2450  }
2451 
2452  lpwfs = alloc_object(&hIC->hdr, &FTPSESSIONVtbl, sizeof(ftp_session_t));
2453  if (NULL == lpwfs)
2454  {
2456  return NULL;
2457  }
2458 
2459  if (nServerPort == INTERNET_INVALID_PORT_NUMBER)
2461  else
2462  lpwfs->serverport = nServerPort;
2463 
2464  lpwfs->hdr.htype = WH_HFTPSESSION;
2465  lpwfs->hdr.dwFlags = dwFlags;
2466  lpwfs->hdr.dwContext = dwContext;
2467  lpwfs->hdr.dwInternalFlags |= dwInternalFlags;
2468  lpwfs->download_in_progress = NULL;
2469  lpwfs->sndSocket = -1;
2470  lpwfs->lstnSocket = -1;
2471  lpwfs->pasvSocket = -1;
2472 
2473  WININET_AddRef( &hIC->hdr );
2474  lpwfs->lpAppInfo = hIC;
2475  list_add_head( &hIC->hdr.children, &lpwfs->hdr.entry );
2476 
2477  if(hIC->proxy && hIC->accessType == INTERNET_OPEN_TYPE_PROXY) {
2478  if(wcschr(hIC->proxy, ' '))
2479  FIXME("Several proxies not implemented.\n");
2480  if(hIC->proxyBypass)
2481  FIXME("Proxy bypass is ignored.\n");
2482  }
2483  if (!lpszUserName || !lpszUserName[0]) {
2484  HKEY key;
2485  WCHAR szPassword[MAX_PATH];
2486  DWORD len = sizeof(szPassword);
2487 
2488  lpwfs->lpszUserName = heap_strdupW(L"anonymous");
2489 
2490  RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", &key);
2491  if (RegQueryValueExW(key, L"EmailName", NULL, NULL, (LPBYTE)szPassword, &len)) {
2492  /* Nothing in the registry, get the username and use that as the password */
2493  if (!GetUserNameW(szPassword, &len)) {
2494  /* Should never get here, but use an empty password as failsafe */
2495  lstrcpyW(szPassword, L"");
2496  }
2497  }
2498  RegCloseKey(key);
2499 
2500  TRACE("Password used for anonymous ftp : (%s)\n", debugstr_w(szPassword));
2501  lpwfs->lpszPassword = heap_strdupW(szPassword);
2502  }
2503  else {
2504  lpwfs->lpszUserName = heap_strdupW(lpszUserName);
2506  }
2507  lpwfs->servername = heap_strdupW(lpszServerName);
2508 
2509  /* Don't send a handle created callback if this handle was created with InternetOpenUrl */
2510  if (!(lpwfs->hdr.dwInternalFlags & INET_OPENURL))
2511  {
2513 
2514  iar.dwResult = (DWORD_PTR)lpwfs->hdr.hInternet;
2515  iar.dwError = ERROR_SUCCESS;
2516 
2517  INTERNET_SendCallback(&hIC->hdr, dwContext,
2519  sizeof(INTERNET_ASYNC_RESULT));
2520  }
2521 
2523  (LPWSTR) lpszServerName, (lstrlenW(lpszServerName)+1) * sizeof(WCHAR));
2524 
2525  sock_namelen = sizeof(socketAddr);
2526  if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen, szaddr))
2527  {
2529  goto lerror;
2530  }
2531 
2532  if (socketAddr.sin_family != AF_INET)
2533  {
2534  WARN("unsupported address family %d\n", socketAddr.sin_family);
2536  goto lerror;
2537  }
2538 
2540  szaddr, strlen(szaddr)+1);
2541 
2542  init_winsock();
2543  nsocket = socket(AF_INET,SOCK_STREAM,0);
2544  if (nsocket == -1)
2545  {
2547  goto lerror;
2548  }
2549 
2551  szaddr, strlen(szaddr)+1);
2552 
2553  if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0)
2554  {
2555  ERR("Unable to connect (%d)\n", WSAGetLastError());
2557  closesocket(nsocket);
2558  }
2559  else
2560  {
2561  TRACE("Connected to server\n");
2562  lpwfs->sndSocket = nsocket;
2564  szaddr, strlen(szaddr)+1);
2565 
2566  sock_namelen = sizeof(lpwfs->socketAddress);
2567  getsockname(nsocket, (struct sockaddr *) &lpwfs->socketAddress, &sock_namelen);
2568 
2569  if (FTP_ConnectToHost(lpwfs))
2570  {
2571  TRACE("Successfully logged into server\n");
2572  bSuccess = TRUE;
2573  }
2574  }
2575 
2576 lerror:
2577  if (!bSuccess)
2578  {
2579  WININET_Release(&lpwfs->hdr);
2580  return NULL;
2581  }
2582 
2583  return lpwfs->hdr.hInternet;
2584 }
2585 
2586 
2587 /***********************************************************************
2588  * FTP_ConnectToHost (internal)
2589  *
2590  * Connect to a ftp server
2591  *
2592  * RETURNS
2593  * TRUE on success
2594  * NULL on failure
2595  *
2596  */
2598 {
2599  INT nResCode;
2600  BOOL bSuccess = FALSE;
2601 
2602  TRACE("\n");
2603  FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2604 
2605  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_USER, lpwfs->lpszUserName, 0, 0, 0))
2606  goto lend;
2607 
2608  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2609  if (nResCode)
2610  {
2611  /* Login successful... */
2612  if (nResCode == 230)
2613  bSuccess = TRUE;
2614  /* User name okay, need password... */
2615  else if (nResCode == 331)
2616  bSuccess = FTP_SendPassword(lpwfs);
2617  /* Need account for login... */
2618  else if (nResCode == 332)
2619  bSuccess = FTP_SendAccount(lpwfs);
2620  else
2621  FTP_SetResponseError(nResCode);
2622  }
2623 
2624  TRACE("Returning %d\n", bSuccess);
2625 lend:
2626  return bSuccess;
2627 }
2628 
2629 /***********************************************************************
2630  * FTP_GetNextLine (internal)
2631  *
2632  * Parse next line in directory string listing
2633  *
2634  * RETURNS
2635  * Pointer to beginning of next line
2636  * NULL on failure
2637  *
2638  */
2639 
2640 static LPSTR FTP_GetNextLine(INT nSocket, LPDWORD dwLen)
2641 {
2642  struct timeval tv = {RESPONSE_TIMEOUT,0};
2643  FD_SET set;
2644  INT nRecv = 0;
2645  LPSTR lpszBuffer = INTERNET_GetResponseBuffer();
2646 
2647  TRACE("\n");
2648 
2649  FD_ZERO(&set);
2650  FD_SET(nSocket, &set);
2651 
2652  while (nRecv < MAX_REPLY_LEN)
2653  {
2654  if (select(nSocket+1, &set, NULL, NULL, &tv) > 0)
2655  {
2656  if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
2657  {
2659  return NULL;
2660  }
2661 
2662  if (lpszBuffer[nRecv] == '\n')
2663  {
2664  lpszBuffer[nRecv] = '\0';
2665  *dwLen = nRecv - 1;
2666  TRACE(":%d %s\n", nRecv, lpszBuffer);
2667  return lpszBuffer;
2668  }
2669  if (lpszBuffer[nRecv] != '\r')
2670  nRecv++;
2671  }
2672  else
2673  {
2675  return NULL;
2676  }
2677  }
2678 
2679  return NULL;
2680 }
2681 
2682 /***********************************************************************
2683  * FTP_SendCommandA (internal)
2684  *
2685  * Send command to server
2686  *
2687  * RETURNS
2688  * TRUE on success
2689  * NULL on failure
2690  *
2691  */
2692 static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam,
2693  INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext)
2694 {
2695  DWORD len;
2696  CHAR *buf;
2697  DWORD nBytesSent = 0;
2698  int nRC = 0;
2699  DWORD dwParamLen;
2700 
2701  TRACE("%d: (%s) %d\n", ftpCmd, debugstr_a(lpszParam), nSocket);
2702 
2703  if (lpfnStatusCB)
2704  {
2705  lpfnStatusCB(hdr->hInternet, dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
2706  }
2707 
2708  dwParamLen = lpszParam?strlen(lpszParam)+1:0;
2709  len = dwParamLen + strlen(szFtpCommands[ftpCmd]) + strlen(szCRLF);
2710  if (NULL == (buf = heap_alloc(len+1)))
2711  {
2713  return FALSE;
2714  }
2715  sprintf(buf, "%s%s%s%s", szFtpCommands[ftpCmd], dwParamLen ? " " : "",
2716  dwParamLen ? lpszParam : "", szCRLF);
2717 
2718  TRACE("Sending (%s) len(%d)\n", debugstr_a(buf), len);
2719  while((nBytesSent < len) && (nRC != -1))
2720  {
2721  nRC = sock_send(nSocket, buf+nBytesSent, len - nBytesSent, 0);
2722  nBytesSent += nRC;
2723  }
2724  heap_free(buf);
2725 
2726  if (lpfnStatusCB)
2727  {
2728  lpfnStatusCB(hdr->hInternet, dwContext, INTERNET_STATUS_REQUEST_SENT,
2729  &nBytesSent, sizeof(DWORD));
2730  }
2731 
2732  TRACE("Sent %d bytes\n", nBytesSent);
2733  return (nRC != -1);
2734 }
2735 
2736 /***********************************************************************
2737  * FTP_SendCommand (internal)
2738  *
2739  * Send command to server
2740  *
2741  * RETURNS
2742  * TRUE on success
2743  * NULL on failure
2744  *
2745  */
2746 static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam,
2747  INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext)
2748 {
2749  BOOL ret;
2750  LPSTR lpszParamA = heap_strdupWtoA(lpszParam);
2751  ret = FTP_SendCommandA(nSocket, ftpCmd, lpszParamA, lpfnStatusCB, hdr, dwContext);
2752  heap_free(lpszParamA);
2753  return ret;
2754 }
2755 
2756 /***********************************************************************
2757  * FTP_ReceiveResponse (internal)
2758  *
2759  * Receive response from server
2760  *
2761  * RETURNS
2762  * Reply code on success
2763  * 0 on failure
2764  *
2765  */
2767 {
2768  LPSTR lpszResponse = INTERNET_GetResponseBuffer();
2769  DWORD nRecv;
2770  INT rc = 0;
2771  char firstprefix[5];
2772  BOOL multiline = FALSE;
2773 
2774  TRACE("socket(%d)\n", lpwfs->sndSocket);
2775 
2777 
2778  while(1)
2779  {
2780  if (!FTP_GetNextLine(lpwfs->sndSocket, &nRecv))
2781  goto lerror;
2782 
2783  if (nRecv >= 3)
2784  {
2785  if(!multiline)
2786  {
2787  if(lpszResponse[3] != '-')
2788  break;
2789  else
2790  { /* Start of multiline response. Loop until we get "nnn " */
2791  multiline = TRUE;
2792  memcpy(firstprefix, lpszResponse, 3);
2793  firstprefix[3] = ' ';
2794  firstprefix[4] = '\0';
2795  }
2796  }
2797  else
2798  {
2799  if(!memcmp(firstprefix, lpszResponse, 4))
2800  break;
2801  }
2802  }
2803  }
2804 
2805  if (nRecv >= 3)
2806  {
2807  rc = atoi(lpszResponse);
2808 
2810  &nRecv, sizeof(DWORD));
2811  }
2812 
2813 lerror:
2814  TRACE("return %d\n", rc);
2815  return rc;
2816 }
2817 
2818 
2819 /***********************************************************************
2820  * FTP_SendPassword (internal)
2821  *
2822  * Send password to ftp server
2823  *
2824  * RETURNS
2825  * TRUE on success
2826  * NULL on failure
2827  *
2828  */
2830 {
2831  INT nResCode;
2832  BOOL bSuccess = FALSE;
2833 
2834  TRACE("\n");
2835  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PASS, lpwfs->lpszPassword, 0, 0, 0))
2836  goto lend;
2837 
2838  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2839  if (nResCode)
2840  {
2841  TRACE("Received reply code %d\n", nResCode);
2842  /* Login successful... */
2843  if (nResCode == 230)
2844  bSuccess = TRUE;
2845  /* Command not implemented, superfluous at the server site... */
2846  /* Need account for login... */
2847  else if (nResCode == 332)
2848  bSuccess = FTP_SendAccount(lpwfs);
2849  else
2850  FTP_SetResponseError(nResCode);
2851  }
2852 
2853 lend:
2854  TRACE("Returning %d\n", bSuccess);
2855  return bSuccess;
2856 }
2857 
2858 
2859 /***********************************************************************
2860  * FTP_SendAccount (internal)
2861  *
2862  *
2863  *
2864  * RETURNS
2865  * TRUE on success
2866  * FALSE on failure
2867  *
2868  */
2870 {
2871  INT nResCode;
2872  BOOL bSuccess = FALSE;
2873 
2874  TRACE("\n");
2875  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_ACCT, L"noaccount", 0, 0, 0))
2876  goto lend;
2877 
2878  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2879  if (nResCode)
2880  bSuccess = TRUE;
2881  else
2882  FTP_SetResponseError(nResCode);
2883 
2884 lend:
2885  return bSuccess;
2886 }
2887 
2888 
2889 /***********************************************************************
2890  * FTP_SendStore (internal)
2891  *
2892  * Send request to upload file to ftp server
2893  *
2894  * RETURNS
2895  * TRUE on success
2896  * FALSE on failure
2897  *
2898  */
2899 static BOOL FTP_SendStore(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType)
2900 {
2901  INT nResCode;
2902  BOOL bSuccess = FALSE;
2903 
2904  TRACE("\n");
2905  if (!FTP_InitListenSocket(lpwfs))
2906  goto lend;
2907 
2908  if (!FTP_SendType(lpwfs, dwType))
2909  goto lend;
2910 
2911  if (!FTP_SendPortOrPasv(lpwfs))
2912  goto lend;
2913 
2914  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_STOR, lpszRemoteFile, 0, 0, 0))
2915  goto lend;
2916  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
2917  if (nResCode)
2918  {
2919  if (nResCode == 150 || nResCode == 125)
2920  bSuccess = TRUE;
2921  else
2922  FTP_SetResponseError(nResCode);
2923  }
2924 
2925 lend:
2926  if (!bSuccess && lpwfs->lstnSocket != -1)
2927  {
2928  closesocket(lpwfs->lstnSocket);
2929  lpwfs->lstnSocket = -1;
2930  }
2931 
2932  return bSuccess;
2933 }
2934 
2935 
2936 /***********************************************************************
2937  * FTP_InitListenSocket (internal)
2938  *
2939  * Create a socket to listen for server response
2940  *
2941  * RETURNS
2942  * TRUE on success
2943  * FALSE on failure
2944  *
2945  */
2947 {
2948  BOOL bSuccess = FALSE;
2949  socklen_t namelen = sizeof(lpwfs->lstnSocketAddress);
2950 
2951  TRACE("\n");
2952 
2953  init_winsock();
2954  lpwfs->lstnSocket = socket(AF_INET, SOCK_STREAM, 0);
2955  if (lpwfs->lstnSocket == -1)
2956  {
2957  TRACE("Unable to create listening socket\n");
2958  goto lend;
2959  }
2960 
2961  /* We obtain our ip addr from the name of the command channel socket */
2962  lpwfs->lstnSocketAddress = lpwfs->socketAddress;
2963 
2964  /* and get the system to assign us a port */
2965  lpwfs->lstnSocketAddress.sin_port = htons(0);
2966 
2967  if (bind(lpwfs->lstnSocket,(struct sockaddr *) &lpwfs->lstnSocketAddress, sizeof(lpwfs->lstnSocketAddress)) == -1)
2968  {
2969  TRACE("Unable to bind socket\n");
2970  goto lend;
2971  }
2972 
2973  if (listen(lpwfs->lstnSocket, MAX_BACKLOG) == -1)
2974  {
2975  TRACE("listen failed\n");
2976  goto lend;
2977  }
2978 
2979  if (getsockname(lpwfs->lstnSocket, (struct sockaddr *) &lpwfs->lstnSocketAddress, &namelen) != -1)
2980  bSuccess = TRUE;
2981 
2982 lend:
2983  if (!bSuccess && lpwfs->lstnSocket != -1)
2984  {
2985  closesocket(lpwfs->lstnSocket);
2986  lpwfs->lstnSocket = -1;
2987  }
2988 
2989  return bSuccess;
2990 }
2991 
2992 
2993 /***********************************************************************
2994  * FTP_SendType (internal)
2995  *
2996  * Tell server type of data being transferred
2997  *
2998  * RETURNS
2999  * TRUE on success
3000  * FALSE on failure
3001  *
3002  * W98SE doesn't cache the type that's currently set
3003  * (i.e. it sends it always),
3004  * so we probably don't want to do that either.
3005  */
3006 static BOOL FTP_SendType(ftp_session_t *lpwfs, DWORD dwType)
3007 {
3008  INT nResCode;
3009  WCHAR type[] = L"I";
3010  BOOL bSuccess = FALSE;
3011 
3012  TRACE("\n");
3013  if (dwType & INTERNET_FLAG_TRANSFER_ASCII)
3014  type[0] = 'A';
3015 
3016  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_TYPE, type, 0, 0, 0))
3017  goto lend;
3018 
3019  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext)/100;
3020  if (nResCode)
3021  {
3022  if (nResCode == 2)
3023  bSuccess = TRUE;
3024  else
3025  FTP_SetResponseError(nResCode);
3026  }
3027 
3028 lend:
3029  return bSuccess;
3030 }
3031 
3032 
3033 #if 0 /* FIXME: should probably be used for FtpGetFileSize */
3034 /***********************************************************************
3035  * FTP_GetFileSize (internal)
3036  *
3037  * Retrieves from the server the size of the given file
3038  *
3039  * RETURNS
3040  * TRUE on success
3041  * FALSE on failure
3042  *
3043  */
3044 static BOOL FTP_GetFileSize(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD *dwSize)
3045 {
3046  INT nResCode;
3047  BOOL bSuccess = FALSE;
3048 
3049  TRACE("\n");
3050 
3051  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_SIZE, lpszRemoteFile, 0, 0, 0))
3052  goto lend;
3053 
3054  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
3055  if (nResCode)
3056  {
3057  if (nResCode == 213) {
3058  /* Now parses the output to get the actual file size */
3059  int i;
3060  LPSTR lpszResponseBuffer = INTERNET_GetResponseBuffer();
3061 
3062  for (i = 0; (lpszResponseBuffer[i] != ' ') && (lpszResponseBuffer[i] != '\0'); i++) ;
3063  if (lpszResponseBuffer[i] == '\0') return FALSE;
3064  *dwSize = atol(&(lpszResponseBuffer[i + 1]));
3065 
3066  bSuccess = TRUE;
3067  } else {
3068  FTP_SetResponseError(nResCode);
3069  }
3070  }
3071 
3072 lend:
3073  return bSuccess;
3074 }
3075 #endif
3076 
3077 
3078 /***********************************************************************
3079  * FTP_SendPort (internal)
3080  *
3081  * Tell server which port to use
3082  *
3083  * RETURNS
3084  * TRUE on success
3085  * FALSE on failure
3086  *
3087  */
3089 {
3090  INT nResCode;
3091  WCHAR szIPAddress[64];
3092  BOOL bSuccess = FALSE;
3093  TRACE("\n");
3094 
3095  swprintf(szIPAddress, ARRAY_SIZE(szIPAddress), L"%d,%d,%d,%d,%d,%d",
3096  lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x000000FF,
3097  (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x0000FF00)>>8,
3098  (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0x00FF0000)>>16,
3099  (lpwfs->lstnSocketAddress.sin_addr.S_un.S_addr&0xFF000000)>>24,
3100  lpwfs->lstnSocketAddress.sin_port & 0xFF,
3101  (lpwfs->lstnSocketAddress.sin_port & 0xFF00)>>8);
3102 
3103  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PORT, szIPAddress, 0, 0, 0))
3104  goto lend;
3105 
3106  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
3107  if (nResCode)
3108  {
3109  if (nResCode == 200)
3110  bSuccess = TRUE;
3111  else
3112  FTP_SetResponseError(nResCode);
3113  }
3114 
3115 lend:
3116  return bSuccess;
3117 }
3118 
3119 
3120 /***********************************************************************
3121  * FTP_DoPassive (internal)
3122  *
3123  * Tell server that we want to do passive transfers
3124  * and connect data socket
3125  *
3126  * RETURNS
3127  * TRUE on success
3128  * FALSE on failure
3129  *
3130  */
3132 {
3133  INT nResCode;
3134  BOOL bSuccess = FALSE;
3135 
3136  TRACE("\n");
3137  if (!FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_PASV, NULL, 0, 0, 0))
3138  goto lend;
3139 
3140  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
3141  if (nResCode)
3142  {
3143  if (nResCode == 227)
3144  {
3145  LPSTR lpszResponseBuffer = INTERNET_GetResponseBuffer();
3146  LPSTR p;
3147  int f[6];
3148  int i;
3149  char *pAddr, *pPort;
3150  INT nsocket = -1;
3151  struct sockaddr_in dataSocketAddress;
3152 
3153  p = lpszResponseBuffer+4; /* skip status code */
3154  while (*p != '\0' && (*p < '0' || *p > '9')) p++;
3155 
3156  if (*p == '\0')
3157  {
3158  ERR("no address found in response, aborting\n");
3159  goto lend;
3160  }
3161 
3162  if (sscanf(p, "%d,%d,%d,%d,%d,%d", &f[0], &f[1], &f[2], &f[3],
3163  &f[4], &f[5]) != 6)
3164  {
3165  ERR("unknown response address format '%s', aborting\n", p);
3166  goto lend;
3167  }
3168  for (i=0; i < 6; i++)
3169  f[i] = f[i] & 0xff;
3170 
3171  dataSocketAddress = lpwfs->socketAddress;
3172  pAddr = (char *)&(dataSocketAddress.sin_addr.S_un.S_addr);
3173  pPort = (char *)&(dataSocketAddress.sin_port);
3174  pAddr[0] = f[0];
3175  pAddr[1] = f[1];
3176  pAddr[2] = f[2];
3177  pAddr[3] = f[3];
3178  pPort[0] = f[4];
3179  pPort[1] = f[5];
3180 
3181  nsocket = socket(AF_INET,SOCK_STREAM,0);
3182  if (nsocket == -1)
3183  goto lend;
3184 
3185  if (connect(nsocket, (struct sockaddr *)&dataSocketAddress, sizeof(dataSocketAddress)))
3186  {
3187  ERR("can't connect passive FTP data port.\n");
3188  closesocket(nsocket);
3189  goto lend;
3190  }
3191  lpwfs->pasvSocket = nsocket;
3192  bSuccess = TRUE;
3193  }
3194  else
3195  FTP_SetResponseError(nResCode);
3196  }
3197 
3198 lend:
3199  return bSuccess;
3200 }
3201 
3202 
3204 {
3205  if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE)
3206  {
3207  if (!FTP_DoPassive(lpwfs))
3208  return FALSE;
3209  }
3210  else
3211  {
3212  if (!FTP_SendPort(lpwfs))
3213  return FALSE;
3214  }
3215  return TRUE;
3216 }
3217 
3218 
3219 /***********************************************************************
3220  * FTP_GetDataSocket (internal)
3221  *
3222  * Either accepts an incoming data socket connection from the server
3223  * or just returns the already opened socket after a PASV command
3224  * in case of passive FTP.
3225  *
3226  *
3227  * RETURNS
3228  * TRUE on success
3229  * FALSE on failure
3230  *
3231  */
3232 static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket)
3233 {
3234  struct sockaddr_in saddr;
3235  socklen_t addrlen = sizeof(saddr);
3236 
3237  TRACE("\n");
3238  if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE)
3239  {
3240  *nDataSocket = lpwfs->pasvSocket;
3241  lpwfs->pasvSocket = -1;
3242  }
3243  else
3244  {
3245  *nDataSocket = accept(lpwfs->lstnSocket, (struct sockaddr *) &saddr, &addrlen);
3246  closesocket(lpwfs->lstnSocket);
3247  lpwfs->lstnSocket = -1;
3248  }
3249  return *nDataSocket != -1;
3250 }
3251 
3252 
3253 /***********************************************************************
3254  * FTP_SendData (internal)
3255  *
3256  * Send data to the server
3257  *
3258  * RETURNS
3259  * TRUE on success
3260  * FALSE on failure
3261  *
3262  */
3263 static BOOL FTP_SendData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile)
3264 {
3266  DWORD nBytesRead = 0;
3267  DWORD nBytesSent = 0;
3268  DWORD nTotalSent = 0;
3269  DWORD nBytesToSend, nLen;
3270  int nRC = 1;
3271  time_t s_long_time, e_long_time;
3272  LONG nSeconds;
3273  CHAR *lpszBuffer;
3274 
3275  TRACE("\n");
3276  lpszBuffer = heap_alloc_zero(sizeof(CHAR)*DATA_PACKET_SIZE);
3277 
3278  /* Get the size of the file. */
3280  time(&s_long_time);
3281 
3282  do
3283  {
3284  nBytesToSend = nBytesRead - nBytesSent;
3285 
3286  if (nBytesToSend <= 0)
3287  {
3288  /* Read data from file. */
3289  nBytesSent = 0;
3290  if (!ReadFile(hFile, lpszBuffer, DATA_PACKET_SIZE, &nBytesRead, 0))
3291  ERR("Failed reading from file\n");
3292 
3293  if (nBytesRead > 0)
3294  nBytesToSend = nBytesRead;
3295  else
3296  break;
3297  }
3298 
3299  nLen = DATA_PACKET_SIZE < nBytesToSend ?
3300  DATA_PACKET_SIZE : nBytesToSend;
3301  nRC = sock_send(nDataSocket, lpszBuffer, nLen, 0);
3302 
3303  if (nRC != -1)
3304  {
3305  nBytesSent += nRC;
3306  nTotalSent += nRC;
3307  }
3308 
3309  /* Do some computation to display the status. */
3310  time(&e_long_time);
3311  nSeconds = e_long_time - s_long_time;
3312  if( nSeconds / 60 > 0 )
3313  {
3314  TRACE( "%d bytes of %d bytes (%d%%) in %d min %d sec estimated remaining time %d sec\n",
3315  nTotalSent, fi.nFileSizeLow, nTotalSent*100/fi.nFileSizeLow, nSeconds / 60,
3316  nSeconds % 60, (fi.nFileSizeLow - nTotalSent) * nSeconds / nTotalSent );
3317  }
3318  else
3319  {
3320  TRACE( "%d bytes of %d bytes (%d%%) in %d sec estimated remaining time %d sec\n",
3321  nTotalSent, fi.nFileSizeLow, nTotalSent*100/fi.nFileSizeLow, nSeconds,
3322  (fi.nFileSizeLow - nTotalSent) * nSeconds / nTotalSent);
3323  }
3324  } while (nRC != -1);
3325 
3326  TRACE("file transfer complete!\n");
3327 
3328  heap_free(lpszBuffer);
3329  return nTotalSent;
3330 }
3331 
3332 
3333 /***********************************************************************
3334  * FTP_SendRetrieve (internal)
3335  *
3336  * Send request to retrieve a file
3337  *
3338  * RETURNS
3339  * Number of bytes to be received on success
3340  * 0 on failure
3341  *
3342  */
3343 static BOOL FTP_SendRetrieve(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType)
3344 {
3345  INT nResCode;
3346  BOOL ret;
3347 
3348  TRACE("\n");
3349  if (!(ret = FTP_InitListenSocket(lpwfs)))
3350  goto lend;
3351 
3352  if (!(ret = FTP_SendType(lpwfs, dwType)))
3353  goto lend;
3354 
3355  if (!(ret = FTP_SendPortOrPasv(lpwfs)))
3356  goto lend;
3357 
3358  if (!(ret = FTP_SendCommand(lpwfs->sndSocket, FTP_CMD_RETR, lpszRemoteFile, 0, 0, 0)))
3359  goto lend;
3360 
3361  nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
3362  if ((nResCode != 125) && (nResCode != 150)) {
3363  /* That means that we got an error getting the file. */
3364  FTP_SetResponseError(nResCode);
3365  ret = FALSE;
3366  }
3367 
3368 lend:
3369  if (!ret && lpwfs->lstnSocket != -1)
3370  {
3371  closesocket(lpwfs->lstnSocket);
3372  lpwfs->lstnSocket = -1;
3373  }
3374 
3375  return ret;
3376 }
3377 
3378 
3379 /***********************************************************************
3380  * FTP_RetrieveData (internal)
3381  *
3382  * Retrieve data from server
3383  *
3384  * RETURNS
3385  * TRUE on success
3386  * FALSE on failure
3387  *
3388  */
3390 {
3391  DWORD nBytesWritten;
3392  INT nRC = 0;
3393  CHAR *lpszBuffer;
3394 
3395  TRACE("\n");
3396 
3397  lpszBuffer = heap_alloc_zero(sizeof(CHAR)*DATA_PACKET_SIZE);
3398  if (NULL == lpszBuffer)
3399  {
3401  return FALSE;
3402  }
3403 
3404  while (nRC != -1)
3405  {
3406  nRC = sock_recv(nDataSocket, lpszBuffer, DATA_PACKET_SIZE, 0);
3407  if (nRC != -1)
3408  {
3409  /* other side closed socket. */
3410  if (nRC == 0)
3411  goto recv_end;
3412  WriteFile(hFile, lpszBuffer, nRC, &nBytesWritten, NULL);
3413  }
3414  }
3415 
3416  TRACE("Data transfer complete\n");
3417 
3418 recv_end:
3419  heap_free(lpszBuffer);
3420  return (nRC != -1);
3421 }
3422 
3423 /***********************************************************************
3424  * FTPFINDNEXT_Destroy (internal)
3425  *
3426  * Deallocate session handle
3427  */
3429 {
3431  DWORD i;
3432 
3433  TRACE("\n");
3434 
3435  WININET_Release(&lpwfn->lpFtpSession->hdr);
3436 
3437  for (i = 0; i < lpwfn->size; i++)
3438  {
3439  heap_free(lpwfn->lpafp[i].lpszName);
3440  }
3441  heap_free(lpwfn->lpafp);
3442 }
3443 
3445 {
3448 
3449  TRACE("index(%d) size(%d)\n", find->index, find->size);
3450 
3452 
3453  if (find->index < find->size) {
3454  FTP_ConvertFileProp(&find->lpafp[find->index], find_data);
3455  find->index++;
3456 
3457  TRACE("Name: %s\nSize: %d\n", debugstr_w(find_data->cFileName), find_data->nFileSizeLow);
3458  }else {
3460  }
3461 
3462  if (find->hdr.dwFlags & INTERNET_FLAG_ASYNC)
3463  {
3465 
3466  iar.dwResult = (res == ERROR_SUCCESS);
3467  iar.dwError = res;
3468 
3469  INTERNET_SendCallback(&find->hdr, find->hdr.dwContext,
3471  sizeof(INTERNET_ASYNC_RESULT));
3472  }
3473 
3474  return res;
3475 }
3476 
3477 typedef struct {
3481 
3483 {
3485 
3487 }
3488 
3490 {
3491  switch(option) {
3493  TRACE("INTERNET_OPTION_HANDLE_TYPE\n");
3494 
3495  if (*size < sizeof(ULONG))
3497 
3498  *size = sizeof(DWORD);
3500  return ERROR_SUCCESS;
3501  }
3502 
3503  return INET_QueryOption(hdr, option, buffer, size, unicode);
3504 }
3505 
3507 {
3509 
3510  if (find->lpFtpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC)
3511  {
3512  find_next_task_t *task;
3513 
3514  task = alloc_async_task(&find->hdr, FTPFINDNEXT_AsyncFindNextFileProc, sizeof(*task));
3515  task->find_data = data;
3516 
3517  INTERNET_AsyncCall(&task->hdr);
3518  return ERROR_SUCCESS;
3519  }
3520 
3522 }
3523 
3526  NULL,
3529  NULL,
3530  NULL,
3531  NULL,
3533 };
3534 
3535 /***********************************************************************
3536  * FTP_ReceiveFileList (internal)
3537  *
3538  * Read file list from server
3539  *
3540  * RETURNS
3541  * Handle to file list on success
3542  * NULL on failure
3543  *
3544  */
3545 static HINTERNET FTP_ReceiveFileList(ftp_session_t *lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
3546  LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext)
3547 {
3548  DWORD dwSize = 0;
3549  LPFILEPROPERTIESW lpafp = NULL;
3550  LPWININETFTPFINDNEXTW lpwfn = NULL;
3551 
3552  TRACE("(%p,%d,%s,%p,%08lx)\n", lpwfs, nSocket, debugstr_w(lpszSearchFile), lpFindFileData, dwContext);
3553 
3554  if (FTP_ParseDirectory(lpwfs, nSocket, lpszSearchFile, &lpafp, &dwSize))
3555  {
3556  if(lpFindFileData)
3557  FTP_ConvertFileProp(lpafp, lpFindFileData);
3558 
3559  lpwfn = alloc_object(&lpwfs->hdr, &FTPFINDNEXTVtbl, sizeof(WININETFTPFINDNEXTW));
3560  if (lpwfn)
3561  {
3562  lpwfn->hdr.htype = WH_HFTPFINDNEXT;
3563  lpwfn->hdr.dwContext = dwContext;
3564  lpwfn->index = 1; /* Next index is 1 since we return index 0 */
3565  lpwfn->size = dwSize;
3566  lpwfn->lpafp = lpafp;
3567 
3568  WININET_AddRef( &lpwfs->hdr );
3569  lpwfn->lpFtpSession = lpwfs;
3570  list_add_head( &lpwfs->hdr.children, &lpwfn->hdr.entry );
3571  }
3572  }
3573 
3574  TRACE("Matched %d files\n", dwSize);
3575  return lpwfn ? lpwfn->hdr.hInternet : NULL;
3576 }
3577 
3578 
3579 /***********************************************************************
3580  * FTP_ConvertFileProp (internal)
3581  *
3582  * Converts FILEPROPERTIESW struct to WIN32_FIND_DATAA
3583  *
3584  * RETURNS
3585  * TRUE on success
3586  * FALSE on failure
3587  *
3588  */
3590 {
3591  BOOL bSuccess = FALSE;
3592 
3593  ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAW));
3594 
3595  if (lpafp)
3596  {
3597  SystemTimeToFileTime( &lpafp->tmLastModified, &lpFindFileData->ftLastAccessTime );
3598  lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime;
3599  lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime;
3600 
3601  /* Not all fields are filled in */
3602  lpFindFileData->nFileSizeHigh = 0; /* We do not handle files bigger than 0xFFFFFFFF bytes yet :-) */
3603  lpFindFileData->nFileSizeLow = lpafp->nSize;
3604 
3605  if (lpafp->bIsDirectory)
3606  lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
3607 
3608  if (lpafp->lpszName)
3609  lstrcpynW(lpFindFileData->cFileName, lpafp->lpszName, MAX_PATH);
3610 
3611  bSuccess = TRUE;
3612  }
3613 
3614  return bSuccess;
3615 }
3616 
3617 /***********************************************************************
3618  * FTP_ParseNextFile (internal)
3619  *
3620  * Parse the next line in file listing
3621  *
3622  * RETURNS
3623  * TRUE on success
3624  * FALSE on failure
3625  */
3626 static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW lpfp)
3627 {
3628  static const char szSpace[] = " \t";
3629  DWORD nBufLen;
3630  char *pszLine;
3631  char *pszToken;
3632  char *pszTmp;
3633  BOOL found = FALSE;
3634  int i;
3635 
3636  lpfp->lpszName = NULL;
3637  do {
3638  if(!(pszLine = FTP_GetNextLine(nSocket, &nBufLen)))
3639  return FALSE;
3640 
3641  pszToken = strtok(pszLine, szSpace);
3642  /* ls format
3643  * <Permissions> <NoLinks> <owner> <group> <size> <date> <time or year> <filename>
3644  *
3645  * For instance:
3646  * drwx--s--- 2 pcarrier ens 512 Sep 28 1995 pcarrier
3647  */
3648  if(!isdigit(pszToken[0]) && 10 == strlen(pszToken)) {
3649  if(!FTP_ParsePermission(pszToken, lpfp))
3650  lpfp->bIsDirectory = FALSE;
3651  for(i=0; i<=3; i++) {
3652  if(!(pszToken = strtok(NULL, szSpace)))
3653  break;
3654  }
3655  if(!pszToken) continue;
3656  if(lpfp->bIsDirectory) {
3657  TRACE("Is directory\n");
3658  lpfp->nSize = 0;
3659  }
3660  else {
3661  TRACE("Size: %s\n", pszToken);
3662  lpfp->nSize = atol(pszToken);
3663  }
3664 
3665  lpfp->tmLastModified.wSecond = 0;
3666  lpfp->tmLastModified.wMinute = 0;
3667  lpfp->tmLastModified.wHour = 0;
3668  lpfp->tmLastModified.wDay = 0;
3669  lpfp->tmLastModified.wMonth = 0;
3670  lpfp->tmLastModified.wYear = 0;
3671 
3672  /* Determine month */
3673  pszToken = strtok(NULL, szSpace);
3674  if(!pszToken) continue;
3675  if(strlen(pszToken) >= 3) {
3676  pszToken[3] = 0;
3677  if((pszTmp = StrStrIA(szMonths, pszToken)))
3678  lpfp->tmLastModified.wMonth = ((pszTmp - szMonths) / 3)+1;
3679  }
3680  /* Determine day */
3681  pszToken = strtok(NULL, szSpace);
3682  if(!pszToken) continue;
3683  lpfp->tmLastModified.wDay = atoi(pszToken);
3684  /* Determine time or year */
3685  pszToken = strtok(NULL, szSpace);
3686  if(!pszToken) continue;
3687  if((pszTmp = strchr(pszToken, ':'))) {
3688  SYSTEMTIME curr_time;
3689  *pszTmp = 0;
3690  pszTmp++;
3691  lpfp->tmLastModified.wMinute = atoi(pszTmp);
3692  lpfp->tmLastModified.wHour = atoi(pszToken);
3693  GetLocalTime( &curr_time );
3694  lpfp->tmLastModified.wYear = curr_time.wYear;
3695  }
3696  else {
3697  lpfp->tmLastModified.wYear = atoi(pszToken);
3698  lpfp->tmLastModified.wHour = 12;
3699  }
3700  TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
3703 
3704  pszToken = strtok(NULL, szSpace);
3705  if(!pszToken) continue;
3706  lpfp->lpszName = heap_strdupAtoW(pszToken);
3707  TRACE("File: %s\n", debugstr_w(lpfp->lpszName));
3708  }
3709  /* NT way of parsing ... :
3710 
3711  07-13-03 08:55PM <DIR> sakpatch
3712  05-09-03 06:02PM 12656686 2003-04-21bgm_cmd_e.rgz
3713  */
3714  else if(isdigit(pszToken[0]) && 8 == strlen(pszToken)) {
3715  int mon, mday, year, hour, min;
3716  lpfp->permissions = 0xFFFF; /* No idea, put full permission :-) */
3717 
3718  sscanf(pszToken, "%d-%d-%d", &mon, &mday, &year);
3719  lpfp->tmLastModified.wDay = mday;
3720  lpfp->tmLastModified.wMonth = mon;
3721  lpfp->tmLastModified.wYear = year;
3722 
3723  /* Hacky and bad Y2K protection :-) */
3724  if (lpfp->tmLastModified.wYear < 70) lpfp->tmLastModified.wYear += 2000;
3725 
3726  pszToken = strtok(NULL, szSpace);
3727  if(!pszToken) continue;
3728  sscanf(pszToken, "%d:%d", &hour, &min);
3729  lpfp->tmLastModified.wHour = hour;
3730  lpfp->tmLastModified.wMinute = min;
3731  if((pszToken[5] == 'P') && (pszToken[6] == 'M')) {
3732  lpfp->tmLastModified.wHour += 12;
3733  }
3734  lpfp->tmLastModified.wSecond = 0;
3735 
3736  TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
3739 
3740  pszToken = strtok(NULL, szSpace);
3741  if(!pszToken) continue;
3742  if(!stricmp(pszToken, "<DIR>")) {
3743  lpfp->bIsDirectory = TRUE;
3744  lpfp->nSize = 0;
3745  TRACE("Is directory\n");
3746  }
3747  else {
3748  lpfp->bIsDirectory = FALSE;
3749  lpfp->nSize = atol(pszToken);
3750  TRACE("Size: %d\n", lpfp->nSize);
3751  }
3752 
3753  pszToken = strtok(NULL, szSpace);
3754  if(!pszToken) continue;
3755  lpfp->lpszName = heap_strdupAtoW(pszToken);
3756  TRACE("Name: %s\n", debugstr_w(lpfp->lpszName));
3757  }
3758  /* EPLF format - http://cr.yp.to/ftp/list/eplf.html */
3759  else if(pszToken[0] == '+') {
3760  FIXME("EPLF Format not implemented\n");
3761  }
3762 
3763  if(lpfp->lpszName) {
3764  if((lpszSearchFile == NULL) ||
3765  (PathMatchSpecW(lpfp->lpszName, lpszSearchFile))) {
3766  found = TRUE;
3767  TRACE("Matched: %s\n", debugstr_w(lpfp->lpszName));
3768  }
3769  else {
3770  heap_free(lpfp->lpszName);
3771  lpfp->lpszName = NULL;
3772  }
3773  }
3774  } while(!found);
3775  return TRUE;
3776 }
3777 
3778 /***********************************************************************
3779  * FTP_ParseDirectory (internal)
3780  *
3781  * Parse string of directory information
3782  *
3783  * RETURNS
3784  * TRUE on success
3785  * FALSE on failure
3786  */
3787 static BOOL FTP_ParseDirectory(ftp_session_t *lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
3788  LPFILEPROPERTIESW *lpafp, LPDWORD dwfp)
3789 {
3790  BOOL bSuccess = TRUE;
3791  INT sizeFilePropArray = 500;/*20; */
3792  INT indexFilePropArray = -1;
3793 
3794  TRACE("\n");
3795 
3796  /* Allocate initial file properties array */
3797  *lpafp = heap_alloc_zero(sizeof(FILEPROPERTIESW)*(sizeFilePropArray));
3798  if (!*lpafp)
3799  return FALSE;
3800 
3801  do {
3802  if (indexFilePropArray+1 >= sizeFilePropArray)
3803  {
3804  LPFILEPROPERTIESW tmpafp;
3805 
3806  sizeFilePropArray *= 2;
3807  tmpafp = heap_realloc_zero(*lpafp, sizeof(FILEPROPERTIESW)*sizeFilePropArray);
3808  if (NULL == tmpafp)
3809  {
3810  bSuccess = FALSE;
3811  break;
3812  }
3813 
3814  *lpafp = tmpafp;
3815  }
3816  indexFilePropArray++;
3817  } while (FTP_ParseNextFile(nSocket, lpszSearchFile, &(*lpafp)[indexFilePropArray]));
3818 
3819  if (bSuccess && indexFilePropArray)
3820  {
3821  if (indexFilePropArray < sizeFilePropArray - 1)
3822  {
3823  LPFILEPROPERTIESW tmpafp;
3824 
3825  tmpafp = heap_realloc(*lpafp, sizeof(FILEPROPERTIESW)*indexFilePropArray);
3826  if (NULL != tmpafp)
3827  *lpafp = tmpafp;
3828  }
3829  *dwfp = indexFilePropArray;
3830  }
3831  else
3832  {
3833  heap_free(*lpafp);
3835  bSuccess = FALSE;
3836  }
3837 
3838  return bSuccess;
3839 }
3840 
3841 
3842 /***********************************************************************
3843  * FTP_ParsePermission (internal)
3844  *
3845  * Parse permission string of directory information
3846  *
3847  * RETURNS
3848  * TRUE on success
3849  * FALSE on failure
3850  *
3851  */
3852 static BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESW lpfp)
3853 {
3854  BOOL bSuccess = TRUE;
3855  unsigned short nPermission = 0;
3856  INT nPos = 1;
3857  INT nLast = 9;
3858 
3859  TRACE("\n");
3860  if ((*lpszPermission != 'd') && (*lpszPermission != '-') && (*lpszPermission != 'l'))
3861  {
3862  bSuccess = FALSE;
3863  return bSuccess;
3864  }
3865 
3866  lpfp->bIsDirectory = (*lpszPermission == 'd');
3867  do
3868  {
3869  switch (nPos)
3870  {
3871  case 1:
3872  nPermission |= (*(lpszPermission+1) == 'r' ? 1 : 0) << 8;
3873  break;
3874  case 2:
3875  nPermission |= (*(lpszPermission+2) == 'w' ? 1 : 0) << 7;
3876  break;
3877  case 3:
3878  nPermission |= (*(lpszPermission+3) == 'x' ? 1 : 0) << 6;
3879  break;
3880  case 4:
3881  nPermission |= (*(lpszPermission+4) == 'r' ? 1 : 0) << 5;
3882  break;
3883  case 5:
3884  nPermission |= (*(lpszPermission+5) == 'w' ? 1 : 0) << 4;
3885  break;
3886  case 6:
3887  nPermission |= (*(lpszPermission+6) == 'x' ? 1 : 0) << 3;
3888  break;
3889  case 7:
3890  nPermission |= (*(lpszPermission+7) == 'r' ? 1 : 0) << 2;
3891  break;
3892  case 8:
3893  nPermission |= (*(lpszPermission+8) == 'w' ? 1 : 0) << 1;
3894  break;
3895  case 9:
3896  nPermission |= (*(lpszPermission+9) == 'x' ? 1 : 0);
3897  break;
3898  }
3899  nPos++;
3900  }while (nPos <= nLast);
3901 
3902  lpfp->permissions = nPermission;
3903  return bSuccess;
3904 }
3905 
3906 
3907 /***********************************************************************
3908  * FTP_SetResponseError (internal)
3909  *
3910  * Set the appropriate error code for a given response from the server
3911  *
3912  * RETURNS
3913  *
3914  */
3916 {
3917  DWORD dwCode = 0;
3918 
3919  switch(dwResponse)
3920  {
3921  case 425: /* Cannot open data connection. */
3923  break;
3924 
3925  case 426: /* Connection closed, transfer aborted. */
3927  break;
3928 
3929  case 530: /* Not logged in. Login incorrect. */
3931  break;
3932 
3933  case 421: /* Service not available - Server may be shutting down. */
3934  case 450: /* File action not taken. File may be busy. */
3935  case 451: /* Action aborted. Server error. */
3936  case 452: /* Action not taken. Insufficient storage space on server. */
3937  case 500: /* Syntax error. Command unrecognized. */
3938  case 501: /* Syntax error. Error in parameters or arguments. */
3939  case 502: /* Command not implemented. */
3940  case 503: /* Bad sequence of commands. */
3941  case 504: /* Command not implemented for that parameter. */
3942  case 532: /* Need account for storing files */
3943  case 550: /* File action not taken. File not found or no access. */
3944  case 551: /* Requested action aborted. Page type unknown */
3945  case 552: /* Action aborted. Exceeded storage allocation */
3946  case 553: /* Action not taken. File name not allowed. */
3947 
3948  default:
3950  break;
3951  }
3952 
3953  INTERNET_SetLastError(dwCode);
3954  return dwCode;
3955 }
#define ERROR_INTERNET_INCORRECT_HANDLE_TYPE
Definition: wininet.h:2007
PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER pAddr
BOOL WINAPI CreateUrlCacheEntryW(LPCWSTR lpszUrlName, DWORD dwExpectedFileSize, LPCWSTR lpszFileExtension, LPWSTR lpszFileName, DWORD dwReserved)
Definition: urlcache.c:2815
Definition: winsock.h:66
static BOOL FTP_SendPort(ftp_session_t *)
Definition: ftp.c:3088
static BOOL FTP_DoPassive(ftp_session_t *)
Definition: ftp.c:3131
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static LPSTR FTP_GetNextLine(INT nSocket, LPDWORD dwLen)
Definition: ftp.c:2640
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD flags
Definition: ftp.c:1460
#define ERROR_INTERNET_CONNECTION_ABORTED
Definition: wininet.h:2019
BOOL WINAPI FtpCreateDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory)
Definition: ftp.c:566
DWORD nFileSizeHigh
Definition: winbase.h:937
#define CloseHandle
Definition: compat.h:598
static BOOL FTP_SendType(ftp_session_t *, DWORD dwType)
Definition: ftp.c:3006
char hdr[14]
Definition: iptest.cpp:33
static LPWSTR heap_strndupW(LPCWSTR str, unsigned len)
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static BOOL FTP_ConnectToHost(ftp_session_t *)
Definition: ftp.c:2597
static void AsyncFtpDeleteFileProc(task_header_t *hdr)
Definition: ftp.c:1793
BOOL WINAPI FtpGetFileA(HINTERNET hInternet, LPCSTR lpszRemoteFile, LPCSTR lpszNewFile, BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, DWORD_PTR dwContext)
Definition: ftp.c:1559
#define ERROR_SUCCESS
Definition: deptool.c:10
int data
Definition: ftp.c:70
BOOL WINAPI FtpRenameFileA(HINTERNET hFtpSession, LPCSTR lpszSrc, LPCSTR lpszDest)
Definition: ftp.c:2067
static DWORD FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD size, DWORD *written)
Definition: ftp.c:1215
void INTERNET_SetLastError(DWORD dwError)
Definition: internet.c:3837
#define WideCharToMultiByte
Definition: compat.h:111
HINTERNET WINAPI FtpFindFirstFileW(HINTERNET hConnect, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:757
#define error(str)
Definition: mkdosfs.c:1605
BOOL WINAPI FtpGetFileW(HINTERNET hInternet, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile, BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, DWORD_PTR dwContext)
Definition: ftp.c:1610
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static DWORD FTP_SetResponseError(DWORD dwResponse)
Definition: ftp.c:3915
#define ERROR_INTERNET_EXTENDED_ERROR
Definition: wininet.h:1992
DWORD dwStructSize
Definition: wininet.h:211
#define ERROR_INTERNET_DISCONNECTED
Definition: wininet.h:2072
WORD wMonth
Definition: winbase.h:900
Definition: http.c:7251
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: ftp_var.h:139
#define TRUE
Definition: types.h:120
static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam, INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext)
Definition: ftp.c:2692
WCHAR * dst_file
Definition: ftp.c:2084
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
static const object_vtbl_t FTPFILEVtbl
Definition: ftp.c:1295
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define CP_ACP
Definition: compat.h:109
WCHAR * remote_file
Definition: ftp.c:243
static BOOL FTP_InitListenSocket(ftp_session_t *)
Definition: ftp.c:2946
BOOL WINAPI FtpPutFileW(HINTERNET hConnect, LPCWSTR lpszLocalFile, LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:272
#define INTERNET_STATUS_REQUEST_SENT
Definition: wininet.h:888
LPSTR INTERNET_GetResponseBuffer(void)
Definition: internet.c:3937
#define HKEY_CURRENT_USER
Definition: winreg.h:11
struct sockaddr_in socketAddress
Definition: ftp.c:81
WCHAR * file_name
Definition: ftp.c:1458
char CHAR
Definition: xmlstorage.h:175
LPWSTR lpszUserName
Definition: ftp.c:86
HINTERNET WINAPI FtpOpenFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:1485
LPWSTR servername
Definition: ftp.c:83
#define WARN(fmt,...)
Definition: debug.h:112
BOOL WINAPI FtpSetCurrentDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory)
Definition: ftp.c:456
#define INTERNET_STATUS_CONNECTING_TO_SERVER
Definition: wininet.h:885
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
static BOOL res_to_le(DWORD res)
Definition: ftp.c:207
WCHAR * remote_file
Definition: ftp.c:1578
DWORD INET_SetOption(object_header_t *hdr, DWORD option, void *buf, DWORD size)
Definition: internet.c:2753
static BOOL FTP_FtpPutFileW(ftp_session_t *, LPCWSTR lpszLocalFile, LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:344
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
unsigned short permissions
Definition: ftp.c:95
struct list children
Definition: internet.h:286
struct FILEPROPERTIESW * LPFILEPROPERTIESW
DWORD_PTR context
Definition: ftp.c:733
#define ERROR_INTERNET_ITEM_NOT_FOUND
Definition: wininet.h:2017
#define INTERNET_OPEN_TYPE_PROXY
Definition: wininet.h:523
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1664
ftp_file_t * download_in_progress
Definition: ftp.c:80
#define ioctlsocket
Definition: ncftp.h:481
GLuint buffer
Definition: glext.h:5915
_In_opt_ LPSTR _In_opt_ LPSTR lpszPassword
Definition: winbase.h:2690
HINTERNET WINAPI FtpFindFirstFileA(HINTERNET hConnect, LPCSTR lpszSearchFile, LPWIN32_FIND_DATAA lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:709
LPFILEPROPERTIESW lpafp
Definition: ftp.c:104
#define closesocket
Definition: ncftp.h:477
task_header_t hdr
Definition: ftp.c:241
WIN32_FIND_DATAW * find_file_data
Definition: ftp.c:731
WIN32_FIND_DATAW * find_data
Definition: ftp.c:3479
static void AsyncFtpFindFirstFileProc(task_header_t *hdr)
Definition: ftp.c:736
static void FTPFINDNEXT_Destroy(object_header_t *hdr)
Definition: ftp.c:3428
__u16 time
Definition: mkdosfs.c:366
#define swprintf
Definition: precomp.h:40
static const CHAR *const szFtpCommands[]
Definition: ftp.c:142
#define FD_ZERO(set)
Definition: winsock.h:96
char * LPSTR
Definition: xmlstorage.h:182
task_header_t hdr
Definition: ftp.c:3478
const char * filename
Definition: ioapi.h:135
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define FD_SET(fd, set)
Definition: winsock.h:89
#define lstrlenW
Definition: compat.h:609
DWORD * directory_len
Definition: ftp.c:948
LPWSTR lpszHostName
Definition: wininet.h:215
GLint namelen
Definition: glext.h:7232
static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif)
Definition: ftp.c:1226
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
int32_t INT
Definition: typedefs.h:58
static BOOLEAN bSuccess
Definition: drive.cpp:432
static DWORD FTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
Definition: ftp.c:2379
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength) DECLSPEC_HIDDEN
static BOOL FTP_FtpCreateDirectoryW(ftp_session_t *, LPCWSTR lpszDirectory)
Definition: ftp.c:661
static const WCHAR szSpace[]
Definition: msipriv.h:1110
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static int find_data(const struct Vector *v, const BYTE *pData, int size)
Definition: filtermapper.c:162
#define INTERNET_INVALID_PORT_NUMBER
Definition: wininet.h:36
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD_PTR dwContext
Definition: internet.h:278
#define INTERNET_STATUS_CONNECTION_CLOSED
Definition: wininet.h:894
BOOL WINAPI FtpCreateDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory)
Definition: ftp.c:599
struct sockaddr_in lstnSocketAddress
Definition: ftp.c:82
#define lstrcpynW
Definition: compat.h:597
#define ERROR_INTERNET_CANNOT_CONNECT
Definition: wininet.h:2018
task_header_t hdr
Definition: ftp.c:729
static BOOL FTP_SendData(ftp_session_t *, INT nDataSocket, HANDLE hFile)
Definition: ftp.c:3263
DWORD_PTR context
Definition: ftp.c:1583
DWORD_PTR context
Definition: ftp.c:1461
WCHAR * new_file
Definition: ftp.c:1579
WORD INTERNET_PORT
Definition: winhttp.h:38
HINTERNET WINAPI FtpOpenFileA(HINTERNET hFtpSession, LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:1443
static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData)
Definition: ftp.c:3589
#define sprintf(buf, format,...)
Definition: sprintf.c:55
HANDLE cache_file_handle
Definition: ftp.c:70
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
Definition: ftp.c:63
static INT FTP_ReceiveResponse(ftp_session_t *, DWORD_PTR dwContext)
Definition: ftp.c:2766
WORD wYear
Definition: winbase.h:899
DWORD nFileSizeLow
Definition: winbase.h:938
static BOOL FTP_SendStore(ftp_session_t *, LPCWSTR lpszRemoteFile, DWORD dwType)
Definition: ftp.c:2899
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
#define MAX_REPLY_LEN
Definition: request.c:2568
#define FALSE
Definition: types.h:117
DWORD WINAPI FtpGetFileSize(HINTERNET hFile, LPDWORD lpdwFileSizeHigh)
Definition: ftp.c:1757
BOOL WINAPI FtpCommandA(HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags, LPCSTR lpszCommand, DWORD_PTR dwContext, HINTERNET *phFtpCommand)
Definition: ftp.c:2218
INTERNET_PORT nPort
Definition: wininet.h:217
BOOL WINAPI FtpRemoveDirectoryA(HINTERNET hFtpSession, LPCSTR lpszDirectory)
Definition: ftp.c:1924
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
BOOL GetAddress(const WCHAR *, INTERNET_PORT, SOCKADDR *, int *, char *) DECLSPEC_HIDDEN
Definition: utility.c:133
#define INTERNET_STATUS_CLOSING_CONNECTION
Definition: wininet.h:893
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3296
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
DWORD INTERNET_GetLastError(void)
Definition: internet.c:3858
DWORD accessType
Definition: internet.h:297
#define FIXME(fmt,...)
Definition: debug.h:111
BOOL WINAPI FtpGetCurrentDirectoryA(HINTERNET hFtpSession, LPSTR lpszCurrentDirectory, LPDWORD lpdwCurrentDirectory)
Definition: ftp.c:916
static BOOL FTP_SendPassword(ftp_session_t *)
Definition: ftp.c:2829
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI FtpRenameFileW(HINTERNET hFtpSession, LPCWSTR lpszSrc, LPCWSTR lpszDest)
Definition: ftp.c:2109
static void FTPSESSION_CloseConnection(object_header_t *hdr)
Definition: ftp.c:2354
WCHAR * search_file
Definition: ftp.c:730
DWORD_PTR context
Definition: ftp.c:245
struct WININETFTPFINDNEXTW * LPWININETFTPFINDNEXTW
WORD wMinute
Definition: winbase.h:904
static DWORD_PTR
Definition: ftp.c:44
static WCHAR available[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2336
Definition: getopt.h:108
#define INTERNET_STATUS_RECEIVING_RESPONSE
Definition: wininet.h:889
object_header_t * WININET_AddRef(object_header_t *info)
Definition: internet.c:169
WCHAR lpszDest[260]
SYSTEMTIME tmLastModified
Definition: ftp.c:94
static BOOL FTP_SendPortOrPasv(ftp_session_t *)
Definition: ftp.c:3203
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
static UINT set(struct ID3DXConstantTableImpl *table, IDirect3DDevice9 *device, struct ctab_constant *constant, const void **indata, D3DXPARAMETER_TYPE intype, UINT *size, UINT incol, D3DXPARAMETER_CLASS inclass, UINT index, BOOL is_pointer)
Definition: shader.c:1102
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
unsigned int dir
Definition: maze.c:112
const char * LPCSTR
Definition: xmlstorage.h:183
static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:1317
ftp_session_t * lpFtpSession
Definition: ftp.c:66
#define isdigit(c)
Definition: acclib.h:68
static WCHAR * heap_strdupAtoW(const char *str)
Definition: appwiz.h:80
int pasvSocket
Definition: ftp.c:79
task_header_t hdr
Definition: ftp.c:1457
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define OPEN_EXISTING
Definition: compat.h:634
WCHAR * file_name
Definition: ftp.c:1790
static void AsyncFtpRenameFileProc(task_header_t *hdr)
Definition: ftp.c:2087
static BOOL FTP_FtpRemoveDirectoryW(ftp_session_t *, LPCWSTR lpszDirectory)
Definition: ftp.c:2018
static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx)
Definition: ftp.c:1255
_Check_return_ _CRTIMP int __cdecl stricmp(_In_z_ const char *_Str1, _In_z_ const char *_Str2)
static BOOL FTP_RetrieveFileData(ftp_session_t *, INT nDataSocket, HANDLE hFile)
Definition: ftp.c:3389
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
static void FTPFINDNEXT_AsyncFindNextFileProc(task_header_t *hdr)
Definition: ftp.c:3482
FTP_COMMAND
Definition: ftp.c:116
#define INTERNET_STATUS_NAME_RESOLVED
Definition: wininet.h:884
task_header_t hdr
Definition: ftp.c:1577
static BOOL FTP_FtpSetCurrentDirectoryW(ftp_session_t *, LPCWSTR lpszDirectory)
Definition: ftp.c:516
DWORD INET_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
Definition: internet.c:2654
object_header_t hdr
Definition: ftp.c:65
GLfloat f
Definition: glext.h:7540
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
#define TRACE(s)
Definition: solgame.cpp:4
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
GLsizeiptr size
Definition: glext.h:5919
object_header_t hdr
Definition: ftp.c:75
#define INTERNET_OPTION_HANDLE_TYPE
Definition: wininet.h:710
INTERNET_PORT serverport
Definition: ftp.c:84
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
BOOL WINAPI FtpSetCurrentDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory)
Definition: ftp.c:419
BOOL WINAPI GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
Definition: fileinfo.c:458
LPWSTR lpszName
Definition: ftp.c:92
int nDataSocket
Definition: ftp.c:68
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
LPWSTR lpszPassword
Definition: ftp.c:85
static const WCHAR url[]
Definition: encode.c:1432
static char * heap_strdupWtoA(const WCHAR *str)
BOOL WINAPI FtpPutFileA(HINTERNET hConnect, LPCSTR lpszLocalFile, LPCSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:224
static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW fileprop)
Definition: ftp.c:3626
struct list entry
Definition: internet.h:285
INTERNET_SCHEME nScheme
Definition: wininet.h:214
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
BOOL session_deleted
Definition: ftp.c:67
#define INTERNET_HANDLE_TYPE_FTP_FILE
Definition: wininet.h:808
static BOOL FTP_FtpGetFileW(ftp_session_t *, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile, BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, DWORD_PTR dwContext)
Definition: ftp.c:1687
unsigned long DWORD
Definition: ntddk_ex.h:95
int socklen_t
Definition: tcp.c:35
#define ERROR_INTERNET_NAME_NOT_RESOLVED
Definition: wininet.h:1996
static const CHAR szMonths[]
Definition: ftp.c:165
WCHAR cFileName[MAX_PATH]
Definition: winbase.h:941
#define ERROR_FTP_TRANSFER_IN_PROGRESS
Definition: wininet.h:2046
#define INTERNET_DEFAULT_FTP_PORT
Definition: wininet.h:38
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
task_header_t hdr
Definition: ftp.c:1789
LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch)
Definition: string.c:355
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define szCRLF
Definition: ftp.c:108
GLbitfield flags
Definition: glext.h:7161
WORD wSecond
Definition: winbase.h:905
DWORD_PTR dwResult
Definition: wininet.h:155
LPWSTR proxy
Definition: internet.h:293
BOOL WINAPI FtpGetCurrentDirectoryW(HINTERNET hFtpSession, LPWSTR lpszCurrentDirectory, LPDWORD lpdwCurrentDirectory)
Definition: ftp.c:971
FILETIME ftLastWriteTime
Definition: winbase.h:936
object_header_t * hdr
Definition: internet.h:390
#define INTERNET_FLAG_ASYNC
Definition: wininet.h:64
int ret
DWORD flags
Definition: ftp.c:244
static void AsyncFtpPutFileProc(task_header_t *hdr)
Definition: ftp.c:248
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
LPWSTR lpszUserName
Definition: wininet.h:218
#define INTERNET_FLAG_TRANSFER_ASCII
Definition: wininet.h:90
static const WCHAR L[]
Definition: oid.c:1250
static BOOL FTP_GetDataSocket(ftp_session_t *, LPINT nDataSocket)
Definition: ftp.c:3232
BOOL WINAPI FtpRemoveDirectoryW(HINTERNET hFtpSession, LPCWSTR lpszDirectory)
Definition: ftp.c:1956
WCHAR * src_file
Definition: ftp.c:2083
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
LPWSTR lpszUrlPath
Definition: wininet.h:222
HKEY key
Definition: reg.c:42
#define INTERNET_STATUS_SENDING_REQUEST
Definition: wininet.h:887
void * alloc_object(object_header_t *parent, const object_vtbl_t *vtbl, size_t size)
Definition: internet.c:103
static BOOL FTP_ParseDirectory(ftp_session_t *, INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW *lpafp, LPDWORD dwfp)
Definition: ftp.c:3787
static void WININET_find_data_WtoA(LPWIN32_FIND_DATAW dataW, LPWIN32_FIND_DATAA dataA)
Definition: internet.h:214
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
DWORD nSize
Definition: ftp.c:93
#define INTERNET_STATUS_RESOLVING_NAME
Definition: wininet.h:883
WCHAR * directory
Definition: ftp.c:432
FILETIME ftLastAccessTime
Definition: winbase.h:935
#define INTERNET_HANDLE_TYPE_CONNECT_FTP
Definition: wininet.h:803
void * alloc_async_task(object_header_t *hdr, async_task_proc_t proc, size_t size)
Definition: internet.c:3894
#define GENERIC_READ
Definition: compat.h:135
#define wcsrchr
Definition: compat.h:16
task_header_t hdr
Definition: ftp.c:946
uint32_t DWORD_PTR
Definition: typedefs.h:65
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
_In_ HANDLE hFile
Definition: mswsock.h:90
static BOOL FTP_SendAccount(ftp_session_t *)
Definition: ftp.c:2869
#define ERROR_INTERNET_TIMEOUT
Definition: wininet.h:1991
unsigned char BYTE
Definition: xxhash.c:193
HINTERNET hInternet
Definition: internet.h:275
static const object_vtbl_t FTPFINDNEXTVtbl
Definition: ftp.c:3524
int sndSocket
Definition: ftp.c:77
static DWORD FTPFILE_LockRequestFile(object_header_t *hdr, req_file_t **ret)
Definition: ftp.c:1288
WCHAR * cache_file
Definition: ftp.c:69
static BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESW lpfp)
Definition: ftp.c:3852
static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read, DWORD flags, DWORD_PTR context)
Definition: ftp.c:1190
BOOL WININET_Release(object_header_t *info)
Definition: internet.c:211
struct in_addr sin_addr
Definition: winsock.h:512
#define DATA_PACKET_SIZE
Definition: ftp.c:107
#define ERR(fmt,...)
Definition: debug.h:110
static void AsyncFtpGetCurrentDirectoryProc(task_header_t *hdr)
Definition: ftp.c:951
#define INTERNET_ERROR_BASE
Definition: wininet.h:1988
WORD wDay
Definition: winbase.h:902
#define INTERNET_FLAG_PASSIVE
Definition: wininet.h:65
object_header_t hdr
Definition: internet.h:291
DWORD dwInternalFlags
Definition: internet.h:281
#define CREATE_ALWAYS
Definition: disk.h:72
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
static int sock_send(int fd, const void *msg, size_t len, int flags)
Definition: net.c:38
BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags, LPWSTR lpszUrl, LPDWORD lpdwUrlLength)
Definition: internet.c:4425
DWORD local_attr
Definition: ftp.c:1581
static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
Definition: ftp.c:814
#define ERROR_INTERNET_LOGIN_FAILURE
Definition: wininet.h:2004
BOOL WINAPI FtpDeleteFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName)
Definition: ftp.c:1814
#define FTP_TRANSFER_TYPE_BINARY
Definition: wininet.h:919
task_header_t hdr
Definition: ftp.c:2082
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
#define lstrcpyW
Definition: compat.h:608
static BOOL FTP_FtpDeleteFileW(ftp_session_t *, LPCWSTR lpszFileName)
Definition: ftp.c:1876
int lstnSocket
Definition: ftp.c:78
__kernel_time_t time_t
Definition: linux.h:252
#define byte(x, n)
Definition: tomcrypt.h:118
#define INTERNET_STATUS_REQUEST_COMPLETE
Definition: wininet.h:898
#define ARRAY_SIZE(a)
Definition: main.h:24
task_header_t hdr
Definition: ftp.c:431
static void FTPFILE_AsyncQueryDataAvailableProc(task_header_t *task)
Definition: ftp.c:1248
WCHAR * directory
Definition: ftp.c:947
#define INET_OPENURL
Definition: internet.h:243
static BOOL FTP_FtpRenameFileW(ftp_session_t *, LPCWSTR lpszSrc, LPCWSTR lpszDest)
Definition: ftp.c:2172
WORD wHour
Definition: winbase.h:903
object_header_t hdr
Definition: ftp.c:100
static const object_vtbl_t FTPSESSIONVtbl
Definition: ftp.c:2396
#define ReadFile(a, b, c, d, e)
Definition: compat.h:601
#define INTERNET_STATUS_CONNECTED_TO_SERVER
Definition: wininet.h:886
#define min(a, b)
Definition: monoChain.cc:55
BOOL WINAPI FtpCommandW(HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags, LPCWSTR lpszCommand, DWORD_PTR dwContext, HINTERNET *phFtpCommand)
Definition: ftp.c:2254
#define NULL
Definition: types.h:112
DWORD dwFileAttributes
Definition: winbase.h:933
static void AsyncFtpSetCurrentDirectoryProc(task_header_t *hdr)
Definition: ftp.c:435
DWORD access
Definition: ftp.c:1459
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
static DWORD FTPFINDNEXT_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
Definition: ftp.c:3489
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define MAX_BACKLOG
Definition: ftp.c:109
#define CreateFileW
Definition: compat.h:600
static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam, INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext)
Definition: ftp.c:2746
static DWORD FTPFILE_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
Definition: ftp.c:1142
static DWORD FTPFINDNEXT_FindNextFileW(object_header_t *hdr, void *data)
Definition: ftp.c:3506
BOOL WINAPI PathMatchSpecW(LPCWSTR lpszPath, LPCWSTR lpszMask)
Definition: path.c:1963
static TAGID TAGID find
Definition: db.cpp:155
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
Definition: name.c:38
#define RESPONSE_TIMEOUT
Definition: ftp.c:59
GLuint res
Definition: glext.h:9613
uint32_t * LPDWORD
Definition: typedefs.h:59
DWORD INTERNET_AsyncCall(task_header_t *task)
Definition: internet.c:3915
#define INET6_ADDRSTRLEN
Definition: ws2ipdef.h:132
WINE_DEFAULT_DEBUG_CHANNEL(urlmon)
unsigned int ULONG
Definition: retypes.h:1
#define AF_INET
Definition: tcpip.h:117
static void FTPSESSION_Destroy(object_header_t *hdr)
Definition: ftp.c:2341
#define FTP_CONDITION_MASK
Definition: ftp.c:114
WCHAR * local_file
Definition: ftp.c:242
static void AsyncFtpOpenFileProc(task_header_t *hdr)
Definition: ftp.c:1464
INTERNET_STATUS_CALLBACK lpfnStatusCB
Definition: internet.h:284
BOOL bIsDirectory
Definition: ftp.c:91
#define CREATE_NEW
Definition: disk.h:69
#define INTERNET_STATUS_HANDLE_CREATED
Definition: wininet.h:895
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static BOOL FTP_SendRetrieve(ftp_session_t *, LPCWSTR lpszRemoteFile, DWORD dwType)
Definition: ftp.c:3343
#define SOCK_STREAM
Definition: tcpip.h:118
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
FILETIME ftCreationTime
Definition: winbase.h:934
static HINTERNET FTP_ReceiveFileList(ftp_session_t *, INT nSocket, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext)
Definition: ftp.c:3545
#define htons(x)
Definition: module.h:213
appinfo_t * lpAppInfo
Definition: ftp.c:76
static HINTERNET *static INTERNET_STATUS_CALLBACK
Definition: ftp.c:45
#define INTERNET_OPTION_DATAFILE_NAME
Definition: wininet.h:727