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