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

📄 ftpobj.cpp

📁 很好用的ftp源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    DESCRIPTION:
        Render the data in the requested format and put it into the
    STGMEDIUM structure.
\*****************************************************************************/
HRESULT CFtpObj::GetData(LPFORMATETC pfe, LPSTGMEDIUM pstg)
{
    int ife;
    HRESULT hr;

    hr = _FindDataForGet(pfe, &ife);
    if (SUCCEEDED(hr))
    {
        if (ife == DROP_FCont)
            hr = _RenderFileContents(pfe, pstg);
        else
        {
            hr = _ForceRender(ife);
            if (SUCCEEDED(hr))  // May not succeed for security reasons.
            {
                ASSERT(m_stgCache[ife].hGlobal);

                // It's possible to use the hacking STGMEDIUM.pUnkForRelease to give away
                // pointers to our data, but we then need massive amounts of code to babysite
                // the lifetime of those pointers.  This becomes more work when ::SetData() can
                // replace that data, so we just take the hit of the memcpy for less code.
                hr = CopyStgMediumWrap(&m_stgCache[ife], pstg);
                ASSERT(SUCCEEDED(hr));
                ASSERT(NULL == pstg->pUnkForRelease);
                //TraceMsg(TF_FTPDRAGDROP, "CFtpObj::GetData() pstg->hGlobal=%#08lx. pstg->pUnkForRelease=%#08lx.", pstg->hGlobal, pstg->pUnkForRelease);
            }
        }

        TraceMsgWithFormat(TF_FTPDRAGDROP, "CFtpObj::GetData()", pfe, "Format in static list", hr);
    }
    else
    {
        int nIndex = _FindExtraDataIndex(pfe);

        if (-1 == nIndex)
            hr = E_FAIL;
        else
        {
            FORMATETC_STGMEDIUM fs;

            DSA_GetItem(m_hdsaSetData, nIndex, &fs);
            hr = CopyStgMediumWrap(&fs.medium, pstg);
        }

        TraceMsgWithFormat(TF_FTPDRAGDROP, "CFtpObj::GetData()", pfe, "Looking in dyn list", hr);
    }

    return hr;
}


/*****************************************************************************\
    IDataObject::GetDataHere

    Render the data in the requested format and put it into the
    object provided by the caller.
\*****************************************************************************/
HRESULT CFtpObj::GetDataHere(FORMATETC *pfe, STGMEDIUM *pstg)
{
    TraceMsg(TF_FTPDRAGDROP, "CFtpObj::GetDataHere() pfe->cfFormat=%d.", pfe->cfFormat);
    return E_NOTIMPL;
}



/*****************************************************************************\
    FUNCTION: IDataObject::QueryGetData

    DESCRIPTION:
       Indicate whether we could provide data in the requested format.
\*****************************************************************************/
HRESULT CFtpObj::QueryGetData(FORMATETC *pfe)
{
    int ife;
    HRESULT hr = _FindDataForGet(pfe, &ife);
    
    if (FAILED(hr))
    {
        // If it wasn't one of the types we offer, see if it was given to us via
        // IDataObject::SetData().
        int nIndex = _FindExtraDataIndex(pfe);

        if (-1 != nIndex)
            hr = S_OK;
    }

    TraceMsgWithFormat(TF_FTPDRAGDROP, "CFtpObj::QueryGetData()", pfe, "", hr);
    return hr;
}


/*****************************************************************************\
      FUNCTION: IDataObject::GetCanonicalFormatEtc
  
      DESCRIPTION:
      Our data are not sensitive to device-specific renderings,
      so we do what the book tells us to do.
 
      Or we *try* to do what the book tells us to do.
 
      OLE random documentation of the day:
      IDataObject::GetCanonicalFormatEtc.
 
      Turns out that the man page contradicts itself within sentences:
 
         DATA_S_SAMEFORMATETC - The FORMATETC structures are the same
                    and NULL is returned in pfeOut.
 
         If the data object never provides device-specific renderings,
         the implementation of IDataObject::GetCanonicalFormatEtc
         simply copies the input FORMATETC to the output FORMATETC,
         stores a null in the ptd field, and returns DATA_S_SAMEFORMATETC.
 
      And it turns out that the shell doesn't do *either* of these things.
      It just returns DATA_S_SAMEFORMATETC and doesn't touch pfeOut.
 
      The book is even more confused.  Under pfeOut, it says
 
         The value is NULL if the method returns DATA_S_SAMEFORMATETC.
 
      This makes no sense.  The caller provides the value of pfeOut.
      How can the caller possibly know that the method is going to return
      DATA_S_SAMEFORMATETC before it calls it?  If you expect the
      method to write "pfeOut = 0" before returning, you're nuts.  That
      communicates nothing to the caller.
 
      I'll just do what the shell does.
\*****************************************************************************/
HRESULT CFtpObj::GetCanonicalFormatEtc(FORMATETC *pfeIn, FORMATETC *pfeOut)
{
    return DATA_S_SAMEFORMATETC;
}


