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.

558 lines
18 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: Dataobj.h
  7. //
  8. // Contents: Wifi Policy management Snapin
  9. //
  10. //
  11. // History: TaroonM
  12. // 10/30/01
  13. //
  14. //----------------------------------------------------------------------------
  15. #ifndef _DATAOBJ_H
  16. #define _DATAOBJ_H
  17. #define ByteOffset(base, offset) (((LPBYTE)base)+offset)
  18. /////////////////////////////////////////////////////////////////////////////
  19. // class CSnapInClipboardFormats - contains the clipboard formats supported
  20. // by the WIRELESS snap-in
  21. class CSnapInClipboardFormats
  22. {
  23. public:
  24. // Clipboard formats that are required by the console
  25. static unsigned int m_cfNodeType; // Required by the console
  26. static unsigned int m_cfNodeTypeString; // Required by the console
  27. static unsigned int m_cfDisplayName; // Required by the console
  28. static unsigned int m_cfCoClass; // Required by the console
  29. // static unsigned int m_cfInternal; // Step 3
  30. static unsigned int m_cfWorkstation; // Published information
  31. static unsigned int m_cfDSObjectNames; // Published information
  32. static unsigned int m_cfPolicyObject;
  33. };
  34. /////////////////////////////////////////////////////////////////////////////
  35. // Template class to extract the TYPE format from the data object
  36. template <class TYPE>
  37. TYPE* Extract(LPDATAOBJECT lpDataObject, unsigned int cf)
  38. {
  39. ASSERT(lpDataObject != NULL);
  40. TYPE* p = NULL;
  41. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  42. FORMATETC formatetc = { (CLIPFORMAT)cf, NULL,
  43. DVASPECT_CONTENT, -1, TYMED_HGLOBAL
  44. };
  45. // Allocate memory for the stream
  46. int len = (int)((cf == CDataObject::m_cfWorkstation) ?
  47. ((MAX_COMPUTERNAME_LENGTH+1) * sizeof(TYPE)) : sizeof(TYPE));
  48. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, len);
  49. // Get the workstation name from the data object
  50. do
  51. {
  52. if (stgmedium.hGlobal == NULL)
  53. {
  54. TRACE(_T("Extract - stgmedium.hGlobal == NULL\n"));
  55. break;
  56. }
  57. if (lpDataObject->GetDataHere(&formatetc, &stgmedium) != S_OK)
  58. {
  59. TRACE(_T("Extract - GetDataHere FAILED\n"));
  60. break;
  61. }
  62. p = reinterpret_cast<TYPE*>(stgmedium.hGlobal);
  63. if (p == NULL)
  64. {
  65. TRACE(_T("Extract - stgmedium.hGlobal cast to NULL\n"));
  66. break;
  67. }
  68. } while (FALSE);
  69. return p;
  70. }
  71. // helper methods extracting data from data object
  72. // INTERNAL * ExtractInternalFormat(LPDATAOBJECT lpDataObject);
  73. wchar_t * ExtractWorkstation(LPDATAOBJECT lpDataObject);
  74. GUID * ExtractNodeType(LPDATAOBJECT lpDataObject);
  75. CLSID * ExtractClassID(LPDATAOBJECT lpDataObject);
  76. #define FREE_DATA(pData) \
  77. ASSERT(pData != NULL); \
  78. do { if (pData != NULL) \
  79. GlobalFree(pData); } \
  80. while(0);
  81. /////////////////////////////////////////////////////////////////////////////
  82. // Template class implementing IDataObject for the WIRELESS snap-in
  83. template <class T>
  84. class ATL_NO_VTABLE CDataObjectImpl :
  85. public IDataObject,
  86. public CSnapInClipboardFormats
  87. {
  88. friend class CComponentImpl;
  89. // Construction/Destruction
  90. public:
  91. CDataObjectImpl()
  92. #ifdef _DEBUG
  93. : m_ComponentData( NULL )
  94. #endif
  95. {
  96. DSOBJECTObjectNamesPtr (NULL);
  97. POLICYOBJECTPtr (NULL);
  98. // INTERNALCookie (0);
  99. };
  100. ~CDataObjectImpl()
  101. {
  102. #ifdef _DEBUG
  103. SetComponentData( NULL );
  104. #endif
  105. if (DSOBJECTObjectNamesPtr() != NULL)
  106. {
  107. // TODO: we need to free the memory associated with this
  108. ASSERT (0);
  109. // and null the member ptr
  110. DSOBJECTObjectNamesPtr(NULL);
  111. }
  112. if (POLICYOBJECTPtr() != NULL)
  113. {
  114. delete POLICYOBJECTPtr();
  115. POLICYOBJECTPtr (NULL);
  116. }
  117. };
  118. // Standard IDataObject methods
  119. public:
  120. // Implemented
  121. STDMETHOD(GetData)(LPFORMATETC lpFormatetcIn, LPSTGMEDIUM lpMedium);
  122. STDMETHOD(GetDataHere)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium);
  123. STDMETHOD(SetData)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium, BOOL bRelease);
  124. // Not Implemented
  125. private:
  126. STDMETHOD(QueryGetData)(LPFORMATETC lpFormatetc)
  127. { return E_NOTIMPL; };
  128. STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC lpFormatetcIn, LPFORMATETC lpFormatetcOut)
  129. { return E_NOTIMPL; };
  130. STDMETHOD(DAdvise)(LPFORMATETC lpFormatetc, DWORD advf,
  131. LPADVISESINK pAdvSink, LPDWORD pdwConnection)
  132. { return E_NOTIMPL; };
  133. STDMETHOD(DUnadvise)(DWORD dwConnection)
  134. { return E_NOTIMPL; };
  135. STDMETHOD(EnumDAdvise)(LPENUMSTATDATA* ppEnumAdvise)
  136. { return E_NOTIMPL; };
  137. STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc)
  138. { return E_NOTIMPL; };
  139. // Implementation
  140. public:
  141. STDMETHOD_(const GUID*, GetDataObjectTypeGuid)() { return &cNodeTypeWirelessMan; }
  142. STDMETHOD_(const wchar_t*, GetDataStringObjectTypeGuid)() { return cszNodeTypeWirelessMan; }
  143. // This is used only as a diagnostic in debug builds to track if
  144. // anyone is hanging on to any data objects that's have been handed out
  145. // Snapin's should view context data objects as ephemeral.
  146. #ifdef _DEBUG
  147. public:
  148. void SetComponentData(CComponentDataImpl* pCCD)
  149. {
  150. ASSERT((m_ComponentData == NULL && pCCD != NULL) || pCCD == NULL);
  151. m_ComponentData = pCCD;
  152. } ;
  153. private:
  154. CComponentDataImpl* m_ComponentData;
  155. #endif
  156. public:
  157. // access functions for IDataObject hglobal data in its raw form(s)
  158. // void INTERNALCookie(long cookie) { m_internalData.cookie( cookie );}
  159. // long INTERNALCookie() {return m_internalData.cookie();}
  160. // void INTERNALType(DATA_OBJECT_TYPES type) {ASSERT(m_internalData.type() == CCT_UNINITIALIZED); m_internalData.type(type);}
  161. // DATA_OBJECT_TYPES INTERNALType() {return m_internalData.type();}
  162. //void INTERNALclsid(const CLSID& clsid) {m_internalData.clsid( clsid );}
  163. //CLSID INTERNALclsid () {return m_internalData.clsid();}
  164. void clsid(const CLSID& clsid) {m_clsid = clsid;}
  165. CLSID clsid () {return m_clsid;}
  166. void DSOBJECTObjectNamesPtr (DSOBJECTNAMES* pDSObjectNames) {m_pDSObjectNamesPtr = pDSObjectNames;}
  167. DSOBJECTNAMES* DSOBJECTObjectNamesPtr () {return m_pDSObjectNamesPtr;}
  168. void POLICYOBJECTPtr (POLICYOBJECT* pPolicyObjPtr) {m_pPolicyObjPtr = pPolicyObjPtr;}
  169. POLICYOBJECT* POLICYOBJECTPtr () {return m_pPolicyObjPtr;}
  170. void NodeName (CString &strNodeName) {m_strNodeName = strNodeName;};
  171. CString NodeName () {return m_strNodeName;};
  172. protected:
  173. // allocate hglobal helpers
  174. HRESULT CreateNodeTypeData(LPSTGMEDIUM lpMedium);
  175. HRESULT CreateNodeTypeStringData(LPSTGMEDIUM lpMedium);
  176. HRESULT CreateDisplayName(LPSTGMEDIUM lpMedium);
  177. HRESULT CreateInternal(LPSTGMEDIUM lpMedium);
  178. HRESULT CreateWorkstationName(LPSTGMEDIUM lpMedium);
  179. HRESULT CreateCoClassID(LPSTGMEDIUM lpMedium);
  180. HRESULT CreateDSObjectNames(LPSTGMEDIUM lpMedium);
  181. HRESULT CreatePolicyObject(LPSTGMEDIUM lpMedium);
  182. HRESULT Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium);
  183. int DataGlobalAllocLen (CLIPFORMAT cf);
  184. // data associated with this IDataObject
  185. // INTERNAL m_internalData;
  186. POLICYOBJECT* m_pPolicyObjPtr;
  187. DSOBJECTNAMES* m_pDSObjectNamesPtr;
  188. CString m_strNodeName;
  189. // Class ID of who created this data object
  190. CLSID m_clsid;
  191. };
  192. /////////////////////////////////////////////////////////////////////////////
  193. // template CDataObjectImpl - IDataObject interface
  194. template <class T>
  195. STDMETHODIMP CDataObjectImpl<T>::GetData(LPFORMATETC lpFormatetcIn, LPSTGMEDIUM lpMedium)
  196. {
  197. OPT_TRACE(_T("CDataObjectImpl<T>::GetData this-%p\n"), this);
  198. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  199. T* pThis = (T*)this;
  200. // allocate the memory
  201. int iLen = DataGlobalAllocLen (lpFormatetcIn->cfFormat);
  202. if (iLen != -1)
  203. {
  204. // allocate the required amount of memory
  205. lpMedium->hGlobal = GlobalAlloc(GMEM_SHARE, iLen);
  206. // make sure they know they need to free this memory
  207. lpMedium->pUnkForRelease = NULL;
  208. // put the data in it
  209. if (lpMedium->hGlobal != NULL)
  210. {
  211. // make use of
  212. return pThis->GetDataHere(lpFormatetcIn, lpMedium);
  213. }
  214. }
  215. OPT_TRACE(_T("CDataObjectImpl<T>::GetData format-%i return E_UNEXPECTED\n"), lpFormatetcIn->cfFormat);
  216. return E_UNEXPECTED;
  217. }
  218. template <class T>
  219. STDMETHODIMP CDataObjectImpl<T>::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  220. {
  221. OPT_TRACE(_T("CDataObjectImpl<T>::GetDataHere this-%p\n"), this);
  222. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  223. #ifdef DO_TRACE
  224. {
  225. CLIPFORMAT cfDebug = lpFormatetc->cfFormat;
  226. if (cfDebug == m_cfNodeType)
  227. {
  228. OPT_TRACE(_T(" Format: NodeTypeData\n"));
  229. } else if (cfDebug == m_cfCoClass)
  230. {
  231. OPT_TRACE(_T(" Format: CoClassID\n"));
  232. } else if(cfDebug == m_cfNodeTypeString)
  233. {
  234. OPT_TRACE(_T(" Format: NodeTypeString\n"));
  235. } else if (cfDebug == m_cfDisplayName)
  236. {
  237. OPT_TRACE(_T(" Format: DisplayName\n"));
  238. //} else if (cfDebug == m_cfInternal)
  239. //{
  240. // OPT_TRACE(_T(" Format: INTERNAL\n"));
  241. } else if (cfDebug == m_cfWorkstation)
  242. {
  243. OPT_TRACE(_T(" Format: Workstation\n"));
  244. } else if (cfDebug == m_cfDSObjectNames)
  245. {
  246. OPT_TRACE(_T(" Format: DSObjectNames\n"));
  247. } else if (cfDebug == m_cfPolicyObject)
  248. {
  249. OPT_TRACE(_T(" Format: PolicyObject\n"));
  250. } else
  251. {
  252. OPT_TRACE(_T(" ERROR, Unknown format\n"));
  253. }
  254. }
  255. #endif //#ifdef DO_TRACE
  256. HRESULT hr = DV_E_CLIPFORMAT;
  257. T* pThis = (T*)this;
  258. // Based on the CLIPFORMAT create the alloc the correct amount
  259. // of memory and write the data to it
  260. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  261. if (cf == m_cfNodeType)
  262. {
  263. hr = pThis->CreateNodeTypeData(lpMedium);
  264. } else if (cf == m_cfCoClass)
  265. {
  266. hr = pThis->CreateCoClassID(lpMedium);
  267. } else if(cf == m_cfNodeTypeString)
  268. {
  269. hr = pThis->CreateNodeTypeStringData(lpMedium);
  270. } else if (cf == m_cfDisplayName)
  271. {
  272. hr = pThis->CreateDisplayName(lpMedium);
  273. //} else if (cf == m_cfInternal)
  274. //{
  275. // hr = pThis->CreateInternal(lpMedium);
  276. } else if (cf == m_cfWorkstation)
  277. {
  278. hr = pThis->CreateWorkstationName(lpMedium);
  279. } else if (cf == m_cfDSObjectNames)
  280. {
  281. hr = pThis->CreateDSObjectNames(lpMedium);
  282. } else if (cf == m_cfPolicyObject)
  283. {
  284. hr = pThis->CreatePolicyObject (lpMedium);
  285. }
  286. return hr;
  287. }
  288. template <class T>
  289. STDMETHODIMP CDataObjectImpl<T>::SetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium, BOOL bRelease)
  290. {
  291. OPT_TRACE(_T("CDataObjectImpl<T>::SetData this-%p\n"), this);
  292. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  293. HRESULT hr = E_NOTIMPL;
  294. // only implemeneted for cf == m_cfPolicyObject
  295. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  296. if (cf == m_cfPolicyObject)
  297. {
  298. // let our POLICYOBJECT pull its data out of the ObjMedium
  299. if (POLICYOBJECTPtr() != NULL)
  300. {
  301. hr = POLICYOBJECTPtr()->FromObjMedium (lpMedium);
  302. // did the user OK or Apply some settings?
  303. if (POLICYOBJECTPtr()->dwInterfaceFlags() == POFLAG_APPLY)
  304. {
  305. // well then...
  306. ASSERT (0);
  307. ::MMCPropertyChangeNotify(POLICYOBJECTPtr()->lMMCUpdateHandle(), NULL /*INTERNALCookie()*/);
  308. }
  309. }
  310. }
  311. return hr;
  312. }
  313. /////////////////////////////////////////////////////////////////////////////
  314. // template CDataObjectImpl - protected members
  315. template <class T>
  316. HRESULT CDataObjectImpl<T>::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  317. {
  318. // Create the node type object in GUID format
  319. const GUID* pcObjectType = NULL;
  320. T* pThis = (T*)this;
  321. // get correct object type
  322. pcObjectType = pThis->GetDataObjectTypeGuid ();
  323. return Create(reinterpret_cast<const void*>(pcObjectType), sizeof(GUID), lpMedium);
  324. }
  325. template <class T>
  326. HRESULT CDataObjectImpl<T>::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  327. {
  328. // Create the node type object in GUID string format
  329. const wchar_t* cszObjectType = NULL;
  330. T* pThis = (T*)this;
  331. // get correct object type string
  332. cszObjectType = pThis->GetDataStringObjectTypeGuid ();
  333. return Create(cszObjectType, ((wcslen(cszObjectType)+1) * sizeof(wchar_t)), lpMedium);
  334. }
  335. template <class T>
  336. HRESULT CDataObjectImpl<T>::CreateDisplayName(LPSTGMEDIUM lpMedium)
  337. {
  338. // This is the display named used in the scope pane and snap-in manager
  339. return Create(NodeName(), ((NodeName().GetLength()+1) * sizeof(wchar_t)), lpMedium);
  340. }
  341. template <class T>
  342. HRESULT CDataObjectImpl<T>::CreateWorkstationName(LPSTGMEDIUM lpMedium)
  343. {
  344. wchar_t pzName[MAX_COMPUTERNAME_LENGTH+1] = {0};
  345. DWORD len = MAX_COMPUTERNAME_LENGTH+1;
  346. if (GetComputerName(pzName, &len) == FALSE)
  347. {
  348. TRACE(_T("CDataObjectImpl<T>::CreateWorkstationName returning E_FAIL\n"));
  349. return E_FAIL;
  350. }
  351. // Add 1 for the NULL and calculate the bytes for the stream
  352. return Create(pzName, ((len+1)* sizeof(wchar_t)), lpMedium);
  353. }
  354. template <class T>
  355. HRESULT CDataObjectImpl<T>::CreateCoClassID(LPSTGMEDIUM lpMedium)
  356. {
  357. // Create the CoClass information
  358. return Create(reinterpret_cast<const void*>(&clsid()), sizeof(CLSID), lpMedium);
  359. }
  360. template <class T>
  361. HRESULT CDataObjectImpl<T>::CreateDSObjectNames(LPSTGMEDIUM lpMedium)
  362. {
  363. int len = 0;
  364. HRESULT hr = S_OK;
  365. len = DataGlobalAllocLen((CLIPFORMAT)m_cfDSObjectNames);
  366. hr = Create(DSOBJECTObjectNamesPtr(), len, lpMedium);
  367. return(hr);
  368. }
  369. template <class T>
  370. HRESULT CDataObjectImpl<T>::CreatePolicyObject(LPSTGMEDIUM lpMedium)
  371. {
  372. HRESULT hr = E_UNEXPECTED;
  373. // can only do this if there is a POLICYOBJECTPtr
  374. if (POLICYOBJECTPtr() != NULL)
  375. {
  376. // allocate a POLICYOBJECTSTRUCT of the correct length
  377. int iLen = POLICYOBJECTPtr()->DataGlobalAllocLen();
  378. POLICYOBJECTSTRUCT* pPolicyStruct = (POLICYOBJECTSTRUCT* ) malloc (iLen);
  379. if (POLICYOBJECTPtr()->ToPolicyStruct (pPolicyStruct) == S_OK)
  380. {
  381. return Create (reinterpret_cast<const void*>(pPolicyStruct), iLen, lpMedium);
  382. };
  383. }
  384. return hr;
  385. }
  386. template <class T>
  387. HRESULT CDataObjectImpl<T>::Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  388. {
  389. HRESULT hr = DV_E_TYMED;
  390. // Do some simple validation
  391. if (pBuffer == NULL || lpMedium == NULL)
  392. return E_POINTER;
  393. // Make sure the type medium is HGLOBAL
  394. if (lpMedium->tymed == TYMED_HGLOBAL)
  395. {
  396. // Create the stream on the hGlobal passed in
  397. LPSTREAM lpStream;
  398. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  399. if (hr == S_OK)
  400. {
  401. // Write to the stream the number of bytes
  402. unsigned long written;
  403. hr = lpStream->Write(pBuffer, len, &written);
  404. // Because we told CreateStreamOnHGlobal with 'FALSE',
  405. // only the stream is released here.
  406. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  407. // at the correct time. This is according to the IDataObject specification.
  408. lpStream->Release();
  409. }
  410. }
  411. return hr;
  412. }
  413. template <class T>
  414. int CDataObjectImpl<T>::DataGlobalAllocLen (CLIPFORMAT cf)
  415. {
  416. int iLen = -1;
  417. // need to determine the correct amount of space depending on the time
  418. if (cf == CSnapInClipboardFormats::m_cfCoClass)
  419. {
  420. iLen = sizeof (CLSID);
  421. } else if (cf == m_cfNodeType)
  422. {
  423. iLen = sizeof (GUID);
  424. } else if (cf == m_cfWorkstation)
  425. {
  426. iLen = ((MAX_COMPUTERNAME_LENGTH+1) * sizeof(wchar_t));
  427. } else if (cf == m_cfDSObjectNames)
  428. {
  429. // compute size of the DSOBJECTNAMES structure
  430. if (DSOBJECTObjectNamesPtr() != NULL)
  431. {
  432. CString strName = (LPWSTR)ByteOffset(DSOBJECTObjectNamesPtr(), DSOBJECTObjectNamesPtr()->aObjects[0].offsetName);;
  433. CString strClass = (LPWSTR)ByteOffset(DSOBJECTObjectNamesPtr(), DSOBJECTObjectNamesPtr()->aObjects[0].offsetClass);;
  434. iLen = sizeof(DSOBJECTNAMES) + sizeof(DSOBJECT);
  435. iLen += strName.GetLength()*sizeof(wchar_t)+1 + strClass.GetLength()*sizeof(wchar_t)+1;
  436. }
  437. } else if (cf == m_cfPolicyObject)
  438. {
  439. // compute size of the needed POLICYSTORAGE structure
  440. iLen = POLICYOBJECTPtr()->DataGlobalAllocLen();
  441. } else
  442. {
  443. // unknown type!!
  444. }
  445. return iLen;
  446. }
  447. /////////////////////////////////////////////////////////////////////////////
  448. // class CDataObject - standalone instantiation of IDataObject implementation
  449. class CDataObject :
  450. public CDataObjectImpl <CDataObject>,
  451. public CComObjectRoot
  452. {
  453. friend class CComponentImpl;
  454. public:
  455. CDataObject() {};
  456. virtual ~CDataObject() {};
  457. // ATL Maps
  458. DECLARE_NOT_AGGREGATABLE(CDataObject)
  459. BEGIN_COM_MAP(CDataObject)
  460. COM_INTERFACE_ENTRY(IDataObject)
  461. END_COM_MAP()
  462. // Standard IDataObject methods implemented in CDataObjectImpl
  463. };
  464. #endif