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

📄 ftpobj.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

HRESULT CFtpObj::_SetProgressDialogValues(int nIndex)
{
    HRESULT hr = S_OK;

    m_nStartIndex = nIndex;
    if (EVAL(m_ppd))
    {
        // Calculate m_nEndIndex
        while (nIndex < m_pflHfpl->GetCount())
        {
            if (!FtpPidl_IsDirectory(m_pflHfpl->GetPidl(nIndex), FALSE))
                m_nEndIndex = nIndex;
            nIndex++;
        }

        for (nIndex = 0; nIndex < m_pflHfpl->GetCount(); nIndex++)
        {
            LPCITEMIDLIST pidl = m_pflHfpl->GetPidl(nIndex);
            m_uliTotal.QuadPart += FtpPidl_GetFileSize(pidl);
        }

        // Reset because the above for loop can take a long time and the estimated time
        // is based on the time between ::StartProgressDialog() and the first
        // ::SetProgress() call.
        EVAL(SUCCEEDED(m_ppd->Timer(PDTIMER_RESET, NULL)));
   }

    return hr;
}


HRESULT CFtpObj::_CloseProgressDialog(void)
{
    m_nStartIndex = -1; // Indicate we haven't inited yet.
    if (m_ppd)
    {
        EVAL(SUCCEEDED(m_ppd->StopProgressDialog()));
        IUnknown_Set((IUnknown **)&m_ppd, NULL);
    }
    return S_OK;
}


HRESULT CFtpObj::_RefThread(void)
{
    if (NULL == m_punkThreadRef)
    {
        // This is valid to fail from some hosts who won't go away,
        // so they don't need to support ref counting threads.
        SHGetThreadRef(&m_punkThreadRef);
    }

    return S_OK;
}


HRESULT CFtpObj::_RenderFileContents(LPFORMATETC pfe, LPSTGMEDIUM pstg)
{
    HRESULT hr = E_INVALIDARG;

    // callers have a bad habit of asking for lindex == -1 because
    // that means 'all' data.  But how can you hand out one IStream* for
    // all files?
    if (-1 != pfe->lindex)
    {
        LPITEMIDLIST pidl = m_pflHfpl->GetPidl(pfe->lindex);
        //    FileContents are always regenerated afresh.
        pstg->pUnkForRelease = 0;
        pstg->tymed = TYMED_ISTREAM;

        if (EVAL(pidl))
        {
            hr = _DoProgressForLegacySystemsStart(pidl, pfe->lindex);
            if (SUCCEEDED(hr))
            {
                // Is it a directory?
                if (FtpPidl_IsDirectory(pidl, FALSE))
                {
                    // Yes, so pack the name and attributes
                    hr = DV_E_LINDEX;
                    AssertMsg(0, TEXT("Someone is asking for a FILECONTENTs for a directory item."));
                }
                else
                {
                    // No, so give them the stream.
                    
                    // shell32 v5 will display progress dialogs, but we need to
                    // display progress dialogs for shell32 v3 or v4.  We do this
                    // by creating the progress dialog when the caller asks for the
                    // first stream.  We then need to find out when they call for
                    // the last stream and then hand off the IProgressDialog to the
                    // CFtpStm.  The CFtpStm will then close down the dialog when the
                    // caller closes it.
                    hr = CFtpStm_Create(m_pfd, pidl, GENERIC_READ, &pstg->pstm, m_uliCompleted, m_uliTotal, m_ppd, (pfe->lindex == m_nEndIndex));
                    EVAL(SUCCEEDED(_DoProgressForLegacySystemsPost(pidl, (pfe->lindex == m_nEndIndex))));
                }
            }
            else
            {
                // The user may have cancelled
                ASSERT(HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr);
            }
        }

        if (FAILED(hr))
            _CloseProgressDialog();
    }

    //TraceMsg(TF_FTPDRAGDROP, "CFtpObj::GetData() CFtpStm_Create() returned hr=%#08lx", hr);
    return hr;
}


