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.

217 lines
6.7 KiB

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