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.

376 lines
8.9 KiB

  1. /*++
  2. Copyright (C) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. DATAOBJ.CPP
  5. Abstract:
  6. Implementation of IDataObject for data communication
  7. --*/
  8. #include "StdAfx.h"
  9. #include "smlogcfg.h"
  10. #include "smnode.h"
  11. #include "dataobj.h"
  12. // MMC uses these to get necessary information from our snapin about
  13. // our nodes.
  14. // Register the clipboard formats
  15. unsigned int CDataObject::s_cfMmcMachineName =
  16. RegisterClipboardFormat(CF_MMC_SNAPIN_MACHINE_NAME);
  17. unsigned int CDataObject::s_cfDisplayName =
  18. RegisterClipboardFormat(CCF_DISPLAY_NAME);
  19. unsigned int CDataObject::s_cfNodeType =
  20. RegisterClipboardFormat(CCF_NODETYPE);
  21. unsigned int CDataObject::s_cfSnapinClsid =
  22. RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  23. unsigned int CDataObject::s_cfInternal =
  24. RegisterClipboardFormat(CF_INTERNAL);
  25. #ifdef _DEBUG // For tracking data objects
  26. static UINT nCount = 0;
  27. WCHAR wszMsg[64];
  28. #endif
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CDataObject - This class is used to pass data back and forth with MMC. It
  31. // uses a standard interface, IDataObject to acomplish this.
  32. // Refer to OLE documentation for a description of clipboard
  33. // formats and the IdataObject interface.
  34. //---------------------------------------------------------------------------
  35. // Added some code to check on data objects
  36. CDataObject::CDataObject()
  37. : m_cRefs(0),
  38. m_ulCookie(0),
  39. m_Context(CCT_UNINITIALIZED),
  40. m_CookieType(COOKIE_IS_ROOTNODE)
  41. {
  42. #ifdef _DEBUG
  43. swprintf( wszMsg, L"DATAOBJECT Create %u\n", nCount );
  44. LOCALTRACE( wszMsg );
  45. nCount++;
  46. #endif
  47. } // end Constructor()
  48. //---------------------------------------------------------------------------
  49. // Added some code to check on data objects
  50. //
  51. CDataObject::~CDataObject()
  52. {
  53. if ( ( COOKIE_IS_COUNTERMAINNODE == m_CookieType )
  54. || ( COOKIE_IS_TRACEMAINNODE == m_CookieType )
  55. || ( COOKIE_IS_ALERTMAINNODE == m_CookieType ) )
  56. {
  57. ASSERT( m_ulCookie );
  58. }
  59. #ifdef _DEBUG
  60. swprintf( wszMsg, L"DATAOBJECT Delete %u\n", nCount );
  61. LOCALTRACE( wszMsg );
  62. nCount--;
  63. #endif
  64. } // end Destructor()
  65. /////////////////////////////////////////////////////////////////////////////
  66. // IDataObject implementation
  67. //
  68. //---------------------------------------------------------------------------
  69. // Fill the hGlobal in pmedium with the requested data
  70. //
  71. STDMETHODIMP
  72. CDataObject::GetDataHere
  73. (
  74. FORMATETC *pFormatEtc, // [in] Pointer to the FORMATETC structure
  75. STGMEDIUM *pMedium // [out] Pointer to the STGMEDIUM structure
  76. )
  77. {
  78. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  79. HRESULT hr = DV_E_FORMATETC; // Unknown format
  80. const CLIPFORMAT cf = pFormatEtc->cfFormat;
  81. IStream *pStream = NULL;
  82. pMedium->pUnkForRelease = NULL; // by OLE spec
  83. do // Write data to the stream based
  84. { // of the clipformat
  85. hr = CreateStreamOnHGlobal( pMedium->hGlobal, FALSE, &pStream );
  86. if ( FAILED(hr) )
  87. return hr; // Minimal error checking
  88. if( cf == s_cfDisplayName )
  89. {
  90. hr = WriteDisplayName( pStream );
  91. }
  92. else if( cf == s_cfInternal)
  93. {
  94. hr = WriteInternal (pStream);
  95. }
  96. else if( cf == s_cfMmcMachineName)
  97. {
  98. hr = WriteMachineName( pStream );
  99. }
  100. else if( cf == s_cfNodeType )
  101. {
  102. hr = WriteNodeType( pStream );
  103. }
  104. else if( cf == s_cfSnapinClsid )
  105. {
  106. hr = WriteClsid( pStream );
  107. }
  108. } while( 0 );
  109. pStream->Release();
  110. return hr;
  111. } // end GetDataHere()
  112. /////////////////////////////////////////////////////////////////////////////
  113. // Support methods
  114. //
  115. //---------------------------------------------------------------------------
  116. // Write the appropriate GUID to the stream
  117. //
  118. HRESULT
  119. CDataObject::WriteNodeType
  120. (
  121. IStream* pStream // [in] Stream we are writing to
  122. )
  123. {
  124. const GUID *pGuid = NULL;
  125. switch( m_CookieType )
  126. {
  127. case COOKIE_IS_ROOTNODE:
  128. pGuid = &GUID_RootNode;
  129. break;
  130. case COOKIE_IS_COUNTERMAINNODE:
  131. pGuid = &GUID_CounterMainNode;
  132. break;
  133. case COOKIE_IS_TRACEMAINNODE:
  134. pGuid = &GUID_TraceMainNode;
  135. break;
  136. case COOKIE_IS_ALERTMAINNODE:
  137. pGuid = &GUID_AlertMainNode;
  138. break;
  139. default:
  140. ASSERT( FALSE );
  141. return E_UNEXPECTED;
  142. }
  143. return pStream->Write( (PVOID)pGuid, sizeof(GUID), NULL );
  144. } // end WriteNodeType()
  145. //---------------------------------------------------------------------------
  146. // Writes the display name to the stream. This is the name associated
  147. // with the root node
  148. //
  149. HRESULT
  150. CDataObject::WriteDisplayName
  151. (
  152. IStream* pStream // [in] Stream we are writing to
  153. )
  154. {
  155. CString strName;
  156. ULONG ulSizeofName;
  157. ResourceStateManager rsm;
  158. if( NULL == m_ulCookie )
  159. {
  160. // Add Local vs machine name when implement machine name override/change.
  161. // NOTE: For root node, cookie is either NULL or points to a root node object.
  162. strName.LoadString( IDS_MMC_DEFAULT_NAME );
  163. } else {
  164. PSMNODE pTmp = reinterpret_cast<PSMNODE>(m_ulCookie);
  165. //??? strName = *pTmp->GetDisplayName();
  166. strName = pTmp->GetDisplayName();
  167. }
  168. ulSizeofName = strName.GetLength();
  169. ulSizeofName++; // Count null character
  170. ulSizeofName *= sizeof(WCHAR);
  171. return pStream->Write((LPCWSTR)strName, ulSizeofName, NULL);
  172. } // end WriteDisplayName()
  173. //---------------------------------------------------------------------------
  174. // Writes the machine name to the stream.
  175. //
  176. HRESULT
  177. CDataObject::WriteMachineName
  178. (
  179. IStream* pStream // [in] Stream we are writing to
  180. )
  181. {
  182. CString strName;
  183. ULONG ulSizeOfName;
  184. if( NULL == m_ulCookie ) {
  185. // Cookie is null if not an extension. In that case, only support
  186. // local machine.
  187. strName = L""; // local
  188. } else {
  189. PSMNODE pTmp = reinterpret_cast<PSMNODE>(m_ulCookie);
  190. strName = pTmp->GetMachineName();
  191. }
  192. ulSizeOfName = strName.GetLength();
  193. ulSizeOfName++; // Count null character
  194. ulSizeOfName *= sizeof(WCHAR);
  195. return pStream->Write((LPCWSTR)strName, ulSizeOfName, NULL);
  196. } // end WriteMachineName()
  197. //---------------------------------------------------------------------------
  198. // Writes a pointer to this data object to the stream
  199. //
  200. HRESULT
  201. CDataObject::WriteInternal
  202. (
  203. IStream* pStream // [in] Stream we are writing to
  204. )
  205. {
  206. CDataObject *pThis = this;
  207. return pStream->Write( &pThis, sizeof(CDataObject*), NULL );
  208. } // end WriteInternal
  209. //---------------------------------------------------------------------------
  210. // Writes the Class ID to the stream
  211. //
  212. HRESULT
  213. CDataObject::WriteClsid
  214. (
  215. IStream* pStream // [in] Stream we are writing to
  216. )
  217. {
  218. return pStream->Write( &CLSID_ComponentData,
  219. sizeof(CLSID_ComponentData),
  220. NULL
  221. );
  222. } // end WriteClsid()
  223. //---------------------------------------------------------------------------
  224. // The cookie is what ever we decide it is going to be.
  225. // This is being called from QueryDataObject. Refer to that code.
  226. //
  227. VOID
  228. CDataObject::SetData
  229. (
  230. MMC_COOKIE ulCookie, // [in] Unique indentifier
  231. DATA_OBJECT_TYPES Context, // [in] Context of the caller
  232. COOKIETYPE Type // [in] Type of cookie
  233. )
  234. {
  235. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  236. ASSERT( NULL == m_ulCookie );
  237. m_ulCookie = ulCookie;
  238. m_Context = Context;
  239. m_CookieType = Type;
  240. } // end SetData()
  241. /////////////////////////////////////////////////////////////////////////////
  242. // IUnknown implementation
  243. //
  244. //---------------------------------------------------------------------------
  245. // Standard implementation
  246. //
  247. STDMETHODIMP
  248. CDataObject::QueryInterface
  249. (
  250. REFIID riid,
  251. LPVOID *ppvObj
  252. )
  253. {
  254. HRESULT hr = S_OK;
  255. do
  256. {
  257. if( NULL == ppvObj )
  258. {
  259. hr = E_INVALIDARG;
  260. break;
  261. }
  262. if (IsEqualIID(riid, IID_IUnknown))
  263. {
  264. *ppvObj = (IUnknown *)(IDataObject *)this;
  265. }
  266. else if (IsEqualIID(riid, IID_IDataObject))
  267. {
  268. *ppvObj = (IUnknown *)(IDataObject *)this;
  269. }
  270. else
  271. {
  272. hr = E_NOINTERFACE;
  273. *ppvObj = NULL;
  274. break;
  275. }
  276. // If we got this far we are handing out a new interface pointer on
  277. // this object, so addref it.
  278. AddRef();
  279. } while (0);
  280. return hr;
  281. } // end QueryInterface()
  282. //---------------------------------------------------------------------------
  283. // Standard implementation
  284. //
  285. STDMETHODIMP_(ULONG)
  286. CDataObject::AddRef()
  287. {
  288. return InterlockedIncrement((LONG*) &m_cRefs);
  289. }
  290. //---------------------------------------------------------------------------
  291. // Standard implementation
  292. //
  293. STDMETHODIMP_(ULONG)
  294. CDataObject::Release()
  295. {
  296. ULONG cRefsTemp;
  297. cRefsTemp = InterlockedDecrement((LONG *)&m_cRefs);
  298. if( 0 == cRefsTemp )
  299. {
  300. delete this;
  301. }
  302. return cRefsTemp;
  303. } // end Release()