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

📄 ftpobj.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        {
            m_pflHfpl->AddRef();
            pPidlList = m_pflHfpl;
        }

        if (pPidlList)
        {
            hGlobal = Misc_HFGD_Create(pPidlList, m_pff->GetPrivatePidlReference(), fUnicode);
            IUnknown_Set(&m_pflHfpl, pPidlList);
            m_pflHfpl->TraceDump(m_pff->GetPrivatePidlReference(), TEXT("_DelayRender_FGD() TraceDump after"));
            pPidlList->Release();
        }
    }
    else
    {
        // Suppress future UI.  We don't need to check any more
        // because our pidl won't change.  We could not pass PUAF_WARN_IF_DENIED
        // but that won't suppress the UI in the prompt case. (Only admins can
        // turn on the prompt case).
        m_fCheckSecurity = FALSE;
    }

    return hGlobal;
}


/*****************************************************************************\
    FUNCTION: _DelayRender_IDList

    DESCRIPTION:
        Delay-render an ID List Array (HIDA)
\*****************************************************************************/
HRESULT CFtpObj::_DelayRender_IDList(STGMEDIUM * pStgMedium)
{
    pStgMedium->hGlobal = Misc_HIDA_Create(m_pff->GetPublicRootPidlReference(), m_pflHfpl);

    ASSERT(pStgMedium->hGlobal);
    return S_OK;
}


/*****************************************************************************\
    FUNCTION: _DelayRender_URL

    DESCRIPTION:
        The caller wants an URL in an Ansi String
\*****************************************************************************/
HRESULT CFtpObj::_DelayRender_URL(STGMEDIUM * pStgMedium)
{
    LPSTR pszUrl = NULL;
    LPITEMIDLIST pidlFull = NULL;
    LPITEMIDLIST pidl = m_pflHfpl->GetPidl(0);

    ASSERT(pidl);   // We need this
    // Sometimes m_pflHfpl->GetPidl(0) is fully qualified and
    // sometimes it's not.
    if (!FtpID_IsServerItemID(pidl))
    {
        pidlFull = ILCombine(m_pfd->GetPidlReference(), pidl);
        pidl = pidlFull;
    }

    ASSERT(m_pflHfpl->GetCount() == 1); // How do we give them more than 1 URL?
    if (pidl)
    {
        TCHAR szUrl[MAX_URL_STRING];

        if (EVAL(SUCCEEDED(UrlCreateFromPidl(pidl, SHGDN_FORADDRESSBAR, szUrl, ARRAYSIZE(szUrl), (ICU_ESCAPE | ICU_USERNAME), TRUE))))
        {
            DWORD cchSize = (lstrlen(szUrl) + 1);

            pszUrl = (LPSTR) LocalAlloc(LPTR, (cchSize * sizeof(CHAR)));
            if (EVAL(pszUrl))
                SHTCharToAnsi(szUrl, pszUrl, cchSize);
        }

        ILFree(pidlFull);
    }

    pStgMedium->hGlobal = (HGLOBAL) pszUrl;
    return S_OK;
}



#pragma BEGIN_CONST_DATA

DROPEFFECT c_deCopyLink = DROPEFFECT_COPY | DROPEFFECT_LINK;
DROPEFFECT c_deLink     =          DROPEFFECT_LINK;

#pragma END_CONST_DATA
/*****************************************************************************\
    FUNCTION: _DelayRender_PrefDe

    DESCRIPTION:
        Delay-render a preferred drop effect.
 
    The preferred drop effect is DROPEFFECT_COPY (with DROPEFFECT_LINK as fallback),
    unless you are dragging an FTP site, in which case it's just DROPEFFECT_LINK.
 
    DROPEFFECT_MOVE is never preferred.  We can do it; it just isn't preferred.
 
    BUGBUG/NOTES: About DROPEFFECT_MOVE
    We cannot support Move on platforms before NT5 because of a Recycle Bin bug
    were it would clain to have succeeded with the copy but it actually didn't
    copy anything.  On NT5, the Recycle Bin drop target will call pDataObject->SetData()
    with a data type of "Dropped On" and the data being the CLSID of the drop
    target in addition to really copying the files to the recycle bin.  This will 
    let us delete the files knowing they are in the recycle bin.
\*****************************************************************************/
HRESULT CFtpObj::_DelayRender_PrefDe(STGMEDIUM * pStgMedium)
{
    DROPEFFECT * pde;

    if (!m_pfd->IsRoot())
        pde = &c_deCopyLink;
    else
        pde = &c_deLink;

    return Misc_CreateHglob(sizeof(*pde), pde, &pStgMedium->hGlobal);
}