/*****************************************************************************\
      FUNCTION: IDataObject::SetData
  
      DESCRIPTION:
      We let people change TYMED_HGLOBAL gizmos, but nothing else.
  
      We need to do a careful two-step when replacing the HGLOBAL.
      If the user gave us a plain HGLOBAL without a pUnkForRelease,
      we need to invent our own pUnkForRelease to track it.  But we
      don't want to release the old STGMEDIUM until we're sure we
      can accept the new one.
  
      fRelease == 0 makes life doubly interesting, because we also
      have to clone the HGLOBAL (and remember to free the clone on the
      error path).
  
      _SOMEDAY_/TODO -- Need to support PerformedDropEffect so we can
      clean up stuff on a cut/paste.
\*****************************************************************************/
HRESULT CFtpObj::SetData(FORMATETC *pfe, STGMEDIUM *pstg, BOOL fRelease)
{
    int ife;
    HRESULT hr;

    hr = _FindData(pfe, &ife);
    if (SUCCEEDED(hr))
    {
        if (ife == DROP_FCont)
        {
            TraceMsg(TF_FTPDRAGDROP, "CFtpObj::SetData(FORMATETC.cfFormat=%d) ife == DROP_FCont", pfe->cfFormat);
            hr = DV_E_FORMATETC;
        }
        else
        {
            ASSERT(g_dropTypes[ife].tymed == TYMED_HGLOBAL);
            ASSERT(pstg->tymed == TYMED_HGLOBAL);
            if (EVAL(pstg->hGlobal))
            {
                STGMEDIUM stg = {0};

                hr = CopyStgMediumWrap(pstg, &stg);
                if (EVAL(SUCCEEDED(hr)))
                {
                    ReleaseStgMedium(&m_stgCache[ife]);
                    m_stgCache[ife] = stg;
                }
            }
            else
            {            // Tried to SetData a _DelayRender
                hr = DV_E_STGMEDIUM;    // You idiot you
            }
        }

        TraceMsgWithFormat(TF_FTPDRAGDROP, "CFtpObj::SetData()", pfe, "in static list", hr);
    }
    else
    {
        hr = _SetExtraData(pfe, pstg, fRelease);
        TraceMsgWithFormat(TF_FTPDRAGDROP, "CFtpObj::SetData()", pfe, "in dyn list", hr);
    }

    return hr;
}


/*****************************************************************************\
      FUNCTION: IDataObject::EnumFormatEtc
  
      DESCRIPTION:
        _UNDOCUMENTED_:  If you drag something from a DefView, it will
      check the data object to see if it has a hida.  If so, then it
      will cook up a CFSTR_SHELLIDLISTOFFSET *for you* and SetData
      the information into the data object.  So in order to get
      position-aware drag/drop working, you must allow DefView to change
      your CFSTR_SHELLIDLISTOFFSET.
 
     We allow all FORMATETCs to be modified except for FileContents.
\*****************************************************************************/
HRESULT CFtpObj::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenum)
{
    HRESULT hres;

    switch (dwDirection)
    {
    case DATADIR_GET:
        hres = CFtpEfe_Create(DROP_OFFERMAX - DROP_FCont, &g_dropTypes[DROP_FCont],
                   &m_stgCache[DROP_FCont], this, ppenum);
        TraceMsg(TF_FTPDRAGDROP, "CFtpObj::EnumFormatEtc(DATADIR_GET) CFtpEfe_Create() returned hres=%#08lx", hres);
        break;

    case DATADIR_SET:
        hres = CFtpEfe_Create(DROP_OFFERMAX - DROP_OFFERMIN, &g_dropTypes[DROP_OFFERMIN],
                   &m_stgCache[DROP_OFFERMIN], NULL, ppenum);
        TraceMsg(TF_FTPDRAGDROP, "CFtpObj::EnumFormatEtc(DATADIR_SET) CFtpEfe_Create() returned hres=%#08lx", hres);
        break;

    default:
        ASSERT(0);
        hres = E_NOTIMPL;
        break;
    }

    return hres;
}


