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.

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