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

📄 ftpobj.cpp

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


LPWSTR OLESTRAlloc(DWORD cchSize)
{
    return (LPWSTR) new WCHAR [cchSize + 1];
}


/*****************************************************************************\
    FUNCTION: StgMediumLoadFromStream

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

    if (pStm && pMedium)
    {
        STGMEDIUM_PERSISTSTRUCT smps;

        pMedium->pUnkForRelease = NULL;
        hr = pStm->Read(&smps, SIZEOF(smps), NULL);
        if (EVAL(SUCCEEDED(hr)))
        {
            pMedium->tymed = smps.dwTymed;
            ASSERT(!pMedium->pUnkForRelease);

            switch (pMedium->tymed)
            {
            case TYMED_HGLOBAL:
            {
                IStream * pstmTemp;
                hr = CreateStreamOnHGlobal(NULL, FALSE, &pstmTemp);
                if (EVAL(SUCCEEDED(hr)))
                {
                    ULARGE_INTEGER uli = {0};

                    uli.LowPart = smps.dwExtraSize;
                    hr = pStm->CopyTo(pstmTemp, uli, NULL, NULL);
                    if (EVAL(SUCCEEDED(hr)))
                    {
                        hr = GetHGlobalFromStream(pstmTemp, &pMedium->hGlobal);
                    }

                    pstmTemp->Release();
                }
            }
            break;

            case TYMED_FILE:
                pMedium->lpszFileName = OLESTRAlloc(smps.dwExtraSize / sizeof(WCHAR));
                if (pMedium->lpszFileName)
                    hr = pStm->Read(pMedium->lpszFileName, smps.dwExtraSize, NULL);
                else
                    hr = E_OUTOFMEMORY;
                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.
                // Some future version must have done the save, so skip the
                // data so we don't leave unread data.
                if (0 != smps.dwExtraSize)
                {
                    LARGE_INTEGER li = {0};

                    li.LowPart = smps.dwExtraSize;
                    EVAL(SUCCEEDED(pStm->Seek(li, STREAM_SEEK_CUR, NULL)));
                }
                hr = E_NOTIMPL;
                break;
            }
        }
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FORMATETC_STGMEDIUMSaveToStream

    DESCRIPTION:
\*****************************************************************************/
HRESULT FORMATETC_STGMEDIUMSaveToStream(IStream *pStm, FORMATETC_STGMEDIUM * pfdops)
{
    HRESULT hr = E_INVALIDARG;

    if (pStm)
    {
        hr = FormatEtcSaveToStream(pStm, &pfdops->formatEtc);
        if (EVAL(SUCCEEDED(hr)))
            hr = StgMediumSaveToStream(pStm, &pfdops->medium);
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: FORMATETC_STGMEDIUMLoadFromStream

    DESCRIPTION:
\*****************************************************************************/
HRESULT FORMATETC_STGMEDIUMLoadFromStream(IStream *pStm, FORMATETC_STGMEDIUM * pfdops)
{
    HRESULT hr = E_INVALIDARG;

    if (pStm)
    {
        hr = FormatEtcLoadFromStream(pStm, &pfdops->formatEtc);
        if (EVAL(SUCCEEDED(hr)))
            hr = StgMediumLoadFromStream(pStm, &pfdops->medium);
    }

    return hr;
}



/////////////////////////////////
////// IAsynchDataObject Impl
/////////////////////////////////


/*****************************************************************************\
    FUNCTION: IAsyncOperation::GetAsyncMode

    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::GetAsyncMode(BOOL * pfIsOpAsync)
{
    *pfIsOpAsync = TRUE;
    return S_OK;
}
  

/*****************************************************************************\
    FUNCTION: IAsyncOperation::StartOperation

    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::StartOperation(IBindCtx * pbcReserved)
{
    ASSERT(!pbcReserved);
    m_fDidAsynchStart = TRUE;

    return S_OK;
}
  

/*****************************************************************************\
    FUNCTION: IAsyncOperation::InOperation

    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::InOperation(BOOL * pfInAsyncOp)
{
    if (m_fDidAsynchStart)
        *pfInAsyncOp = TRUE;
    else
        *pfInAsyncOp = FALSE;

    return S_OK;
}
  

/*****************************************************************************\
    FUNCTION: IAsyncOperation::EndOperation

    DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::EndOperation(HRESULT hResult, IBindCtx * pbcReserved, DWORD dwEffects)
{
    if (SUCCEEDED(hResult) &&
        (DROPEFFECT_MOVE == dwEffects))
    {
        CFtpPidlList * pPidlListNew = CreateRelativePidlList(m_pff, m_pflHfpl);

        if (pPidlListNew)
        {
            Misc_DeleteHfpl(m_pff, GetDesktopWindow(), pPidlListNew);
            pPidlListNew->Release();
        }
    }
 
    m_fDidAsynchStart = FALSE;
    return S_OK;
}
  


/////////////////////////////////
////// IPersistStream Impl
/////////////////////////////////


/*****************************************************************************\
    FUNCTION: IPersistStream::Load

    DESCRIPTION:
        See IPersistStream::Save() for the layout of the stream.
\*****************************************************************************/
HRESULT CFtpObj::Load(IStream *pStm)
{
    HRESULT hr = E_INVALIDARG;

    if (pStm)
    {
        FTPDATAOBJ_PERSISTSTRUCT fdoss;
        DWORD dwNumPidls;
        DWORD dwNumStgMedium;

        hr = pStm->Read(&fdoss, SIZEOF(fdoss), NULL);   // #1
        // If we rev the version, read it now (fdoss.dwVersion)

        if (EVAL(SUCCEEDED(hr)))
        {
            LPITEMIDLIST pidl = NULL;       // ILLoadFromStream frees the param

            ASSERT(!m_pff);
            m_fFGDRendered = fdoss.fFGDRendered;

            hr = ILLoadFromStream(pStm, &pidl); // #2
            if (EVAL(SUCCEEDED(hr)))
            {
                hr = SHBindToIDList(pidl, NULL, IID_CFtpFolder, (void **)&m_pff);
                if (EVAL(SUCCEEDED(hr)))
                    m_pfd = m_pff->GetFtpDir();

                ASSERT(m_pfd);
                ILFree(pidl);
            }
        }

        if (EVAL(SUCCEEDED(hr)))
        {
            hr = pStm->Read(&dwNumPidls, SIZEOF(dwNumPidls), NULL);  // #3
            if (EVAL(SUCCEEDED(hr)))
                hr = CFtpPidlList_Create(0, NULL, &m_pflHfpl);
        }

        if (EVAL(SUCCEEDED(hr)))
        {
            for (int nIndex = 0; (nIndex < (int)dwNumPidls) && SUCCEEDED(hr); nIndex++)
            {
                LPITEMIDLIST pidl = NULL;       // ILLoadFromStream frees the param

                hr = ILLoadFromStream(pStm, &pidl); // #4
                if (EVAL(SUCCEEDED(hr)))
                {
                    hr = m_pflHfpl->InsertSorted(pidl);
                    ILFree(pidl);
                }
            }
        }

        if (EVAL(SUCCEEDED(hr)))
            hr = pStm->Read(&dwNumStgMedium, SIZEOF(dwNumStgMedium), NULL);  // #5

        if (EVAL(SUCCEEDED(hr)))
        {
            for (int nIndex = 0; (nIndex < (int)dwNumStgMedium) && SUCCEEDED(hr); nIndex++)
            {
                FORMATETC_STGMEDIUM fs;

                hr = FORMATETC_STGMEDIUMLoadFromStream(pStm, &fs);   // #6
                if (EVAL(SUCCEEDED(hr)))
                    DSA_AppendItem(m_hdsaSetData, &fs);
            }
        }

        if (EVAL(SUCCEEDED(hr)))
        {
            // We may be reading a version newer than us, so skip their data.
            if (0 != fdoss.dwExtraSize)
            {
                LARGE_INTEGER li = {0};
                
                li.LowPart = fdoss.dwExtraSize;
                hr = pStm->Seek(li, STREAM_SEEK_CUR, NULL);
            }
        }
    }

    return hr;
}


/*****************************************************************************\
    FUNCTION: IPersistStream::Save

    DESCRIPTION:
        The stream will be layed out in the following way:

    Version 1:
        1. FTPDATAOBJ_PERSISTSTRUCT - Constant sized data.
        <PidlList BEGIN>
            2. PIDL pidl - Pidl for m_pff.  It will be a public pidl (fully qualified
                        from the shell root)
            3. DWORD dwNumPidls - Number of pidls coming.
            4. PIDL pidl(n) - Pidl in slot (n) of m_pflHfpl
        <PidlList END>
        5. DWORD dwNumStgMedium - Number of FORMATETC_STGMEDIUMs coming
        6. FORMATETC_STGMEDIUM fmtstg(n) - dwNumStgMedium FORMATETC_STGMEDIUMs.
\*****************************************************************************/
HRESULT CFtpObj::Save(IStream *pStm, BOOL fClearDirty)
{
    HRESULT hr = E_INVALIDARG;

    if (pStm)
    {
        FTPDATAOBJ_PERSISTSTRUCT fdoss = {0};
        DWORD dwNumPidls = m_pflHfpl->GetCount();
        DWORD dwNumStgMedium = DSA_GetItemCount(m_hdsaSetData);

        fdoss.dwVersion = 1;
        fdoss.fFGDRendered = m_fFGDRendered;
        hr = pStm->Write(&fdoss, SIZEOF(fdoss), NULL);  // #1
        if (EVAL(SUCCEEDED(hr)))
        {
            ASSERT(m_pff);
            hr = ILSaveToStream(pStm, m_pff->GetPublicRootPidlReference()); // #2
        }

        if (EVAL(SUCCEEDED(hr)))
            hr = pStm->Write(&dwNumPidls, SIZEOF(dwNumPidls), NULL);  // #3

        if (EVAL(SUCCEEDED(hr)))
        {
            for (int nIndex = 0; (nIndex < (int)dwNumPidls) && SUCCEEDED(hr); nIndex++)
            {
                LPITEMIDLIST pidlCur = m_pflHfpl->GetPidl(nIndex);

                ASSERT(pidlCur);
                hr = ILSaveToStream(pStm, pidlCur); // #4
            }
        }

        if (EVAL(SUCCEEDED(hr)))
            hr = pStm->Write(&dwNumStgMedium, SIZEOF(dwNumStgMedium), NULL);  // #5

        if (EVAL(SUCCEEDED(hr)))
        {
            for (int nIndex = 0; (nIndex < (int)dwNumStgMedium) && SUCCEEDED(hr); nIndex++)
            {
                FORMATETC_STGMEDIUM fs;

                DSA_GetItem(m_hdsaSetData, nIndex, &fs);

                hr = FORMATETC_STGMEDIUMSaveToStream(pStm, &fs);   // #6
            }
        }

    }

    return hr;
}


#define MAX_STREAM_SIZE    (500 * 1024) // 500k
/*****************************************************************************\
    FUNCTION: IPersistStream::GetSizeMax

    DESCRIPTION:
        Now this is tough.  I can't calculate the real value because I don't know
    how big the hglobals are going to be for the user provided data.  I will
    assume everything fits in
\*****************************************************************************/
HRESULT CFtpObj::GetSizeMax(ULARGE_INTEGER * pcbSize)
{
    if (pcbSize)
    {
        pcbSize->HighPart = 0;
        pcbSize->LowPart = MAX_STREAM_SIZE;
    }
    
    return E_NOTIMPL;
}


/////////////////////////////////
////// IDataObject Impl
/////////////////////////////////

/*****************************************************************************\
    FUNCTION: IDataObject::GetData

⌨️ 快捷键说明

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