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.

339 lines
9.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: dataobj.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "domobj.h"
  12. #include "cdomain.h"
  13. #include "dataobj.h"
  14. #include <dsgetdc.h>
  15. #include <lm.h>
  16. extern "C"
  17. {
  18. #include <lmapibuf.h>
  19. }
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. ///////////////////////////////////////////////////////////////////////////////
  26. // Sample code to show how to Create DataObjects
  27. // Minimal error checking for clarity
  28. ///////////////////////////////////////////////////////////////////////////////
  29. // Snap-in NodeType in both GUID format and string format
  30. // Note - Typically there is a node type for each different object, sample
  31. // only uses one node type.
  32. // Clipboard formats that are required by the console
  33. CLIPFORMAT CDataObject::m_cfNodeType = (CLIPFORMAT)RegisterClipboardFormat(CCF_NODETYPE);
  34. CLIPFORMAT CDataObject::m_cfNodeTypeString = (CLIPFORMAT)RegisterClipboardFormat(CCF_SZNODETYPE);
  35. CLIPFORMAT CDataObject::m_cfDisplayName = (CLIPFORMAT)(CLIPFORMAT)RegisterClipboardFormat(CCF_DISPLAY_NAME);
  36. CLIPFORMAT CDataObject::m_cfCoClass = (CLIPFORMAT)RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  37. // internal clipboard format
  38. CLIPFORMAT CDataObject::m_cfInternal = (CLIPFORMAT)RegisterClipboardFormat(CCF_DS_DOMAIN_TREE_SNAPIN_INTERNAL);
  39. // Property Page Clipboard formats
  40. CLIPFORMAT CDataObject::m_cfDsObjectNames =
  41. (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  42. CLIPFORMAT CDataObject::m_cfDsDisplayOptions =
  43. (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DS_DISPLAY_SPEC_OPTIONS);
  44. CLIPFORMAT CDataObject::m_cfGetIPropSheetCfg =
  45. (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DS_PROPSHEETCONFIG);
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CDataObject implementations
  48. STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  49. {
  50. HRESULT hr = DV_E_CLIPFORMAT;
  51. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  52. // Based on the CLIPFORMAT write data to the stream
  53. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  54. if(cf == m_cfNodeType)
  55. {
  56. hr = CreateNodeTypeData(lpMedium);
  57. }
  58. else if(cf == m_cfNodeTypeString)
  59. {
  60. hr = CreateNodeTypeStringData(lpMedium);
  61. }
  62. else if (cf == m_cfDisplayName)
  63. {
  64. hr = CreateDisplayName(lpMedium);
  65. }
  66. else if (cf == m_cfInternal)
  67. {
  68. hr = CreateInternal(lpMedium);
  69. }
  70. else if (cf == m_cfCoClass)
  71. {
  72. hr = CreateCoClassID(lpMedium);
  73. }
  74. return hr;
  75. }
  76. STDMETHODIMP CDataObject::GetData(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
  77. {
  78. if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM)))
  79. {
  80. return E_INVALIDARG;
  81. }
  82. if (!(pFormatEtc->tymed & TYMED_HGLOBAL))
  83. {
  84. return DV_E_TYMED;
  85. }
  86. CComponentDataImpl* pCD = dynamic_cast<CComponentDataImpl*>(m_pComponentData);
  87. if (pCD == NULL)
  88. {
  89. return E_FAIL;
  90. }
  91. if (pFormatEtc->cfFormat == m_cfDsObjectNames)
  92. {
  93. // Return the object name and class.
  94. CDomainObject* pDomainObject = reinterpret_cast<CDomainObject*>(m_internal.m_cookie);
  95. if (pDomainObject == NULL)
  96. {
  97. return E_INVALIDARG;
  98. }
  99. LPCWSTR lpszNamingContext = pDomainObject->GetNCName();
  100. LPCWSTR lpszClass = pDomainObject->GetClass();
  101. // build an LDAP path out of the DN
  102. CString strPath;
  103. if (pDomainObject->PdcAvailable())
  104. {
  105. strPath = L"LDAP://";
  106. strPath += pDomainObject->GetPDC();
  107. strPath += L"/";
  108. strPath += lpszNamingContext;
  109. TRACE(L"DomAdmin::CDataObject::GetData domain path: %s\n", (PCWSTR)strPath);
  110. }
  111. else
  112. {
  113. pCD->GetBasePathsInfo()->ComposeADsIPath(strPath, lpszNamingContext);
  114. }
  115. int cbPath = sizeof(TCHAR) * (_tcslen(strPath) + 1);
  116. int cbClass = sizeof(TCHAR) * (_tcslen(lpszClass) + 1);
  117. int cbStruct = sizeof(DSOBJECTNAMES);
  118. LPDSOBJECTNAMES pDSObj;
  119. pDSObj = (LPDSOBJECTNAMES)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  120. cbStruct + cbPath + cbClass);
  121. if (pDSObj == NULL)
  122. {
  123. return STG_E_MEDIUMFULL;
  124. }
  125. pDSObj->clsidNamespace = CLSID_DomainAdmin;
  126. pDSObj->cItems = 1;
  127. pDSObj->aObjects[0].dwFlags = pDomainObject->PdcAvailable() ? 0 : DSOBJECT_READONLYPAGES;
  128. pDSObj->aObjects[0].dwProviderFlags = 0;
  129. pDSObj->aObjects[0].offsetName = cbStruct;
  130. pDSObj->aObjects[0].offsetClass = cbStruct + cbPath;
  131. _tcscpy((LPTSTR)((BYTE *)pDSObj + cbStruct), strPath);
  132. _tcscpy((LPTSTR)((BYTE *)pDSObj + cbStruct + cbPath), lpszClass);
  133. pMedium->hGlobal = (HGLOBAL)pDSObj;
  134. }
  135. else if (pFormatEtc->cfFormat == m_cfDsDisplayOptions)
  136. {
  137. // Get the DSDISPLAYSPECOPTIONS structure.
  138. // Use the value cached in the component data.
  139. CComponentDataImpl* pCD = dynamic_cast<CComponentDataImpl*>(m_pComponentData);
  140. if (pCD != NULL)
  141. {
  142. PDSDISPLAYSPECOPTIONS pDsDisplaySpecOptions =
  143. pCD->GetDsDisplaySpecOptionsCFHolder()->Get();
  144. pMedium->hGlobal = (HGLOBAL)pDsDisplaySpecOptions;
  145. if (pDsDisplaySpecOptions == NULL)
  146. return E_OUTOFMEMORY;
  147. }
  148. else
  149. {
  150. return E_FAIL;
  151. }
  152. }
  153. else if (pFormatEtc->cfFormat == m_cfGetIPropSheetCfg)
  154. {
  155. // Added by JEFFJON 1/26/99
  156. PPROPSHEETCFG pSheetCfg;
  157. pSheetCfg = (PPROPSHEETCFG)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  158. sizeof(PROPSHEETCFG));
  159. if (pSheetCfg == NULL)
  160. {
  161. return STG_E_MEDIUMFULL;
  162. }
  163. pSheetCfg->lNotifyHandle = m_lNotifyHandle;
  164. pSheetCfg->hwndParentSheet = m_hwndParentSheet;
  165. pSheetCfg->hwndHidden = pCD->GetHiddenWindow();
  166. CFolderObject* pFolderObject = reinterpret_cast<CFolderObject*>(m_internal.m_cookie);
  167. pSheetCfg->wParamSheetClose = reinterpret_cast<WPARAM>(pFolderObject);
  168. pMedium->hGlobal = (HGLOBAL)pSheetCfg;
  169. }
  170. else
  171. {
  172. return DV_E_FORMATETC;
  173. }
  174. pMedium->tymed = TYMED_HGLOBAL;
  175. pMedium->pUnkForRelease = NULL;
  176. return S_OK;
  177. }
  178. STDMETHODIMP
  179. CDataObject::SetData(FORMATETC * pFormatEtc, STGMEDIUM * pMedium,
  180. BOOL fRelease)
  181. {
  182. if (pFormatEtc->cfFormat == m_cfGetIPropSheetCfg)
  183. {
  184. if (!(pFormatEtc->tymed & TYMED_HGLOBAL))
  185. {
  186. return DV_E_TYMED;
  187. }
  188. PPROPSHEETCFG pSheetCfg = (PPROPSHEETCFG)pMedium->hGlobal;
  189. // don't overwrite existing data.
  190. if (0 == m_lNotifyHandle)
  191. {
  192. m_lNotifyHandle = pSheetCfg->lNotifyHandle;
  193. }
  194. if (NULL == m_hwndParentSheet)
  195. {
  196. m_hwndParentSheet = pSheetCfg->hwndParentSheet;
  197. }
  198. if (fRelease)
  199. {
  200. GlobalFree(pMedium->hGlobal);
  201. }
  202. return S_OK;
  203. }
  204. else
  205. {
  206. return DV_E_FORMATETC;
  207. }
  208. }
  209. STDMETHODIMP CDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc)
  210. {
  211. return E_NOTIMPL;
  212. }
  213. /////////////////////////////////////////////////////////////////////////////
  214. // CDataObject creation members
  215. HRESULT CDataObject::Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  216. {
  217. HRESULT hr = DV_E_TYMED;
  218. // Do some simple validation
  219. if (pBuffer == NULL || lpMedium == NULL)
  220. return E_POINTER;
  221. // Make sure the type medium is HGLOBAL
  222. if (lpMedium->tymed == TYMED_HGLOBAL)
  223. {
  224. // Create the stream on the hGlobal passed in
  225. LPSTREAM lpStream;
  226. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  227. if (SUCCEEDED(hr))
  228. {
  229. // Write to the stream the number of bytes
  230. unsigned long written;
  231. hr = lpStream->Write(pBuffer, len, &written);
  232. // Because we told CreateStreamOnHGlobal with 'FALSE',
  233. // only the stream is released here.
  234. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  235. // at the correct time. This is according to the IDataObject specification.
  236. lpStream->Release();
  237. }
  238. }
  239. return hr;
  240. }
  241. HRESULT CDataObject::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  242. {
  243. // Create the node type object in GUID format
  244. return Create(reinterpret_cast<const void*>(&cDefaultNodeType), sizeof(GUID), lpMedium);
  245. }
  246. HRESULT CDataObject::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  247. {
  248. // Create the node type object in GUID string format
  249. return Create(cszDefaultNodeType, ((wcslen(cszDefaultNodeType)+1) * sizeof(wchar_t)), lpMedium);
  250. }
  251. HRESULT CDataObject::CreateDisplayName(LPSTGMEDIUM lpMedium)
  252. {
  253. // This is the display named used in the scope pane and snap-in manager
  254. // Load the name from resource
  255. // Note - if this is not provided, the console will used the snap-in name
  256. CString szDispName;
  257. szDispName.LoadString(IDS_NODENAME);
  258. return Create(szDispName, ((szDispName.GetLength()+1) * sizeof(wchar_t)), lpMedium);
  259. }
  260. HRESULT CDataObject::CreateInternal(LPSTGMEDIUM lpMedium)
  261. {
  262. return Create(&m_internal, sizeof(INTERNAL), lpMedium);
  263. }
  264. //+----------------------------------------------------------------------------
  265. //
  266. // Method: CDSDataObject::CreateCoClassID
  267. //
  268. // Synopsis:
  269. //
  270. //-----------------------------------------------------------------------------
  271. HRESULT
  272. CDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  273. {
  274. CLSID CoClassID;
  275. CoClassID = CLSID_DomainAdmin;
  276. return Create(&CoClassID, sizeof(CLSID), lpMedium);
  277. }