/*****************************************************************************\
    FUNCTION: IsEqualFORMATETC
  
    DESCRIPTION:
        The two fields of a FORMATETC that need to match to be equivalent are:
    cfFormat and lindex.
\*****************************************************************************/
BOOL IsEqualFORMATETC(FORMATETC * pfe1, FORMATETC * pfe2)
{
    BOOL fIsEqual = FALSE;

    if ((pfe1->cfFormat == pfe2->cfFormat) && (pfe1->lindex == pfe2->lindex))
    {
        fIsEqual = TRUE;
    }

    return fIsEqual;
}


/*****************************************************************************\
      FUNCTION: _FreeExtraData
  
      DESCRIPTION:
\*****************************************************************************/
int CFtpObj::_DSA_FreeCB(LPVOID pvItem, LPVOID pvlparam)
{
    FORMATETC_STGMEDIUM * pfs = (FORMATETC_STGMEDIUM *) pvItem;

    if (EVAL(pfs))
        ReleaseStgMedium(&(pfs->medium));

    return 1;
}


/*****************************************************************************\
      FUNCTION: _FindSetDataIndex
  
      DESCRIPTION:
\*****************************************************************************/
int CFtpObj::_FindExtraDataIndex(FORMATETC *pfe)
{
    int nIndex;

    for (nIndex = (DSA_GetItemCount(m_hdsaSetData) - 1); nIndex >= 0; nIndex--)
    {
        FORMATETC_STGMEDIUM * pfs = (FORMATETC_STGMEDIUM *) DSA_GetItemPtr(m_hdsaSetData, nIndex);

        if (IsEqualFORMATETC(pfe, &pfs->formatEtc))
        {
            return nIndex;
        }
    }

    return -1;
}


/*****************************************************************************\
      FUNCTION: _SetExtraData
  
      DESCRIPTION:
        We don't render the data, but we will carry it because someone may need
      or want it.  This is the case with the drag source's defview pushing in
      the icon points via CFSTR_SHELLIDLISTOFFSET for the drop target.
\*****************************************************************************/
HRESULT CFtpObj::_SetExtraData(FORMATETC *pfe, STGMEDIUM *pstg, BOOL fRelease)
{
    HRESULT hr;
    int nIndex = _FindExtraDataIndex(pfe);

    // Do we already have someone's copy?
    if (-1 == nIndex)
    {
        FORMATETC_STGMEDIUM fs;

        fs.formatEtc = *pfe;

        // If there is a pointer, copy the data because we can't maintain the lifetime
        // of the pointer.
        if (fs.formatEtc.ptd)
        {
            fs.dvTargetDevice = *(pfe->ptd);
            fs.formatEtc.ptd = &fs.dvTargetDevice;
        }

        hr = CopyStgMediumWrap(pstg, &fs.medium);
        if (EVAL(SUCCEEDED(hr)))
        {
            // No, so just append it to the end.
            DSA_AppendItem(m_hdsaSetData, &fs);
        }
    }
    else
    {
        FORMATETC_STGMEDIUM fs;

        DSA_GetItem(m_hdsaSetData, nIndex, &fs);
        // Free the previous guy.
        ReleaseStgMedium(&fs.medium);

        // Yes, so Replace it.
        hr = CopyStgMediumWrap(pstg, &fs.medium);
        if (EVAL(SUCCEEDED(hr)))
        {
            // Replace the data.
            DSA_SetItem(m_hdsaSetData, nIndex, &fs);
        }
    }

    return hr;
}


typedef struct
{
    DWORD dwVersion;
    DWORD dwExtraSize;   // After pidl list
    BOOL fFGDRendered;
    DWORD dwReserved1;
    DWORD dwReserved2;
} FTPDATAOBJ_PERSISTSTRUCT;