/*****************************************************************************\
    FUNCTION: _RenderOlePersist

    DESCRIPTION:
        When the copy source goes away (the process shuts down), it calls
    OleFlushClipboard.  OLE will then copy our data, release us, and then
    give out our data later.  This works for most things except for:
    1. When lindex needs to very.  This doesn't work because ole doesn't know
       how to ask us how may lindexs they need to copy.
    2. If this object has a private interface OLE doesn't know about.  For us,
       it's IAsyncOperation.

   To get around this problem, we want OLE to recreate us when some possible
   paste target calls OleGetClipboard.  We want OLE to call OleLoadFromStream()
   to have us CoCreated and reload our persisted data via IPersistStream.
   OLE doesn't want to do this by default or they may have backward compat
   problems so they want a sign from the heavens, or at least from us, that
   we will work.  They ping our "OleClipboardPersistOnFlush" clipboard format
   to ask this.
\*****************************************************************************/
HRESULT CFtpObj::_RenderOlePersist(STGMEDIUM * pStgMedium)
{
    // The actual cookie value is opaque to the outside world.  Since
    // we don't use it either, we just leave it at zero in case we use
    // it in the future.  It's mere existence will cause OLE to do the
    // use our IPersistStream, which is what we want.
    DWORD dwCookie = 0;
    return Misc_CreateHglob(sizeof(dwCookie), &dwCookie, &pStgMedium->hGlobal);
}


/*****************************************************************************\
    FUNCTION: _RenderFGD

    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::_RenderFGD(int nIndex, STGMEDIUM * pStgMedium)
{
    HRESULT hr = _DoProgressForLegacySystemsPre();

    if (SUCCEEDED(hr))
        pStgMedium->hGlobal = _DelayRender_FGD((DROP_FGDW == nIndex) ? TRUE : FALSE);

    if (!pStgMedium->hGlobal)
        hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);    // Probably failed because of Zones check.

    return hr;
}


/*****************************************************************************\
    FUNCTION: _ForceRender

    DESCRIPTION:
        We previously delayed rendering the data for perf reasons.  This function
    was called, so we now need to render the data.
\*****************************************************************************/
HRESULT CFtpObj::_ForceRender(int nIndex)
{
    HRESULT hr = S_OK;

    // We only support HGLOBALs here, but the caller may be valid
    // to ask for something we don't support or an extended data.
    //    ASSERT((m_stgCache[nIndex].tymed) == TYMED_HGLOBAL);

    if (!m_stgCache[nIndex].hGlobal)
    {
        STGMEDIUM medium = {TYMED_HGLOBAL, 0, NULL};

        switch (nIndex)
        {
        case DROP_FCont:
            ASSERT(0);
            break;
        case DROP_FGDW:
        case DROP_FGDA:
            hr = _RenderFGD(nIndex, &medium);
            break;
        case DROP_IDList:
            hr = _DelayRender_IDList(&medium);
            break;
/* Nuke
        case DROP_Offsets:
            ASSERT(0);
//            hglob = _DelayRender_Offsets();
            break;
*/
        case DROP_PrefDe:
            hr = _DelayRender_PrefDe(&medium);
            break;
        case DROP_PerfDe:
            ASSERT(0);
//            hglob = _DelayRender_PerfDe();
            break;
        case DROP_FTP_PRIVATE:
            hr = DV_E_FORMATETC;
            break;
        case DROP_OLEPERSIST:
            hr = _RenderOlePersist(&medium);
            break;
        case DROP_Hdrop:
            ASSERT(0);
//            hglob = _DelayRender_Hdrop();
            break;
        case DROP_FNMA:
            ASSERT(0);
//            hglob = _DelayRender_FNM();
            break;
        case DROP_FNMW:
            ASSERT(0);
//            hglob = _DelayRender_FNM();
            break;
        case DROP_URL:
            hr = _DelayRender_URL(&medium);
            break;
        default:
            ASSERT(0);      // Should never hit.
            break;
        }

        if (medium.hGlobal)  // Will fail if the Zones Security Check Fails.
        {
            m_stgCache[nIndex].pUnkForRelease = NULL;
            m_stgCache[nIndex].hGlobal = medium.hGlobal;
        }
        else
        {
            if (S_OK == hr)
                hr = E_OUTOFMEMORY;
        }
    }

    if (FAILED(hr))
        TraceMsg(TF_FTPDRAGDROP, "CFtpObj::_ForceRender() FAILED. hres=%#08lx", hr);

    return hr;
}


