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.

344 lines
12 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 "stdafx.h"
  19. #include "DataObj.h"
  20. #include "DeleBase.h"
  21. #include "EvtVwr.h"
  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. #define _T_CCF_MACHINE_NAME _T("MMC_SNAPIN_MACHINE_NAME")
  34. #define _T_CCF_EV_VIEWS _T("CF_EV_VIEWS")
  35. #define _T_CCF_SNAPIN_PRELOADS _T("CCF_SNAPIN_PRELOADS")
  36. // These are the clipboard formats that we must supply at a minimum.
  37. // mmc.h actually defined these.
  38. UINT CDataObject::s_cfDisplayName = RegisterClipboardFormat(_T_CCF_DISPLAY_NAME);
  39. UINT CDataObject::s_cfNodeType = RegisterClipboardFormat(_T_CCF_NODETYPE);
  40. UINT CDataObject::s_cfSZNodeType = RegisterClipboardFormat(_T_CCF_SZNODETYPE);
  41. UINT CDataObject::s_cfSnapinClsid = RegisterClipboardFormat(_T_CCF_SNAPIN_CLASSID);
  42. UINT CDataObject::s_cfInternal = RegisterClipboardFormat(_T_CCF_INTERNAL_SNAPIN);
  43. //Clipboard formats required by Event Viewer extension
  44. UINT CDataObject::s_cfMachineName = RegisterClipboardFormat(_T_CCF_MACHINE_NAME );
  45. UINT CDataObject::s_cfEventViews = RegisterClipboardFormat(_T_CCF_EV_VIEWS);
  46. //CCF_SNAPIN_PRELOADS clipboard format. We need to support this to receive
  47. //the MMCN_PRELOAD notification.
  48. UINT CDataObject::s_cfPreload = RegisterClipboardFormat(_T_CCF_SNAPIN_PRELOADS);
  49. CDataObject::CDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES context)
  50. : m_lCookie(cookie), m_context(context), m_cref(0)
  51. {
  52. }
  53. CDataObject::~CDataObject()
  54. {
  55. }
  56. ///////////////////////
  57. // IUnknown implementation
  58. ///////////////////////
  59. STDMETHODIMP CDataObject::QueryInterface(REFIID riid, LPVOID *ppv)
  60. {
  61. if (!ppv)
  62. return E_FAIL;
  63. *ppv = NULL;
  64. if (IsEqualIID(riid, IID_IUnknown))
  65. *ppv = static_cast<IDataObject *>(this);
  66. else if (IsEqualIID(riid, IID_IDataObject))
  67. *ppv = static_cast<IDataObject *>(this);
  68. if (*ppv)
  69. {
  70. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  71. return S_OK;
  72. }
  73. return E_NOINTERFACE;
  74. }
  75. STDMETHODIMP_(ULONG) CDataObject::AddRef()
  76. {
  77. return InterlockedIncrement((LONG *)&m_cref);
  78. }
  79. STDMETHODIMP_(ULONG) CDataObject::Release()
  80. {
  81. if (InterlockedDecrement((LONG *)&m_cref) == 0)
  82. {
  83. delete this;
  84. return 0;
  85. }
  86. return m_cref;
  87. }
  88. /////////////////////////////////////////////////////////////////////////////
  89. // IDataObject implementation
  90. //
  91. HRESULT CDataObject::GetDataHere(
  92. FORMATETC *pFormatEtc, // [in] Pointer to the FORMATETC structure
  93. STGMEDIUM *pMedium // [out] Pointer to the STGMEDIUM structure
  94. )
  95. {
  96. USES_CONVERSION;
  97. const CLIPFORMAT cf = pFormatEtc->cfFormat;
  98. IStream *pStream = NULL;
  99. CDelegationBase *base = GetBaseNodeObject();
  100. HRESULT hr = CreateStreamOnHGlobal( pMedium->hGlobal, FALSE, &pStream );
  101. if ( FAILED(hr) )
  102. return hr; // Minimal error checking
  103. hr = DV_E_FORMATETC; // Unknown format
  104. if (cf == s_cfDisplayName) {
  105. LPOLESTR wszName = NULL;
  106. const _TCHAR *pszName = base->GetDisplayName();
  107. wszName = (LPOLESTR)T2COLE(pszName);
  108. // get length of original string and convert it accordingly
  109. ULONG ulSizeofName = lstrlen(pszName);
  110. ulSizeofName++; // Count null character
  111. ulSizeofName *= sizeof(WCHAR);
  112. hr = pStream->Write(wszName, ulSizeofName, NULL);
  113. } else if (cf == s_cfNodeType) {
  114. const GUID *pGUID = (const GUID *)&base->getNodeType();
  115. hr = pStream->Write(pGUID, sizeof(GUID), NULL);
  116. } else if (cf == s_cfSZNodeType) {
  117. LPOLESTR szGuid;
  118. hr = StringFromCLSID(base->getNodeType(), &szGuid);
  119. // get length of original string and convert it accordingly
  120. ULONG ulSizeofName = lstrlenW(szGuid);
  121. ulSizeofName++; // Count null character
  122. ulSizeofName *= sizeof(WCHAR);
  123. if (SUCCEEDED(hr)) {
  124. hr = pStream->Write(szGuid, ulSizeofName, NULL);
  125. CoTaskMemFree(szGuid);
  126. }
  127. } else if (cf == s_cfSnapinClsid) {
  128. const GUID *pGUID = NULL;
  129. pGUID = &CLSID_CompData;
  130. hr = pStream->Write(pGUID, sizeof(GUID), NULL);
  131. } else if (cf == s_cfInternal) {
  132. // we are being asked to get our this pointer from the IDataObject interface
  133. // only our own snap-in objects will know how to do this.
  134. CDataObject *pThis = this;
  135. hr = pStream->Write( &pThis, sizeof(CDataObject*), NULL );
  136. } else if(cf == s_cfMachineName) {
  137. // Event Viewer will ask for this to determine which machine to
  138. // to retrieve the log from.
  139. LPOLESTR wszMachineName = NULL;
  140. const _TCHAR *pszMachineName = base->GetMachineName();
  141. wszMachineName = (LPOLESTR)T2COLE(pszMachineName);
  142. // get length of original string and convert it accordingly
  143. ULONG ulSizeofName = lstrlen(pszMachineName);
  144. ulSizeofName++; // Count null character
  145. ulSizeofName *= sizeof(WCHAR);
  146. hr = pStream->Write(wszMachineName, ulSizeofName, NULL);
  147. } else if (cf == s_cfPreload) {
  148. BOOL bPreload = TRUE;
  149. hr = pStream->Write( (PVOID)&bPreload, sizeof(BOOL), NULL );
  150. }
  151. pStream->Release();
  152. return hr;
  153. }
  154. STDMETHODIMP CDataObject::GetData
  155. (
  156. LPFORMATETC pFormatEtc, //[in] Pointer to the FORMATETC structure
  157. LPSTGMEDIUM pStgMedium //[out] Pointer to the STGMEDIUM structure
  158. )
  159. {
  160. const CLIPFORMAT cf = pFormatEtc->cfFormat;
  161. _ASSERT( NULL != pFormatEtc );
  162. _ASSERT( NULL != pStgMedium );
  163. HRESULT hr = S_FALSE;
  164. if( pFormatEtc->cfFormat == s_cfEventViews )
  165. {
  166. hr = RetrieveEventViews( pStgMedium );
  167. }
  168. return hr;
  169. } //end GetData()
  170. /////////////////////////////////////////////////////////////////////////////
  171. // Global helper functions to help work with dataobjects and
  172. // clipboard formats
  173. //---------------------------------------------------------------------------
  174. // Returns the current object based on the s_cfInternal clipboard format
  175. //
  176. CDataObject* GetOurDataObject (
  177. LPDATAOBJECT lpDataObject // [in] IComponent pointer
  178. )
  179. {
  180. HRESULT hr = S_OK;
  181. CDataObject *pSDO = NULL;
  182. // check to see if the data object is a special data object.
  183. if ( IS_SPECIAL_DATAOBJECT (lpDataObject) )
  184. {
  185. //Code for handling a special data object goes here.
  186. //Note that the MMC SDK samples do not handle
  187. //special data objects, so we exit if we get one.
  188. return NULL;
  189. }
  190. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  191. FORMATETC formatetc = { CDataObject::s_cfInternal, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  192. // Allocate memory for the stream
  193. stgmedium.hGlobal = GlobalAlloc( GMEM_SHARE, sizeof(CDataObject *));
  194. if (!stgmedium.hGlobal) {
  195. hr = E_OUTOFMEMORY;
  196. }
  197. if SUCCEEDED(hr)
  198. // Attempt to get data from the object
  199. hr = lpDataObject->GetDataHere( &formatetc, &stgmedium );
  200. // stgmedium now has the data we need
  201. if (SUCCEEDED(hr)) {
  202. pSDO = *(CDataObject **)(stgmedium.hGlobal);
  203. }
  204. // if we have memory free it
  205. if (stgmedium.hGlobal)
  206. GlobalFree(stgmedium.hGlobal);
  207. return pSDO;
  208. } // end GetOurDataObject()
  209. //---------------------------------------------------------------------------
  210. // This function fills out the STGMEDIUM in reponse to call to GetDataHere()
  211. // with CF_EV_VIEWS as the clipformat. We display a custom view of the
  212. // System log in this sample.
  213. // The macros and other defines are in DataObject.h
  214. //
  215. HRESULT CDataObject::RetrieveEventViews
  216. (
  217. LPSTGMEDIUM pStgMedium //[in] Where we will store CF_EV_VIEWS
  218. )
  219. {
  220. USES_CONVERSION;
  221. HRESULT hr = S_OK;
  222. WCHAR szFileName[_MAX_PATH]; // Build the path to the log
  223. CDelegationBase *base = GetBaseNodeObject();
  224. LPOLESTR szServerName = NULL;
  225. const _TCHAR *pszMachineName = base->GetMachineName();
  226. szServerName = (LPOLESTR)T2COLE(pszMachineName);
  227. // wcscpy( szFileName, L"\\\\" );
  228. // wcscat( szFileName, szServerName );
  229. wcscpy( szFileName, szServerName );
  230. wcscat( szFileName, L"\\Admin$\\System32\\Config\\SysEvent.Evt" );
  231. LPWSTR szSourceName = L"System"; // Log to access
  232. LPWSTR szDisplayName = L"System Events"; // Title of our view
  233. // Allocate some memory
  234. HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, 1024 );
  235. if( NULL == hMem )
  236. return STG_E_MEDIUMFULL;
  237. // Get a pointer to our data
  238. BYTE* pPos = reinterpret_cast<BYTE*>(::GlobalLock(hMem));
  239. LONG nLen = 0;
  240. // Add the CF_EV_VIEWS header info
  241. ADD_BOOL( TRUE, pPos ); // fOnlyTheseViews
  242. ADD_USHORT( 1, pPos ); // cViews - Just one view
  243. ///////////////////////////////////////////////////////////////////////////
  244. // This information is repeated for each view we want to display
  245. // Add a filtered System Log
  246. ADD_ULONG( ELT_SYSTEM, pPos ); // EVENTLOGTYPE
  247. ADD_USHORT( VIEWINFO_CUSTOM, pPos ); // fViewFlags
  248. ADD_STRING( szServerName, nLen, pPos ); // wszServerName - Null for local machine
  249. ADD_STRING( szSourceName, nLen, pPos ); // wszSourceName - "SYSTEM" for SystemLog
  250. ADD_STRING( szFileName, nLen, pPos ); // wszFileName - UNC or local path to log
  251. ADD_STRING( szDisplayName,nLen, pPos ); // wszDisplayName - Name of the custom view
  252. // EV_SCOPE_FILTER data
  253. ADD_ULONG( EV_ALL_ERRORS, pPos ); // fRecType
  254. ADD_USHORT( 0, pPos ); // usCategory
  255. ADD_BOOL( FALSE, pPos ); // fEventID
  256. ADD_ULONG( 0, pPos ); // ulEventID
  257. ADD_STRING( L"", nLen, pPos ); // szSource-"NetLogon","TCPMon" etc
  258. ADD_STRING( L"", nLen, pPos ); // szUser
  259. ADD_STRING( L"", nLen, pPos ); // szComputer
  260. ADD_ULONG( 0, pPos ); // ulFrom
  261. ADD_ULONG( 0, pPos ); // ulTo
  262. ::GlobalUnlock( hMem ); // Unlock and set the rest of the
  263. pStgMedium->hGlobal = hMem; // StgMedium variables
  264. pStgMedium->tymed = TYMED_HGLOBAL;
  265. pStgMedium->pUnkForRelease = NULL;
  266. ATLTRACE(_T("CDataObject::RetrieveEventVeiws-> Returned S_OK \n") );
  267. return hr;
  268. } //end RetrieveEventVeiws()