⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpapi.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************\
    FILE: ftpapi.cpp

    DESCRIPTION:
        This file contains functions to perform the following 2 things:

    1. WININET WRAPPERS: Wininet APIs have either wierd bugs or bugs that come thru the APIs
    from the server.  It's also important to keep track of the perf impact
    of each call.  These wrappers solve these problems.

    2. FTP STRs to PIDLs: These wrappers will take ftp filenames and file paths
    that come in from the server and turn them into pidls.  These pidls contain
    both a unicode display string and the filename/path in wire bytes for future
    server requests.
\*****************************************************************************/

#include "priv.h"
#include "util.h"
#include "encoding.h"
#include "ftpapi.h"


///////////////////////////////////////////////////////////////////////////////////////////
// 1. WININET WRAPPERS: Wininet APIs have either wierd bugs or bugs that come thru the APIs
// from the server.  It's also important to keep track of the perf impact
// of each call.  These wrappers solve these problems.
///////////////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************\
    FUNCTION: FtpSetCurrentDirectoryWrap

    DESCRIPTION:

    PERF Notes:
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 1ms
        To: rigel.cyberpass.net <San Diego, CA>: 140ms - 200ms
        To: ftp.rz.uni-frankfurt.de <Germany>: 570ms - 2496ms
\*****************************************************************************/
HRESULT FtpSetCurrentDirectoryWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFtpPath)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    // WARNING: FtpSetCurrentDirectory() may fail if it's not really a directory.
    // PERF: Status FtpGetCurrentDirectory/FtpSetCurrentDirectory() takes
    //  180-280ms on ftp.microsoft.com on average.
    //  500-2000ms on ftp://ftp.tu-clausthal.de/ on average
    //  0-10ms on ftp://shapitst/ on average
    DEBUG_CODE(DebugStartWatch());
    if (!FtpSetCurrentDirectoryA(hConnect, pwFtpPath))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpSetCurrentDirectory(%#08lx, \"%hs\") returned %u. Time=%lums", hConnect, pwFtpPath, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpGetCurrentDirectoryWrap

    DESCRIPTION:

    PERF Notes:
    These are for short directory listings.  Long listings can take 3-10x.
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 1ms - 4ms
        To: rigel.cyberpass.net <San Diego, CA>: 132ms - 213ms
        To: ftp.rz.uni-frankfurt.de <Germany>: 507ms - 2012ms
\*****************************************************************************/
HRESULT FtpGetCurrentDirectoryWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPWIRESTR pwFtpPath, DWORD cchCurrentDirectory)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    // PERF: Status FtpGetCurrentDirectory/FtpSetCurrentDirectory() takes
    //  180-280ms on ftp.microsoft.com on average.
    //  500-2000ms on ftp://ftp.tu-clausthal.de/ on average
    //  0-10ms on ftp://shapitst/ on average
    DEBUG_CODE(DebugStartWatch());
    if (!FtpGetCurrentDirectoryA(hConnect, pwFtpPath, &cchCurrentDirectory))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpGetCurrentDirectoryA(%#08lx, \"%hs\") returned %u. Time=%lums", hConnect, pwFtpPath, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpGetFileExWrap

    DESCRIPTION:

    PERF Notes:   (*** Depends on file size ***)
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 100ms - 1,000ms+
        To: rigel.cyberpass.net <San Diego, CA>: 1210ms - 1610ms
        To: ftp.rz.uni-frankfurt.de <Germany>: ???????
\*****************************************************************************/
HRESULT FtpGetFileExWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFtpPath/*Src*/, LPCWSTR pwzFilePath/*Dest*/, BOOL fFailIfExists,
                       DWORD dwFlagsAndAttributes, DWORD dwFlags, DWORD_PTR dwContext)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    DEBUG_CODE(DebugStartWatch());
    if (!FtpGetFileEx(hConnect, pwFtpPath, pwzFilePath, fFailIfExists, dwFlagsAndAttributes, dwFlags, dwContext))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
        if (HRESULT_FROM_WIN32(ERROR_INTERNET_OPERATION_CANCELLED) == hr)
            hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpGetFileEx(%#08lx, \"%hs\", \"%ls\") returned %u. Time=%lums", hConnect, pwFtpPath, pwzFilePath, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpPutFileExWrap

    DESCRIPTION:

    PERF Notes:   (*** Depends on file size ***)
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 194ms - 400ms+
        To: rigel.cyberpass.net <San Diego, CA>: 1662ms - 8454ms
        To: ftp.rz.uni-frankfurt.de <Germany>: ???????
\*****************************************************************************/
HRESULT FtpPutFileExWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWSTR pwzFilePath/*Src*/, LPCWIRESTR pwFtpPath/*Dest*/, DWORD dwFlags, DWORD_PTR dwContext)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    DEBUG_CODE(DebugStartWatch());
    if (!FtpPutFileEx(hConnect, pwzFilePath, pwFtpPath, dwFlags, dwContext))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpPutFileEx(%#08lx, \"%ls\", \"%hs\") returned %u. Time=%lums", hConnect, pwzFilePath, pwFtpPath, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpDeleteFileWrap

    DESCRIPTION:

    PERF Notes:
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 4ms (22ms once in a while)
        To: rigel.cyberpass.net <San Diego, CA>: 175ms - 291ms
        To: ftp.rz.uni-frankfurt.de <Germany>: ???????
\*****************************************************************************/
HRESULT FtpDeleteFileWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFtpFileName)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    DEBUG_CODE(DebugStartWatch());
    if (!FtpDeleteFileA(hConnect, pwFtpFileName))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpDeleteFile(%#08lx, \"%hs\") returned %u. Time=%lums", hConnect, pwFtpFileName, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpRenameFileWrap

    DESCRIPTION:

    PERF Notes:
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 4ms
        To: rigel.cyberpass.net <San Diego, CA>: 329ms - 446ms
        To: ftp.rz.uni-frankfurt.de <Germany>: ???????
\*****************************************************************************/
HRESULT FtpRenameFileWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFtpFileNameExisting, LPCWIRESTR pwFtpFileNameNew)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    DEBUG_CODE(DebugStartWatch());
    if (!FtpRenameFileA(hConnect, pwFtpFileNameExisting, pwFtpFileNameNew))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpRenameFile(%#08lx, \"%hs\", \"%hs\") returned %u. Time=%lums", hConnect, pwFtpFileNameExisting, pwFtpFileNameNew, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpOpenFileWrap

    DESCRIPTION:

    PERF Notes:
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 2ms
        To: rigel.cyberpass.net <San Diego, CA>: 757ms - 817ms
        To: ftp.rz.uni-frankfurt.de <Germany>: 2112ms - 10026ms
\*****************************************************************************/
HRESULT FtpOpenFileWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFtpFileName, DWORD dwAccess, DWORD dwFlags, DWORD_PTR dwContext, HINTERNET * phFileHandle)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    DEBUG_CODE(DebugStartWatch());
    *phFileHandle = FtpOpenFileA(hConnect, pwFtpFileName, dwAccess, dwFlags, dwContext);
    if (!*phFileHandle)
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpOpenFile(%#08lx, \"%hs\") returned %u. Time=%lums", hConnect, pwFtpFileName, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpCreateDirectoryWrap

    DESCRIPTION:

    PERF Notes:
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 3ms
        To: rigel.cyberpass.net <San Diego, CA>: 210ms - 350ms
        To: ftp.rz.uni-frankfurt.de <Germany>: ???????
\*****************************************************************************/
HRESULT FtpCreateDirectoryWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFtpPath)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    DEBUG_CODE(DebugStartWatch());
    if (!FtpCreateDirectoryA(hConnect, pwFtpPath))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpCreateDirectoryA(%#08lx, \"%hs\") returned %u. Time=%lums", hConnect, pwFtpPath, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FtpRemoveDirectoryWrap

    DESCRIPTION:

    PERF Notes:
    [Direct Net Connection]
        To: shapitst <Down the Hall>: 2ms
        To: rigel.cyberpass.net <San Diego, CA>: 157ms - 227ms
        To: ftp.rz.uni-frankfurt.de <Germany>: ???????
\*****************************************************************************/
HRESULT FtpRemoveDirectoryWrap(HINTERNET hConnect, BOOL fAssertOnFailure, LPCWIRESTR pwFtpPath)
{
    HRESULT hr = S_OK;
    DWORD dwError = 0;

    DEBUG_CODE(DebugStartWatch());
    if (!FtpRemoveDirectoryA(hConnect, pwFtpPath))
    {
        dwError = GetLastError();
        hr = HRESULT_FROM_WIN32(dwError);
    }
    DEBUG_CODE(TraceMsg(TF_WININET_DEBUG, "FtpRemoveDirectory(%#08lx, \"%hs\") returned %u. Time=%lums", hConnect, pwFtpPath, dwError, DebugStopWatch()));

    if (fAssertOnFailure)
    {
        WININET_ASSERT(SUCCEEDED(hr));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -