#include "config.h"
#include "wine/port.h"
+#if defined(__MINGW32__) || defined (_MSC_VER)
+#include <ws2tcpip.h>
+#endif
+
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
#include <time.h>
#include <assert.h>
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
-typedef struct _WININETFTPSESSIONW WININETFTPSESSIONW;
+typedef struct _ftp_session_t ftp_session_t;
typedef struct
{
- WININETHANDLEHEADER hdr;
- WININETFTPSESSIONW *lpFtpSession;
+ object_header_t hdr;
+ ftp_session_t *lpFtpSession;
BOOL session_deleted;
int nDataSocket;
-} WININETFTPFILE, *LPWININETFTPFILE;
+ WCHAR *cache_file;
+ HANDLE cache_file_handle;
+} ftp_file_t;
-typedef struct _WININETFTPSESSIONW
+struct _ftp_session_t
{
- WININETHANDLEHEADER hdr;
- WININETAPPINFOW *lpAppInfo;
+ object_header_t hdr;
+ appinfo_t *lpAppInfo;
int sndSocket;
int lstnSocket;
int pasvSocket; /* data socket connected by us in case of passive FTP */
- LPWININETFTPFILE download_in_progress;
+ ftp_file_t *download_in_progress;
struct sockaddr_in socketAddress;
struct sockaddr_in lstnSocketAddress;
+ LPWSTR servername;
+ INTERNET_PORT serverport;
LPWSTR lpszPassword;
LPWSTR lpszUserName;
-} *LPWININETFTPSESSIONW;
+};
typedef struct
{
BOOL bIsDirectory;
LPWSTR lpszName;
DWORD nSize;
- struct tm tmLastModified;
+ SYSTEMTIME tmLastModified;
unsigned short permissions;
} FILEPROPERTIESW, *LPFILEPROPERTIESW;
typedef struct
{
- WININETHANDLEHEADER hdr;
- WININETFTPSESSIONW *lpFtpSession;
+ object_header_t hdr;
+ ftp_session_t *lpFtpSession;
DWORD index;
DWORD size;
LPFILEPROPERTIESW lpafp;
static const WCHAR szNoAccount[] = {'n','o','a','c','c','o','u','n','t','\0'};
static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam,
- INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext);
-static BOOL FTP_SendStore(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType);
-static BOOL FTP_GetDataSocket(LPWININETFTPSESSIONW lpwfs, LPINT nDataSocket);
-static BOOL FTP_SendData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile);
-static INT FTP_ReceiveResponse(LPWININETFTPSESSIONW lpwfs, DWORD_PTR dwContext);
-static BOOL FTP_SendRetrieve(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType);
-static BOOL FTP_RetrieveFileData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile);
-static BOOL FTP_InitListenSocket(LPWININETFTPSESSIONW lpwfs);
-static BOOL FTP_ConnectToHost(LPWININETFTPSESSIONW lpwfs);
-static BOOL FTP_SendPassword(LPWININETFTPSESSIONW lpwfs);
-static BOOL FTP_SendAccount(LPWININETFTPSESSIONW lpwfs);
-static BOOL FTP_SendType(LPWININETFTPSESSIONW lpwfs, DWORD dwType);
-static BOOL FTP_SendPort(LPWININETFTPSESSIONW lpwfs);
-static BOOL FTP_DoPassive(LPWININETFTPSESSIONW lpwfs);
-static BOOL FTP_SendPortOrPasv(LPWININETFTPSESSIONW lpwfs);
+ INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext);
+static BOOL FTP_SendStore(ftp_session_t*, LPCWSTR lpszRemoteFile, DWORD dwType);
+static BOOL FTP_GetDataSocket(ftp_session_t*, LPINT nDataSocket);
+static BOOL FTP_SendData(ftp_session_t*, INT nDataSocket, HANDLE hFile);
+static INT FTP_ReceiveResponse(ftp_session_t*, DWORD_PTR dwContext);
+static BOOL FTP_SendRetrieve(ftp_session_t*, LPCWSTR lpszRemoteFile, DWORD dwType);
+static BOOL FTP_RetrieveFileData(ftp_session_t*, INT nDataSocket, HANDLE hFile);
+static BOOL FTP_InitListenSocket(ftp_session_t*);
+static BOOL FTP_ConnectToHost(ftp_session_t*);
+static BOOL FTP_SendPassword(ftp_session_t*);
+static BOOL FTP_SendAccount(ftp_session_t*);
+static BOOL FTP_SendType(ftp_session_t*, DWORD dwType);
+static BOOL FTP_SendPort(ftp_session_t*);
+static BOOL FTP_DoPassive(ftp_session_t*);
+static BOOL FTP_SendPortOrPasv(ftp_session_t*);
static BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESW lpfp);
static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW fileprop);
-static BOOL FTP_ParseDirectory(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
+static BOOL FTP_ParseDirectory(ftp_session_t*, INT nSocket, LPCWSTR lpszSearchFile,
LPFILEPROPERTIESW *lpafp, LPDWORD dwfp);
-static HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
+static HINTERNET FTP_ReceiveFileList(ftp_session_t*, INT nSocket, LPCWSTR lpszSearchFile,
LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext);
static DWORD FTP_SetResponseError(DWORD dwResponse);
static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData);
-static BOOL FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
+static BOOL FTP_FtpPutFileW(ftp_session_t*, LPCWSTR lpszLocalFile,
LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext);
-static BOOL FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
-static BOOL FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
-static HINTERNET FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs,
+static BOOL FTP_FtpSetCurrentDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory);
+static BOOL FTP_FtpCreateDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory);
+static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t*,
LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext);
-static BOOL FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory,
+static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t*, LPWSTR lpszCurrentDirectory,
LPDWORD lpdwCurrentDirectory);
-static BOOL FTP_FtpRenameFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest);
-static BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
-static BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName);
-static HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName,
- DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext);
-static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
+static BOOL FTP_FtpRenameFileW(ftp_session_t*, LPCWSTR lpszSrc, LPCWSTR lpszDest);
+static BOOL FTP_FtpRemoveDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory);
+static BOOL FTP_FtpDeleteFileW(ftp_session_t*, LPCWSTR lpszFileName);
+static BOOL FTP_FtpGetFileW(ftp_session_t*, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
DWORD_PTR dwContext);
+/* A temporary helper until we get rid of INTERNET_GetLastError calls */
+static BOOL res_to_le(DWORD res)
+{
+ if(res != ERROR_SUCCESS)
+ INTERNET_SetLastError(res);
+ return res == ERROR_SUCCESS;
+}
/***********************************************************************
* FtpPutFileA (WININET.@)
LPWSTR lpwzNewRemoteFile;
BOOL ret;
- lpwzLocalFile = lpszLocalFile?WININET_strdup_AtoW(lpszLocalFile):NULL;
- lpwzNewRemoteFile = lpszNewRemoteFile?WININET_strdup_AtoW(lpszNewRemoteFile):NULL;
+ lpwzLocalFile = heap_strdupAtoW(lpszLocalFile);
+ lpwzNewRemoteFile = heap_strdupAtoW(lpszNewRemoteFile);
ret = FtpPutFileW(hConnect, lpwzLocalFile, lpwzNewRemoteFile,
dwFlags, dwContext);
HeapFree(GetProcessHeap(), 0, lpwzLocalFile);
static void AsyncFtpPutFileProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPPUTFILEW const *req = &workRequest->u.FtpPutFileW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
BOOL WINAPI FtpPutFileW(HINTERNET hConnect, LPCWSTR lpszLocalFile,
LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
if (!lpszLocalFile || !lpszNewRemoteFile)
return FALSE;
}
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hConnect );
if (!lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
workRequest.asyncproc = AsyncFtpPutFileProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
- req->lpszLocalFile = WININET_strdupW(lpszLocalFile);
- req->lpszNewRemoteFile = WININET_strdupW(lpszNewRemoteFile);
+ req->lpszLocalFile = heap_strdupW(lpszLocalFile);
+ req->lpszNewRemoteFile = heap_strdupW(lpszNewRemoteFile);
req->dwFlags = dwFlags;
req->dwContext = dwContext;
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-static BOOL FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
+static BOOL FTP_FtpPutFileW(ftp_session_t *lpwfs, LPCWSTR lpszLocalFile,
LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext)
{
HANDLE hFile;
BOOL bSuccess = FALSE;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
INT nResCode;
TRACE(" lpszLocalFile(%s) lpszNewRemoteFile(%s)\n", debugstr_w(lpszLocalFile), debugstr_w(lpszNewRemoteFile));
}
if (lpwfs->lstnSocket != -1)
+ {
closesocket(lpwfs->lstnSocket);
+ lpwfs->lstnSocket = -1;
+ }
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
{
LPWSTR lpwzDirectory;
BOOL ret;
- lpwzDirectory = lpszDirectory?WININET_strdup_AtoW(lpszDirectory):NULL;
+ lpwzDirectory = heap_strdupAtoW(lpszDirectory);
ret = FtpSetCurrentDirectoryW(hConnect, lpwzDirectory);
HeapFree(GetProcessHeap(), 0, lpwzDirectory);
return ret;
static void AsyncFtpSetCurrentDirectoryProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPSETCURRENTDIRECTORYW const *req = &workRequest->u.FtpSetCurrentDirectoryW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
*/
BOOL WINAPI FtpSetCurrentDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory)
{
- LPWININETFTPSESSIONW lpwfs = NULL;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs = NULL;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
if (!lpszDirectory)
goto lend;
}
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hConnect );
if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
workRequest.asyncproc = AsyncFtpSetCurrentDirectoryProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpSetCurrentDirectoryW;
- req->lpszDirectory = WININET_strdupW(lpszDirectory);
+ req->lpszDirectory = heap_strdupW(lpszDirectory);
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-static BOOL FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
+static BOOL FTP_FtpSetCurrentDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirectory)
{
INT nResCode;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
DWORD bSuccess = FALSE;
TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory));
LPWSTR lpwzDirectory;
BOOL ret;
- lpwzDirectory = lpszDirectory?WININET_strdup_AtoW(lpszDirectory):NULL;
+ lpwzDirectory = heap_strdupAtoW(lpszDirectory);
ret = FtpCreateDirectoryW(hConnect, lpwzDirectory);
HeapFree(GetProcessHeap(), 0, lpwzDirectory);
return ret;
static void AsyncFtpCreateDirectoryProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPCREATEDIRECTORYW const *req = &workRequest->u.FtpCreateDirectoryW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE(" %p\n", lpwfs);
*/
BOOL WINAPI FtpCreateDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hConnect );
if (!lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
workRequest.asyncproc = AsyncFtpCreateDirectoryProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpCreateDirectoryW;
- req->lpszDirectory = WININET_strdupW(lpszDirectory);
+ req->lpszDirectory = heap_strdupW(lpszDirectory);
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-static BOOL FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
+static BOOL FTP_FtpCreateDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirectory)
{
INT nResCode;
BOOL bSuccess = FALSE;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory));
LPWIN32_FIND_DATAW lpFindFileDataW;
HINTERNET ret;
- lpwzSearchFile = lpszSearchFile?WININET_strdup_AtoW(lpszSearchFile):NULL;
+ lpwzSearchFile = heap_strdupAtoW(lpszSearchFile);
lpFindFileDataW = lpFindFileData?&wfd:NULL;
ret = FtpFindFirstFileW(hConnect, lpwzSearchFile, lpFindFileDataW, dwFlags, dwContext);
HeapFree(GetProcessHeap(), 0, lpwzSearchFile);
- if(lpFindFileData) {
+ if (ret && lpFindFileData)
WININET_find_data_WtoA(lpFindFileDataW, lpFindFileData);
- }
+
return ret;
}
static void AsyncFtpFindFirstFileProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPFINDFIRSTFILEW const *req = &workRequest->u.FtpFindFirstFileW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
HINTERNET WINAPI FtpFindFirstFileW(HINTERNET hConnect,
LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
HINTERNET r = NULL;
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hConnect );
if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
workRequest.asyncproc = AsyncFtpFindFirstFileProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpFindFirstFileW;
- req->lpszSearchFile = (lpszSearchFile == NULL) ? NULL : WININET_strdupW(lpszSearchFile);
+ req->lpszSearchFile = (lpszSearchFile == NULL) ? NULL : heap_strdupW(lpszSearchFile);
req->lpFindFileData = lpFindFileData;
req->dwFlags = dwFlags;
req->dwContext= dwContext;
* NULL on failure
*
*/
-static HINTERNET FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs,
+static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs,
LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext)
{
INT nResCode;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
HINTERNET hFindNext = NULL;
TRACE("\n");
lend:
if (lpwfs->lstnSocket != -1)
+ {
closesocket(lpwfs->lstnSocket);
+ lpwfs->lstnSocket = -1;
+ }
hIC = lpwfs->lpAppInfo;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
if (hFindNext)
{
- iar.dwResult = (DWORD)hFindNext;
+ iar.dwResult = (DWORD_PTR)hFindNext;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
- iar.dwResult = (DWORD)hFindNext;
+ iar.dwResult = (DWORD_PTR)hFindNext;
iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
&iar, sizeof(INTERNET_ASYNC_RESULT));
static void AsyncFtpGetCurrentDirectoryProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPGETCURRENTDIRECTORYW const *req = &workRequest->u.FtpGetCurrentDirectoryW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
BOOL WINAPI FtpGetCurrentDirectoryW(HINTERNET hFtpSession, LPWSTR lpszCurrentDirectory,
LPDWORD lpdwCurrentDirectory)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
TRACE("%p %p %p\n", hFtpSession, lpszCurrentDirectory, lpdwCurrentDirectory);
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession );
if (NULL == lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
req->lpszDirectory = lpszCurrentDirectory;
req->lpdwDirectory = lpdwCurrentDirectory;
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-static BOOL FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory,
+static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t *lpwfs, LPWSTR lpszCurrentDirectory,
LPDWORD lpdwCurrentDirectory)
{
INT nResCode;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
DWORD bSuccess = FALSE;
/* Clear any error information */
if (nResCode == 257) /* Extract directory name */
{
DWORD firstpos, lastpos, len;
- LPWSTR lpszResponseBuffer = WININET_strdup_AtoW(INTERNET_GetResponseBuffer());
+ LPWSTR lpszResponseBuffer = heap_strdupAtoW(INTERNET_GetResponseBuffer());
for (firstpos = 0, lastpos = 0; lpszResponseBuffer[lastpos]; lastpos++)
{
return bSuccess;
}
-/***********************************************************************
- * FtpOpenFileA (WININET.@)
- *
- * Open a remote file for writing or reading
- *
- * RETURNS
- * HINTERNET handle on success
- * NULL on failure
- *
- */
-HINTERNET WINAPI FtpOpenFileA(HINTERNET hFtpSession,
- LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
- DWORD_PTR dwContext)
-{
- LPWSTR lpwzFileName;
- HINTERNET ret;
-
- lpwzFileName = lpszFileName?WININET_strdup_AtoW(lpszFileName):NULL;
- ret = FtpOpenFileW(hFtpSession, lpwzFileName, fdwAccess, dwFlags, dwContext);
- HeapFree(GetProcessHeap(), 0, lpwzFileName);
- return ret;
-}
-
-
-static void AsyncFtpOpenFileProc(WORKREQUEST *workRequest)
-{
- struct WORKREQ_FTPOPENFILEW const *req = &workRequest->u.FtpOpenFileW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
-
- TRACE("%p\n", lpwfs);
-
- FTP_FtpOpenFileW(lpwfs, req->lpszFilename,
- req->dwAccess, req->dwFlags, req->dwContext);
- HeapFree(GetProcessHeap(), 0, req->lpszFilename);
-}
-
-/***********************************************************************
- * FtpOpenFileW (WININET.@)
- *
- * Open a remote file for writing or reading
- *
- * RETURNS
- * HINTERNET handle on success
- * NULL on failure
- *
- */
-HINTERNET WINAPI FtpOpenFileW(HINTERNET hFtpSession,
- LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
- DWORD_PTR dwContext)
-{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
- HINTERNET r = NULL;
-
- TRACE("(%p,%s,0x%08x,0x%08x,0x%08lx)\n", hFtpSession,
- debugstr_w(lpszFileName), fdwAccess, dwFlags, dwContext);
-
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
- if (!lpwfs)
- {
- INTERNET_SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (WH_HFTPSESSION != lpwfs->hdr.htype)
- {
- INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
- goto lend;
- }
-
- if ((!lpszFileName) ||
- ((fdwAccess != GENERIC_READ) && (fdwAccess != GENERIC_WRITE)) ||
- ((dwFlags & FTP_CONDITION_MASK) > FTP_TRANSFER_TYPE_BINARY))
- {
- INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
- }
-
- if (lpwfs->download_in_progress != NULL)
- {
- INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
- goto lend;
- }
-
- hIC = lpwfs->lpAppInfo;
- if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
- {
- WORKREQUEST workRequest;
- struct WORKREQ_FTPOPENFILEW *req;
-
- workRequest.asyncproc = AsyncFtpOpenFileProc;
- workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
- req = &workRequest.u.FtpOpenFileW;
- req->lpszFilename = WININET_strdupW(lpszFileName);
- req->dwAccess = fdwAccess;
- req->dwFlags = dwFlags;
- req->dwContext = dwContext;
-
- INTERNET_AsyncCall(&workRequest);
- r = NULL;
- }
- else
- {
- r = FTP_FtpOpenFileW(lpwfs, lpszFileName, fdwAccess, dwFlags, dwContext);
- }
-
-lend:
- WININET_Release( &lpwfs->hdr );
-
- return r;
-}
-
/***********************************************************************
* FTPFILE_Destroy(internal)
* the 'transfer complete' message (this is a bit of a hack though :-/ )
*
*/
-static void FTPFILE_Destroy(WININETHANDLEHEADER *hdr)
+static void FTPFILE_Destroy(object_header_t *hdr)
{
- LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
- LPWININETFTPSESSIONW lpwfs = lpwh->lpFtpSession;
+ ftp_file_t *lpwh = (ftp_file_t*) hdr;
+ ftp_session_t *lpwfs = lpwh->lpFtpSession;
INT nResCode;
TRACE("\n");
- WININET_Release(&lpwh->lpFtpSession->hdr);
+ if (lpwh->cache_file_handle != INVALID_HANDLE_VALUE)
+ CloseHandle(lpwh->cache_file_handle);
+
+ HeapFree(GetProcessHeap(), 0, lpwh->cache_file);
if (!lpwh->session_deleted)
lpwfs->download_in_progress = NULL;
nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n");
+ WININET_Release(&lpwh->lpFtpSession->hdr);
+
HeapFree(GetProcessHeap(), 0, lpwh);
}
-static DWORD FTPFILE_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+static DWORD FTPFILE_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
switch(option) {
case INTERNET_OPTION_HANDLE_TYPE:
*size = sizeof(DWORD);
*(DWORD*)buffer = INTERNET_HANDLE_TYPE_FTP_FILE;
return ERROR_SUCCESS;
- }
+ case INTERNET_OPTION_DATAFILE_NAME:
+ {
+ DWORD required;
+ ftp_file_t *file = (ftp_file_t *)hdr;
- FIXME("Not implemented option %d\n", option);
- return ERROR_INTERNET_INVALID_OPTION;
+ TRACE("INTERNET_OPTION_DATAFILE_NAME\n");
+
+ if (!file->cache_file)
+ {
+ *size = 0;
+ return ERROR_INTERNET_ITEM_NOT_FOUND;
+ }
+ if (unicode)
+ {
+ required = (lstrlenW(file->cache_file) + 1) * sizeof(WCHAR);
+ if (*size < required)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = required;
+ memcpy(buffer, file->cache_file, *size);
+ return ERROR_SUCCESS;
+ }
+ else
+ {
+ required = WideCharToMultiByte(CP_ACP, 0, file->cache_file, -1, NULL, 0, NULL, NULL);
+ if (required > *size)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ *size = WideCharToMultiByte(CP_ACP, 0, file->cache_file, -1, buffer, *size, NULL, NULL);
+ return ERROR_SUCCESS;
+ }
+ }
+ }
+ return INET_QueryOption(option, buffer, size, unicode);
}
-static DWORD FTPFILE_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read)
+static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read)
{
- WININETFTPFILE *file = (WININETFTPFILE*)hdr;
+ ftp_file_t *file = (ftp_file_t*)hdr;
int res;
+ DWORD error;
if (file->nDataSocket == -1)
return ERROR_INTERNET_DISCONNECTED;
res = recv(file->nDataSocket, buffer, size, MSG_WAITALL);
*read = res>0 ? res : 0;
- return res>=0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME*/
+ error = res >= 0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME */
+ if (error == ERROR_SUCCESS && file->cache_file)
+ {
+ DWORD bytes_written;
+
+ if (!WriteFile(file->cache_file_handle, buffer, *read, &bytes_written, NULL))
+ WARN("WriteFile failed: %u\n", GetLastError());
+ }
+ return error;
+}
+
+static DWORD FTPFILE_ReadFileExA(object_header_t *hdr, INTERNET_BUFFERSA *buffers,
+ DWORD flags, DWORD_PTR context)
+{
+ return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength);
}
-static BOOL FTPFILE_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written)
+static DWORD FTPFILE_ReadFileExW(object_header_t *hdr, INTERNET_BUFFERSW *buffers,
+ DWORD flags, DWORD_PTR context)
{
- LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr;
+ return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength);
+}
+
+static DWORD FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD size, DWORD *written)
+{
+ ftp_file_t *lpwh = (ftp_file_t*) hdr;
int res;
res = send(lpwh->nDataSocket, buffer, size, 0);
*written = res>0 ? res : 0;
- return res >= 0;
+ return res >= 0 ? ERROR_SUCCESS : sock_get_error(errno);
+}
+
+static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif)
+{
+ INTERNET_ASYNC_RESULT iar;
+ BYTE buffer[4096];
+ int available;
+
+ TRACE("%p\n", file);
+
+ available = recv(file->nDataSocket, buffer, sizeof(buffer), MSG_PEEK);
+
+ if(available != -1) {
+ iar.dwResult = (DWORD_PTR)file->hdr.hInternet;
+ iar.dwError = first_notif ? 0 : available;
+ }else {
+ iar.dwResult = 0;
+ iar.dwError = INTERNET_GetLastError();
+ }
+
+ INTERNET_SendCallback(&file->hdr, file->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar,
+ sizeof(INTERNET_ASYNC_RESULT));
+}
+
+static void FTPFILE_AsyncQueryDataAvailableProc(WORKREQUEST *workRequest)
+{
+ ftp_file_t *file = (ftp_file_t*)workRequest->hdr;
+
+ FTP_ReceiveRequestData(file, FALSE);
+}
+
+static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx)
+{
+ ftp_file_t *file = (ftp_file_t*) hdr;
+ int retval, unread = 0;
+
+ TRACE("(%p %p %x %lx)\n", file, available, flags, ctx);
+
+#ifdef FIONREAD
+ retval = ioctlsocket(file->nDataSocket, FIONREAD, &unread);
+ if (!retval)
+ TRACE("%d bytes of queued, but unread data\n", unread);
+#else
+ FIXME("FIONREAD not available\n");
+#endif
+
+ *available = unread;
+
+ if(!unread) {
+ BYTE byte;
+
+ *available = 0;
+
+ retval = recv(file->nDataSocket, &byte, 1, MSG_PEEK);
+ if(retval > 0) {
+ WORKREQUEST workRequest;
+
+ *available = 0;
+ workRequest.asyncproc = FTPFILE_AsyncQueryDataAvailableProc;
+ workRequest.hdr = WININET_AddRef( &file->hdr );
+
+ INTERNET_AsyncCall(&workRequest);
+
+ return ERROR_IO_PENDING;
+ }
+ }
+
+ return ERROR_SUCCESS;
}
-static const HANDLEHEADERVtbl FTPFILEVtbl = {
+
+static const object_vtbl_t FTPFILEVtbl = {
FTPFILE_Destroy,
NULL,
FTPFILE_QueryOption,
NULL,
FTPFILE_ReadFile,
- NULL,
+ FTPFILE_ReadFileExA,
+ FTPFILE_ReadFileExW,
FTPFILE_WriteFile,
- NULL,
+ FTPFILE_QueryDataAvailable,
NULL
};
* NULL on failure
*
*/
-HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs,
+static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs,
LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
DWORD_PTR dwContext)
{
INT nDataSocket;
BOOL bSuccess = FALSE;
- LPWININETFTPFILE lpwh = NULL;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_file_t *lpwh = NULL;
+ appinfo_t *hIC = NULL;
HINTERNET handle = NULL;
TRACE("\n");
/* Get data socket to server */
if (bSuccess && FTP_GetDataSocket(lpwfs, &nDataSocket))
{
- lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPFILE));
+ lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(ftp_file_t));
lpwh->hdr.htype = WH_HFILE;
lpwh->hdr.vtbl = &FTPFILEVtbl;
lpwh->hdr.dwFlags = dwFlags;
lpwh->hdr.dwContext = dwContext;
+ lpwh->hdr.dwInternalFlags = 0;
lpwh->hdr.refs = 1;
lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB;
lpwh->nDataSocket = nDataSocket;
- lpwh->session_deleted = FALSE;
+ lpwh->cache_file = NULL;
+ lpwh->cache_file_handle = INVALID_HANDLE_VALUE;
+ lpwh->session_deleted = FALSE;
WININET_AddRef( &lpwfs->hdr );
lpwh->lpFtpSession = lpwfs;
}
if (lpwfs->lstnSocket != -1)
+ {
closesocket(lpwfs->lstnSocket);
+ lpwfs->lstnSocket = -1;
+ }
+
+ if (bSuccess && fdwAccess == GENERIC_READ)
+ {
+ WCHAR filename[MAX_PATH + 1];
+ URL_COMPONENTSW uc;
+ DWORD len;
+
+ memset(&uc, 0, sizeof(uc));
+ uc.dwStructSize = sizeof(uc);
+ uc.nScheme = INTERNET_SCHEME_FTP;
+ uc.lpszHostName = lpwfs->servername;
+ uc.nPort = lpwfs->serverport;
+ uc.lpszUserName = lpwfs->lpszUserName;
+ uc.lpszUrlPath = heap_strdupW(lpszFileName);
+
+ if (!InternetCreateUrlW(&uc, 0, NULL, &len) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ WCHAR *url = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+
+ if (url && InternetCreateUrlW(&uc, 0, url, &len) && CreateUrlCacheEntryW(url, 0, NULL, filename, 0))
+ {
+ lpwh->cache_file = heap_strdupW(filename);
+ lpwh->cache_file_handle = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (lpwh->cache_file_handle == INVALID_HANDLE_VALUE)
+ {
+ WARN("Could not create cache file: %u\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, lpwh->cache_file);
+ lpwh->cache_file = NULL;
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, url);
+ }
+ HeapFree(GetProcessHeap(), 0, uc.lpszUrlPath);
+ }
hIC = lpwfs->lpAppInfo;
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
if (lpwh)
{
- iar.dwResult = (DWORD)handle;
+ iar.dwResult = (DWORD_PTR)handle;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED,
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
- iar.dwResult = (DWORD)bSuccess;
- iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
- SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
- &iar, sizeof(INTERNET_ASYNC_RESULT));
+ if(bSuccess) {
+ FTP_ReceiveRequestData(lpwh, TRUE);
+ }else {
+ iar.dwResult = 0;
+ iar.dwError = INTERNET_GetLastError();
+ SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
+ &iar, sizeof(INTERNET_ASYNC_RESULT));
+ }
}
lend:
}
+/***********************************************************************
+ * FtpOpenFileA (WININET.@)
+ *
+ * Open a remote file for writing or reading
+ *
+ * RETURNS
+ * HINTERNET handle on success
+ * NULL on failure
+ *
+ */
+HINTERNET WINAPI FtpOpenFileA(HINTERNET hFtpSession,
+ LPCSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
+ DWORD_PTR dwContext)
+{
+ LPWSTR lpwzFileName;
+ HINTERNET ret;
+
+ lpwzFileName = heap_strdupAtoW(lpszFileName);
+ ret = FtpOpenFileW(hFtpSession, lpwzFileName, fdwAccess, dwFlags, dwContext);
+ HeapFree(GetProcessHeap(), 0, lpwzFileName);
+ return ret;
+}
+
+
+static void AsyncFtpOpenFileProc(WORKREQUEST *workRequest)
+{
+ struct WORKREQ_FTPOPENFILEW const *req = &workRequest->u.FtpOpenFileW;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
+
+ TRACE("%p\n", lpwfs);
+
+ FTP_FtpOpenFileW(lpwfs, req->lpszFilename,
+ req->dwAccess, req->dwFlags, req->dwContext);
+ HeapFree(GetProcessHeap(), 0, req->lpszFilename);
+}
+
+/***********************************************************************
+ * FtpOpenFileW (WININET.@)
+ *
+ * Open a remote file for writing or reading
+ *
+ * RETURNS
+ * HINTERNET handle on success
+ * NULL on failure
+ *
+ */
+HINTERNET WINAPI FtpOpenFileW(HINTERNET hFtpSession,
+ LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags,
+ DWORD_PTR dwContext)
+{
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
+ HINTERNET r = NULL;
+
+ TRACE("(%p,%s,0x%08x,0x%08x,0x%08lx)\n", hFtpSession,
+ debugstr_w(lpszFileName), fdwAccess, dwFlags, dwContext);
+
+ lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession );
+ if (!lpwfs)
+ {
+ INTERNET_SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (WH_HFTPSESSION != lpwfs->hdr.htype)
+ {
+ INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
+ goto lend;
+ }
+
+ if ((!lpszFileName) ||
+ ((fdwAccess != GENERIC_READ) && (fdwAccess != GENERIC_WRITE)) ||
+ ((dwFlags & FTP_CONDITION_MASK) > FTP_TRANSFER_TYPE_BINARY))
+ {
+ INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
+ goto lend;
+ }
+
+ if (lpwfs->download_in_progress != NULL)
+ {
+ INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
+ goto lend;
+ }
+
+ hIC = lpwfs->lpAppInfo;
+ if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
+ {
+ WORKREQUEST workRequest;
+ struct WORKREQ_FTPOPENFILEW *req;
+
+ workRequest.asyncproc = AsyncFtpOpenFileProc;
+ workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
+ req = &workRequest.u.FtpOpenFileW;
+ req->lpszFilename = heap_strdupW(lpszFileName);
+ req->dwAccess = fdwAccess;
+ req->dwFlags = dwFlags;
+ req->dwContext = dwContext;
+
+ INTERNET_AsyncCall(&workRequest);
+ r = NULL;
+ }
+ else
+ {
+ r = FTP_FtpOpenFileW(lpwfs, lpszFileName, fdwAccess, dwFlags, dwContext);
+ }
+
+lend:
+ WININET_Release( &lpwfs->hdr );
+
+ return r;
+}
+
+
/***********************************************************************
* FtpGetFileA (WININET.@)
*
LPWSTR lpwzNewFile;
BOOL ret;
- lpwzRemoteFile = lpszRemoteFile?WININET_strdup_AtoW(lpszRemoteFile):NULL;
- lpwzNewFile = lpszNewFile?WININET_strdup_AtoW(lpszNewFile):NULL;
+ lpwzRemoteFile = heap_strdupAtoW(lpszRemoteFile);
+ lpwzNewFile = heap_strdupAtoW(lpszNewFile);
ret = FtpGetFileW(hInternet, lpwzRemoteFile, lpwzNewFile, fFailIfExists,
dwLocalFlagsAttribute, dwInternetFlags, dwContext);
HeapFree(GetProcessHeap(), 0, lpwzRemoteFile);
static void AsyncFtpGetFileProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPGETFILEW const *req = &workRequest->u.FtpGetFileW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
DWORD_PTR dwContext)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
if (!lpszRemoteFile || !lpszNewFile)
return FALSE;
}
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hInternet );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hInternet );
if (!lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
workRequest.asyncproc = AsyncFtpGetFileProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpGetFileW;
- req->lpszRemoteFile = WININET_strdupW(lpszRemoteFile);
- req->lpszNewFile = WININET_strdupW(lpszNewFile);
+ req->lpszRemoteFile = heap_strdupW(lpszRemoteFile);
+ req->lpszNewFile = heap_strdupW(lpszNewFile);
req->dwLocalFlagsAttribute = dwLocalFlagsAttribute;
req->fFailIfExists = fFailIfExists;
req->dwFlags = dwInternetFlags;
req->dwContext = dwContext;
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
+static BOOL FTP_FtpGetFileW(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
DWORD_PTR dwContext)
{
BOOL bSuccess = FALSE;
HANDLE hFile;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
TRACE("lpszRemoteFile(%s) lpszNewFile(%s)\n", debugstr_w(lpszRemoteFile), debugstr_w(lpszNewFile));
}
if (lpwfs->lstnSocket != -1)
+ {
closesocket(lpwfs->lstnSocket);
+ lpwfs->lstnSocket = -1;
+ }
CloseHandle(hFile);
&iar, sizeof(INTERNET_ASYNC_RESULT));
}
+ if (!bSuccess) DeleteFileW(lpszNewFile);
return bSuccess;
}
LPWSTR lpwzFileName;
BOOL ret;
- lpwzFileName = lpszFileName?WININET_strdup_AtoW(lpszFileName):NULL;
+ lpwzFileName = heap_strdupAtoW(lpszFileName);
ret = FtpDeleteFileW(hFtpSession, lpwzFileName);
HeapFree(GetProcessHeap(), 0, lpwzFileName);
return ret;
static void AsyncFtpDeleteFileProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPDELETEFILEW const *req = &workRequest->u.FtpDeleteFileW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
*/
BOOL WINAPI FtpDeleteFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession );
if (!lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
workRequest.asyncproc = AsyncFtpDeleteFileProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpDeleteFileW;
- req->lpszFilename = WININET_strdupW(lpszFileName);
+ req->lpszFilename = heap_strdupW(lpszFileName);
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName)
+BOOL FTP_FtpDeleteFileW(ftp_session_t *lpwfs, LPCWSTR lpszFileName)
{
INT nResCode;
BOOL bSuccess = FALSE;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
TRACE("%p\n", lpwfs);
LPWSTR lpwzDirectory;
BOOL ret;
- lpwzDirectory = lpszDirectory?WININET_strdup_AtoW(lpszDirectory):NULL;
+ lpwzDirectory = heap_strdupAtoW(lpszDirectory);
ret = FtpRemoveDirectoryW(hFtpSession, lpwzDirectory);
HeapFree(GetProcessHeap(), 0, lpwzDirectory);
return ret;
static void AsyncFtpRemoveDirectoryProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPREMOVEDIRECTORYW const *req = &workRequest->u.FtpRemoveDirectoryW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
*/
BOOL WINAPI FtpRemoveDirectoryW(HINTERNET hFtpSession, LPCWSTR lpszDirectory)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession );
if (!lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
workRequest.asyncproc = AsyncFtpRemoveDirectoryProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpRemoveDirectoryW;
- req->lpszDirectory = WININET_strdupW(lpszDirectory);
+ req->lpszDirectory = heap_strdupW(lpszDirectory);
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory)
+BOOL FTP_FtpRemoveDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirectory)
{
INT nResCode;
BOOL bSuccess = FALSE;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
TRACE("\n");
LPWSTR lpwzDest;
BOOL ret;
- lpwzSrc = lpszSrc?WININET_strdup_AtoW(lpszSrc):NULL;
- lpwzDest = lpszDest?WININET_strdup_AtoW(lpszDest):NULL;
+ lpwzSrc = heap_strdupAtoW(lpszSrc);
+ lpwzDest = heap_strdupAtoW(lpszDest);
ret = FtpRenameFileW(hFtpSession, lpwzSrc, lpwzDest);
HeapFree(GetProcessHeap(), 0, lpwzSrc);
HeapFree(GetProcessHeap(), 0, lpwzDest);
static void AsyncFtpRenameFileProc(WORKREQUEST *workRequest)
{
struct WORKREQ_FTPRENAMEFILEW const *req = &workRequest->u.FtpRenameFileW;
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr;
TRACE("%p\n", lpwfs);
*/
BOOL WINAPI FtpRenameFileW(HINTERNET hFtpSession, LPCWSTR lpszSrc, LPCWSTR lpszDest)
{
- LPWININETFTPSESSIONW lpwfs;
- LPWININETAPPINFOW hIC = NULL;
+ ftp_session_t *lpwfs;
+ appinfo_t *hIC = NULL;
BOOL r = FALSE;
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession );
if (!lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
workRequest.asyncproc = AsyncFtpRenameFileProc;
workRequest.hdr = WININET_AddRef( &lpwfs->hdr );
req = &workRequest.u.FtpRenameFileW;
- req->lpszSrcFile = WININET_strdupW(lpszSrc);
- req->lpszDestFile = WININET_strdupW(lpszDest);
+ req->lpszSrcFile = heap_strdupW(lpszSrc);
+ req->lpszDestFile = heap_strdupW(lpszDest);
- r = INTERNET_AsyncCall(&workRequest);
+ r = res_to_le(INTERNET_AsyncCall(&workRequest));
}
else
{
* FALSE on failure
*
*/
-BOOL FTP_FtpRenameFileW( LPWININETFTPSESSIONW lpwfs,
- LPCWSTR lpszSrc, LPCWSTR lpszDest)
+BOOL FTP_FtpRenameFileW(ftp_session_t *lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest)
{
INT nResCode;
BOOL bSuccess = FALSE;
- LPWININETAPPINFOW hIC = NULL;
+ appinfo_t *hIC = NULL;
TRACE("\n");
return FALSE;
}
- if (!(cmdW = WININET_strdup_AtoW(lpszCommand)))
+ if (!(cmdW = heap_strdupAtoW(lpszCommand)))
{
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
LPCWSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand )
{
BOOL r = FALSE;
- LPWININETFTPSESSIONW lpwfs;
+ ftp_session_t *lpwfs;
LPSTR cmd = NULL;
DWORD len, nBytesSent= 0;
INT nResCode, nRC = 0;
return FALSE;
}
- lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect );
+ lpwfs = (ftp_session_t*) WININET_GetObject( hConnect );
if (!lpwfs)
{
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
*
* Deallocate session handle
*/
-static void FTPSESSION_Destroy(WININETHANDLEHEADER *hdr)
+static void FTPSESSION_Destroy(object_header_t *hdr)
{
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) hdr;
TRACE("\n");
HeapFree(GetProcessHeap(), 0, lpwfs->lpszPassword);
HeapFree(GetProcessHeap(), 0, lpwfs->lpszUserName);
+ HeapFree(GetProcessHeap(), 0, lpwfs->servername);
HeapFree(GetProcessHeap(), 0, lpwfs);
}
-static void FTPSESSION_CloseConnection(WININETHANDLEHEADER *hdr)
+static void FTPSESSION_CloseConnection(object_header_t *hdr)
{
- LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr;
+ ftp_session_t *lpwfs = (ftp_session_t*) hdr;
TRACE("\n");
INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
}
-static DWORD FTPSESSION_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+static DWORD FTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
switch(option) {
case INTERNET_OPTION_HANDLE_TYPE:
return ERROR_SUCCESS;
}
- FIXME("Not implemented option %d\n", option);
- return ERROR_INTERNET_INVALID_OPTION;
+ return INET_QueryOption(option, buffer, size, unicode);
}
-static const HANDLEHEADERVtbl FTPSESSIONVtbl = {
+static const object_vtbl_t FTPSESSIONVtbl = {
FTPSESSION_Destroy,
FTPSESSION_CloseConnection,
FTPSESSION_QueryOption,
*
*/
-HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
+HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
DWORD dwInternalFlags)
INT nsocket = -1;
UINT sock_namelen;
BOOL bSuccess = FALSE;
- LPWININETFTPSESSIONW lpwfs = NULL;
+ ftp_session_t *lpwfs = NULL;
HINTERNET handle = NULL;
+ char szaddr[INET_ADDRSTRLEN];
TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n",
hIC, debugstr_w(lpszServerName),
assert( hIC->hdr.htype == WH_HINIT );
- if (NULL == lpszUserName && NULL != lpszPassword)
+ if ((!lpszUserName || !*lpszUserName) && lpszPassword && *lpszPassword)
{
INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
goto lerror;
}
- lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPSESSIONW));
+ lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(ftp_session_t));
if (NULL == lpwfs)
{
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
}
if (nServerPort == INTERNET_INVALID_PORT_NUMBER)
- nServerPort = INTERNET_DEFAULT_FTP_PORT;
+ lpwfs->serverport = INTERNET_DEFAULT_FTP_PORT;
+ else
+ lpwfs->serverport = nServerPort;
lpwfs->hdr.htype = WH_HFTPSESSION;
lpwfs->hdr.vtbl = &FTPSESSIONVtbl;
if(hIC->lpszProxyBypass)
FIXME("Proxy bypass is ignored.\n");
}
- if ( !lpszUserName) {
+ if (!lpszUserName || !strlenW(lpszUserName)) {
HKEY key;
WCHAR szPassword[MAX_PATH];
DWORD len = sizeof(szPassword);
- lpwfs->lpszUserName = WININET_strdupW(szDefaultUsername);
+ lpwfs->lpszUserName = heap_strdupW(szDefaultUsername);
RegOpenKeyW(HKEY_CURRENT_USER, szKey, &key);
if (RegQueryValueExW(key, szValue, NULL, NULL, (LPBYTE)szPassword, &len)) {
RegCloseKey(key);
TRACE("Password used for anonymous ftp : (%s)\n", debugstr_w(szPassword));
- lpwfs->lpszPassword = WININET_strdupW(szPassword);
+ lpwfs->lpszPassword = heap_strdupW(szPassword);
}
else {
- lpwfs->lpszUserName = WININET_strdupW(lpszUserName);
-
- if (lpszPassword)
- lpwfs->lpszPassword = WININET_strdupW(lpszPassword);
- else
- lpwfs->lpszPassword = WININET_strdupW(szEmpty);
+ lpwfs->lpszUserName = heap_strdupW(lpszUserName);
+ lpwfs->lpszPassword = heap_strdupW(lpszPassword ? lpszPassword : szEmpty);
}
+ lpwfs->servername = heap_strdupW(lpszServerName);
/* Don't send a handle created callback if this handle was created with InternetOpenUrl */
if (!(lpwfs->hdr.dwInternalFlags & INET_OPENURL))
{
INTERNET_ASYNC_RESULT iar;
- iar.dwResult = (DWORD)handle;
+ iar.dwResult = (DWORD_PTR)handle;
iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(&hIC->hdr, dwContext,
}
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_RESOLVING_NAME,
- (LPWSTR) lpszServerName, strlenW(lpszServerName));
+ (LPWSTR) lpszServerName, (strlenW(lpszServerName)+1) * sizeof(WCHAR));
- if (!GetAddress(lpszServerName, nServerPort, &socketAddr))
+ sock_namelen = sizeof(socketAddr);
+ if (!GetAddress(lpszServerName, lpwfs->serverport, (struct sockaddr *)&socketAddr, &sock_namelen))
{
INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED);
goto lerror;
}
+ if (socketAddr.sin_family != AF_INET)
+ {
+ WARN("unsupported address family %d\n", socketAddr.sin_family);
+ INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
+ goto lerror;
+ }
+
+ inet_ntop(socketAddr.sin_family, &socketAddr.sin_addr, szaddr, sizeof(szaddr));
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED,
- (LPWSTR) lpszServerName, strlenW(lpszServerName));
+ szaddr, strlen(szaddr)+1);
nsocket = socket(AF_INET,SOCK_STREAM,0);
if (nsocket == -1)
}
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER,
- &socketAddr, sizeof(struct sockaddr_in));
+ szaddr, strlen(szaddr)+1);
- if (connect(nsocket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) < 0)
+ if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0)
{
ERR("Unable to connect (%s)\n", strerror(errno));
INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT);
+ closesocket(nsocket);
}
else
{
TRACE("Connected to server\n");
lpwfs->sndSocket = nsocket;
SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTED_TO_SERVER,
- &socketAddr, sizeof(struct sockaddr_in));
+ szaddr, strlen(szaddr)+1);
sock_namelen = sizeof(lpwfs->socketAddress);
getsockname(nsocket, (struct sockaddr *) &lpwfs->socketAddress, &sock_namelen);
handle = NULL;
}
- if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
- {
- INTERNET_ASYNC_RESULT iar;
-
- iar.dwResult = bSuccess ? (DWORD_PTR)lpwfs : 0;
- iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
- SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_REQUEST_COMPLETE,
- &iar, sizeof(INTERNET_ASYNC_RESULT));
- }
-
return handle;
}
* NULL on failure
*
*/
-static BOOL FTP_ConnectToHost(LPWININETFTPSESSIONW lpwfs)
+static BOOL FTP_ConnectToHost(ftp_session_t *lpwfs)
{
INT nResCode;
BOOL bSuccess = FALSE;
*
*/
static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam,
- INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext)
+ INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext)
{
DWORD len;
CHAR *buf;
*
*/
static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam,
- INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext)
+ INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext)
{
BOOL ret;
- LPSTR lpszParamA = lpszParam?WININET_strdup_WtoA(lpszParam):NULL;
+ LPSTR lpszParamA = heap_strdupWtoA(lpszParam);
ret = FTP_SendCommandA(nSocket, ftpCmd, lpszParamA, lpfnStatusCB, hdr, dwContext);
HeapFree(GetProcessHeap(), 0, lpszParamA);
return ret;
* 0 on failure
*
*/
-INT FTP_ReceiveResponse(LPWININETFTPSESSIONW lpwfs, DWORD_PTR dwContext)
+INT FTP_ReceiveResponse(ftp_session_t *lpwfs, DWORD_PTR dwContext)
{
LPSTR lpszResponse = INTERNET_GetResponseBuffer();
DWORD nRecv;
* NULL on failure
*
*/
-static BOOL FTP_SendPassword(LPWININETFTPSESSIONW lpwfs)
+static BOOL FTP_SendPassword(ftp_session_t *lpwfs)
{
INT nResCode;
BOOL bSuccess = FALSE;
* FALSE on failure
*
*/
-static BOOL FTP_SendAccount(LPWININETFTPSESSIONW lpwfs)
+static BOOL FTP_SendAccount(ftp_session_t *lpwfs)
{
INT nResCode;
BOOL bSuccess = FALSE;
* FALSE on failure
*
*/
-static BOOL FTP_SendStore(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType)
+static BOOL FTP_SendStore(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType)
{
INT nResCode;
BOOL bSuccess = FALSE;
* FALSE on failure
*
*/
-static BOOL FTP_InitListenSocket(LPWININETFTPSESSIONW lpwfs)
+static BOOL FTP_InitListenSocket(ftp_session_t *lpwfs)
{
BOOL bSuccess = FALSE;
- socklen_t namelen = sizeof(struct sockaddr_in);
+ socklen_t namelen = sizeof(lpwfs->lstnSocketAddress);
TRACE("\n");
lpwfs->lstnSocketAddress = lpwfs->socketAddress;
/* and get the system to assign us a port */
- lpwfs->lstnSocketAddress.sin_port = htons((u_short) 0);
+ lpwfs->lstnSocketAddress.sin_port = htons(0);
- if (bind(lpwfs->lstnSocket,(struct sockaddr *) &lpwfs->lstnSocketAddress, sizeof(struct sockaddr_in)) == -1)
+ if (bind(lpwfs->lstnSocket,(struct sockaddr *) &lpwfs->lstnSocketAddress, sizeof(lpwfs->lstnSocketAddress)) == -1)
{
TRACE("Unable to bind socket\n");
goto lend;
* (i.e. it sends it always),
* so we probably don't want to do that either.
*/
-static BOOL FTP_SendType(LPWININETFTPSESSIONW lpwfs, DWORD dwType)
+static BOOL FTP_SendType(ftp_session_t *lpwfs, DWORD dwType)
{
INT nResCode;
WCHAR type[] = { 'I','\0' };
* FALSE on failure
*
*/
-static BOOL FTP_GetFileSize(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD *dwSize)
+static BOOL FTP_GetFileSize(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD *dwSize)
{
INT nResCode;
BOOL bSuccess = FALSE;
* FALSE on failure
*
*/
-static BOOL FTP_SendPort(LPWININETFTPSESSIONW lpwfs)
+static BOOL FTP_SendPort(ftp_session_t *lpwfs)
{
static const WCHAR szIPFormat[] = {'%','d',',','%','d',',','%','d',',','%','d',',','%','d',',','%','d','\0'};
INT nResCode;
* FALSE on failure
*
*/
-static BOOL FTP_DoPassive(LPWININETFTPSESSIONW lpwfs)
+static BOOL FTP_DoPassive(ftp_session_t *lpwfs)
{
INT nResCode;
BOOL bSuccess = FALSE;
}
-static BOOL FTP_SendPortOrPasv(LPWININETFTPSESSIONW lpwfs)
+static BOOL FTP_SendPortOrPasv(ftp_session_t *lpwfs)
{
if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE)
{
* FALSE on failure
*
*/
-static BOOL FTP_GetDataSocket(LPWININETFTPSESSIONW lpwfs, LPINT nDataSocket)
+static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket)
{
struct sockaddr_in saddr;
socklen_t addrlen = sizeof(struct sockaddr);
if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE)
{
*nDataSocket = lpwfs->pasvSocket;
+ lpwfs->pasvSocket = -1;
}
else
{
* FALSE on failure
*
*/
-static BOOL FTP_SendData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile)
+static BOOL FTP_SendData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile)
{
BY_HANDLE_FILE_INFORMATION fi;
DWORD nBytesRead = 0;
* 0 on failure
*
*/
-static BOOL FTP_SendRetrieve(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType)
+static BOOL FTP_SendRetrieve(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType)
{
INT nResCode;
BOOL ret;
* FALSE on failure
*
*/
-static BOOL FTP_RetrieveFileData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile)
+static BOOL FTP_RetrieveFileData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile)
{
DWORD nBytesWritten;
INT nRC = 0;
*
* Deallocate session handle
*/
-static void FTPFINDNEXT_Destroy(WININETHANDLEHEADER *hdr)
+static void FTPFINDNEXT_Destroy(object_header_t *hdr)
{
LPWININETFTPFINDNEXTW lpwfn = (LPWININETFTPFINDNEXTW) hdr;
DWORD i;
HeapFree(GetProcessHeap(), 0, lpwfn);
}
-static DWORD WINAPI FTPFINDNEXT_FindNextFileProc(WININETFTPFINDNEXTW *find, LPVOID data)
+static DWORD FTPFINDNEXT_FindNextFileProc(WININETFTPFINDNEXTW *find, LPVOID data)
{
WIN32_FIND_DATAW *find_data = data;
DWORD res = ERROR_SUCCESS;
FTPFINDNEXT_FindNextFileProc((WININETFTPFINDNEXTW*)workRequest->hdr, req->lpFindFileData);
}
-static DWORD FTPFINDNEXT_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
+static DWORD FTPFINDNEXT_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
{
switch(option) {
case INTERNET_OPTION_HANDLE_TYPE:
return ERROR_SUCCESS;
}
- FIXME("Not implemented option %d\n", option);
- return ERROR_INTERNET_INVALID_OPTION;
+ return INET_QueryOption(option, buffer, size, unicode);
}
-static DWORD FTPFINDNEXT_FindNextFileW(WININETHANDLEHEADER *hdr, void *data)
+static DWORD FTPFINDNEXT_FindNextFileW(object_header_t *hdr, void *data)
{
WININETFTPFINDNEXTW *find = (WININETFTPFINDNEXTW*)hdr;
return FTPFINDNEXT_FindNextFileProc(find, data);
}
-static const HANDLEHEADERVtbl FTPFINDNEXTVtbl = {
+static const object_vtbl_t FTPFINDNEXTVtbl = {
FTPFINDNEXT_Destroy,
NULL,
FTPFINDNEXT_QueryOption,
NULL,
NULL,
NULL,
+ NULL,
FTPFINDNEXT_FindNextFileW
};
* NULL on failure
*
*/
-static HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
+static HINTERNET FTP_ReceiveFileList(ftp_session_t *lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext)
{
DWORD dwSize = 0;
if (lpafp)
{
- /* Convert 'Unix' time to Windows time */
- RtlSecondsSince1970ToTime(mktime(&lpafp->tmLastModified),
- (LARGE_INTEGER *) &(lpFindFileData->ftLastAccessTime));
+ SystemTimeToFileTime( &lpafp->tmLastModified, &lpFindFileData->ftLastAccessTime );
lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime;
lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime;
lpfp->nSize = atol(pszToken);
}
- lpfp->tmLastModified.tm_sec = 0;
- lpfp->tmLastModified.tm_min = 0;
- lpfp->tmLastModified.tm_hour = 0;
- lpfp->tmLastModified.tm_mday = 0;
- lpfp->tmLastModified.tm_mon = 0;
- lpfp->tmLastModified.tm_year = 0;
+ lpfp->tmLastModified.wSecond = 0;
+ lpfp->tmLastModified.wMinute = 0;
+ lpfp->tmLastModified.wHour = 0;
+ lpfp->tmLastModified.wDay = 0;
+ lpfp->tmLastModified.wMonth = 0;
+ lpfp->tmLastModified.wYear = 0;
/* Determine month */
pszToken = strtok(NULL, szSpace);
if(strlen(pszToken) >= 3) {
pszToken[3] = 0;
if((pszTmp = StrStrIA(szMonths, pszToken)))
- lpfp->tmLastModified.tm_mon = ((pszTmp - szMonths) / 3)+1;
+ lpfp->tmLastModified.wMonth = ((pszTmp - szMonths) / 3)+1;
}
/* Determine day */
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
- lpfp->tmLastModified.tm_mday = atoi(pszToken);
+ lpfp->tmLastModified.wDay = atoi(pszToken);
/* Determine time or year */
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
if((pszTmp = strchr(pszToken, ':'))) {
- struct tm* apTM;
- time_t aTime;
+ SYSTEMTIME curr_time;
*pszTmp = 0;
pszTmp++;
- lpfp->tmLastModified.tm_min = atoi(pszTmp);
- lpfp->tmLastModified.tm_hour = atoi(pszToken);
- time(&aTime);
- apTM = localtime(&aTime);
- lpfp->tmLastModified.tm_year = apTM->tm_year;
+ lpfp->tmLastModified.wMinute = atoi(pszTmp);
+ lpfp->tmLastModified.wHour = atoi(pszToken);
+ GetLocalTime( &curr_time );
+ lpfp->tmLastModified.wYear = curr_time.wYear;
}
else {
- lpfp->tmLastModified.tm_year = atoi(pszToken) - 1900;
- lpfp->tmLastModified.tm_hour = 12;
+ lpfp->tmLastModified.wYear = atoi(pszToken);
+ lpfp->tmLastModified.wHour = 12;
}
- TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n",
- lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec,
- (lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year,
- lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday);
+ TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
+ lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond,
+ lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay);
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
- lpfp->lpszName = WININET_strdup_AtoW(pszToken);
+ lpfp->lpszName = heap_strdupAtoW(pszToken);
TRACE("File: %s\n", debugstr_w(lpfp->lpszName));
}
/* NT way of parsing ... :
05-09-03 06:02PM 12656686 2003-04-21bgm_cmd_e.rgz
*/
else if(isdigit(pszToken[0]) && 8 == strlen(pszToken)) {
+ int mon, mday, year, hour, min;
lpfp->permissions = 0xFFFF; /* No idea, put full permission :-) */
- sscanf(pszToken, "%d-%d-%d",
- &lpfp->tmLastModified.tm_mon,
- &lpfp->tmLastModified.tm_mday,
- &lpfp->tmLastModified.tm_year);
+ sscanf(pszToken, "%d-%d-%d", &mon, &mday, &year);
+ lpfp->tmLastModified.wDay = mday;
+ lpfp->tmLastModified.wMonth = mon;
+ lpfp->tmLastModified.wYear = year;
/* Hacky and bad Y2K protection :-) */
- if (lpfp->tmLastModified.tm_year < 70)
- lpfp->tmLastModified.tm_year += 100;
-
+ if (lpfp->tmLastModified.wYear < 70) lpfp->tmLastModified.wYear += 2000;
+
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
- sscanf(pszToken, "%d:%d",
- &lpfp->tmLastModified.tm_hour,
- &lpfp->tmLastModified.tm_min);
+ sscanf(pszToken, "%d:%d", &hour, &min);
+ lpfp->tmLastModified.wHour = hour;
+ lpfp->tmLastModified.wMinute = min;
if((pszToken[5] == 'P') && (pszToken[6] == 'M')) {
- lpfp->tmLastModified.tm_hour += 12;
+ lpfp->tmLastModified.wHour += 12;
}
- lpfp->tmLastModified.tm_sec = 0;
+ lpfp->tmLastModified.wSecond = 0;
+
+ TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n",
+ lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond,
+ lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay);
- TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n",
- lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec,
- (lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year,
- lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday);
-
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
if(!strcasecmp(pszToken, "<DIR>")) {
pszToken = strtok(NULL, szSpace);
if(!pszToken) continue;
- lpfp->lpszName = WININET_strdup_AtoW(pszToken);
+ lpfp->lpszName = heap_strdupAtoW(pszToken);
TRACE("Name: %s\n", debugstr_w(lpfp->lpszName));
}
/* EPLF format - http://cr.yp.to/ftp/list/eplf.html */
* TRUE on success
* FALSE on failure
*/
-static BOOL FTP_ParseDirectory(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
+static BOOL FTP_ParseDirectory(ftp_session_t *lpwfs, INT nSocket, LPCWSTR lpszSearchFile,
LPFILEPROPERTIESW *lpafp, LPDWORD dwfp)
{
BOOL bSuccess = TRUE;