/*****************************************************************************\
      FUNCTION: IDataObject::DAdvise
  
      DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::DAdvise(FORMATETC *pfe, DWORD advfl, IAdviseSink *padv, DWORD *pdwConnection)
{
    return OLE_E_ADVISENOTSUPPORTED;
}


/*****************************************************************************\
      FUNCTION: IDataObject::DUnadvise
  
      DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::DUnadvise(DWORD dwConnection)
{
    return OLE_E_ADVISENOTSUPPORTED;
}


/*****************************************************************************\
      FUNCTION: IDataObject::EnumDAdvise
  
      DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj::EnumDAdvise(IEnumSTATDATA **ppeadv)
{
    return OLE_E_ADVISENOTSUPPORTED;
}


/*****************************************************************************\
      FUNCTION: CFtpObj_Create
  
      DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj_Create(CFtpFolder * pff, CFtpPidlList * pflHfpl, REFIID riid, LPVOID * ppvObj)
{
    HRESULT hres;
    CFtpObj * pfo;

    *ppvObj = NULL;

    hres = CFtpObj_Create(pff, pflHfpl, &pfo);
    if (EVAL(SUCCEEDED(hres)))
    {
        pfo->QueryInterface(riid, ppvObj);
        pfo->Release();
    }

     return hres;
}


/*****************************************************************************\
      FUNCTION: CFtpObj_Create
  
      DESCRIPTION:
\*****************************************************************************/
HRESULT CFtpObj_Create(CFtpFolder * pff, CFtpPidlList * pflHfpl, CFtpObj ** ppfo)
{
    HRESULT hres = S_OK;

    if (EVAL(pflHfpl->GetCount()))
    {
        *ppfo = new CFtpObj();

        if (EVAL(*ppfo))
        {
            CFtpObj * pfo = *ppfo;
            pfo->m_pfd = pff->GetFtpDir();

            if (EVAL(pfo->m_pfd))
            {
                pfo->m_pff = pff;
                if (pff)
                    pff->AddRef();

                IUnknown_Set(&pfo->m_pflHfpl, pflHfpl);
                
                if (pfo->m_pflHfpl->GetCount() == 1)
                {
                    pfo->m_stgCache[DROP_URL].tymed = TYMED_HGLOBAL;
                }
            }
            else
            {
                hres = E_FAIL;
                (*ppfo)->Release();
                *ppfo = NULL;
            }
        }
        else
            hres = E_OUTOFMEMORY;

    }
    else
    {
        *ppfo = NULL;
        hres = E_INVALIDARG;        /* Trying to get UI object of nil? */
    }

    return hres;
}


/*****************************************************************************\
    FUNCTION: CFtpObj_Create

    DESCRIPTION:
        This will be called by the Class Factory when the IDataObject gets
    persisted and then wants to be recreated in a new process. (Happens
    after the original thread/process calls OleFlushClipboard.
\*****************************************************************************/
HRESULT CFtpObj_Create(REFIID riid, void ** ppvObj)
{
    HRESULT hr = E_OUTOFMEMORY;
    CFtpObj * pfo = new CFtpObj();

    *ppvObj = NULL;
    if (pfo)
    {
        hr = pfo->QueryInterface(riid, ppvObj);
        pfo->Release();
    }

     return hr;
}

#define SETDATA_GROWSIZE        3

/****************************************************\
    Constructor
\****************************************************/
CFtpObj::CFtpObj() : m_cRef(1)
{
    DllAddRef();

    // This needs to be allocated in Zero Inited Memory.
    // Assert that all Member Variables are inited to Zero.
    ASSERT(!m_pff);
    ASSERT(!m_pfd);
    ASSERT(!m_pflHfpl);
    ASSERT(!m_fDidAsynchStart);

    // NT #245306: If the user drags files from an FTP window (Thread 1)
    //    to a shell window (Thread 2), the shell window will do
    //    the dr

⌨️ 快捷键说明

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