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.

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