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

📄 ftppl.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *
 *    ftppl.cpp - FTP LPITEMIDLIST List object
 *
 *****************************************************************************/

#include "priv.h"
#include "ftppl.h"
#include "ftpurl.h"

typedef struct tagINETENUM
{
    HINTERNET               hint;
    BOOL *                  pfValidhinst;
    LPVOID                  pvData;
    LPFNPROCESSITEMCB       pfnProcessItemCB;
    LPCITEMIDLIST           pidlRoot;
    HRESULT                 hr;
} INETENUM;


/*****************************************************************************\
     FUNCTION: RecursiveEnum
 
    DESCRIPTION:
        This function will pack the parameters needed during the enum.
\*****************************************************************************/
HRESULT CFtpPidlList::RecursiveEnum(LPCITEMIDLIST pidlRoot, LPFNPROCESSITEMCB pfnProcessItemCB, HINTERNET hint, LPVOID pvData)
{
    INETENUM inetEnum = {hint, NULL, pvData, pfnProcessItemCB, pidlRoot, S_OK};

    Enum(RecursiveProcessPidl, (LPVOID) &inetEnum);

    return inetEnum.hr;
}


// lParam can be: 0 == do a case sensitive search.  1 == do a case insensitive search.
int CFtpPidlList::ComparePidlName(LPVOID pvPidl1, LPVOID pvPidl2, LPARAM lParam)
{
    DWORD dwFlags = FCMP_NORMAL;

    if (lParam)
        dwFlags |= FCMP_CASEINSENSE;

    // return < 0 for pvPidl1 before pvPidl2.
    // return == 0 for pvPidl1 equals pvPidl2.
    // return > 0 for pvPidl1 after pvPidl2.
    return FtpItemID_CompareIDsInt(COL_NAME, (LPCITEMIDLIST)pvPidl1, (LPCITEMIDLIST)pvPidl2, dwFlags);
}


HRESULT CFtpPidlList::InsertSorted(LPCITEMIDLIST pidl)
{
    m_pfl->InsertSorted(ILClone(pidl), CFtpPidlList::ComparePidlName, FALSE /*Case Insensitive*/);
    return S_OK;
};


int CFtpPidlList::FindPidlIndex(LPCITEMIDLIST pidlToFind, BOOL fCaseInsensitive)
{
    return m_pfl->SortedSearch((LPVOID) pidlToFind, CFtpPidlList::ComparePidlName, (LPARAM)fCaseInsensitive, DPAS_SORTED);
}


LPITEMIDLIST CFtpPidlList::FindPidl(LPCITEMIDLIST pidlToFind, BOOL fCaseInsensitive)
{
    LPITEMIDLIST pidlFound = NULL;
    int nIndex = FindPidlIndex(pidlToFind, fCaseInsensitive);

    if (-1 != nIndex)
    {
        pidlFound = ILClone(GetPidl(nIndex));
    }

    return pidlFound;
}


HRESULT CFtpPidlList::CompareAndDeletePidl(LPCITEMIDLIST pidlToDelete)
{
    HRESULT hr = S_FALSE;
    int nIndex = FindPidlIndex(pidlToDelete, FALSE /*Case Insensitive*/);

    if (-1 != nIndex)
    {
        LPITEMIDLIST pidlCurrent = GetPidl((UINT)nIndex);
        if (EVAL(pidlCurrent))
        {
            ASSERT(0 == FtpItemID_CompareIDsInt(COL_NAME, pidlCurrent, pidlToDelete, FCMP_NORMAL));
            m_pfl->DeletePtrByIndex(nIndex);
            ILFree(pidlCurrent);    // Deallocate the memory
            hr = S_OK;  // Found and deleted.
        }
    }

    return hr;
}


void CFtpPidlList::Delete(int nIndex)
{
    LPITEMIDLIST pidlToDelete = GetPidl(nIndex);

    ILFree(pidlToDelete);   // Free the memory.
    m_pfl->DeletePtrByIndex(nIndex);
}


HRESULT CFtpPidlList::ReplacePidl(LPCITEMIDLIST pidlSrc, LPCITEMIDLIST pidlDest)
{
    HRESULT hr = S_FALSE;
    int nIndex = FindPidlIndex(pidlSrc, FALSE);

    if (-1 != nIndex)
    {
        LPITEMIDLIST pidlCurrent = GetPidl((UINT)nIndex);
        if (EVAL(pidlCurrent))
        {
            ASSERT(0 == FtpItemID_CompareIDsInt(COL_NAME, pidlCurrent, pidlSrc, FCMP_NORMAL));
            ILFree(pidlCurrent);    // Deallocate the memory
            m_pfl->DeletePtrByIndex(nIndex);
            InsertSorted(pidlDest);         // This function does the ILClone()
            hr = S_OK;  // Found and deleted.
        }
    }

    return hr;
}

void CFtpPidlList::AssertSorted(void)
{
#ifdef DEBUG
    // For perf reasons, we need to keep this list in order.
    // This is mainly because parse display name looks thru
    // the list, so we want that to be fast.
    for (int nIndex = (GetCount() - 2); (nIndex >= 0); nIndex--)
    {
        LPITEMIDLIST pidl1 = GetPidl((UINT)nIndex);
        LPITEMIDLIST pidl2 = GetPidl((UINT)nIndex + 1);

        // Assert that pidl1 comes before pidl2.
        if (!EVAL(0 >= FtpItemID_CompareIDsInt(COL_NAME, pidl1, pidl2, FCMP_NORMAL)))
        {
            TCHAR szPidl1[MAX_PATH];
            TCHAR szPidl2[MAX_PATH];

            if (FtpID_IsServerItemID(pidl1))
                FtpPidl_GetServer(pidl1, szPidl1, ARRAYSIZE(szPidl1));
            else
                FtpPidl_GetDisplayName(pidl1, szPidl1, ARRAYSIZE(szPidl1));

            if (FtpID_IsServerItemID(pidl2))
                FtpPidl_GetServer(pidl2, szPidl2, ARRAYSIZE(szPidl2));
            else
                FtpPidl_GetDisplayName(pidl2, szPidl2, ARRAYSIZE(szPidl2));

            TraceMsg(TF_ERROR, "CFtpPidlList::AssertSorted() '%s' & '%s' where found out of order", szPidl1, szPidl2);
        }
        // We do NOT need to free pidl1 or pidl2 because we get a pointer to someone else's copy.
    }

#endif // DEBUG
}


