Source code of Windows XP (NT5)
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.

471 lines
12 KiB

  1. // DataObj.cpp: Implementation of the Management Console interface
  2. // representation of a data object.
  3. //
  4. // Copyright (c) 1998-1999 Microsoft Corporation
  5. #include "StdAfx.h"
  6. #include "DataObj.h"
  7. // This hack is required because we may be building in an environment
  8. // which doesn't have a late enough version of rpcndr.h
  9. #if __RPCNDR_H_VERSION__ < 440
  10. #define __RPCNDR_H_VERSION__ 440
  11. #define MIDL_INTERFACE(x) interface
  12. #endif
  13. #ifndef __mmc_h__
  14. #include <mmc.h>
  15. #endif // __mmc_h__
  16. #ifndef IDS_NODENAME
  17. #include "Resource.h"
  18. #endif // IDS_NODENAME
  19. // Default initialization of the static members.
  20. // Note that snap-ins only work as unicode binaries, so no conversion is
  21. // required for these strings.
  22. unsigned int CDataObject::m_cfMultiSel = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  23. unsigned int CDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  24. unsigned int CDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  25. unsigned int CDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  26. unsigned int CDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  27. unsigned int CDataObject::m_cfSnapinPreloads = RegisterClipboardFormat(CCF_SNAPIN_PRELOADS);
  28. unsigned int CDataObject::m_cfMachineName = RegisterClipboardFormat(CF_MACHINE_NAME);
  29. unsigned int CDataObject::m_cfInternalObject = RegisterClipboardFormat(CF_INTERNAL_OBJECT);
  30. /*
  31. * CDataObject() - The CDataObject constructor. Register all of the
  32. * appropriate clipboard formats potentially used by the object.
  33. *
  34. * History: a-jsari 9/1/97 Initial version
  35. */
  36. CDataObject::CDataObject()
  37. :m_pbMultiSelData(0), m_cbMultiSelData(0), m_bMultiSelDobj(FALSE),
  38. m_pComponentData(NULL)
  39. {
  40. USES_CONVERSION;
  41. ASSERT(IsValidRegisteredClipboardFormat(m_cfNodeType));
  42. ASSERT(IsValidRegisteredClipboardFormat(m_cfNodeTypeString));
  43. ASSERT(IsValidRegisteredClipboardFormat(m_cfDisplayName));
  44. ASSERT(IsValidRegisteredClipboardFormat(m_cfCoClass));
  45. ASSERT(IsValidRegisteredClipboardFormat(m_cfMultiSel));
  46. ASSERT(IsValidRegisteredClipboardFormat(m_cfSnapinPreloads));
  47. ASSERT(IsValidRegisteredClipboardFormat(m_cfMachineName));
  48. ASSERT(IsValidRegisteredClipboardFormat(m_cfInternalObject));
  49. m_internal.m_cookie = 0;
  50. m_internal.m_type = CCT_UNINITIALIZED;
  51. }
  52. /*
  53. * ~CDataObject() - The Destructor (does nothing)
  54. *
  55. * History: a-jsari 9/1/97 Initial version
  56. */
  57. CDataObject::~CDataObject()
  58. {
  59. }
  60. /*
  61. * GetData - Return in lpMedium the data for the data format in lpFormatetc.
  62. *
  63. * History: a-jsari 9/1/97 Initial version
  64. */
  65. STDMETHODIMP CDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  66. {
  67. TRACE(_T("CDataObject::GetData\n"));
  68. ASSERT(lpFormatetc != NULL);
  69. ASSERT(lpMedium != NULL);
  70. if (!(lpFormatetc && lpMedium)) return E_POINTER;
  71. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  72. HRESULT hr = DV_E_CLIPFORMAT;
  73. if (lpFormatetc->cfFormat == m_cfMultiSel) {
  74. ASSERT(Cookie() == MMC_MULTI_SELECT_COOKIE);
  75. if (Cookie() != MMC_MULTI_SELECT_COOKIE) return E_FAIL;
  76. ASSERT(m_pbMultiSelData != 0);
  77. ASSERT(m_cbMultiSelData != 0);
  78. lpMedium->tymed = TYMED_HGLOBAL;
  79. lpMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE,
  80. (m_cbMultiSelData + sizeof(DWORD)));
  81. if (lpMedium->hGlobal == NULL) return STG_E_MEDIUMFULL;
  82. BYTE *pb = reinterpret_cast<BYTE *>(::GlobalLock(lpMedium->hGlobal));
  83. // Store count.
  84. *((DWORD*)pb) = m_cbMultiSelData / sizeof(GUID);
  85. pb += sizeof(DWORD);
  86. // Store the rest of it.
  87. CopyMemory(pb, m_pbMultiSelData, m_cbMultiSelData);
  88. ::GlobalUnlock(lpMedium->hGlobal);
  89. hr = S_OK;
  90. }
  91. return hr;
  92. }
  93. /*
  94. * GetDataHere - Returns in pMedium, the data requested by the clipboard
  95. * format in pFormatetc
  96. *
  97. * History: a-jsari 9/2/97 Initial version
  98. *
  99. * Note: The HGLOBAL in pMedium will need to be released by the caller.
  100. */
  101. STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC pFormatetc, LPSTGMEDIUM pMedium)
  102. {
  103. TRACE(_T("CDataObject::GetDataHere(%x)\n"), pFormatetc->cfFormat);
  104. ASSERT(pFormatetc != NULL);
  105. ASSERT(pMedium != NULL);
  106. ASSERT(pFormatetc->tymed == TYMED_HGLOBAL);
  107. if (pFormatetc == NULL || pMedium == NULL) return E_POINTER;
  108. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  109. HRESULT hr = DV_E_CLIPFORMAT;
  110. const CLIPFORMAT cf = pFormatetc->cfFormat;
  111. if (cf == m_cfNodeType) {
  112. hr = CreateNodeTypeData(pMedium);
  113. } else if (cf == m_cfCoClass) {
  114. hr = CreateCoClassID(pMedium);
  115. } else if (cf == m_cfNodeTypeString) {
  116. hr = CreateNodeTypeStringData(pMedium);
  117. } else if (cf == m_cfDisplayName) {
  118. hr = CreateDisplayName(pMedium);
  119. } else if (cf == m_cfMachineName) {
  120. hr = CreateMachineName(pMedium);
  121. } else if (cf == m_cfInternalObject) {
  122. hr = CreateInternalObject(pMedium);
  123. } else if (cf == m_cfSnapinPreloads) {
  124. hr = CreateSnapinPreloads(pMedium);
  125. } else {
  126. // Unknown clipboard format.
  127. ASSERT(FALSE);
  128. }
  129. return hr;
  130. }
  131. /*
  132. * EnumFormatEtc - We don't yet return an enumeration interface for our clipboard
  133. * formats.
  134. *
  135. * History: a-jsari 9/2/97 Stub version
  136. */
  137. STDMETHODIMP CDataObject::EnumFormatEtc(DWORD, LPENUMFORMATETC *ppEnumFormatEtc)
  138. {
  139. TRACE(_T("CDataObject::EnumFormatEtc\n"));
  140. ASSERT(ppEnumFormatEtc != NULL);
  141. if (ppEnumFormatEtc == NULL) return E_POINTER;
  142. return E_NOTIMPL;
  143. }
  144. /*
  145. * QueryGetData -
  146. *
  147. * History: a-jsari 9/2/97 Stub version
  148. */
  149. STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC lpFormatetc)
  150. {
  151. TRACE(_T("CDataObject::QueryGetData\n"));
  152. ASSERT(lpFormatetc != NULL);
  153. if (lpFormatetc == NULL) return E_POINTER;
  154. return E_NOTIMPL;
  155. }
  156. /*
  157. * GetCanonicalFormatEtc - Not implemented.
  158. *
  159. * History: a-jsari 9/2/97 Stub version
  160. */
  161. STDMETHODIMP CDataObject::GetCanonicalFormatEtc(LPFORMATETC lpFormatetcIn, LPFORMATETC lpFormatetcOut)
  162. {
  163. TRACE(_T("CDataObject::GetCanonicalFormatEtc\n"));
  164. ASSERT(lpFormatetcIn != NULL);
  165. ASSERT(lpFormatetcOut != NULL);
  166. if (lpFormatetcIn == NULL || lpFormatetcOut == NULL) return E_POINTER;
  167. return E_NOTIMPL;
  168. }
  169. /*
  170. * SetData -
  171. *
  172. * History: a-jsari 9/2/97 Stub version
  173. */
  174. STDMETHODIMP CDataObject::SetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium, BOOL)
  175. {
  176. TRACE(_T("CDataObject::GetCanonicalFormatEtc\n"));
  177. ASSERT(lpFormatetc != NULL);
  178. ASSERT(lpMedium != NULL);
  179. if (lpFormatetc == NULL || lpMedium == NULL) return E_POINTER;
  180. return E_NOTIMPL;
  181. }
  182. /*
  183. * DAdvise -
  184. *
  185. * History: a-jsari 9/2/97 Stub version
  186. */
  187. STDMETHODIMP CDataObject::DAdvise(LPFORMATETC lpFormatetc, DWORD, LPADVISESINK pAdvSink, LPDWORD pdwConnection)
  188. {
  189. TRACE(_T("CDataObject::DAdvise\n"));
  190. ASSERT(lpFormatetc != NULL);
  191. ASSERT(pAdvSink != NULL);
  192. ASSERT(pdwConnection != NULL);
  193. if (lpFormatetc == NULL || pAdvSink == NULL || pdwConnection == NULL) return E_POINTER;
  194. return E_NOTIMPL;
  195. }
  196. /*
  197. * DUnadvise -
  198. *
  199. * History: a-jsari 9/2/97 Stub version
  200. */
  201. STDMETHODIMP CDataObject::DUnadvise(DWORD)
  202. {
  203. TRACE(_T("CDataObject::DUnadvise\n"));
  204. return E_NOTIMPL;
  205. }
  206. /*
  207. * EnumDAdvise -
  208. *
  209. * History: a-jsari 9/2/97 Stub version
  210. */
  211. STDMETHODIMP CDataObject::EnumDAdvise(LPENUMSTATDATA *ppEnumAdvise)
  212. {
  213. TRACE(_T("CDataObject::EnumDAdvise\n"));
  214. ASSERT(ppEnumAdvise != NULL);
  215. if (ppEnumAdvise == NULL) return E_POINTER;
  216. return E_NOTIMPL;
  217. }
  218. /*
  219. * Create - copy size bytes from pBuffer into a globally allocated
  220. * segment into lpMedium.
  221. *
  222. * History: a-jsari 9/1/97 Initial version
  223. */
  224. HRESULT CDataObject::Create(const void *pBuffer, int size, LPSTGMEDIUM lpMedium)
  225. {
  226. HRESULT hr = DV_E_TYMED;
  227. ASSERT(pBuffer != NULL);
  228. ASSERT(lpMedium != NULL);
  229. if (pBuffer == NULL || lpMedium == NULL) return E_POINTER;
  230. // Make sure the type medium is HGLOBAL
  231. if (lpMedium->tymed == TYMED_HGLOBAL) {
  232. LPSTREAM lpStream;
  233. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  234. if (SUCCEEDED(hr)) {
  235. // Write size bytes to the stream.
  236. unsigned long cWritten;
  237. hr = lpStream->Write(pBuffer, size, &cWritten);
  238. // Because we called CreateStreamOnHGlobal with
  239. // fDeleteOnRelease == FALSE, lpMedium->hGlobal points to
  240. // GlobalAlloc'd memory.
  241. //
  242. // Note - the caller (i.e. snap-in, object) is responsible for
  243. // freeing the HGLOBAL at the correct time, following the
  244. // IDataObject specification.
  245. lpStream->Release();
  246. }
  247. }
  248. return hr;
  249. }
  250. /*
  251. * CreateCoClassID - Return an allocated copy of the CLSID in lpMedium.
  252. *
  253. * History: a-jsari 9/1/97 Initial version
  254. *
  255. * Note: The hGlobal in lpMedium must be freed by the caller. (See Create for
  256. * details).
  257. */
  258. HRESULT CDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  259. {
  260. CLSID clsidNew;
  261. clsidNew = ClassID();
  262. HRESULT hr = Create(reinterpret_cast<const void *>(&clsidNew), sizeof(CLSID), lpMedium);
  263. return hr;
  264. }
  265. /*
  266. * CreateSnapinPreloads - Return the preload status for the snapin, which is the
  267. * flag reflecting whether the root node name can be set on load. I think.
  268. * We're not going to do any of that. Implemented because we get asked about
  269. * it when we save our MSC file.
  270. *
  271. * History: a-jsari 3/10/98 Initial version
  272. */
  273. HRESULT CDataObject::CreateSnapinPreloads(LPSTGMEDIUM lpMedium)
  274. {
  275. BOOL fPreload = FALSE;
  276. return Create(reinterpret_cast<const void *>(&fPreload), sizeof(BOOL), lpMedium);
  277. }
  278. /*
  279. * CreateMachineName - Put a wide character string containing the name
  280. * of the system Information Machine into lpMedium
  281. *
  282. * History: a-jsari 9/22/97 Initial version
  283. */
  284. HRESULT CDataObject::CreateMachineName(LPSTGMEDIUM lpMedium)
  285. {
  286. int wMachineNameLength = 0;
  287. LPWSTR szMachineName = NULL;
  288. USES_CONVERSION;
  289. // TSTR to WSTR
  290. if (pComponentData())
  291. {
  292. szMachineName = WSTR_FROM_CSTRING(pComponentData()->MachineName());
  293. if (szMachineName)
  294. wMachineNameLength = wcslen(szMachineName);
  295. }
  296. return Create(szMachineName, ((wMachineNameLength + 1) * sizeof(WCHAR)), lpMedium);
  297. }
  298. /*
  299. * CreateMultiSelData - Return in lpMedium a copy of a pointer to the
  300. * multiple selection.
  301. *
  302. * History: a-jsari 9/1/97 Initial version
  303. */
  304. HRESULT CDataObject::CreateMultiSelData(LPSTGMEDIUM lpMedium)
  305. {
  306. ASSERT(Cookie() == MMC_MULTI_SELECT_COOKIE);
  307. ASSERT(m_pbMultiSelData != 0);
  308. ASSERT(m_cbMultiSelData != 0);
  309. return Create(reinterpret_cast<const void *>(m_pbMultiSelData), m_cbMultiSelData,
  310. lpMedium);
  311. }
  312. /*
  313. * CreateInternalObject - Return in lpMedium a copy of a pointer to the
  314. * current object.
  315. *
  316. * History: a-jsari 9/25/97 Initial version
  317. */
  318. HRESULT CDataObject::CreateInternalObject(LPSTGMEDIUM lpMedium)
  319. {
  320. CDataObject *pCopyOfMe = this;
  321. return Create(reinterpret_cast<const void *>(&pCopyOfMe), sizeof(CDataObject *),
  322. lpMedium);
  323. }
  324. /*
  325. * InstantiateDataObject - Creates the appropriate CDataObject based on the
  326. * type of the data object.
  327. *
  328. * History: a-jsari 9/28/97 Initial version
  329. */
  330. static inline CDataObject *InstantiateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type)
  331. {
  332. CDataObject *rDataObject = NULL;
  333. if (cookie == 0) {
  334. CComObject<CManagerDataObject>* pManagerObject;
  335. CComObject<CManagerDataObject>::CreateInstance(&pManagerObject);
  336. rDataObject = pManagerObject;
  337. } else
  338. switch (type) {
  339. case CCT_SCOPE:
  340. CComObject<CScopeDataObject>* pScopeObject;
  341. CComObject<CScopeDataObject>::CreateInstance(&pScopeObject);
  342. rDataObject = pScopeObject;
  343. break;
  344. case CCT_RESULT:
  345. CComObject<CResultDataObject>* pResultObject;
  346. CComObject<CResultDataObject>::CreateInstance(&pResultObject);
  347. rDataObject = pResultObject;
  348. break;
  349. default:
  350. ASSERT(FALSE);
  351. return NULL;
  352. break;
  353. }
  354. if(rDataObject)
  355. {
  356. rDataObject->SetCookie(cookie);
  357. rDataObject->SetContext(type);
  358. }
  359. return rDataObject;
  360. }
  361. /*
  362. * CreateDataObject - Queries an ATL instantiation of the CDataObject for
  363. * the IDataObject interface pointer represented by cookie and type,
  364. * returning it in ppDataObject.
  365. *
  366. * Return codes:
  367. * S_OK - Successful completion
  368. * E_POINTER - pImpl or ppDataObject is an invalid pointer
  369. * E_FAIL - CComObject<CDataObject>::CreateInstance failed.
  370. *
  371. * History: a-jsari 9/28/97 Initial version
  372. */
  373. HRESULT CDataObject::CreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  374. CSystemInfoScope *pScope, LPDATAOBJECT *ppDataObject)
  375. {
  376. ASSERT(ppDataObject != NULL);
  377. ASSERT(pScope != NULL);
  378. if (ppDataObject == NULL || pScope == NULL) return E_POINTER;
  379. CDataObject *pObject = InstantiateDataObject(cookie, type);
  380. ASSERT(pObject != NULL);
  381. if (pObject == NULL) return E_FAIL;
  382. pObject->SetComponentData(pScope);
  383. return pObject->QueryInterface(IID_IDataObject, reinterpret_cast<void **>(ppDataObject));
  384. }
  385. /*
  386. * CompareObjects - Returns S_OK if lpDataObjectA and lpDataObjectB are equivalent,
  387. * S_FALSE otherwise.
  388. *
  389. * History: a-jsari 10/2/97 Stub version
  390. */
  391. HRESULT CDataObject::CompareObjects(LPDATAOBJECT, LPDATAOBJECT)
  392. {
  393. // FIX: Write this.
  394. return S_FALSE;
  395. }