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

📄 ftpdrop.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            hr = _CopyOneHdrop(szFSSource, szFtpDest);
            if (EVAL(m_ppd))
                EVAL(SUCCEEDED(m_ppd->SetProgress64(m_uliBytesCompleted.QuadPart, m_uliBytesTotal.QuadPart)));

            // Did we fail to copy the file?
            if (FAILED(hr) && (HRESULT_FROM_WIN32(ERROR_CANCELLED) != hr))
            {
                if (!IsValidFtpAnsiFileName(szFSSource) || !IsValidFtpAnsiFileName(szFtpDest))
                    int nResult = DisplayWininetError(m_hwnd, TRUE, HRESULT_CODE(hr), IDS_FTPERR_TITLE_ERROR, IDS_FTPERR_INVALIDFTPNAME, IDS_FTPERR_WININET, MB_OK, m_ppd);
                else
                    int nResult = DisplayWininetError(m_hwnd, TRUE, HRESULT_CODE(hr), IDS_FTPERR_TITLE_ERROR, IDS_FTPERR_FILECOPY, IDS_FTPERR_WININET, MB_OK, m_ppd);
                hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
            }
            if (S_FALSE == hr)
            {
                // _CopyOneHdrop() returning S_FALSE means we hit the end of the iteration,
                // in this case, _ConfirmCopy() only meant to skip this one file, so
                // change to S_OK to continue with the rest of the files.
                hr = S_OK;
            }
        }
    }

    Str_SetPtr((LPTSTR *) &m_pszzFSSource, NULL);
    Str_SetPtr((LPTSTR *) &m_pszzFtpDest, NULL);

    return hr;
}


HRESULT CDropOperation::_ConfirmCopy(LPCWSTR pszLocal, LPCWSTR pszFtpName, BOOL * pfFireChangeNotify)
{
    return ConfirmCopy(pszLocal, pszFtpName, &m_ops, m_hwnd, m_pff, m_pfd, NULL, m_cobj, pfFireChangeNotify);
}


/*****************************************************************************\
    CopyCB

    Callback procedure that copies a single hdrop / map.
\*****************************************************************************/
HRESULT CDropOperation::CopyCB(HINTERNET hint, HINTPROCINFO * phpi, LPVOID pv, BOOL * pfReleaseHint)
{
    LPCOPYONEHDROPINFO pcohi = (LPCOPYONEHDROPINFO) pv;
    pcohi->progInfo.hint = hint;
    HRESULT hr;

    InternetSetStatusCallbackWrap(hint, TRUE, FtpProgressInternetStatusCB);
    hr = CopyFileSysItem(hint, phpi, pcohi);
    if (!pcohi->progInfo.hint)
        *pfReleaseHint = FALSE;     // We had to close hint to get the cancel.

    return hr;
}


HRESULT CDropOperation::_CopyOneHdrop(LPCWSTR pszFSSource, LPCWSTR pszFtpDest)
{
    HRESULT hr;
    BOOL fFireChangeNotify = TRUE;

    pszFtpDest = PathFindFileName(pszFtpDest);

    hr = _ConfirmCopy(pszFSSource, pszFtpDest, &fFireChangeNotify);
    if (S_OK == hr)
    {
        WCHAR wzTo[MAX_PATH];
        COPYONEHDROPINFO cohi = {0};

        cohi.pff = m_pff;
        cohi.pszFSSource = pszFSSource;
        cohi.pszFtpDest = pszFtpDest;
        cohi.pszDir = wzTo;
        cohi.dwOperation = COHDI_COPY_FILES;
        cohi.ops = m_ops;
        cohi.fIsRoot = TRUE;
        cohi.pmlc = &m_mlc;
        cohi.pidlServer = FtpCloneServerID(m_pff->GetPrivatePidlReference());
        cohi.fFireChangeNotify = fFireChangeNotify;
        cohi.progInfo.ppd = m_ppd;

        cohi.progInfo.uliBytesCompleted.QuadPart = m_uliBytesCompleted.QuadPart;
        cohi.progInfo.uliBytesTotal.QuadPart = m_uliBytesTotal.QuadPart;
        EVAL(SUCCEEDED(m_pfd->GetDisplayPath(wzTo, ARRAYSIZE(wzTo))));

        // TODO: have CopyCB also update the dialog.
        hr = m_pfd->WithHint(NULL, m_hwnd, CopyCB, &cohi, NULL, m_pff);

        if (SUCCEEDED(hr) && (m_de == DROPEFFECT_MOVE))
        {
            //  We delete the file with SHFileOperation to keep the
            //  disk free space statistics up to date.
            //
            //  BUGBUG -- If coming from a file name map, maybe it's
            //  being dragged from the recycle bin, in which case, doing
            //  an FO_DELETE will put it back in!
            SHFILEOPSTRUCT sfo = {0};
            
            sfo.hwnd = NULL,                // No HWND so NO UI.
            sfo.wFunc  = FO_DELETE;
            sfo.pFrom  = pszFSSource;       // Multiple files in list.
            sfo.fFlags = (FOF_SILENT | FOF_NOCONFIRMATION /*| FOF_MULTIDESTFILES*/);  // No HWND so NO UI.

            int nResult = SHFileOperation(&sfo);
            if (0 != nResult)
                TraceMsg(TF_ALWAYS, "In CDropOperation::_CopyOneHdrop() and caller wanted MOVE but we couldn't delete the files after the copy.");
        }
        m_uliBytesCompleted = cohi.progInfo.uliBytesCompleted;
        m_uliBytesTotal = cohi.progInfo.uliBytesTotal;
        m_ops = cohi.ops;
    }
    else
    {
        if (S_FALSE == hr)
        {
            // _CopyOneHdrop() returning S_FALSE means we hit the end of the iteration,
            // in this case, _ConfirmCopy() only meant to skip this one file, so
            // change to S_OK to continue with the rest of the files.
            hr = S_OK;
        }
    }

    return hr;
}


