Source code of Windows XP (NT5)
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.

358 lines
9.5 KiB

  1. // This is a part of the Microsoft Management Console.
  2. // Copyright (C) Microsoft Corporation, 1995 - 1999
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Management Console and related
  7. // electronic documentation provided with the interfaces.
  8. #include "stdafx.h"
  9. ///////////////////////////////////////////////////////////////////////////////
  10. // Sample code to show how to Create DataObjects
  11. // Minimal error checking for clarity
  12. ///////////////////////////////////////////////////////////////////////////////
  13. // Snap-in NodeType in both GUID format and string format
  14. // Note - Typically there is a node type for each different object, sample
  15. // only uses one node type.
  16. unsigned int CDataObject::m_cfNodeType = 0;
  17. unsigned int CDataObject::m_cfNodeTypeString = 0;
  18. unsigned int CDataObject::m_cfDisplayName = 0;
  19. unsigned int CDataObject::m_cfCoClass = 0;
  20. unsigned int CDataObject::m_cfInternal = 0;
  21. unsigned int CDataObject::m_cfIsMultiSel = 0;
  22. // The only additional clipboard format supported is to get the workstation name.
  23. unsigned int CDataObject::m_cfWorkstation = 0;
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CDataObject implementations
  26. CDataObject::CDataObject()
  27. {
  28. USES_CONVERSION;
  29. m_cfNodeType = RegisterClipboardFormat(W2T(CCF_NODETYPE));
  30. m_cfNodeTypeString = RegisterClipboardFormat(W2T(CCF_SZNODETYPE));
  31. m_cfDisplayName = RegisterClipboardFormat(W2T(CCF_DISPLAY_NAME));
  32. m_cfCoClass = RegisterClipboardFormat(W2T(CCF_SNAPIN_CLASSID));
  33. m_cfIsMultiSel = RegisterClipboardFormat(W2T(CCF_OBJECT_TYPES_IN_MULTI_SELECT));
  34. m_cfInternal = RegisterClipboardFormat(W2T((LPWSTR)SNAPIN_INTERNAL));
  35. m_cfWorkstation = RegisterClipboardFormat(W2T((LPWSTR)SNAPIN_WORKSTATION));
  36. m_cbMultiSelData = 0;
  37. m_bMultiSelDobj = FALSE;
  38. }
  39. STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC lpFormatetc)
  40. {
  41. HRESULT hr = S_FALSE;
  42. if ( lpFormatetc )
  43. {
  44. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  45. if ( cf == m_cfIsMultiSel )
  46. {
  47. // hr = S_FALSE; // always return this; MMC returns S_OK if ptr to SI_MS_DO
  48. hr = (m_bMultiSelDobj ? S_OK : S_FALSE);
  49. }
  50. else if ( cf == m_cfNodeType ||
  51. cf == m_cfCoClass ||
  52. cf == m_cfNodeTypeString ||
  53. cf == m_cfDisplayName ||
  54. cf == m_cfInternal
  55. )
  56. {
  57. hr = S_OK;
  58. }
  59. }
  60. return hr;
  61. }
  62. STDMETHODIMP CDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  63. {
  64. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  65. HRESULT hr = DV_E_CLIPFORMAT;
  66. if (lpFormatetc->cfFormat == m_cfIsMultiSel)
  67. {
  68. ASSERT(m_internal.m_cookie == MMC_MULTI_SELECT_COOKIE);
  69. if (m_internal.m_cookie != MMC_MULTI_SELECT_COOKIE)
  70. return E_FAIL;
  71. return CreateMultiSelData(lpMedium);
  72. }
  73. return hr;
  74. }
  75. STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  76. {
  77. HRESULT hr = DV_E_CLIPFORMAT;
  78. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  79. // Based on the CLIPFORMAT write data to the stream
  80. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  81. if (cf == m_cfNodeType)
  82. {
  83. hr = CreateNodeTypeData(lpMedium);
  84. }
  85. else if (cf == m_cfCoClass)
  86. {
  87. hr = CreateCoClassID(lpMedium);
  88. }
  89. else if(cf == m_cfNodeTypeString)
  90. {
  91. hr = CreateNodeTypeStringData(lpMedium);
  92. }
  93. else if (cf == m_cfDisplayName)
  94. {
  95. hr = CreateDisplayName(lpMedium);
  96. }
  97. else if (cf == m_cfInternal)
  98. {
  99. hr = CreateInternal(lpMedium);
  100. }
  101. else if (cf == m_cfWorkstation)
  102. {
  103. hr = CreateWorkstationName(lpMedium);
  104. }
  105. return hr;
  106. }
  107. STDMETHODIMP CDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc)
  108. {
  109. return E_NOTIMPL;
  110. }
  111. /////////////////////////////////////////////////////////////////////////////
  112. // CDataObject creation members
  113. HRESULT CDataObject::Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  114. {
  115. HRESULT hr = DV_E_TYMED;
  116. // Do some simple validation
  117. if (pBuffer == NULL || lpMedium == NULL)
  118. return E_POINTER;
  119. // Make sure the type medium is HGLOBAL
  120. if (lpMedium->tymed == TYMED_HGLOBAL)
  121. {
  122. // Create the stream on the hGlobal passed in
  123. LPSTREAM lpStream;
  124. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  125. if (SUCCEEDED(hr))
  126. {
  127. // Write to the stream the number of bytes
  128. unsigned long written;
  129. if (NULL == lpMedium->hGlobal)
  130. {
  131. // always return a valid hGlobal for the caller
  132. hr = GetHGlobalFromStream(lpStream, &lpMedium->hGlobal);
  133. if (hr != S_OK)
  134. goto err;
  135. }
  136. hr = lpStream->Write(pBuffer, len, &written);
  137. // Because we told CreateStreamOnHGlobal with 'FALSE',
  138. // only the stream is released here.
  139. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  140. // at the correct time. This is according to the IDataObject specification.
  141. lpStream->Release();
  142. }
  143. }
  144. err:
  145. return hr;
  146. }
  147. HRESULT CDataObject::CreateVariableLen(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  148. {
  149. HRESULT hr = DV_E_TYMED;
  150. BYTE* pb;
  151. // Do some simple validation
  152. if (pBuffer == NULL || lpMedium == NULL)
  153. {
  154. hr = E_POINTER;
  155. _JumpError(hr, error, "Invalid args");
  156. }
  157. // Make sure the type medium is HGLOBAL
  158. lpMedium->tymed = TYMED_HGLOBAL;
  159. lpMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, (len));
  160. if (NULL == lpMedium->hGlobal)
  161. {
  162. hr = E_OUTOFMEMORY;
  163. _JumpError(hr, error, "GlobalAlloc");
  164. }
  165. pb = reinterpret_cast<BYTE*>(::GlobalLock(lpMedium->hGlobal));
  166. CopyMemory(pb, pBuffer, len);
  167. ::GlobalUnlock(lpMedium->hGlobal);
  168. hr = S_OK;
  169. error:
  170. return hr;
  171. }
  172. HRESULT CDataObject::CreateMultiSelData(LPSTGMEDIUM lpMedium)
  173. {
  174. ASSERT(m_internal.m_cookie == MMC_MULTI_SELECT_COOKIE);
  175. ASSERT(m_cbMultiSelData != 0);
  176. return CreateVariableLen(&m_sGuidObjTypes, m_cbMultiSelData, lpMedium);
  177. }
  178. HRESULT CDataObject::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  179. {
  180. // Create the node type object in GUID format
  181. const GUID* pcObjectType = NULL;
  182. if (m_internal.m_type == CCT_SCOPE)
  183. {
  184. // reid fix
  185. CFolder* pFolder = reinterpret_cast<CFolder*>(m_internal.m_cookie);
  186. switch (pFolder->GetType())
  187. {
  188. case POLICYSETTINGS:
  189. case CA_CERT_TYPE:
  190. pcObjectType = &cNodeTypePolicySettings;
  191. break;
  192. case SCE_EXTENSION:
  193. case GLOBAL_CERT_TYPE:
  194. pcObjectType = &cNodeTypeCertificateTemplate;
  195. break;
  196. }
  197. }
  198. else if (m_internal.m_type == CCT_RESULT)
  199. {
  200. pcObjectType = &cObjectTypeResultItem;
  201. }
  202. return Create(reinterpret_cast<const void*>(pcObjectType), sizeof(GUID),
  203. lpMedium);
  204. }
  205. HRESULT CDataObject::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  206. {
  207. // Create the node type object in GUID string format
  208. const WCHAR* cszObjectType = L"";
  209. if (m_internal.m_type == CCT_SCOPE)
  210. {
  211. CFolder* pFolder = reinterpret_cast<CFolder*>(m_internal.m_cookie);
  212. switch (pFolder->GetType())
  213. {
  214. case POLICYSETTINGS:
  215. case CA_CERT_TYPE:
  216. cszObjectType = cszNodeTypePolicySettings;
  217. break;
  218. case SCE_EXTENSION:
  219. case GLOBAL_CERT_TYPE:
  220. cszObjectType = cszNodeTypeCertificateTemplate;
  221. break;
  222. }
  223. }
  224. else if (m_internal.m_type == CCT_RESULT)
  225. {
  226. cszObjectType = cszObjectTypeResultItem;
  227. }
  228. ASSERT(cszObjectType[0] != 0);
  229. return Create(cszObjectType, ((wcslen(cszObjectType)+1) * sizeof(WCHAR)), lpMedium);
  230. }
  231. HRESULT CDataObject::CreateDisplayName(LPSTGMEDIUM lpMedium)
  232. {
  233. // This is the display named used in the scope pane and snap-in manager
  234. // Load the name to display
  235. // Note - if this is not provided, the console will used the snap-in name
  236. CString szDispName;
  237. szDispName.LoadString(IDS_NODENAME_PREFIX);
  238. USES_CONVERSION;
  239. return Create(szDispName, ((szDispName.GetLength()+1) * sizeof(WCHAR)), lpMedium);
  240. }
  241. HRESULT CDataObject::CreateInternal(LPSTGMEDIUM lpMedium)
  242. {
  243. return Create(&m_internal, sizeof(INTERNAL), lpMedium);
  244. }
  245. HRESULT CDataObject::CreateWorkstationName(LPSTGMEDIUM lpMedium)
  246. {
  247. TCHAR pzName[MAX_COMPUTERNAME_LENGTH+1] = {0};
  248. DWORD len = MAX_COMPUTERNAME_LENGTH+1;
  249. if (GetComputerName(pzName, &len) == FALSE)
  250. return E_FAIL;
  251. // Add 1 for the NULL and calculate the bytes for the stream
  252. USES_CONVERSION;
  253. return Create(T2W(pzName), ((len+1)* sizeof(WCHAR)), lpMedium);
  254. }
  255. HRESULT CDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  256. {
  257. // Create the CoClass information
  258. return Create(reinterpret_cast<const void*>(&m_internal.m_clsid), sizeof(CLSID), lpMedium);
  259. }
  260. ULONG CDataObject::AddCookie(MMC_COOKIE Cookie)
  261. {
  262. m_rgCookies.Add(Cookie);
  263. return m_rgCookies.GetSize()-1;
  264. }
  265. STDMETHODIMP CDataObject::GetCookieAt(ULONG iCookie, MMC_COOKIE *pCookie)
  266. {
  267. if((LONG)iCookie > m_rgCookies.GetSize())
  268. {
  269. return S_FALSE;
  270. }
  271. *pCookie = m_rgCookies[iCookie];
  272. return S_OK;
  273. }
  274. STDMETHODIMP CDataObject::RemoveCookieAt(ULONG iCookie)
  275. {
  276. if((LONG)iCookie > m_rgCookies.GetSize())
  277. {
  278. return S_FALSE;
  279. }
  280. m_rgCookies.RemoveAt(iCookie);
  281. return S_OK;
  282. }