/*****************************************************************************\
    FUNCTION: FormatEtcSaveToStream

    DESCRIPTION:
\*****************************************************************************/
HRESULT FormatEtcSaveToStream(IStream *pStm, FORMATETC * pFormatEtc)
{
    HRESULT hr = E_INVALIDARG;

    if (pStm)
    {
        // We don't support ptd because where would the allocation be
        // on the load?
        if (EVAL(NULL == pFormatEtc->ptd))
        {
            WCHAR szFormatName[MAX_PATH];

            if (EVAL(GetClipboardFormatNameW(pFormatEtc->cfFormat, szFormatName, ARRAYSIZE(szFormatName))))
            {
                DWORD cbFormatNameSize = ((lstrlenW(szFormatName) + 1) * sizeof(szFormatName[0]));

                hr = pStm->Write(pFormatEtc, SIZEOF(*pFormatEtc), NULL);
                if (EVAL(SUCCEEDED(hr)))
                {
                    hr = pStm->Write(&cbFormatNameSize, SIZEOF(cbFormatNameSize), NULL);
                    if (EVAL(SUCCEEDED(hr)))
                    {
                        hr = pStm->Write(szFormatName, cbFormatNameSize, NULL);
                    }
                }
            }
            else
                hr = HRESULT_FROM_WIN32(GetLastError());
        }
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FormatEtcLoadFromStream

    DESCRIPTION:
\*****************************************************************************/
HRESULT FormatEtcLoadFromStream(IStream *pStm, FORMATETC * pFormatEtc)
{
    HRESULT hr = E_INVALIDARG;

    if (pStm)
    {
        hr = pStm->Read(pFormatEtc, SIZEOF(*pFormatEtc), NULL);
        ASSERT(NULL == pFormatEtc->ptd);    // We don't support this.

        if (EVAL(SUCCEEDED(hr)))
        {
            DWORD cbFormatNameSize;

            hr = pStm->Read(&cbFormatNameSize, SIZEOF(cbFormatNameSize), NULL);
            if (EVAL(SUCCEEDED(hr)))
            {
                WCHAR szFormatName[MAX_PATH];

                hr = pStm->Read(szFormatName, cbFormatNameSize, NULL);
                if (EVAL(SUCCEEDED(hr)))
                {
                    pFormatEtc->cfFormat = (CLIPFORMAT)RegisterClipboardFormatW(szFormatName);
                }
            }
        }
        else
            hr = HRESULT_FROM_WIN32(GetLastError());

    }

    return hr;
}


typedef struct
{
    DWORD dwVersion;
    DWORD dwExtraSize;               // After this struct
    DWORD dwTymed;              // What type of data is stored?
    BOOL fUnkForRelease;        // Did we save the object after this?
    DWORD dwReserved1;          //
    DWORD dwReserved2;          //
} STGMEDIUM_PERSISTSTRUCT;

/*****************************************************************************\
    FUNCTION: StgMediumSaveToStream

    DESCRIPTION:
\*****************************************************************************/
HRESULT StgMediumSaveToStream(IStream *pStm, STGMEDIUM * pMedium)
{
    HRESULT hr = E_INVALIDARG;

    if (pStm)
    {
        STGMEDIUM_PERSISTSTRUCT smps = {0};

        smps.dwVersion = 1;
        smps.dwTymed = pMedium->tymed;

        switch (pMedium->tymed)
        {
        case TYMED_HGLOBAL:
        {
            IStream * pstmHGlobal;

            hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &pstmHGlobal);
            if (EVAL(SUCCEEDED(hr)))
            {
                STATSTG statStg;

                hr = pstmHGlobal->Stat(&statStg, STATFLAG_NONAME);
                if (EVAL(SUCCEEDED(hr)))
                {
                    ASSERT(!statStg.cbSize.HighPart);
                    smps.dwExtraSize = statStg.cbSize.LowPart;
                    hr = pStm->Write(&smps, SIZEOF(smps), NULL);
                    if (EVAL(SUCCEEDED(hr)))
                        hr = pstmHGlobal->CopyTo(pStm, statStg.cbSize, NULL, NULL);
                }

                pstmHGlobal->Release();
            }
        }
        break;

        case TYMED_FILE:
            smps.dwExtraSize = ((lstrlenW(pMedium->lpszFileName) + 1) * sizeof(WCHAR));

            hr = pStm->Write(&smps, SIZEOF(smps), NULL);
            if (EVAL(SUCCEEDED(hr)))
            {
                hr = pStm->Write(pMedium->lpszFileName, smps.dwExtraSize, NULL);
                ASSERT(SUCCEEDED(hr));
            }
            break;

        case TYMED_GDI:
        case TYMED_MFPICT:
        case TYMED_ENHMF:
        case TYMED_ISTORAGE:
        case TYMED_ISTREAM:
        default:
            ASSERT(0);  // What are you doing?  Impl this if you need it.
            hr = E_NOTIMPL;
            break;
        }
    }

    return hr;

⌨️ 快捷键说明

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