/*****************************************************************************
    FUNCTION: SetEffect

    DESCRIPTION:
        Set the appropriate drop effect feedback.

    In the absence of keyboard modifiers, use CTRL (copy), unless
    DROPEFFECT_COPY is not available, in which case we use SHIFT (move).

    If anything else is set, then panic out to DROPEFFECT_NONE.

    Note that we do *not* use g_cfPreferredDe.  The only things
    we support are DROPEFFECT_COPY and DROPEFFECT_MOVE, and we always prefer DROPEFFECT_COPY.

    BUGBUG -- ignoring g_cfPreferredDe messes up cut/paste, though.
 *****************************************************************************/

HRESULT CFtpDrop::SetEffect(DROPEFFECT * pde)
{
    DWORD de;            // Preferred drop effect

    // Don't even think about effects that we don't support
    *pde &= m_grfksAvail;

    switch (m_grfks & (MK_SHIFT | MK_CONTROL))
    {
    case 0:            // No modifier, use COPY if possible
        if (*pde & DROPEFFECT_COPY)
        {
    case MK_CONTROL:
            de = DROPEFFECT_COPY;
        }
        else
        {
    case MK_SHIFT:
            de = DROPEFFECT_MOVE;
        }
        break;

    default:
        de = 0;
        break;        // Cannot link
    }
    *pde &= de;

    TraceMsg(TF_FTPDRAGDROP, "CFtpDrop::SetEffect(DROPEFFECT=%08x) m_grfksAvail=%08x", *pde, m_grfksAvail);
    return S_OK;
}


BOOL CFtpDrop::_IsFTPOperationAllowed(IDataObject * pdto)
{
#ifdef FEATURE_FTP_TO_FTP_COPY
    BOOL fIsFTPOperationAllowed = TRUE;

    // There are a few things we don't allow.
    // Is the Drop FTP Location the same
    // folder that the dragged items are already in?
    if (0)
    {
        // TODO:
    }
    
    return fIsFTPOperationAllowed;
#else // FEATURE_FTP_TO_FTP_COPY

    // Disallow all FTP Operations
    return !_HasData(pdto, &g_dropTypes[DROP_FTP_PRIVATE]);
#endif // FEATURE_FTP_TO_FTP_COPY
}


/*****************************************************************************\
    GetEffectsAvail

    Look at the object to see what drop effects are available.

    If we have a file group descriptor or an HDROP,
    then file contents are available.  (We assume that if you have
    a FGD, then a Contents isn't far behind.)

    In a perfect world, we would also validate the contents of
    each file in the group descriptor, to ensure that the contents
    are droppable.  We skimp on that because it's too expensive.
\*****************************************************************************/
DWORD CFtpDrop::GetEffectsAvail(IDataObject * pdto)
{
    DWORD grfksAvail = 0;

    // Is this from an Ftp Shell Extension?
    if (_IsFTPOperationAllowed(pdto))
    {
        // No or it's allowed, then we will accept it.  We reject everything
        // else because we can't do Ftp1->Ftp2 copying without
        // using the local machine as a temp location. (Ftp1->Local->Ftp2)

        if (_HasData(pdto, &g_dropTypes[DROP_Hdrop]) ||
            _HasData(pdto, &g_dropTypes[DROP_FGDW]) ||
            _HasData(pdto, &g_dropTypes[DROP_FGDA]))
        {
            TraceMsg(TF_FTPDRAGDROP, "CFtpDrop::GetEffectsAvail() SUCCEEDED");
            grfksAvail = DROPEFFECT_COPY + DROPEFFECT_MOVE;
        }
        else
        {
            TraceMsg(TF_FTPDRAGDROP, "CFtpDrop::GetEffectsAvail() FAILED");
#ifdef DEBUG
            STGMEDIUM sm;
            HRESULT hres = pdto->GetData(&g_dropTypes[DROP_URL], &sm);
            if (SUCCEEDED(hres))
            {
                TraceMsg(TF_FTPDRAGDROP, "CFtpDrop::GetEffectsAvail(%08x) URL: %hs", pdto, GlobalLock(sm.hGlobal));
                GlobalUnlock(sm.hGlobal);
                ReleaseStgMedium(&sm);
            }
            else
            {
                TraceMsg(TF_FTPDRAGDROP, "CFtpDrop::GetEffectsAvail(%08x) No URL", pdto);
            }
#endif // DEBUG
        }
    }

    return grfksAvail;
}


