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.

653 lines
17 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: dataobj.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 1/17/1996 RaviR Created
  15. //
  16. //____________________________________________________________________________
  17. #include "..\pch\headers.hxx"
  18. #pragma hdrstop
  19. #include "dbg.h"
  20. #include "macros.h"
  21. #include "jobidl.hxx"
  22. #include <StrSafe.h>
  23. extern "C" UINT g_cfJobIDList;
  24. extern "C" UINT g_cfShellIDList;
  25. extern "C" UINT g_cfPreferredDropEffect;
  26. //____________________________________________________________________________
  27. //
  28. // Class: CObjFormats
  29. //
  30. // Purpose: Impements IEnumFORMATETC for job objects.
  31. //____________________________________________________________________________
  32. class CObjFormats : public IEnumFORMATETC
  33. {
  34. friend HRESULT JFGetObjFormats(UINT cfmt, FORMATETC *afmt, LPVOID *ppvObj);
  35. public:
  36. ~CObjFormats() { if (m_aFmt) delete [] m_aFmt; }
  37. // IUnknown methods
  38. DECLARE_STANDARD_IUNKNOWN;
  39. // IEnumFORMATETC methods
  40. STDMETHODIMP Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed);
  41. STDMETHODIMP Skip(ULONG celt);
  42. STDMETHODIMP Reset();
  43. STDMETHODIMP Clone(IEnumFORMATETC ** ppenum);
  44. private:
  45. CObjFormats(UINT cfmt, FORMATETC * afmt)
  46. : m_iFmt(0), m_cFmt(cfmt), m_aFmt(afmt), m_ulRefs(1) {}
  47. UINT m_iFmt;
  48. UINT m_cFmt;
  49. FORMATETC * m_aFmt;
  50. };
  51. //____________________________________________________________________________
  52. //
  53. // Members: IUnknown methods
  54. //____________________________________________________________________________
  55. IMPLEMENT_STANDARD_IUNKNOWN(CObjFormats);
  56. STDMETHODIMP
  57. CObjFormats::QueryInterface(
  58. REFIID riid,
  59. LPVOID FAR* ppvObj)
  60. {
  61. if (IsEqualIID(IID_IUnknown, riid) ||
  62. IsEqualIID(IID_IEnumFORMATETC, riid))
  63. {
  64. *ppvObj = (IUnknown*)(IEnumFORMATETC*) this;
  65. this->AddRef();
  66. return S_OK;
  67. }
  68. *ppvObj = NULL;
  69. return E_NOINTERFACE;
  70. }
  71. //____________________________________________________________________________
  72. //
  73. // Members: IEnumFORMATETC methods
  74. //____________________________________________________________________________
  75. STDMETHODIMP
  76. CObjFormats::Next(
  77. ULONG celt,
  78. FORMATETC *rgelt,
  79. ULONG *pceltFethed)
  80. {
  81. UINT cfetch = 0;
  82. HRESULT hr = S_FALSE;
  83. if (m_iFmt < m_cFmt)
  84. {
  85. cfetch = m_cFmt - m_iFmt;
  86. if (cfetch >= celt)
  87. {
  88. cfetch = celt;
  89. hr = S_OK;
  90. }
  91. CopyMemory(rgelt, &m_aFmt[m_iFmt], cfetch * sizeof(FORMATETC));
  92. m_iFmt += cfetch;
  93. }
  94. if (pceltFethed)
  95. {
  96. *pceltFethed = cfetch;
  97. }
  98. return hr;
  99. }
  100. STDMETHODIMP
  101. CObjFormats::Skip(
  102. ULONG celt)
  103. {
  104. m_iFmt += celt;
  105. if (m_iFmt > m_cFmt)
  106. {
  107. m_iFmt = m_cFmt;
  108. return S_FALSE;
  109. }
  110. return S_OK;
  111. }
  112. STDMETHODIMP
  113. CObjFormats::Reset()
  114. {
  115. m_iFmt = 0;
  116. return S_OK;
  117. }
  118. STDMETHODIMP
  119. CObjFormats::Clone(
  120. IEnumFORMATETC ** ppenum)
  121. {
  122. return E_NOTIMPL;
  123. }
  124. //____________________________________________________________________________
  125. //
  126. // Function: Function to obtain the IEnumFORMATETC interface for jobs.
  127. //____________________________________________________________________________
  128. HRESULT
  129. JFGetObjFormats(
  130. UINT cfmt,
  131. FORMATETC * afmt,
  132. LPVOID * ppvObj)
  133. {
  134. TRACE_FUNCTION(JFGetObjFormats);
  135. FORMATETC * pFmt = new FORMATETC[cfmt];
  136. if (pFmt == NULL)
  137. {
  138. CHECK_HRESULT(E_OUTOFMEMORY);
  139. return E_OUTOFMEMORY;
  140. }
  141. CopyMemory(pFmt, afmt, cfmt * sizeof(FORMATETC));
  142. CObjFormats * pObjFormats = new CObjFormats(cfmt, pFmt);
  143. if (pObjFormats == NULL)
  144. {
  145. delete [] pFmt;
  146. CHECK_HRESULT(E_OUTOFMEMORY);
  147. return E_OUTOFMEMORY;
  148. }
  149. HRESULT hr = pObjFormats->QueryInterface(IID_IEnumFORMATETC, ppvObj);
  150. pObjFormats->Release();
  151. DEBUG_OUT((DEB_TRACE, "RETURNING CObjFormats<%x, %d>\n",
  152. pObjFormats, pObjFormats->m_ulRefs));
  153. return hr;
  154. }
  155. //____________________________________________________________________________
  156. //____________________________________________________________________________
  157. //________________ _______________________________________
  158. //________________ class CJobObject _______________________________________
  159. //________________ _______________________________________
  160. //____________________________________________________________________________
  161. //____________________________________________________________________________
  162. class CJobObject : public IDataObject
  163. {
  164. public:
  165. CJobObject(
  166. LPCTSTR pszFolderPath,
  167. LPITEMIDLIST pidlFolder,
  168. UINT cidl,
  169. LPITEMIDLIST *apidl,
  170. BOOL fCut);
  171. ~CJobObject()
  172. {
  173. ILA_Free(m_cidl, m_apidl);
  174. ILFree(m_pidlFolder);
  175. DEBUG_ASSERT(m_ulRefs == 0);
  176. }
  177. // Iunknown methods
  178. DECLARE_STANDARD_IUNKNOWN;
  179. // IDataObject
  180. STDMETHODIMP GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
  181. STDMETHODIMP GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium);
  182. STDMETHODIMP QueryGetData(FORMATETC *pformatetc);
  183. STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *pformatectIn,
  184. FORMATETC *pformatetcOut);
  185. STDMETHODIMP SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium,
  186. BOOL fRelease);
  187. STDMETHODIMP EnumFormatEtc(DWORD dwDirection,
  188. IEnumFORMATETC **ppenumFormatEtc);
  189. STDMETHODIMP DAdvise(FORMATETC *pformatetc, DWORD advf,
  190. IAdviseSink *pAdvSink, DWORD *pdwConnection);
  191. STDMETHODIMP DUnadvise(DWORD dwConnection);
  192. STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenumAdvise);
  193. private:
  194. LPCTSTR m_pszFolderPath;
  195. LPITEMIDLIST m_pidlFolder;
  196. UINT m_cidl;
  197. LPITEMIDLIST * m_apidl;
  198. BOOL m_fCut; // this is for a cut operation
  199. };
  200. inline
  201. CJobObject::CJobObject(
  202. LPCTSTR pszFolderPath,
  203. LPITEMIDLIST pidlFolder,
  204. UINT cidl,
  205. LPITEMIDLIST *apidl,
  206. BOOL fCut):
  207. m_cidl(cidl),
  208. m_pszFolderPath(pszFolderPath),
  209. m_pidlFolder(pidlFolder),
  210. m_apidl(apidl),
  211. m_ulRefs(1),
  212. m_fCut(fCut)
  213. {
  214. }
  215. //____________________________________________________________________________
  216. //
  217. // Members: IUnknown methods
  218. //____________________________________________________________________________
  219. IMPLEMENT_STANDARD_IUNKNOWN(CJobObject);
  220. STDMETHODIMP
  221. CJobObject::QueryInterface(
  222. REFIID riid,
  223. LPVOID FAR* ppvObj)
  224. {
  225. if (IsEqualIID(IID_IUnknown, riid) ||
  226. IsEqualIID(IID_IDataObject, riid))
  227. {
  228. *ppvObj = (IUnknown*)((IDataObject*)this);
  229. this->AddRef();
  230. return S_OK;
  231. }
  232. *ppvObj = NULL;
  233. return E_NOINTERFACE;
  234. }
  235. //____________________________________________________________________________
  236. //
  237. // Function: DbgPrintFmt
  238. //
  239. // Synopsis: Function to print out the format name.
  240. //____________________________________________________________________________
  241. #if DBG==1
  242. void
  243. DbgPrintFmt(
  244. UINT format)
  245. {
  246. #undef DEB_USEREX
  247. #define DEB_USEREX DEB_USER15
  248. TCHAR szFmtName[550];
  249. int cchFmtName = 550;
  250. if (format == g_cfJobIDList)
  251. {
  252. DEBUG_OUT((DEB_USEREX, "\t\t<Format=Job IDList Array>\n"));
  253. return;
  254. }
  255. else if (format == g_cfPreferredDropEffect)
  256. {
  257. DEBUG_OUT((DEB_USEREX, "\t\t<Format=Preferred DropEffect>\n"));
  258. return;
  259. }
  260. int iRet = GetClipboardFormatName(format, szFmtName, cchFmtName);
  261. if (iRet == 0)
  262. if (GetLastError() == 0)
  263. DEBUG_OUT((DEB_USEREX, "\t\t<Predefined format=%d>\n", format));
  264. else
  265. DEBUG_OUT((DEB_USEREX, "\t\t<Unknown Format=%d>\n", format));
  266. else
  267. DEBUG_OUT((DEB_USEREX, "\t\t<Format=%ws>\n", szFmtName));
  268. }
  269. #define DBG_PRINT_FMT(fmt) DbgPrintFmt(fmt)
  270. #else
  271. #define DBG_PRINT_FMT(fmt)
  272. #endif
  273. //____________________________________________________________________________
  274. //
  275. // Member: CJobObject::IDataObject::GetData
  276. //
  277. // History: 1/31/1996 RaviR Created
  278. //____________________________________________________________________________
  279. STDMETHODIMP
  280. CJobObject::GetData(
  281. FORMATETC *pfmt,
  282. STGMEDIUM *pmedium)
  283. {
  284. TRACE(CJobObject, GetData);
  285. DBG_PRINT_FMT(pfmt->cfFormat);
  286. Win4Assert(g_cfJobIDList != 0);
  287. if (pfmt->tymed & TYMED_HGLOBAL)
  288. {
  289. if (pfmt->cfFormat == CF_HDROP)
  290. {
  291. pmedium->hGlobal = HDROPFromJobIDList(m_pszFolderPath,
  292. m_cidl, (PJOBID *)m_apidl);
  293. }
  294. else if (pfmt->cfFormat == g_cfShellIDList)
  295. {
  296. pmedium->hGlobal = CreateIDListArray(m_pidlFolder,
  297. m_cidl,
  298. (PJOBID *)m_apidl);
  299. }
  300. else if (pfmt->cfFormat == g_cfJobIDList)
  301. {
  302. // Note Ole32's GetHGlobalFromILockBytes uses this
  303. pmedium->hGlobal = HJOBIDA_Create(m_cidl, (PJOBID *)m_apidl);
  304. }
  305. else if (pfmt->cfFormat == g_cfPreferredDropEffect)
  306. {
  307. DWORD *pdw = (DWORD *)GlobalAlloc(GPTR, sizeof(DWORD));
  308. if (pdw)
  309. {
  310. *pdw = m_fCut ? DROPEFFECT_MOVE : DROPEFFECT_COPY;
  311. pmedium->hGlobal = (HGLOBAL)pdw;
  312. }
  313. }
  314. else
  315. {
  316. pmedium->tymed = TYMED_NULL;
  317. pmedium->hGlobal = NULL;
  318. pmedium->pUnkForRelease = NULL;
  319. return DATA_E_FORMATETC;
  320. }
  321. if (pmedium->hGlobal != NULL)
  322. {
  323. pmedium->tymed = TYMED_HGLOBAL;
  324. pmedium->pUnkForRelease = NULL;
  325. return S_OK;
  326. }
  327. else
  328. {
  329. return E_OUTOFMEMORY;
  330. }
  331. }
  332. return DV_E_TYMED;
  333. }
  334. //____________________________________________________________________________
  335. //
  336. // Member: CJobObject::IDataObject::GetDataHere
  337. //____________________________________________________________________________
  338. STDMETHODIMP
  339. CJobObject::GetDataHere(
  340. FORMATETC *pfmt,
  341. STGMEDIUM *pmedium)
  342. {
  343. TRACE(CJobObject, GetDataHere);
  344. DBG_PRINT_FMT(pfmt->cfFormat);
  345. return E_NOTIMPL;
  346. }
  347. //____________________________________________________________________________
  348. //
  349. // Member: CJobObject::IDataObject::QueryGetData
  350. //
  351. // History: 1/31/1996 RaviR Created
  352. //____________________________________________________________________________
  353. STDMETHODIMP
  354. CJobObject::QueryGetData(
  355. FORMATETC *pfmt)
  356. {
  357. TRACE(CJobObject, QueryGetData);
  358. DBG_PRINT_FMT(pfmt->cfFormat);
  359. //
  360. // Check the aspects we support.
  361. //
  362. if (!(DVASPECT_CONTENT & pfmt->dwAspect))
  363. {
  364. return DATA_E_FORMATETC;
  365. }
  366. Win4Assert(g_cfJobIDList != 0);
  367. if (pfmt->cfFormat == CF_HDROP ||
  368. pfmt->cfFormat == g_cfJobIDList ||
  369. pfmt->cfFormat == g_cfShellIDList ||
  370. pfmt->cfFormat == g_cfPreferredDropEffect)
  371. {
  372. return S_OK;
  373. }
  374. return S_FALSE;
  375. }
  376. //____________________________________________________________________________
  377. //
  378. // Member: CJobObject::IDataObject::GetCanonicalFormatEtc
  379. //____________________________________________________________________________
  380. STDMETHODIMP
  381. CJobObject::GetCanonicalFormatEtc(
  382. FORMATETC *pfmtIn,
  383. FORMATETC *pfmtOut)
  384. {
  385. TRACE(CJobObject, GetCanonicalFormatEtc);
  386. *pfmtOut = *pfmtIn;
  387. pfmtOut->ptd = NULL;
  388. return DATA_S_SAMEFORMATETC;
  389. }
  390. //____________________________________________________________________________
  391. //
  392. // Member: CJobObject::IDataObject::SetData
  393. //____________________________________________________________________________
  394. STDMETHODIMP
  395. CJobObject::SetData(
  396. FORMATETC *pfmt,
  397. STGMEDIUM *pmedium,
  398. BOOL fRelease)
  399. {
  400. TRACE(CJobObject, SetData);
  401. DBG_PRINT_FMT(pfmt->cfFormat);
  402. return E_NOTIMPL;
  403. }
  404. //____________________________________________________________________________
  405. //
  406. // Member: CJobObject::IDataObject::EnumFormatEtc
  407. //
  408. // History: 1/31/1996 RaviR Created
  409. //____________________________________________________________________________
  410. STDMETHODIMP
  411. CJobObject::EnumFormatEtc(
  412. DWORD dwDirection,
  413. IEnumFORMATETC **ppenumFormatEtc)
  414. {
  415. TRACE(CJobObject, EnumFormatEtc);
  416. if (dwDirection == DATADIR_SET)
  417. {
  418. return E_FAIL;
  419. }
  420. FORMATETC fmte[] = {
  421. {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
  422. {(CLIPFORMAT)g_cfJobIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
  423. {(CLIPFORMAT)g_cfShellIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
  424. {(CLIPFORMAT)g_cfPreferredDropEffect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
  425. };
  426. HRESULT hr = JFGetObjFormats(ARRAYLEN(fmte), fmte, (void**)ppenumFormatEtc);
  427. return hr;
  428. }
  429. //____________________________________________________________________________
  430. //
  431. // Member: CJobObject::IDataObject::DAdvise
  432. //____________________________________________________________________________
  433. STDMETHODIMP
  434. CJobObject::DAdvise(
  435. FORMATETC *pformatetc,
  436. DWORD advf,
  437. IAdviseSink *pAdvSink,
  438. DWORD *pdwConnection)
  439. {
  440. TRACE(CJobObject, DAdvise);
  441. return E_NOTIMPL;
  442. }
  443. //____________________________________________________________________________
  444. //
  445. // Member: CJobObject::IDataObject::DUnadvise
  446. //____________________________________________________________________________
  447. STDMETHODIMP
  448. CJobObject::DUnadvise(
  449. DWORD dwConnection)
  450. {
  451. TRACE(CJobObject, DUnadvise);
  452. return E_NOTIMPL;
  453. }
  454. //____________________________________________________________________________
  455. //
  456. // Member: CJobObject::IDataObject::EnumDAdvise
  457. //____________________________________________________________________________
  458. STDMETHODIMP
  459. CJobObject::EnumDAdvise(
  460. IEnumSTATDATA **ppenumAdvise)
  461. {
  462. TRACE(CJobObject, EnumDAdvise);
  463. return E_NOTIMPL;
  464. }
  465. //+--------------------------------------------------------------------------
  466. //
  467. // Function: JFGetDataObject
  468. //
  469. // Synopsis: Function to create a data object for jobs in the job folder.
  470. //
  471. // Arguments: [pszFolderPath] - full path to tasks folder
  472. // [pidlFolder] - pidl to that folder, supplied by shell's
  473. // call to IPersistFolder::Initialize.
  474. // [cidl] - number elements in array
  475. // [apidl] - array of idls, each naming a .job object
  476. // [fCut] - TRUE if this is created for cut operation
  477. // [ppvObj] - filled with pointer to new data object
  478. //
  479. // Returns: HRESULT
  480. //
  481. // Modifies: *[ppvObj]
  482. //
  483. // History: 01/31/1996 RaviR Created
  484. // 05-30-1997 DavidMun Pass copy of [pidlFolder]
  485. //
  486. //---------------------------------------------------------------------------
  487. HRESULT
  488. JFGetDataObject(
  489. LPCTSTR pszFolderPath,
  490. LPCITEMIDLIST pidlFolder,
  491. UINT cidl,
  492. LPCITEMIDLIST * apidl,
  493. BOOL fCut,
  494. LPVOID * ppvObj)
  495. {
  496. TRACE_FUNCTION(JFGetDataObject);
  497. LPITEMIDLIST * apidlTemp = ILA_Clone(cidl, apidl);
  498. if (NULL == apidlTemp)
  499. {
  500. CHECK_HRESULT(E_OUTOFMEMORY);
  501. return E_OUTOFMEMORY;
  502. }
  503. LPITEMIDLIST pidlFolderCopy = ILClone(pidlFolder);
  504. if (!pidlFolderCopy)
  505. {
  506. ILA_Free(cidl, apidlTemp);
  507. CHECK_HRESULT(E_OUTOFMEMORY);
  508. return E_OUTOFMEMORY;
  509. }
  510. CJobObject * pJobObjects = new CJobObject(pszFolderPath,
  511. pidlFolderCopy,
  512. cidl,
  513. apidlTemp,
  514. fCut);
  515. if (pJobObjects == NULL)
  516. {
  517. ILA_Free(cidl, apidlTemp);
  518. CHECK_HRESULT(E_OUTOFMEMORY);
  519. return E_OUTOFMEMORY;
  520. }
  521. HRESULT hr = pJobObjects->QueryInterface(IID_IDataObject, ppvObj);
  522. pJobObjects->Release();
  523. return hr;
  524. }