void CFtpPidlList::TraceDump(LPCITEMIDLIST pidl, LPCTSTR pszCaller)
{
#ifdef DEBUG
/*
    TCHAR szUrl[MAX_URL_STRING];

    UrlCreateFromPidl(pidl, SHGDN_FORPARSING, szUrl, ARRAYSIZE(szUrl), ICU_USERNAME, FALSE);
    TraceMsg(TF_PIDLLIST_DUMP, "CFtpPidlList::TraceDump() root is '%s', called from '%s'", szUrl, pszCaller);

    // Let's look at the contents.
    for (int nIndex = (GetCount() - 1); (nIndex >= 0); nIndex--)
    {
        LPITEMIDLIST pidlFull = ILCombine(pidl, GetPidl((UINT)nIndex));

        if (pidlFull)
        {
            UrlCreateFromPidl(pidlFull, SHGDN_FORPARSING, szUrl, ARRAYSIZE(szUrl), ICU_USERNAME, FALSE);
            TraceMsg(TF_PIDLLIST_DUMP, "CFtpPidlList::TraceDump() Index=%d, url=%s", nIndex, szUrl);
            ILFree(pidlFull);
        }
    }
*/
#endif // DEBUG
}

void CFtpPidlList::UseCachedDirListings(BOOL fUseCachedDirListings)
{
    // Normally we do two passes in the tree walker code.  The first
    // pass is to count up the time required to do the download. We
    // normally force WININET to not use cached results because someone
    // else could have changed the contents on the server.
    // On the second pass, we normally do the work (upload, download, delete)
    // and we want to use the cached results to get the perf advantage
    // and the results shouldn't be more than a minute out of date.

    if (fUseCachedDirListings)
        m_dwInetFlags = INTERNET_NO_CALLBACK;
    else
        m_dwInetFlags = (INTERNET_NO_CALLBACK | INTERNET_FLAG_RESYNCHRONIZE | INTERNET_FLAG_RELOAD);
}

BOOL CFtpPidlList::AreAllFolders(void)
{
    BOOL fAllFolder = TRUE;

    for (int nIndex = (GetCount() - 1); fAllFolder && (nIndex >= 0); nIndex--)
    {
        LPITEMIDLIST pidl = GetPidl((UINT)nIndex);
        if (EVAL(pidl))
            fAllFolder = FtpPidl_IsDirectory(pidl, TRUE);

        // We do NOT need to free pidl because we get a pointer to someone else's copy.
    }

    return fAllFolder;
}


BOOL CFtpPidlList::AreAllFiles(void)
{
    BOOL fAllFiles = TRUE;

    for (int nIndex = (GetCount() - 1); fAllFiles && (nIndex >= 0); nIndex--)
    {
        LPITEMIDLIST pidl = GetPidl((UINT)nIndex);
        if (EVAL(pidl))
            fAllFiles = !FtpPidl_IsDirectory(pidl, TRUE);

        // We do NOT need to free pidl because we get a pointer to someone else's copy.
    }

    return fAllFiles;
}


/*****************************************************************************
 *
 *    CFtpPidlList::_Fill
 *
 *    Fill a list with an array.
 *
 *    The elements in the array are copied rather than stolen.
 *
 *****************************************************************************/

HRESULT CFtpPidlList::_Fill(int cpidl, LPCITEMIDLIST rgpidl[])
{
    HRESULT hres = S_OK;

    for (int ipidl = 0; (ipidl < cpidl) && SUCCEEDED(hres); ipidl++)
    {
        ASSERT(IsValidPIDL(rgpidl[ipidl]));
        hres = InsertSorted(rgpidl[ipidl]);
    }

    return hres;
}


/*****************************************************************************
 *
 *    CFtpPidlList::GetPidlList
 *
 *****************************************************************************/

LPCITEMIDLIST * CFtpPidlList::GetPidlList(void)
{
    LPITEMIDLIST * ppidl;

    ppidl = (LPITEMIDLIST *) LocalAlloc(LPTR, sizeof(LPITEMIDLIST) * GetCount());
    if (ppidl)
    {
        int nIndex;

        for (nIndex = 0; nIndex < GetCount(); nIndex++)
        {
            // Later we can make this user ILClone() if we want to be able to wack on the
            // pidl list while this list is being used.
            ppidl[nIndex] = GetPidl(nIndex);
        }
    }

    return (LPCITEMIDLIST *) ppidl;
}


/*****************************************************************************
 *
 *    CFtpPidlList::FreePidlList
 *
 *****************************************************************************/

void CFtpPidlList::FreePidlList(LPCITEMIDLIST * ppidl)
{
    LocalFree(ppidl);
}


/*****************************************************************************
 *
 *    CFtpPidlList_Create
 *
 *    Start up a new pv list, with a recommended initial size and other
 *    callback info.
 *
 *****************************************************************************/

HRESULT CFtpPidlList_Create(int cpidl, LPCITEMIDLIST rgpidl[], CFtpPidlList ** ppflpidl)

⌨️ 快捷键说明

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