Hans Leidekker : wininet: Implement and test FtpCommand{A, W}.
Alexandre Julliard
julliard at winehq.org
Thu Nov 1 07:39:42 CDT 2007
Module: wine
Branch: master
Commit: 9e934ee17889a01242f1bbd5437b59158c2a8adc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9e934ee17889a01242f1bbd5437b59158c2a8adc
Author: Hans Leidekker <hans at it.vu.nl>
Date: Wed Oct 31 22:54:03 2007 +0100
wininet: Implement and test FtpCommand{A, W}.
---
dlls/wininet/ftp.c | 107 +++++++++++++++++++++++++++++++++++++++++++--
dlls/wininet/tests/ftp.c | 42 +++++++++++++++++-
2 files changed, 143 insertions(+), 6 deletions(-)
diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c
index c045217..8c0cc5d 100644
--- a/dlls/wininet/ftp.c
+++ b/dlls/wininet/ftp.c
@@ -4,6 +4,7 @@
* Copyright 1999 Corel Corporation
* Copyright 2004 Mike McCormack for CodeWeavers
* Copyright 2004 Kevin Koltzau
+ * Copyright 2007 Hans Leidekker
*
* Ulrich Czekalla
* Noureddine Jemmali
@@ -1863,10 +1864,34 @@ lend:
BOOL WINAPI FtpCommandA( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags,
LPCSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand )
{
- FIXME("%p %d 0x%08x %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
+ BOOL r;
+ WCHAR *cmdW;
+
+ TRACE("%p %d 0x%08x %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
debugstr_a(lpszCommand), dwContext, phFtpCommand);
- return TRUE;
+ if (fExpectResponse)
+ {
+ FIXME("data connection not supported\n");
+ return FALSE;
+ }
+
+ if (!lpszCommand || !lpszCommand[0])
+ {
+ INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (!(cmdW = WININET_strdup_AtoW(lpszCommand)))
+ {
+ INTERNET_SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ r = FtpCommandW(hConnect, fExpectResponse, dwFlags, cmdW, dwContext, phFtpCommand);
+
+ HeapFree(GetProcessHeap(), 0, cmdW);
+ return r;
}
/***********************************************************************
@@ -1875,10 +1900,82 @@ BOOL WINAPI FtpCommandA( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags
BOOL WINAPI FtpCommandW( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags,
LPCWSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand )
{
- FIXME("%p %d 0x%08x %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
- debugstr_w(lpszCommand), dwContext, phFtpCommand);
+ BOOL r = FALSE;
+ LPWININETFTPSESSIONW lpwfs;
+ LPSTR cmd = NULL;
+ DWORD len, nBytesSent= 0;
+ INT nResCode, nRC = 0;
- return TRUE;
+ TRACE("%p %d 0x%08x %s 0x%08lx %p\n", hConnect, fExpectResponse, dwFlags,
+ debugstr_w(lpszCommand), dwContext, phFtpCommand);
+
+ if (!lpszCommand || !lpszCommand[0])
+ {
+ INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (fExpectResponse)
+ {
+ FIXME("data connection not supported\n");
+ return FALSE;
+ }
+
+ lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect );
+ 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 (lpwfs->download_in_progress != NULL)
+ {
+ INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
+ goto lend;
+ }
+
+ len = WideCharToMultiByte(CP_ACP, 0, lpszCommand, -1, NULL, 0, NULL, NULL) + strlen(szCRLF);
+ if ((cmd = HeapAlloc(GetProcessHeap(), 0, len )))
+ WideCharToMultiByte(CP_ACP, 0, lpszCommand, -1, cmd, len, NULL, NULL);
+ else
+ {
+ INTERNET_SetLastError(ERROR_OUTOFMEMORY);
+ goto lend;
+ }
+
+ strcat(cmd, szCRLF);
+ len--;
+
+ TRACE("Sending (%s) len(%d)\n", cmd, len);
+ while ((nBytesSent < len) && (nRC != -1))
+ {
+ nRC = send(lpwfs->sndSocket, cmd + nBytesSent, len - nBytesSent, 0);
+ if (nRC != -1)
+ {
+ nBytesSent += nRC;
+ TRACE("Sent %d bytes\n", nRC);
+ }
+ }
+
+ if (nBytesSent)
+ {
+ nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext);
+ if (nResCode > 0 && nResCode < 400)
+ r = TRUE;
+ else
+ FTP_SetResponseError(nResCode);
+ }
+
+lend:
+ WININET_Release( &lpwfs->hdr );
+ HeapFree(GetProcessHeap(), 0, cmd);
+ return r;
}
/***********************************************************************
diff --git a/dlls/wininet/tests/ftp.c b/dlls/wininet/tests/ftp.c
index fa13fdc..6d03fb8 100644
--- a/dlls/wininet/tests/ftp.c
+++ b/dlls/wininet/tests/ftp.c
@@ -25,7 +25,6 @@
* TODO:
* Add W-function tests.
* Add missing function tests:
- * FtpCommand
* FtpFindFirstFile
* FtpGetCurrentDirectory
* FtpGetFileSize
@@ -652,6 +651,46 @@ static void test_renamefile(HINTERNET hFtp, HINTERNET hConnect)
"Expected ERROR_INTERNET_INCORRECT_HANDLE_TYPE, got %d\n", GetLastError());
}
+static void test_command(HINTERNET hFtp, HINTERNET hConnect)
+{
+ BOOL ret;
+ DWORD error;
+ unsigned int i;
+ static const struct
+ {
+ BOOL ret;
+ DWORD error;
+ const char *cmd;
+ }
+ command_test[] =
+ {
+ { FALSE, ERROR_INVALID_PARAMETER, NULL },
+ { FALSE, ERROR_INVALID_PARAMETER, "" },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "HELO" },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, " SIZE" },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE " },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg /welcome.msg" },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg" },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "SIZE /welcome.msg " },
+ { TRUE, ERROR_SUCCESS, "SIZE\t/welcome.msg" },
+ { TRUE, ERROR_SUCCESS, "SIZE /welcome.msg" },
+ { FALSE, ERROR_INTERNET_EXTENDED_ERROR, "PWD /welcome.msg" },
+ { TRUE, ERROR_SUCCESS, "PWD" },
+ { TRUE, ERROR_SUCCESS, "PWD\r\n" }
+ };
+
+ for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
+ {
+ SetLastError(0xdeadbeef);
+ ret = FtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
+ error = GetLastError();
+
+ ok(ret == command_test[i].ret, "%d: expected FtpCommandA to %s\n", i, command_test[i].ret ? "succeed" : "fail");
+ ok(error == command_test[i].error, "%d: expected error %u, got %u\n", i, command_test[i].error, error);
+ }
+}
+
START_TEST(ftp)
{
HANDLE hInternet, hFtp, hHttp;
@@ -693,6 +732,7 @@ START_TEST(ftp)
test_putfile(hFtp, hHttp);
test_removedir(hFtp, hHttp);
test_renamefile(hFtp, hHttp);
+ test_command(hFtp, hHttp);
InternetCloseHandle(hHttp);
InternetCloseHandle(hFtp);
More information about the wine-cvs
mailing list