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.

239 lines
6.1 KiB

  1. #include "dataobj.h"
  2. #include "guids.h"
  3. #include "delebase.h"
  4. //
  5. // This is the minimum set of clipboard formats we must implement.
  6. // MMC uses these to get necessary information from our snapin about
  7. // our nodes.
  8. //
  9. //
  10. // We need to do this to get around MMC.IDL - it explicitly defines
  11. // the clipboard formats as WCHAR types...
  12. //
  13. #define _T_CCF_DISPLAY_NAME _T("CCF_DISPLAY_NAME")
  14. #define _T_CCF_NODETYPE _T("CCF_NODETYPE")
  15. #define _T_CCF_SZNODETYPE _T("CCF_SZNODETYPE")
  16. #define _T_CCF_SNAPIN_CLASSID _T("CCF_SNAPIN_CLASSID")
  17. #define _T_CCF_INTERNAL_SNAPIN _T("{2479DB32-5276-11d2-94F5-00C04FB92EC2}")
  18. //
  19. // These are the clipboard formats that we must supply at a minimum.
  20. // mmc.h actually defined these. We can make up our own to use for
  21. // other reasons. We don't need any others at this time.
  22. //
  23. UINT CDataObject::s_cfDisplayName = RegisterClipboardFormat(_T_CCF_DISPLAY_NAME);
  24. UINT CDataObject::s_cfNodeType = RegisterClipboardFormat(_T_CCF_NODETYPE);
  25. UINT CDataObject::s_cfSZNodeType = RegisterClipboardFormat(_T_CCF_SZNODETYPE);
  26. UINT CDataObject::s_cfSnapinClsid = RegisterClipboardFormat(_T_CCF_SNAPIN_CLASSID);
  27. UINT CDataObject::s_cfInternal = RegisterClipboardFormat(_T_CCF_INTERNAL_SNAPIN);
  28. CDataObject::CDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES context)
  29. : m_lCookie(cookie)
  30. , m_context(context)
  31. , m_cref(0)
  32. {
  33. }
  34. CDataObject::~CDataObject()
  35. {
  36. }
  37. ///////////////////////
  38. // IUnknown implementation
  39. ///////////////////////
  40. STDMETHODIMP CDataObject::QueryInterface(REFIID riid, LPVOID *ppv)
  41. {
  42. if( !ppv )
  43. return E_FAIL;
  44. *ppv = NULL;
  45. if( IsEqualIID(riid, IID_IUnknown) )
  46. *ppv = static_cast<IDataObject *>(this);
  47. else if( IsEqualIID( riid, IID_IDataObject ) )
  48. *ppv = static_cast<IDataObject *>(this);
  49. if( *ppv )
  50. {
  51. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  52. return S_OK;
  53. }
  54. return E_NOINTERFACE;
  55. }
  56. STDMETHODIMP_(ULONG) CDataObject::AddRef()
  57. {
  58. return InterlockedIncrement( (LONG *)&m_cref );
  59. }
  60. STDMETHODIMP_(ULONG) CDataObject::Release()
  61. {
  62. if( 0 == InterlockedDecrement( (LONG *) &m_cref ) )
  63. {
  64. delete this;
  65. return 0;
  66. }
  67. return m_cref;
  68. }
  69. /////////////////////////////////////////////////////////////////////////////
  70. // IDataObject implementation
  71. //
  72. HRESULT CDataObject::GetDataHere(
  73. FORMATETC *pFormatEtc, // [in] Pointer to the FORMATETC structure
  74. STGMEDIUM *pMedium // [out] Pointer to the STGMEDIUM structure
  75. )
  76. {
  77. if( ( NULL == pFormatEtc ) || ( NULL == pMedium ) )
  78. {
  79. return E_INVALIDARG;
  80. }
  81. const CLIPFORMAT cf = pFormatEtc->cfFormat;
  82. IStream *pStream = NULL;
  83. HRESULT hr = CreateStreamOnHGlobal( pMedium->hGlobal, FALSE, &pStream );
  84. if( FAILED(hr) )
  85. return hr; // Minimal error checking
  86. hr = DV_E_FORMATETC; // Unknown format
  87. CDelegationBase *base = GetBaseNodeObject();
  88. if( NULL == base )
  89. {
  90. pStream->Release();
  91. return E_FAIL;
  92. }
  93. if( s_cfDisplayName == cf )
  94. {
  95. const _TCHAR *pszName = base->GetDisplayName();
  96. if( NULL == pszName )
  97. {
  98. pStream->Release();
  99. return E_OUTOFMEMORY;
  100. }
  101. //
  102. // Get length of original string and convert it accordingly
  103. //
  104. ULONG ulSizeofName = lstrlen( pszName );
  105. //
  106. // Count null character
  107. //
  108. ulSizeofName++;
  109. ulSizeofName *= sizeof(WCHAR);
  110. hr = pStream->Write(pszName, ulSizeofName, NULL);
  111. }
  112. else if( s_cfNodeType == cf )
  113. {
  114. const GUID *pGUID = (const GUID *)&base->getNodeType();
  115. hr = pStream->Write(pGUID, sizeof(GUID), NULL);
  116. }
  117. else if( s_cfSZNodeType == cf )
  118. {
  119. LPOLESTR pszGuid = NULL;
  120. hr = StringFromCLSID( base->getNodeType(), &pszGuid );
  121. if( SUCCEEDED(hr) )
  122. {
  123. hr = pStream->Write( pszGuid, wcslen(pszGuid), NULL );
  124. CoTaskMemFree( pszGuid );
  125. }
  126. }
  127. else if( s_cfSnapinClsid == cf )
  128. {
  129. const GUID *pGUID = NULL;
  130. pGUID = &CLSID_CUDDIServices;
  131. hr = pStream->Write( pGUID, sizeof(GUID), NULL );
  132. }
  133. else if( s_cfInternal == cf )
  134. {
  135. //
  136. // We are being asked to get our this pointer from the IDataObject interface
  137. // only our own snap-in objects will know how to do this.
  138. //
  139. CDataObject *pThis = this;
  140. hr = pStream->Write( &pThis, sizeof(CDataObject*), NULL );
  141. }
  142. pStream->Release();
  143. return hr;
  144. }
  145. /////////////////////////////////////////////////////////////////////////////
  146. // Global helper functions to help work with dataobjects and
  147. // clipboard formats
  148. //---------------------------------------------------------------------------
  149. // Returns the current object based on the s_cfInternal clipboard format
  150. //
  151. CDataObject* GetOurDataObject( LPDATAOBJECT lpDataObject )
  152. {
  153. HRESULT hr = S_OK;
  154. CDataObject *pSDO = NULL;
  155. //
  156. // Check to see if the data object is a special data object.
  157. //
  158. if( IS_SPECIAL_DATAOBJECT( lpDataObject ) )
  159. {
  160. //
  161. //Code for handling a special data object goes here.
  162. //
  163. //
  164. // We do not handle special data objects, so we exit if we get one.
  165. //
  166. return NULL;
  167. }
  168. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  169. FORMATETC formatetc = { ( CLIPFORMAT ) CDataObject::s_cfInternal, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  170. //
  171. // Allocate memory for the stream
  172. //
  173. stgmedium.hGlobal = GlobalAlloc( GMEM_SHARE, sizeof(CDataObject *) );
  174. if( !stgmedium.hGlobal )
  175. {
  176. hr = E_OUTOFMEMORY;
  177. }
  178. if( SUCCEEDED(hr) )
  179. {
  180. //
  181. // Attempt to get data from the object
  182. //
  183. hr = lpDataObject->GetDataHere( &formatetc, &stgmedium );
  184. }
  185. //
  186. // stgmedium now has the data we need
  187. //
  188. if( SUCCEEDED(hr) )
  189. {
  190. pSDO = *(CDataObject **)(stgmedium.hGlobal);
  191. }
  192. //
  193. // If we have memory free it
  194. //
  195. if( stgmedium.hGlobal )
  196. GlobalFree(stgmedium.hGlobal);
  197. return pSDO;
  198. } // end GetOurDataObject()