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.

208 lines
6.5 KiB

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