ftpefe.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 10k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*****************************************************************************
  2.  *
  3.  *    ftpefe.cpp - IEnumFORMATETC interface
  4.  *
  5.  *****************************************************************************/
  6. #include "priv.h"
  7. #include "ftpefe.h"
  8. #include "ftpobj.h"
  9. /*****************************************************************************
  10.  *    CFtpEfe::_NextOne
  11.  *****************************************************************************/
  12. HRESULT CFtpEfe::_NextOne(FORMATETC * pfetc)
  13. {
  14.     HRESULT hr = S_FALSE;
  15.     while (ShouldSkipDropFormat(m_dwIndex))
  16.         m_dwIndex++;
  17.     ASSERT(m_hdsaFormatEtc);
  18.     if (m_dwIndex < (DWORD) DSA_GetItemCount(m_hdsaFormatEtc))
  19.     {
  20.         DSA_GetItem(m_hdsaFormatEtc, m_dwIndex, (LPVOID) pfetc);
  21.         m_dwIndex++;         // We are off to the next one
  22.         hr = S_OK;
  23.     }
  24.     if ((S_OK != hr) && m_pfo)
  25.     {
  26.         // We finished looking thru the types supported by the IDataObject.
  27.         // Now look for other items inserted by IDataObject::SetData()
  28.         if (m_dwExtraIndex < (DWORD) DSA_GetItemCount(m_pfo->m_hdsaSetData))
  29.         {
  30.             FORMATETC_STGMEDIUM fs;
  31.             DSA_GetItem(m_pfo->m_hdsaSetData, m_dwExtraIndex, (LPVOID) &fs);
  32.             *pfetc = fs.formatEtc;
  33.             m_dwExtraIndex++;         // We are off to the next one
  34.             hr = S_OK;
  35.         }
  36.     }
  37.     return hr;
  38. }
  39. //===========================
  40. // *** IEnumFORMATETC Interface ***
  41. //===========================
  42. /*****************************************************************************
  43.  *
  44.  *    IEnumFORMATETC::Next
  45.  *
  46.  *    Creates a brand new enumerator based on an existing one.
  47.  *
  48.  *
  49.  *    OLE random documentation of the day:  IEnumXXX::Next.
  50.  *
  51.  *    rgelt - Receives an array of size celt (or larger).
  52.  *
  53.  *    "Receives an array"?  No, it doesn't receive an array.
  54.  *    It *is* an array.  The array receives *elements*.
  55.  *
  56.  *    "Or larger"?  Does this mean I can return more than the caller
  57.  *    asked for?  No, of course not, because the caller didn't allocate
  58.  *    enough memory to hold that many return values.
  59.  *
  60.  *    No semantics are assigned to the possibility of celt = 0.
  61.  *    Since I am a mathematician, I treat it as vacuous success.
  62.  *
  63.  *    pcelt is documented as an INOUT parameter, but no semantics
  64.  *    are assigned to its input value.
  65.  *
  66.  *    The dox don't say that you are allowed to return *pcelt < celt
  67.  *    for reasons other than "no more elements", but the shell does
  68.  *    it everywhere, so maybe it's legal...
  69.  *
  70.  *****************************************************************************/
  71. HRESULT CFtpEfe::Next(ULONG celt, FORMATETC * rgelt, ULONG *pceltFetched)
  72. {
  73.     HRESULT hres = S_FALSE;
  74.     DWORD dwIndex;
  75.     // Do they want more and do we have more to give?
  76.     for (dwIndex = 0; dwIndex < celt; dwIndex++)
  77.     {
  78.         if (S_FALSE == _NextOne(&rgelt[dwIndex]))        // Yes, so give away...
  79.             break;
  80.         ASSERT(NULL == rgelt[dwIndex].ptd); // We don't do this correctly.
  81. #ifdef DEBUG
  82.         char szName[MAX_PATH];
  83.         GetCfBufA(rgelt[dwIndex].cfFormat, szName, ARRAYSIZE(szName));
  84.         //TraceMsg(TF_FTP_IDENUM, "CFtpEfe::Next() - Returning %hs", szName);
  85. #endif // DEBUG
  86.     }
  87.     if (pceltFetched)
  88.         *pceltFetched = dwIndex;
  89.     // Were we able to give any?
  90.     if ((0 != dwIndex) || (0 == celt))
  91.         hres = S_OK;
  92.     return hres;
  93. }
  94. /*****************************************************************************
  95.  *    IEnumFORMATETC::Skip
  96.  *****************************************************************************/
  97. HRESULT CFtpEfe::Skip(ULONG celt)
  98. {
  99.     m_dwIndex += celt;
  100.     return S_OK;
  101. }
  102. /*****************************************************************************
  103.  *    IEnumFORMATETC::Reset
  104.  *****************************************************************************/
  105. HRESULT CFtpEfe::Reset(void)
  106. {
  107.     m_dwIndex = 0;
  108.     return S_OK;
  109. }
  110. /*****************************************************************************
  111.  *
  112.  *    IEnumFORMATETC::Clone
  113.  *
  114.  *    Creates a brand new enumerator based on an existing one.
  115.  *
  116.  *****************************************************************************/
  117. HRESULT CFtpEfe::Clone(IEnumFORMATETC **ppenum)
  118. {
  119.     return CFtpEfe_Create((DWORD) DSA_GetItemCount(m_hdsaFormatEtc), m_hdsaFormatEtc, m_dwIndex, m_pfo, ppenum);
  120. }
  121. /*****************************************************************************
  122.  *
  123.  *    CFtpEfe_Create
  124.  *
  125.  *    Creates a brand new enumerator based on a list of possibilities.
  126.  *
  127.  *    Note that we are EVIL and know about CFSTR_FILECONTENTS here:
  128.  *    A FORMATETC of FileContents is always valid.  This is important,
  129.  *    because CFtpObj doesn't actually have a STGMEDIUM for file contents.
  130.  *    (Due to lindex weirdness.)
  131.  *
  132.  *****************************************************************************/
  133. HRESULT CFtpEfe_Create(DWORD dwSize, FORMATETC rgfe[], STGMEDIUM rgstg[], CFtpObj * pfo, CFtpEfe ** ppfefe)
  134. {
  135.     CFtpEfe * pfefe;
  136.     HRESULT hres = E_OUTOFMEMORY;
  137.     pfefe = *ppfefe = new CFtpEfe(dwSize, rgfe, rgstg, pfo);
  138.     if (EVAL(pfefe))
  139.     {
  140.         if (!pfefe->m_hdsaFormatEtc)
  141.             pfefe->Release();
  142.         else
  143.             hres = S_OK;
  144.     }
  145.     if (FAILED(hres) && pfefe)
  146.         IUnknown_Set(ppfefe, NULL);
  147.     return hres;
  148. }
  149. /*****************************************************************************
  150.  *
  151.  *    CFtpEfe_Create
  152.  *
  153.  *    Creates a brand new enumerator based on a list of possibilities.
  154.  *
  155.  *    Note that we are EVIL and know about CFSTR_FILECONTENTS here:
  156.  *    A FORMATETC of FileContents is always valid.  This is important,
  157.  *    because CFtpObj doesn't actually have a STGMEDIUM for file contents.
  158.  *    (Due to lindex weirdness.)
  159.  *
  160.  *****************************************************************************/
  161. HRESULT CFtpEfe_Create(DWORD dwSize, FORMATETC rgfe[], STGMEDIUM rgstg[], CFtpObj * pfo, IEnumFORMATETC ** ppenum)
  162. {
  163.     CFtpEfe * pfefe;
  164.     HRESULT hres = CFtpEfe_Create(dwSize, rgfe, rgstg, pfo, &pfefe);
  165.     if (EVAL(pfefe))
  166.     {
  167.         hres = pfefe->QueryInterface(IID_IEnumFORMATETC, (LPVOID *) ppenum);
  168.         pfefe->Release();
  169.     }
  170.     return hres;
  171. }
  172. /*****************************************************************************
  173.  *
  174.  *    CFtpEfe_Create
  175.  *****************************************************************************/
  176. HRESULT CFtpEfe_Create(DWORD dwSize, HDSA m_hdsaFormatEtc, DWORD dwIndex, CFtpObj * pfo, IEnumFORMATETC ** ppenum)
  177. {
  178.     CFtpEfe * pfefe;
  179.     HRESULT hres = E_OUTOFMEMORY;
  180.     pfefe = new CFtpEfe(dwSize, m_hdsaFormatEtc, pfo, dwIndex);
  181.     if (EVAL(pfefe))
  182.     {
  183.         hres = pfefe->QueryInterface(IID_IEnumFORMATETC, (LPVOID *) ppenum);
  184.         pfefe->Release();
  185.     }
  186.     return hres;
  187. }
  188. /****************************************************
  189.     Constructor
  190. ****************************************************/
  191. CFtpEfe::CFtpEfe(DWORD dwSize, FORMATETC rgfe[], STGMEDIUM rgstg[], CFtpObj * pfo) : m_cRef(1)
  192. {
  193.     DllAddRef();
  194.     // This needs to be allocated in Zero Inited Memory.
  195.     // Assert that all Member Variables are inited to Zero.
  196.     ASSERT(!m_dwIndex);
  197.     ASSERT(!m_hdsaFormatEtc);
  198.     ASSERT(!m_pfo);
  199.     m_hdsaFormatEtc = DSA_Create(sizeof(rgfe[0]), 10);
  200.     if (EVAL(m_hdsaFormatEtc))
  201.     {
  202.         DWORD dwIndex;
  203.         for (dwIndex = 0; dwIndex < dwSize; dwIndex++)
  204.         {
  205. #ifdef    DEBUG
  206.             char szNameDebug[MAX_PATH];
  207.             GetCfBufA(rgfe[dwIndex].cfFormat, szNameDebug, ARRAYSIZE(szNameDebug));
  208. #endif // DEBUG
  209.     
  210.             if (rgfe[dwIndex].tymed == TYMED_ISTREAM ||
  211.                 (rgstg && rgfe[dwIndex].tymed == rgstg[dwIndex].tymed))
  212.             {
  213. #ifdef DEBUG
  214.                 //TraceMsg(TF_FTP_IDENUM, "CFtpEfe() Keeping %hs", szNameDebug);
  215. #endif // DEBUG
  216.                 DSA_SetItem(m_hdsaFormatEtc, dwIndex, &rgfe[dwIndex]);
  217.             }
  218.             else
  219.             {
  220. #ifdef DEBUG
  221.                 //TraceMsg(TF_FTP_IDENUM, "CFtpEfe() Ignoring %hs", szNameDebug);
  222. #endif // DEBUG
  223.             }
  224.         }
  225.     }
  226.     if (pfo)
  227.     {
  228.         m_pfo = pfo;
  229.         m_pfo->AddRef();
  230.     }
  231.     LEAK_ADDREF(LEAK_CFtpEfe);
  232. }
  233. /****************************************************
  234.     Constructor
  235. ****************************************************/
  236. CFtpEfe::CFtpEfe(DWORD dwSize, HDSA hdsaFormatEtc, CFtpObj * pfo, DWORD dwIndex) : m_cRef(1)
  237. {
  238.     DllAddRef();
  239.     // This needs to be allocated in Zero Inited Memory.
  240.     // Assert that all Member Variables are inited to Zero.
  241.     ASSERT(!m_dwIndex);
  242.     ASSERT(!m_hdsaFormatEtc);
  243.     ASSERT(!m_pfo);
  244.     ASSERT(hdsaFormatEtc);
  245.     m_hdsaFormatEtc = DSA_Create(sizeof(FORMATETC), 10);
  246.     if (EVAL(m_hdsaFormatEtc))
  247.     {
  248.         // BUGBUG: What do we do with dwIndex param?
  249.         for (dwIndex = 0; dwIndex < (DWORD) DSA_GetItemCount(hdsaFormatEtc); dwIndex++)
  250.         {
  251.             DSA_SetItem(m_hdsaFormatEtc, dwIndex, DSA_GetItemPtr(hdsaFormatEtc, dwIndex));
  252.         }
  253.     }
  254.     if (pfo)
  255.     {
  256.         m_pfo = pfo;
  257.         m_pfo->AddRef();
  258.     }
  259.     LEAK_ADDREF(LEAK_CFtpEfe);
  260. }
  261. /****************************************************
  262.     Destructor
  263. ****************************************************/
  264. CFtpEfe::~CFtpEfe()
  265. {
  266.     DSA_Destroy(m_hdsaFormatEtc);
  267.     if (m_pfo)
  268.         m_pfo->Release();
  269.     DllRelease();
  270.     LEAK_DELREF(LEAK_CFtpEfe);
  271. }
  272. //===========================
  273. // *** IUnknown Interface ***
  274. //===========================
  275. ULONG CFtpEfe::AddRef()
  276. {
  277.     m_cRef++;
  278.     return m_cRef;
  279. }
  280. ULONG CFtpEfe::Release()
  281. {
  282.     ASSERT(m_cRef > 0);
  283.     m_cRef--;
  284.     if (m_cRef > 0)
  285.         return m_cRef;
  286.     delete this;
  287.     return 0;
  288. }
  289. HRESULT CFtpEfe::QueryInterface(REFIID riid, void **ppvObj)
  290. {
  291.     if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC))
  292.     {
  293.         *ppvObj = SAFECAST(this, IEnumFORMATETC*);
  294.     }
  295.     else
  296.     {
  297.         TraceMsg(TF_FTPQI, "CFtpEfe::QueryInterface() failed.");
  298.         *ppvObj = NULL;
  299.         return E_NOINTERFACE;
  300.     }
  301.     AddRef();
  302.     return S_OK;
  303. }