Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

513 lines
12 KiB

  1. /**************************************************************************
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright 1998 Microsoft Corporation. All Rights Reserved.
  7. **************************************************************************/
  8. /**************************************************************************
  9. File: DataObj.cpp
  10. Description: CDataObject implementation.
  11. **************************************************************************/
  12. /**************************************************************************
  13. #include statements
  14. **************************************************************************/
  15. #include "DataObj.h"
  16. /**************************************************************************
  17. global variables
  18. **************************************************************************/
  19. /**************************************************************************
  20. CDataObject::CDataObject()
  21. **************************************************************************/
  22. CDataObject::CDataObject(CShellFolder *psfParent, LPCITEMIDLIST *aPidls, UINT uItemCount)
  23. {
  24. g_DllRefCount++;
  25. m_uItemCount = 0;
  26. m_psfParent = psfParent;
  27. if(m_psfParent)
  28. m_psfParent->AddRef();
  29. m_ObjRefCount = 1;
  30. m_aPidls = NULL;
  31. SHGetMalloc(&m_pMalloc);
  32. if(!m_pMalloc)
  33. {
  34. delete this;
  35. return;
  36. }
  37. m_pPidlMgr = new CPidlMgr();
  38. m_uItemCount = uItemCount;
  39. AllocPidlTable(uItemCount);
  40. if(m_aPidls)
  41. {
  42. FillPidlTable(aPidls, uItemCount);
  43. }
  44. m_cfPrivateData = RegisterClipboardFormat(CFSTR_SAMPVIEWDATA);
  45. m_cfShellIDList = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
  46. m_cFormatEtc = 2;
  47. m_pFormatEtc = new FORMATETC[m_cFormatEtc];
  48. SETDefFormatEtc(m_pFormatEtc[0], m_cfPrivateData, TYMED_HGLOBAL);
  49. SETDefFormatEtc(m_pFormatEtc[1], m_cfShellIDList, TYMED_HGLOBAL);
  50. m_iCurrent = 0;
  51. }
  52. /**************************************************************************
  53. CDataObject::~CDataObject()
  54. **************************************************************************/
  55. CDataObject::~CDataObject()
  56. {
  57. if(m_psfParent)
  58. m_psfParent->Release();
  59. g_DllRefCount--;
  60. //make sure the pidls are freed
  61. if(m_aPidls && m_pMalloc)
  62. {
  63. FreePidlTable();
  64. }
  65. if(m_pPidlMgr)
  66. delete m_pPidlMgr;
  67. if(m_pMalloc)
  68. m_pMalloc->Release();
  69. //delete [] m_pFormatEtc;
  70. delete m_pFormatEtc;
  71. }
  72. ///////////////////////////////////////////////////////////////////////////
  73. //
  74. // IUnknown Implementation
  75. //
  76. /**************************************************************************
  77. CDataObject::QueryInterface
  78. **************************************************************************/
  79. STDMETHODIMP CDataObject::QueryInterface( REFIID riid,
  80. LPVOID *ppReturn)
  81. {
  82. *ppReturn = NULL;
  83. if(IsEqualIID(riid, IID_IUnknown))
  84. {
  85. *ppReturn = (LPUNKNOWN)(LPCONTEXTMENU)this;
  86. }
  87. else if(IsEqualIID(riid, IID_IDataObject))
  88. {
  89. *ppReturn = (LPDATAOBJECT)this;
  90. }
  91. else if(IsEqualIID(riid, IID_IEnumFORMATETC))
  92. {
  93. *ppReturn = (LPENUMFORMATETC)this;
  94. }
  95. if(*ppReturn)
  96. {
  97. (*(LPUNKNOWN*)ppReturn)->AddRef();
  98. return S_OK;
  99. }
  100. return E_NOINTERFACE;
  101. }
  102. /**************************************************************************
  103. CDataObject::AddRef
  104. **************************************************************************/
  105. STDMETHODIMP_(DWORD) CDataObject::AddRef()
  106. {
  107. return ++m_ObjRefCount;
  108. }
  109. /**************************************************************************
  110. CDataObject::Release
  111. **************************************************************************/
  112. STDMETHODIMP_(DWORD) CDataObject::Release()
  113. {
  114. if(--m_ObjRefCount == 0)
  115. delete this;
  116. return m_ObjRefCount;
  117. }
  118. ///////////////////////////////////////////////////////////////////////////
  119. //
  120. // IDataObject Implementation
  121. //
  122. /**************************************************************************
  123. CDataObject::GetData()
  124. **************************************************************************/
  125. STDMETHODIMP CDataObject::GetData(LPFORMATETC pFE, LPSTGMEDIUM pStgMedium)
  126. {
  127. if(pFE->cfFormat == m_cfPrivateData)
  128. {
  129. LPITEMIDLIST pidlParent;
  130. pidlParent = m_psfParent->CreateFQPidl(NULL);
  131. if(pidlParent)
  132. {
  133. pStgMedium->hGlobal = CreatePrivateClipboardData(pidlParent, m_aPidls, m_uItemCount, FALSE);
  134. m_pPidlMgr->Delete(pidlParent);
  135. if(pStgMedium->hGlobal)
  136. {
  137. pStgMedium->tymed = TYMED_HGLOBAL;
  138. return S_OK;
  139. }
  140. }
  141. return E_OUTOFMEMORY;
  142. }
  143. else if(pFE->cfFormat == m_cfShellIDList)
  144. {
  145. LPITEMIDLIST pidlParent;
  146. pidlParent = m_psfParent->CreateFQPidl(NULL);
  147. if(pidlParent)
  148. {
  149. pStgMedium->hGlobal = CreateShellIDList(pidlParent, m_aPidls, m_uItemCount);
  150. m_pPidlMgr->Delete(pidlParent);
  151. if(pStgMedium->hGlobal)
  152. {
  153. pStgMedium->tymed = TYMED_HGLOBAL;
  154. return S_OK;
  155. }
  156. }
  157. return E_OUTOFMEMORY;
  158. }
  159. return E_INVALIDARG;
  160. }
  161. /**************************************************************************
  162. CDataObject::GetDataHere()
  163. **************************************************************************/
  164. STDMETHODIMP CDataObject::GetDataHere (LPFORMATETC pFE, LPSTGMEDIUM pStgMedium)
  165. {
  166. return E_NOTIMPL;
  167. }
  168. /**************************************************************************
  169. CDataObject::QueryGetData()
  170. **************************************************************************/
  171. STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC pFE)
  172. {
  173. BOOL fReturn = FALSE;
  174. /*
  175. Check the aspects we support. Implementations of this object will only
  176. support DVASPECT_CONTENT.
  177. */
  178. if(!(DVASPECT_CONTENT & pFE->dwAspect))
  179. return DV_E_DVASPECT;
  180. if(pFE->cfFormat == m_cfPrivateData)
  181. {
  182. //
  183. // Now check for an appropriate TYMED.
  184. //
  185. for(UINT i = 0; i < m_cFormatEtc; i++)
  186. {
  187. fReturn |= m_pFormatEtc[i].tymed & pFE->tymed;
  188. }
  189. }
  190. if(pFE->cfFormat == m_cfShellIDList)
  191. {
  192. //
  193. // Now check for an appropriate TYMED.
  194. //
  195. for(UINT i = 0; i < m_cFormatEtc; i++)
  196. {
  197. fReturn |= m_pFormatEtc[i].tymed & pFE->tymed;
  198. }
  199. }
  200. return (fReturn ? S_OK : DV_E_TYMED);
  201. }
  202. /**************************************************************************
  203. CDataObject::GetCanonicalFormatEtc()
  204. **************************************************************************/
  205. STDMETHODIMP CDataObject::GetCanonicalFormatEtc(LPFORMATETC pFEIn, LPFORMATETC pFEOut)
  206. {
  207. if(NULL == pFEOut)
  208. return E_INVALIDARG;
  209. pFEOut->ptd = NULL;
  210. return DATA_S_SAMEFORMATETC;
  211. }
  212. /**************************************************************************
  213. CDataObject::EnumFormatEtc()
  214. **************************************************************************/
  215. STDMETHODIMP CDataObject::EnumFormatEtc( DWORD dwDirection,
  216. IEnumFORMATETC** ppEFE)
  217. {
  218. *ppEFE = NULL;
  219. if(DATADIR_GET == dwDirection)
  220. {
  221. return this->QueryInterface(IID_IEnumFORMATETC, (LPVOID*)ppEFE);
  222. }
  223. return E_NOTIMPL;
  224. }
  225. /**************************************************************************
  226. CDataObject::SetData()
  227. **************************************************************************/
  228. STDMETHODIMP CDataObject::SetData( LPFORMATETC pFE,
  229. LPSTGMEDIUM pStgMedium,
  230. BOOL fRelease)
  231. {
  232. return E_NOTIMPL;
  233. }
  234. /**************************************************************************
  235. CDataObject::DAdvise()
  236. **************************************************************************/
  237. STDMETHODIMP CDataObject::DAdvise( LPFORMATETC pFE,
  238. DWORD advf,
  239. IAdviseSink *ppAdviseSink,
  240. LPDWORD pdwConnection)
  241. {
  242. return E_NOTIMPL;
  243. }
  244. /**************************************************************************
  245. CDataObject::DUnadvise()
  246. **************************************************************************/
  247. STDMETHODIMP CDataObject::DUnadvise(DWORD dwConnection)
  248. {
  249. return E_NOTIMPL;
  250. }
  251. /**************************************************************************
  252. CDataObject::EnumDAdvise()
  253. **************************************************************************/
  254. STDMETHODIMP CDataObject::EnumDAdvise(IEnumSTATDATA** ppEnumAdvise)
  255. {
  256. return E_NOTIMPL;
  257. }
  258. ///////////////////////////////////////////////////////////////////////////
  259. //
  260. // IEnumFORMATETC Implementation
  261. //
  262. STDMETHODIMP CDataObject::Next(ULONG uRequested, LPFORMATETC pFormatEtc, ULONG* pulFetched)
  263. {
  264. if(NULL == m_pFormatEtc)
  265. return S_FALSE;
  266. if(NULL != pulFetched)
  267. *pulFetched = 0L;
  268. if(NULL == pFormatEtc)
  269. return E_INVALIDARG;
  270. ULONG uFetched;
  271. for(uFetched = 0; m_iCurrent < m_cFormatEtc && uRequested > uFetched; uFetched++)
  272. {
  273. *pFormatEtc++ = m_pFormatEtc[m_iCurrent++];
  274. }
  275. if(NULL != pulFetched)
  276. *pulFetched = uFetched;
  277. return ((uFetched == uRequested) ? S_OK : S_FALSE);
  278. }
  279. /**************************************************************************
  280. CDataObject::Skip()
  281. **************************************************************************/
  282. STDMETHODIMP CDataObject::Skip(ULONG cSkip)
  283. {
  284. if((m_iCurrent + cSkip) >= m_cFormatEtc)
  285. return S_FALSE;
  286. m_iCurrent += cSkip;
  287. return S_OK;
  288. }
  289. /**************************************************************************
  290. CDataObject::Reset()
  291. **************************************************************************/
  292. STDMETHODIMP CDataObject::Reset(void)
  293. {
  294. m_iCurrent = 0;
  295. return S_OK;
  296. }
  297. /**************************************************************************
  298. CDataObject::Clone()
  299. **************************************************************************/
  300. STDMETHODIMP CDataObject::Clone(LPENUMFORMATETC* ppEnum)
  301. {
  302. CDataObject* pNew;
  303. *ppEnum = NULL;
  304. // Create the clone.
  305. pNew = new CDataObject(m_psfParent, (LPCITEMIDLIST*)m_aPidls, m_uItemCount);
  306. if (NULL == pNew)
  307. return E_OUTOFMEMORY;
  308. pNew->m_iCurrent = m_iCurrent;
  309. *ppEnum = pNew;
  310. return S_OK;
  311. }
  312. ///////////////////////////////////////////////////////////////////////////
  313. //
  314. // private and utility methods
  315. //
  316. /**************************************************************************
  317. CDataObject::AllocPidlTable()
  318. **************************************************************************/
  319. BOOL CDataObject::AllocPidlTable(DWORD dwEntries)
  320. {
  321. m_aPidls = (LPITEMIDLIST*)m_pMalloc->Alloc(dwEntries * sizeof(LPITEMIDLIST));
  322. if(m_aPidls)
  323. {
  324. //set all of the entries to NULL
  325. ZeroMemory(m_aPidls, dwEntries * sizeof(LPITEMIDLIST));
  326. }
  327. return (m_aPidls != NULL);
  328. }
  329. /**************************************************************************
  330. CDataObject::FreePidlTable()
  331. **************************************************************************/
  332. VOID CDataObject::FreePidlTable(VOID)
  333. {
  334. if(m_aPidls && m_pPidlMgr)
  335. {
  336. UINT i;
  337. for(i = 0; i < m_uItemCount; i++)
  338. m_pPidlMgr->Delete(m_aPidls[i]);
  339. m_pMalloc->Free(m_aPidls);
  340. m_aPidls = NULL;
  341. }
  342. }
  343. /**************************************************************************
  344. CDataObject::FillPidlTable()
  345. **************************************************************************/
  346. BOOL CDataObject::FillPidlTable(LPCITEMIDLIST *aPidls, UINT uItemCount)
  347. {
  348. if(m_aPidls)
  349. {
  350. if(m_pPidlMgr)
  351. {
  352. UINT i;
  353. for(i = 0; i < uItemCount; i++)
  354. {
  355. m_aPidls[i] = m_pPidlMgr->Copy(aPidls[i]);
  356. }
  357. return TRUE;
  358. }
  359. }
  360. return FALSE;
  361. }