/*****************************************************************************\
    FUNCTION: _DoProgressForLegacySystemsPre

    DESCRIPTION:
        Shell's pre-NT5 didn't do progress on the File Contents drop, so we
    will do it here.  This function will display a progress dialog while we
    walk the server and expand the pidls that are needed to be copied.
    Later, 
\*****************************************************************************/
HRESULT CFtpObj::_DoProgressForLegacySystemsPre(void)
{
    HRESULT hr = S_OK;

    if (DEBUG_LEGACY_PROGRESS || (SHELL_VERSION_NT5 > GetShellVersion()))
    {
        TraceMsg(TF_ALWAYS, "CFtpObj::_DoProgressForLegacySystemsPre() going to do the Legacy dialogs.");

        // Do we need to initialize the list?
        if (!m_ppd && (-1 == m_nStartIndex))
        {
            // Yes, so create the create the dialog and find the sizes of the list.
            if (m_ppd)
                _CloseProgressDialog();

            m_uliCompleted.QuadPart = 0;
            m_uliTotal.QuadPart = 0;
            m_ppd = CProgressDialog_CreateInstance(IDS_COPY_TITLE, IDA_FTPDOWNLOAD);
            if (EVAL(m_ppd))
            {
                WCHAR wzProgressDialogStr[MAX_PATH];

                // Tell the user we are calculating how long it will take.
                if (EVAL(LoadStringW(HINST_THISDLL, IDS_PROGRESS_DOWNLOADTIMECALC, wzProgressDialogStr, ARRAYSIZE(wzProgressDialogStr))))
                    EVAL(SUCCEEDED(m_ppd->SetLine(2, wzProgressDialogStr, FALSE, NULL)));

                // We give a NULL punkEnableModless because we don't want to go modal.
                EVAL(SUCCEEDED(m_ppd->StartProgressDialog(NULL, NULL, PROGDLG_AUTOTIME, NULL)));
           }
        }
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: _DoProgressForLegacySystemsStart

    DESCRIPTION:
        Shell's pre-NT5 didn't do progress on the File Contents drop, so we
    will do it here.  Only return FAILED(hr) if IProgressDialog::HasUserCancelled().
\*****************************************************************************/
HRESULT CFtpObj::_DoProgressForLegacySystemsStart(LPCITEMIDLIST pidl, int nIndex)
{
    HRESULT hr = S_OK;

    if (DEBUG_LEGACY_PROGRESS || (SHELL_VERSION_NT5 > GetShellVersion()))
    {
        TraceMsg(TF_ALWAYS, "CFtpObj::_DoProgressForLegacySystemsStart() going to do the Legacy dialogs.");

        // Do we need to initialize the list?
        if (-1 == m_nStartIndex)
            hr = _SetProgressDialogValues(nIndex);   // Yes, so do so.

        if (EVAL(m_ppd))
        {
            WCHAR wzTemplate[MAX_PATH];
            WCHAR wzPath[MAX_PATH];
            WCHAR wzStatusText[MAX_PATH];
            LPITEMIDLIST pidlBase = (LPITEMIDLIST) pidl;

            EVAL(SUCCEEDED(m_ppd->StartProgressDialog(NULL, NULL, PROGDLG_AUTOTIME, NULL)));

            // Generate the string "Downloading <FileName>..." status string
            EVAL(LoadStringW(HINST_THISDLL, IDS_DOWNLOADING, wzTemplate, ARRAYSIZE(wzTemplate)));
            wnsprintfW(wzStatusText, ARRAYSIZE(wzStatusText), wzTemplate, FtpPidl_GetLastItemDisplayName(pidl));
            EVAL(SUCCEEDED(m_ppd->SetLine(1, wzStatusText, FALSE, NULL)));

            if (FtpPidl_IsDirectory(pidl, FALSE))
            {
                pidlBase = ILClone(pidl);
                ILRemoveLastID(pidlBase);
            }

            // Generate the string "From <SrcFileDir>" status string
            GetDisplayPathFromPidl(pidlBase, wzPath, ARRAYSIZE(wzPath), TRUE);
            EVAL(LoadStringW(HINST_THISDLL, IDS_DL_SRC_DIR, wzTemplate, ARRAYSIZE(wzTemplate)));
            wnsprintfW(wzStatusText, ARRAYSIZE(wzStatusText), wzTemplate, wzPath);
            EVAL(SUCCEEDED(m_ppd->SetLine(2, wzStatusText, FALSE, NULL)));

            EVAL(SUCCEEDED(m_ppd->SetProgress64(m_uliCompleted.QuadPart, m_uliTotal.QuadPart)));
            TraceMsg(TF_ALWAYS, "CFtpObj::_DoProgressForLegacySystemsStart() SetProgress64(%#08lx, %#08lx)", m_uliCompleted.LowPart, m_uliTotal.LowPart);
            if (m_ppd->HasUserCancelled())
                hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);

            if (pidlBase != pidl)   // Did we allocated it?
                ILFree(pidlBase);
        }
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: _DoProgressForLegacySystemsPost

    DESCRIPTION:
        Shell's pre-NT5 didn't do progress on the File Contents drop, so we
    will do it here.  Only return FAILED(hr) if IProgressDialog::HasUserCancelled().
\*****************************************************************************/
HRESULT CFtpObj::_DoProgressForLegacySystemsPost(LPCITEMIDLIST pidl, BOOL fLast)
{
    HRESULT hr = S_OK;

    if ((DEBUG_LEGACY_PROGRESS || (SHELL_VERSION_NT5 > GetShellVersion())) && EVAL(m_ppd))
    {
        if (pidl)
        {
            // Add the file size to the Completed.
            m_uliCompleted.QuadPart += FtpPidl_GetFileSize(pidl);
        }

        TraceMsg(TF_ALWAYS, "CFtpObj::_DoProgressForLegacySystemsPost() Closing DLG");

        if (fLast)
            IUnknown_Set((IUnknown **)&m_ppd, NULL);    // The stream will close the dialog and release it.
    }

    return hr;
}

⌨️ 快捷键说明

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