/*****************************************************************************\
    GetEffect

    Return the drop effect to use.

    If this is a nondefault drag/drop, then put up a menu.  Else,
    just go with the default.

    m_de = default effect
    m_pde -> possible effects (and receives result)
\*****************************************************************************/
DROPEFFECT CFtpDrop::GetEffect(POINTL pt)
{
    TraceMsg(TF_FTPDRAGDROP, "CFtpDrop::GetEffect() m_de=%08x. m_grfks=%08x", m_de, m_grfks);

    if (m_de && (m_grfks & MK_RBUTTON))
    {
        HMENU hmenuMain = LoadMenu(g_hinst, MAKEINTRESOURCE(IDM_DROPCONTEXT));
        HMENU hmenu = GetSubMenu(hmenuMain, 0);
        DROPEFFECT de;

        ASSERT(*m_pde & m_de);
        SetMenuDefaultItem(hmenu, m_de, 0);
        if (!(*m_pde & DROPEFFECT_COPY))
            DeleteMenu(hmenu, DROPEFFECT_COPY, MF_BYCOMMAND);

        if (!(*m_pde & DROPEFFECT_MOVE))
            DeleteMenu(hmenu, DROPEFFECT_MOVE, MF_BYCOMMAND);

        // _UNOBVIOUS_:  Defview is incestuous with itself.
        // If the drop target originated from Shell32.dll, then
        // it leaves the image of the dropped object on the screen
        // while the menu is up, which is nice.  Otherwise, it removes
        // the image of the dropped object before the drop target
        // receives its IDropTarget::Drop.
        // Which means that outside shell extensions can't take
        // advantage of the "pretty drop UI" feature.

        // _UNOBVIOUS_:  Have to force foregroundness, else the input
        // gets screwed up.
        if (m_hwnd)
            SetForegroundWindow(m_hwnd);

        de = TrackPopupMenuEx(hmenu,
                      TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_VERTICAL |
                      TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y,
                      m_hwnd, 0);

        DestroyMenu(hmenuMain);
        m_de = de;
    }
    *m_pde = m_de;

    TraceMsg(TF_FTPDRAGDROP, "CFtpDrop::GetEffect(%08x) -> %08x", this, m_de);
    return m_de;
}


/****************************************************\
    FUNCTION: _StartBackgroundInteration

    DESCRIPTION:
\****************************************************/
HRESULT CFtpDrop::_StartBackgroundInteration(void)
{
    CDropOperation * pDropOperation;
    HRESULT hr = CDropOperation_Create(m_pff, m_hwnd, m_pszzFSSource, m_pszzFtpDest, &pDropOperation, m_de, m_ops, m_cobj);
    
    // Did it succeed?
    if (EVAL(SUCCEEDED(hr)))
    {
        // Yes, so NULL out m_pszzFSSource, m_pszzFtpDest because we gave them our copies.
        //  Ugly but allocation is uglier.
        m_pszzFSSource = NULL;
        m_pszzFtpDest = NULL;

        EVAL(SUCCEEDED(hr = pDropOperation->DoOperation(TRUE)));
        pDropOperation->Release();
    }

    return hr;
}


/****************************************************\
    FUNCTION: _DoCountIteration

    DESCRIPTION:
\****************************************************/
HRESULT CFtpDrop::_DoCountIteration(void)
{
    HRESULT hr = S_OK;
    LPCTSTR pszzFSSource = m_pszzFSSource;
    LPCTSTR pszzFtpDest = m_pszzFtpDest;

    while (S_OK == hr)
    {
        TCHAR szFSSource[MAX_PATH];
        TCHAR szFtpDest[MAX_PATH];

        hr = _EnumOneHdrop(&pszzFSSource, &pszzFtpDest, szFSSource, ARRAYSIZE(szFSSource), szFtpDest, ARRAYSIZE(szFtpDest));
        if (S_OK == hr)
            m_cobj++;
    }

    if (hr == S_FALSE)
        hr = S_OK;        // Enumerated to completion

⌨️ 快捷键说明

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