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.

693 lines
13 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. dataobj.cpp
  5. Abstract:
  6. Snapin data object
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "inetmgr.h"
  18. #include "cinetmgr.h"
  19. #include "dataobj.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. //
  26. // Snap-in NodeType in both GUID format and string format
  27. // Note - Typically there is a node type for each different object, sample
  28. // only uses one node type.
  29. //
  30. unsigned int CDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  31. unsigned int CDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  32. unsigned int CDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  33. unsigned int CDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  34. /*
  35. //
  36. // Multi-select
  37. //
  38. unsigned int CDataObject::m_cfpMultiSelDataObj = RegisterClipboardFormat(CCF_MMC_MULTISELECT_DATAOBJECT);
  39. unsigned int CDataObject::m_cfMultiObjTypes = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  40. unsigned int CDataObject::m_cfMultiSelDataObjs = RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
  41. */
  42. //
  43. // Internal
  44. //
  45. unsigned int CDataObject::m_cfInternal = RegisterClipboardFormat(ISM_SNAPIN_INTERNAL);
  46. //
  47. // Published Information
  48. //
  49. unsigned int CDataObject::m_cfISMMachineName = RegisterClipboardFormat(ISM_SNAPIN_MACHINE_NAME);
  50. unsigned int CDataObject::m_cfMyComputMachineName = RegisterClipboardFormat(MYCOMPUT_MACHINE_NAME);
  51. unsigned int CDataObject::m_cfISMService = RegisterClipboardFormat(ISM_SNAPIN_SERVICE);
  52. unsigned int CDataObject::m_cfISMInstance = RegisterClipboardFormat(ISM_SNAPIN_INSTANCE);
  53. unsigned int CDataObject::m_cfISMParentPath = RegisterClipboardFormat(ISM_SNAPIN_PARENT_PATH);
  54. unsigned int CDataObject::m_cfISMNode = RegisterClipboardFormat(ISM_SNAPIN_NODE);
  55. unsigned int CDataObject::m_cfISMMetaPath = RegisterClipboardFormat(ISM_SNAPIN_META_PATH);
  56. STDMETHODIMP
  57. CDataObject::GetDataHere(
  58. IN LPFORMATETC lpFormatetc,
  59. IN LPSTGMEDIUM lpMedium
  60. )
  61. /*++
  62. Routine Description:
  63. Write requested information type to the given medium
  64. Arguments:
  65. LPFORMATETC lpFormatetc : Format etc
  66. LPSTGMEDIUM lpMedium : Medium to write to.
  67. Return Value:
  68. HRESULT
  69. --*/
  70. {
  71. HRESULT hr = DV_E_CLIPFORMAT;
  72. //
  73. // Based on the CLIPFORMAT write data to the stream
  74. //
  75. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  76. if (cf == m_cfNodeType)
  77. {
  78. hr = CreateNodeTypeData(lpMedium);
  79. }
  80. else if (cf == m_cfNodeTypeString)
  81. {
  82. hr = CreateNodeTypeStringData(lpMedium);
  83. }
  84. else if (cf == m_cfCoClass)
  85. {
  86. hr = CreateCoClassID(lpMedium);
  87. }
  88. else if (cf == m_cfDisplayName)
  89. {
  90. hr = CreateDisplayName(lpMedium);
  91. }
  92. else if (cf == m_cfInternal)
  93. {
  94. hr = CreateInternal(lpMedium);
  95. }
  96. else if (cf == m_cfISMMachineName)
  97. {
  98. hr = CreateMachineName(lpMedium);
  99. }
  100. /*
  101. multi-select pulled
  102. else if (cf == m_cfpMultiSelDataObj)
  103. {
  104. TRACEEOLID("CCF_MMC_MULTISELECT_DATAOBJECT");
  105. }
  106. else if (cf == m_cfMultiObjTypes)
  107. {
  108. TRACEEOLID("CCF_OBJECT_TYPES_IN_MULTI_SELECT");
  109. }
  110. else if (cf == m_cfMultiSelDataObjs)
  111. {
  112. TRACEEOLID("CCF_MULTI_SELECT_SNAPINS");
  113. }
  114. */
  115. else if (cf == m_cfISMService)
  116. {
  117. hr = CreateMetaField(lpMedium, META_SERVICE);
  118. }
  119. else if (cf == m_cfISMInstance)
  120. {
  121. hr = CreateMetaField(lpMedium, META_INSTANCE);
  122. }
  123. else if (cf == m_cfISMParentPath)
  124. {
  125. hr = CreateMetaField(lpMedium, META_PARENT);
  126. }
  127. else if (cf == m_cfISMNode)
  128. {
  129. hr = CreateMetaField(lpMedium, META_NODE);
  130. }
  131. else if (cf == m_cfISMMetaPath)
  132. {
  133. hr = CreateMetaField(lpMedium, META_WHOLE);
  134. }
  135. else
  136. {
  137. TRACEEOLID("Unrecognized format");
  138. hr = DV_E_CLIPFORMAT;
  139. }
  140. return hr;
  141. }
  142. STDMETHODIMP
  143. CDataObject::GetData(
  144. IN LPFORMATETC lpFormatetcIn,
  145. IN LPSTGMEDIUM lpMedium
  146. )
  147. /*++
  148. Routine Description:
  149. Get data from the data object
  150. Arguments:
  151. LPFORMATETC lpFormatetcIn : Formatetc Input
  152. LPSTGMEDIUM lpMedium : Pointer to medium
  153. Return Value:
  154. HRESULT
  155. --*/
  156. {
  157. //
  158. // Not implemented
  159. //
  160. return E_NOTIMPL;
  161. }
  162. STDMETHODIMP
  163. CDataObject::EnumFormatEtc(
  164. IN DWORD dwDirection,
  165. IN LPENUMFORMATETC * ppEnumFormatEtc
  166. )
  167. /*++
  168. Routine Description:
  169. Enumerate format etc information
  170. Arguments:
  171. DWORD dwDirection : Direction
  172. LPENUMFORMATETC * ppEnumFormatEtc : Format etc array
  173. Return Value:
  174. HRESULT
  175. --*/
  176. {
  177. //
  178. // Not implemented
  179. //
  180. return E_NOTIMPL;
  181. }
  182. //
  183. // CDataObject creation members
  184. //
  185. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  186. HRESULT
  187. CDataObject::Create(
  188. IN const void * pBuffer,
  189. IN int len,
  190. IN LPSTGMEDIUM lpMedium
  191. )
  192. /*++
  193. Routine Description:
  194. Create information on the given medium
  195. Arguments:
  196. const void * pBuffer : Data buffer
  197. int len : Size of data
  198. LPSTGMEDIUM lpMedium : Medium to write to.
  199. Return Value:
  200. HRESULT
  201. --*/
  202. {
  203. HRESULT hr = DV_E_TYMED;
  204. //
  205. // Do some simple validation
  206. //
  207. if (pBuffer == NULL || lpMedium == NULL)
  208. {
  209. return E_POINTER;
  210. }
  211. //
  212. // Make sure the type medium is HGLOBAL
  213. //
  214. if (lpMedium->tymed == TYMED_HGLOBAL)
  215. {
  216. //
  217. // Create the stream on the hGlobal passed in
  218. //
  219. LPSTREAM lpStream;
  220. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  221. if (SUCCEEDED(hr))
  222. {
  223. //
  224. // Write to the stream the number of bytes
  225. //
  226. unsigned long written;
  227. hr = lpStream->Write(pBuffer, len, &written);
  228. //
  229. // Because we called CreateStreamOnHGlobal with 'FALSE',
  230. // only the stream is released here.
  231. // Note - the caller (i.e. snap-in, object) will free
  232. // the HGLOBAL at the correct time. This is according to
  233. // the IDataObject specification.
  234. //
  235. lpStream->Release();
  236. }
  237. }
  238. return hr;
  239. }
  240. HRESULT
  241. CDataObject::CreateNodeTypeData(
  242. IN LPSTGMEDIUM lpMedium
  243. )
  244. /*++
  245. Routine Description:
  246. Create node type data on medium
  247. Arguments:
  248. LPSTGMEDIUM lpMedium : Medium to write to.
  249. Return Value:
  250. HRESULT
  251. --*/
  252. {
  253. //
  254. // Create the node type object in GUID format
  255. //
  256. const GUID * pcObjectType = NULL;
  257. if (m_internal.m_cookie == NULL)
  258. {
  259. //
  260. // Blank CIISNode, must be the static root
  261. //
  262. pcObjectType = &cInternetRootNode;
  263. }
  264. else
  265. {
  266. //
  267. // Ask the object what kind of object it is.
  268. //
  269. CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
  270. pcObjectType = pObject->GetGUIDPtr();
  271. }
  272. return Create((const void *)pcObjectType, sizeof(GUID), lpMedium);
  273. }
  274. HRESULT
  275. CDataObject::CreateNodeTypeStringData(
  276. IN LPSTGMEDIUM lpMedium
  277. )
  278. /*++
  279. Routine Description:
  280. Create node type in string format
  281. Arguments:
  282. LPSTGMEDIUM lpMedium : Medium to write to.
  283. Return Value:
  284. HRESULT
  285. --*/
  286. {
  287. //
  288. // Create the node type object in GUID string format
  289. //
  290. const wchar_t * cszObjectType = NULL;
  291. CString str;
  292. if (m_internal.m_cookie == NULL)
  293. {
  294. //
  295. // This must be the static root node
  296. //
  297. cszObjectType = GUIDToCString(cInternetRootNode, str);
  298. }
  299. else
  300. {
  301. //
  302. // Ask the CIISObject what type it is
  303. //
  304. CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
  305. cszObjectType = GUIDToCString(pObject->QueryGUID(), str);
  306. }
  307. return Create(
  308. cszObjectType,
  309. ((wcslen(cszObjectType) + 1) * sizeof(wchar_t)),
  310. lpMedium
  311. );
  312. }
  313. HRESULT
  314. CDataObject::CreateDisplayName(
  315. IN LPSTGMEDIUM lpMedium
  316. )
  317. /*++
  318. Routine Description:
  319. CDataObject implementations
  320. Arguments:
  321. Return Value:
  322. HRESULT
  323. --*/
  324. {
  325. //
  326. // This is the display name used in the scope pane and snap-in manager
  327. //
  328. // Load the name from resource
  329. // Note - if this is not provided, the console will used the snap-in name
  330. //
  331. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  332. CString szDispName;
  333. szDispName.LoadString(IDS_NODENAME);
  334. return Create(
  335. szDispName,
  336. ((szDispName.GetLength() + 1) * sizeof(wchar_t)),
  337. lpMedium
  338. );
  339. }
  340. HRESULT
  341. CDataObject::CreateInternal(
  342. IN LPSTGMEDIUM lpMedium
  343. )
  344. /*++
  345. Routine Description:
  346. CDataObject implementations
  347. Arguments:
  348. Return Value:
  349. HRESULT
  350. --*/
  351. {
  352. return Create(&m_internal, sizeof(INTERNAL), lpMedium);
  353. }
  354. HRESULT
  355. CDataObject::CreateMachineName(
  356. IN LPSTGMEDIUM lpMedium
  357. )
  358. /*++
  359. Routine Description:
  360. Create the machine name
  361. Arguments:
  362. LPSTGMEDIUM lpMedium : Address of STGMEDIUM object
  363. Return Value:
  364. HRESULT
  365. --*/
  366. {
  367. wchar_t pzName[MAX_PATH + 1] = {0};
  368. DWORD len; // = MAX_PATH + 1;
  369. CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
  370. if (pObject == NULL)
  371. {
  372. ASSERT(FALSE);
  373. return E_FAIL;
  374. }
  375. lstrcpyn(pzName, pObject->GetMachineName(), MAX_PATH);
  376. len = lstrlen(pzName);
  377. //
  378. // Add 1 for the NULL and calculate the bytes for the stream
  379. //
  380. return Create(pzName, ((len + 1) * sizeof(wchar_t)), lpMedium);
  381. }
  382. HRESULT
  383. CDataObject::CreateMetaField(
  384. IN LPSTGMEDIUM lpMedium,
  385. IN META_FIELD fld
  386. )
  387. /*++
  388. Routine Description:
  389. Create a field from the metabase path, indicated by fld, or the entire
  390. path.
  391. Arguments:
  392. LPSTGMEDIUM lpMedium : Address of STGMEDIUM object
  393. META_FIELD fld : Type of metabase information
  394. Return Value:
  395. HRESULT
  396. --*/
  397. {
  398. CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
  399. if (pObject == NULL)
  400. {
  401. //
  402. // Static root node has no metabase path
  403. //
  404. ASSERT(FALSE);
  405. return E_FAIL;
  406. }
  407. //
  408. // Generate complete metabase path for this node
  409. //
  410. CString strField;
  411. CString strMetaPath;
  412. pObject->BuildFullPath(strMetaPath, TRUE);
  413. if (fld == META_WHOLE)
  414. {
  415. //
  416. // Whole metabase path requested
  417. //
  418. strField = strMetaPath;
  419. }
  420. else
  421. {
  422. //
  423. // A portion of the metabase is requested. Return the requested
  424. // portion
  425. //
  426. LPCTSTR lpMetaPath = (LPCTSTR)strMetaPath;
  427. LPCTSTR lpEndPath = lpMetaPath + strMetaPath.GetLength() + 1;
  428. LPCTSTR lpSvc = NULL;
  429. LPCTSTR lpInstance = NULL;
  430. LPCTSTR lpParent = NULL;
  431. LPCTSTR lpNode = NULL;
  432. //
  433. // Break up the metabase path in portions
  434. //
  435. if (lpSvc = _tcschr(lpMetaPath, _T('/')))
  436. {
  437. ++lpSvc;
  438. if (lpInstance = _tcschr(lpSvc, _T('/')))
  439. {
  440. ++lpInstance;
  441. if (lpParent = _tcschr(lpInstance, _T('/')))
  442. {
  443. ++lpParent;
  444. lpNode = _tcsrchr(lpParent, _T('/'));
  445. if (lpNode)
  446. {
  447. ++lpNode;
  448. }
  449. }
  450. }
  451. }
  452. int n1, n2;
  453. switch(fld)
  454. {
  455. case META_SERVICE:
  456. //
  457. // Requested the service string
  458. //
  459. if (lpSvc)
  460. {
  461. n1 = DIFF(lpSvc - lpMetaPath);
  462. n2 = lpInstance ? DIFF(lpInstance - lpSvc) : DIFF(lpEndPath - lpSvc);
  463. strField = strMetaPath.Mid(n1, n2 - 1);
  464. }
  465. break;
  466. case META_INSTANCE:
  467. //
  468. // Requested the instance number
  469. //
  470. if (lpInstance)
  471. {
  472. n1 = DIFF(lpInstance - lpMetaPath);
  473. n2 = lpParent ? DIFF(lpParent - lpInstance) : DIFF(lpEndPath - lpInstance);
  474. strField = strMetaPath.Mid(n1, n2 - 1);
  475. }
  476. break;
  477. case META_PARENT:
  478. //
  479. // Requestd the parent path
  480. //
  481. if (lpParent)
  482. {
  483. n1 = DIFF(lpParent - lpMetaPath);
  484. n2 = lpNode ? DIFF(lpNode - lpParent) : DIFF(lpEndPath - lpParent);
  485. strField = strMetaPath.Mid(n1, n2 - 1);
  486. }
  487. break;
  488. case META_NODE:
  489. //
  490. // Requested the node name
  491. //
  492. if (lpNode)
  493. {
  494. n1 = DIFF(lpNode - lpMetaPath);
  495. n2 = DIFF(lpEndPath - lpNode);
  496. strField = strMetaPath.Mid(n1, n2 - 1);
  497. }
  498. break;
  499. default:
  500. //
  501. // Bogus
  502. //
  503. ASSERT(FALSE);
  504. return E_FAIL;
  505. }
  506. }
  507. TRACEEOLID("Requested metabase path data: " << strField);
  508. int len = strField.GetLength() + 1;
  509. return Create((LPCTSTR)strField, (len) * sizeof(TCHAR), lpMedium);
  510. }
  511. HRESULT
  512. CDataObject::CreateCoClassID(
  513. IN LPSTGMEDIUM lpMedium
  514. )
  515. /*++
  516. Routine Description:
  517. Create the CoClassID
  518. Arguments:
  519. LPSTGMEDIUM lpMedium : Medium
  520. Return Value:
  521. HRESULT
  522. --*/
  523. {
  524. //
  525. // Create the CoClass information
  526. //
  527. return Create((const void *)&m_internal.m_clsid, sizeof(CLSID), lpMedium);
  528. }