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.

1019 lines
31 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. ipsmcomp.cpp
  7. This file contains the derived implementations from CComponent
  8. and CComponentData for the IPSecMon snapin.
  9. FILE HISTORY:
  10. */
  11. #include "stdafx.h"
  12. #include "root.h"
  13. #include "server.h"
  14. #include <atlimpl.cpp>
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. DWORD gdwIpsmSnapVersion;
  21. UINT aColumns[IPSECMON_NODETYPE_MAX][MAX_COLUMNS] =
  22. {
  23. {IDS_ROOT_NAME, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  24. {IDS_SERVER_NAME, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  25. {IDS_COL_QM_SA_SRC, IDS_COL_QM_SA_DEST, IDS_COL_QM_SA_PROT, IDS_COL_QM_SA_SRC_PORT, IDS_COL_QM_SA_DES_PORT, IDS_COL_QM_SA_POL, IDS_COL_QM_SA_AUTH, IDS_COL_QM_SA_CONF, IDS_COL_QM_SA_INTEGRITY, IDS_COL_QM_SA_MY_TNL, IDS_COL_QM_SA_PEER_TNL, 0, 0, 0}, //IPSECMON_QM_SA
  26. {IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST, IDS_COL_FLTR_SRC_PORT, IDS_COL_FLTR_DEST_PORT, IDS_COL_FLTR_SRC_TNL, IDS_COL_FLTR_DEST_TNL, IDS_COL_FLTR_PROT, IDS_COL_FLTR_IN_FLAG, IDS_COL_FLTR_OUT_FLAG, IDS_COL_QM_POLICY, IDS_COL_IF_TYPE, 0, 0}, // IPSMSNAP_FILTER
  27. {IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST, IDS_COL_FLTR_SRC_PORT, IDS_COL_FLTR_DEST_PORT, IDS_COL_FLTR_SRC_TNL, IDS_COL_FLTR_DEST_TNL, IDS_COL_FLTR_PROT, IDS_COL_FLTR_FLAG, IDS_COL_FLTR_DIR, IDS_COL_QM_POLICY, IDS_COL_FLTR_WEIGHT, 0, 0}, // IPSECMON_SPECIFIC_FILTER
  28. {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_QUICK_MODE
  29. {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_MAIN_MODE
  30. {IDS_COL_MM_POL_NAME,IDS_COL_MM_POL_OFFER,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_MM_POLICY
  31. {IDS_COL_QM_POL_NAME,IDS_COL_QM_POL_OFFER,0,0,0,0,0,0,0,0,0,0,0,0}, //IPSECMON_QM_POLICY
  32. {IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST, IDS_COL_MM_FLTR_POL, IDS_COL_MM_FLTR_AUTH,IDS_COL_IF_TYPE,0,0,0,0,0,0,0,0}, // IPSMSNAP_MM_FILTER
  33. {IDS_COL_FLTR_NAME, IDS_COL_FLTR_SRC, IDS_COL_FLTR_DEST,IDS_COL_FLTR_DIR,IDS_COL_MM_FLTR_POL,IDS_COL_MM_FLTR_AUTH,IDS_COL_FLTR_WEIGHT,0,0,0,0,0,0,0}, // IPSMSNAP_MM_SP_FILTER
  34. {IDS_COL_MM_SA_ME,IDS_COL_MM_SA_PEER,IDS_COL_MM_SA_AUTH,IDS_COL_MM_SA_ENCRYPITON,IDS_COL_MM_SA_INTEGRITY,IDS_COL_MM_SA_DH,0,0,0,0,0,0,0,0}, //IPSECMON_MM_SA
  35. {0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  36. };
  37. //
  38. // CODEWORK this should be in a resource, for example code on loading data resources see
  39. // D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
  40. // JonN 10/11/96
  41. //
  42. int aColumnWidths[IPSECMON_NODETYPE_MAX][MAX_COLUMNS] =
  43. {
  44. {200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSMSNAP_ROOT
  45. {200 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSMSNAP_SERVER
  46. {150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_QM_SA
  47. {150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_FILTER
  48. {150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_SPECIFIC_FILTER
  49. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_QUICK_MODE
  50. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MAIN_MODE
  51. {150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_POLICY
  52. {150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_QM_POLICY
  53. {150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_FILTER
  54. {150 ,150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_SP_FILTER
  55. {150 ,150 ,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // IPSECMON_MM_SA
  56. {AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH},
  57. };
  58. #define HI HIDDEN
  59. #define EN ENABLED
  60. MMC_CONSOLE_VERB g_ConsoleVerbs[] =
  61. {
  62. MMC_VERB_OPEN,
  63. MMC_VERB_COPY,
  64. MMC_VERB_PASTE,
  65. MMC_VERB_DELETE,
  66. MMC_VERB_PROPERTIES,
  67. MMC_VERB_RENAME,
  68. MMC_VERB_REFRESH,
  69. MMC_VERB_PRINT
  70. };
  71. // default states for the console verbs
  72. MMC_BUTTON_STATE g_ConsoleVerbStates[IPSECMON_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
  73. {
  74. {HI, HI, HI, HI, HI, HI, HI, HI}, // IPSMSNAP_ROOT
  75. {HI, HI, HI, EN, EN, HI, HI, HI}, // IPSMSNAP_SERVER
  76. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_SA
  77. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_FILTER
  78. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_SPECIFIC_FILTER
  79. {HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_QUICK_MODE,
  80. {HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_MAIN_MODE,
  81. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_POLICY
  82. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_POLICY
  83. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_FILTER
  84. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SP_FILTER
  85. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SA
  86. {HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_QM_SA_ITEM,
  87. {HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_FILTER_ITEM
  88. {HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_SPECIFIC_FILTER_ITEM,
  89. {HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_MM_POLICY_ITEM
  90. {HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_QM_POLICY_ITEM
  91. {HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_MM_FILTER_ITEM
  92. {HI, HI, HI, HI, EN, HI, HI, HI}, // IPSECMON_MM_SP_FILTER_ITEM
  93. {HI, HI, HI, HI, EN, HI, HI, HI} // IPSECMON_MM_SA_ITEM
  94. };
  95. // default states for the console verbs
  96. MMC_BUTTON_STATE g_ConsoleVerbStatesMultiSel[IPSECMON_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
  97. {
  98. {HI, HI, HI, HI, HI, HI, HI, HI}, // IPSMSNAP_ROOT
  99. {HI, HI, HI, EN, EN, HI, HI, HI}, // IPSMSNAP_SERVER
  100. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_SA
  101. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_FILTER
  102. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_SPECIFIC_FILTER
  103. {HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_QUICK_MODE,
  104. {HI, HI, HI, HI, HI, HI, HI, HI}, // IPSECMON_MAIN_MODE,
  105. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_POLICY
  106. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_QM_POLICY
  107. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_FILTER
  108. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SP_FILTER
  109. {HI, HI, HI, EN, HI, HI, EN, HI}, // IPSECMON_MM_SA
  110. {HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_QM_SA_ITEM,
  111. {HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_FILTER_ITEM
  112. {HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_SPECIFIC_FILTER_ITEM,
  113. {HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_MM_POLICY_ITEM
  114. {HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_QM_POLICY_ITEM
  115. {HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_MM_FILTER_ITEM
  116. {HI, HI, HI, EN, HI, HI, HI, HI}, // IPSECMON_MM_SP_FILTER_ITEM
  117. {HI, HI, HI, EN, HI, HI, HI, HI} // IPSECMON_MM_SA_ITEM
  118. };
  119. //TODO
  120. // Help ID array for help on scope items
  121. DWORD g_dwMMCHelp[IPSECMON_NODETYPE_MAX] =
  122. {
  123. IPSMSNAP_HELP_ROOT, // IPSMSNAP_ROOT
  124. IPSMSNAP_HELP_SERVER, // IPSMSNAP_SERVER
  125. IPSMSNAP_HELP_PROVIDER, // IPSECMON_QM_SA
  126. IPSMSNAP_HELP_ROOT, // IPSECMON_FILTAER
  127. IPSMSNAP_HELP_DEVICE, // IPSECMON_QM_SA_ITEM
  128. };
  129. // icon defines
  130. UINT g_uIconMap[ICON_IDX_MAX + 1][2] =
  131. {
  132. {IDI_ICON01, ICON_IDX_SERVER},
  133. {IDI_ICON02, ICON_IDX_SERVER_BUSY},
  134. {IDI_ICON03, ICON_IDX_SERVER_CONNECTED},
  135. {IDI_ICON04, ICON_IDX_SERVER_LOST_CONNECTION},
  136. {IDI_ICON05, ICON_IDX_MACHINE},
  137. {IDI_ICON06, ICON_IDX_FOLDER_CLOSED},
  138. {IDI_ICON07, ICON_IDX_FOLDER_OPEN},
  139. {IDI_IPSECMON_SNAPIN, ICON_IDX_PRODUCT},
  140. {IDI_IPSM_FILTER, ICON_IDX_FILTER},
  141. {IDI_IPSM_POLICY, ICON_IDX_POLICY},
  142. {0, 0}
  143. };
  144. /*!--------------------------------------------------------------------------
  145. GetSystemMessage
  146. Use FormatMessage() to get a system error message
  147. Author: EricDav
  148. ---------------------------------------------------------------------------*/
  149. LONG
  150. GetSystemMessage
  151. (
  152. UINT nId,
  153. TCHAR * chBuffer,
  154. int cbBuffSize
  155. )
  156. {
  157. TCHAR * pszText = NULL ;
  158. HINSTANCE hdll = NULL ;
  159. DWORD flags = FORMAT_MESSAGE_IGNORE_INSERTS
  160. | FORMAT_MESSAGE_MAX_WIDTH_MASK;
  161. //
  162. // Interpret the error. Need to special case
  163. // the lmerr & ntstatus ranges, as well as
  164. // dhcp server error messages.
  165. //
  166. if( nId >= NERR_BASE && nId <= MAX_NERR )
  167. {
  168. hdll = LoadLibrary( _T("netmsg.dll") );
  169. }
  170. else if( nId >= 0x40000000L )
  171. {
  172. hdll = LoadLibrary( _T("ntdll.dll") );
  173. }
  174. if( hdll == NULL )
  175. {
  176. flags |= FORMAT_MESSAGE_FROM_SYSTEM;
  177. }
  178. else
  179. {
  180. flags |= FORMAT_MESSAGE_FROM_HMODULE;
  181. }
  182. //
  183. // Let FormatMessage do the dirty work.
  184. //
  185. DWORD dwResult = ::FormatMessage( flags,
  186. (LPVOID) hdll,
  187. nId,
  188. 0,
  189. chBuffer,
  190. cbBuffSize,
  191. NULL ) ;
  192. if( hdll != NULL )
  193. {
  194. LONG err = GetLastError();
  195. FreeLibrary( hdll );
  196. if ( dwResult == 0 )
  197. {
  198. ::SetLastError( err );
  199. }
  200. }
  201. return dwResult ? 0 : ::GetLastError() ;
  202. }
  203. /*!--------------------------------------------------------------------------
  204. LoadMessage
  205. Loads the error message from the correct DLL.
  206. Author: EricDav
  207. ---------------------------------------------------------------------------*/
  208. BOOL
  209. LoadMessage
  210. (
  211. UINT nIdPrompt,
  212. TCHAR * chMsg,
  213. int nMsgSize
  214. )
  215. {
  216. BOOL bOk;
  217. //
  218. // Substitute a friendly message for "RPC server not
  219. // available" and "No more endpoints available from
  220. // the endpoint mapper".
  221. //
  222. if (nIdPrompt == RPC_S_UNKNOWN_IF)
  223. {
  224. nIdPrompt = IDS_ERR_SPD_DOWN;
  225. }
  226. else if (nIdPrompt == RPC_S_SERVER_UNAVAILABLE)
  227. {
  228. nIdPrompt = IDS_ERR_SPD_UNAVAILABLE;
  229. }
  230. //
  231. // If it's a socket error or our error, the text is in our resource fork.
  232. // Otherwise, use FormatMessage() and the appropriate DLL.
  233. //
  234. if (nIdPrompt >= IDS_ERR_BASE && nIdPrompt < IDS_MESG_MAX)
  235. {
  236. //
  237. // It's in our resource fork
  238. //
  239. bOk = ::LoadString( AfxGetInstanceHandle(), nIdPrompt, chMsg, nMsgSize ) != 0 ;
  240. }
  241. else
  242. {
  243. //
  244. // It's in the system somewhere.
  245. //
  246. bOk = GetSystemMessage( nIdPrompt, chMsg, nMsgSize ) == 0 ;
  247. }
  248. //
  249. // If the error message did not compute, replace it.
  250. //
  251. if ( ! bOk )
  252. {
  253. TCHAR chBuff [STRING_LENGTH_MAX] ;
  254. static const TCHAR * pszReplacement = _T("System Error: %ld");
  255. const TCHAR * pszMsg = pszReplacement ;
  256. //
  257. // Try to load the generic (translatable) error message text
  258. //
  259. if ( ::LoadString( AfxGetInstanceHandle(), IDS_ERR_MESSAGE_GENERIC,
  260. chBuff, DimensionOf(chBuff) ) != 0 )
  261. {
  262. pszMsg = chBuff ;
  263. }
  264. ::wsprintf( chMsg, pszMsg, nIdPrompt ) ;
  265. }
  266. return bOk;
  267. }
  268. /*!--------------------------------------------------------------------------
  269. IpsmMessageBox
  270. Puts up a message box with the corresponding error text.
  271. Author: EricDav
  272. ---------------------------------------------------------------------------*/
  273. int
  274. IpsmMessageBox
  275. (
  276. UINT nIdPrompt,
  277. UINT nType,
  278. const TCHAR * pszSuffixString,
  279. UINT nHelpContext
  280. )
  281. {
  282. TCHAR chMesg [4000] = {0};
  283. BOOL bOk ;
  284. bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(chMesg[0]));
  285. if ( pszSuffixString )
  286. {
  287. ::lstrcat( chMesg, _T(" ") ) ;
  288. ::lstrcat( chMesg, pszSuffixString ) ;
  289. }
  290. return ::AfxMessageBox( chMesg, nType, nHelpContext ) ;
  291. }
  292. /*!--------------------------------------------------------------------------
  293. IpsmMessageBoxEx
  294. Puts up a message box with the corresponding error text.
  295. Author: EricDav
  296. ---------------------------------------------------------------------------*/
  297. int
  298. IpsmMessageBoxEx
  299. (
  300. UINT nIdPrompt,
  301. LPCTSTR pszPrefixMessage,
  302. UINT nType,
  303. UINT nHelpContext
  304. )
  305. {
  306. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  307. TCHAR chMesg[4000] = {0};
  308. CString strMessage;
  309. BOOL bOk;
  310. bOk = LoadMessage(nIdPrompt, chMesg, sizeof(chMesg)/sizeof(chMesg[0]));
  311. if ( pszPrefixMessage )
  312. {
  313. strMessage = pszPrefixMessage;
  314. strMessage += _T("\n");
  315. strMessage += _T("\n");
  316. strMessage += chMesg;
  317. }
  318. else
  319. {
  320. strMessage = chMesg;
  321. }
  322. return AfxMessageBox(strMessage, nType, nHelpContext);
  323. }
  324. /*---------------------------------------------------------------------------
  325. Class CIpsmComponent implementation
  326. ---------------------------------------------------------------------------*/
  327. CIpsmComponent::CIpsmComponent()
  328. {
  329. m_pbmpToolbar = NULL;
  330. }
  331. CIpsmComponent::~CIpsmComponent()
  332. {
  333. if (m_pbmpToolbar)
  334. {
  335. delete m_pbmpToolbar;
  336. m_pbmpToolbar = NULL;
  337. }
  338. }
  339. STDMETHODIMP CIpsmComponent::InitializeBitmaps(MMC_COOKIE cookie)
  340. {
  341. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  342. ASSERT(m_spImageList != NULL);
  343. HICON hIcon;
  344. for (int i = 0; i < ICON_IDX_MAX; i++)
  345. {
  346. hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
  347. if (hIcon)
  348. {
  349. // call mmc
  350. VERIFY(SUCCEEDED(m_spImageList->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1])));
  351. }
  352. }
  353. return S_OK;
  354. }
  355. /*!--------------------------------------------------------------------------
  356. CIpsmComponent::QueryDataObject
  357. Implementation of IComponent::QueryDataObject. We need this for
  358. virtual listbox support. MMC calls us back normally with the cookie
  359. we handed it... In the case of the VLB, it hands us the index of
  360. the item. So, we need to do some extra checking...
  361. Author: EricDav
  362. ---------------------------------------------------------------------------*/
  363. STDMETHODIMP
  364. CIpsmComponent::QueryDataObject
  365. (
  366. MMC_COOKIE cookie,
  367. DATA_OBJECT_TYPES type,
  368. LPDATAOBJECT* ppDataObject
  369. )
  370. {
  371. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  372. HRESULT hr = hrOK;
  373. SPITFSNode spSelectedNode;
  374. SPITFSResultHandler spResultHandler;
  375. long lViewOptions;
  376. LPOLESTR pViewType;
  377. CDataObject * pDataObject;
  378. COM_PROTECT_TRY
  379. {
  380. // check to see what kind of result view type the selected node has
  381. CORg (GetSelectedNode(&spSelectedNode));
  382. CORg (spSelectedNode->GetResultHandler(&spResultHandler));
  383. CORg (spResultHandler->OnGetResultViewType(this, spSelectedNode->GetData(TFS_DATA_COOKIE), &pViewType, &lViewOptions));
  384. if ( (lViewOptions & MMC_VIEW_OPTIONS_OWNERDATALIST) ||
  385. (cookie == MMC_MULTI_SELECT_COOKIE) )
  386. {
  387. if (cookie == MMC_MULTI_SELECT_COOKIE)
  388. {
  389. // this is a special case for multiple select. We need to build a list
  390. // of GUIDs and the code to do this is in the handler...
  391. spResultHandler->OnCreateDataObject(this, cookie, type, ppDataObject);
  392. }
  393. else
  394. {
  395. // this node has a virtual listbox for the result pane. Gerenate
  396. // a special data object using the selected node as the cookie
  397. Assert(m_spComponentData != NULL);
  398. CORg (m_spComponentData->QueryDataObject(reinterpret_cast<MMC_COOKIE>((ITFSNode *) spSelectedNode), type, ppDataObject));
  399. }
  400. pDataObject = reinterpret_cast<CDataObject *>(*ppDataObject);
  401. pDataObject->SetVirtualIndex((int) cookie);
  402. }
  403. else
  404. {
  405. // just forward this to the component data
  406. Assert(m_spComponentData != NULL);
  407. CORg (m_spComponentData->QueryDataObject(cookie, type, ppDataObject));
  408. }
  409. COM_PROTECT_ERROR_LABEL;
  410. }
  411. COM_PROTECT_CATCH
  412. return hr;
  413. }
  414. /*!--------------------------------------------------------------------------
  415. CIpsmComponent::CompareObjects
  416. Implementation of IComponent::CompareObjects
  417. MMC calls this to compare two objects
  418. We override this for the virtual listbox case. With a virtual listbox,
  419. the cookies are the same, but the index in the internal structs
  420. indicate which item the dataobject refers to. So, we need to look
  421. at the indicies instead of just the cookies.
  422. Author:
  423. ---------------------------------------------------------------------------*/
  424. STDMETHODIMP
  425. CIpsmComponent::CompareObjects
  426. (
  427. LPDATAOBJECT lpDataObjectA,
  428. LPDATAOBJECT lpDataObjectB
  429. )
  430. {
  431. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  432. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  433. return E_POINTER;
  434. // Make sure both data object are mine
  435. SPINTERNAL spA;
  436. SPINTERNAL spB;
  437. HRESULT hr = S_FALSE;
  438. COM_PROTECT_TRY
  439. {
  440. spA = ExtractInternalFormat(lpDataObjectA);
  441. spB = ExtractInternalFormat(lpDataObjectB);
  442. if (spA != NULL && spB != NULL)
  443. {
  444. if (spA->m_cookie != spB->m_cookie)
  445. {
  446. hr = S_FALSE;
  447. }
  448. else
  449. {
  450. if (spA->HasVirtualIndex() && spB->HasVirtualIndex())
  451. {
  452. hr = (spA->GetVirtualIndex() == spB->GetVirtualIndex()) ? S_OK : S_FALSE;
  453. }
  454. else
  455. {
  456. hr = S_OK;
  457. }
  458. }
  459. }
  460. }
  461. COM_PROTECT_CATCH
  462. return hr;
  463. }
  464. /*!--------------------------------------------------------------------------
  465. CIpsmComponentData::SetControlbar
  466. -
  467. Author: EricDav, KennT
  468. ---------------------------------------------------------------------------*/
  469. HRESULT
  470. CIpsmComponent::SetControlbar
  471. (
  472. LPCONTROLBAR pControlbar
  473. )
  474. {
  475. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  476. HRESULT hr = hrOK;
  477. if (pControlbar)
  478. {
  479. }
  480. // store the control bar away for future use
  481. m_spControlbar.Set(pControlbar);
  482. return hr;
  483. }
  484. /*!--------------------------------------------------------------------------
  485. CIpsmComponentData::ControlbarNotify
  486. -
  487. Author: EricDav
  488. ---------------------------------------------------------------------------*/
  489. STDMETHODIMP
  490. CIpsmComponent::ControlbarNotify
  491. (
  492. MMC_NOTIFY_TYPE event,
  493. LPARAM arg,
  494. LPARAM param
  495. )
  496. {
  497. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  498. HRESULT hr = hrOK;
  499. return hr;
  500. }
  501. /*!--------------------------------------------------------------------------
  502. CIpsmComponentData::OnSnapinHelp
  503. -
  504. Author: EricDav
  505. ---------------------------------------------------------------------------*/
  506. STDMETHODIMP
  507. CIpsmComponent::OnSnapinHelp
  508. (
  509. LPDATAOBJECT pDataObject,
  510. LPARAM arg,
  511. LPARAM param
  512. )
  513. {
  514. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  515. HRESULT hr = hrOK;
  516. //TODO add the help info here
  517. HtmlHelpA(NULL, "ipsecconcepts.chm", HH_DISPLAY_TOPIC, 0);
  518. return hr;
  519. }
  520. /*---------------------------------------------------------------------------
  521. Class CIpsmComponentData implementation
  522. ---------------------------------------------------------------------------*/
  523. CIpsmComponentData::CIpsmComponentData()
  524. {
  525. gdwIpsmSnapVersion = IPSMSNAP_VERSION;
  526. }
  527. /*!--------------------------------------------------------------------------
  528. CIpsmComponentData::OnInitialize
  529. -
  530. Author: EricDav, KennT
  531. ---------------------------------------------------------------------------*/
  532. STDMETHODIMP CIpsmComponentData::OnInitialize(LPIMAGELIST pScopeImage)
  533. {
  534. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  535. HICON hIcon;
  536. for (int i = 0; i < ICON_IDX_MAX; i++)
  537. {
  538. hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
  539. if (hIcon)
  540. {
  541. // call mmc
  542. VERIFY(SUCCEEDED(pScopeImage->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1])));
  543. }
  544. }
  545. return hrOK;
  546. }
  547. /*!--------------------------------------------------------------------------
  548. CIpsmComponentData::OnDestroy
  549. -
  550. Author: EricDav, KennT
  551. ---------------------------------------------------------------------------*/
  552. STDMETHODIMP CIpsmComponentData::OnDestroy()
  553. {
  554. m_spNodeMgr.Release();
  555. return hrOK;
  556. }
  557. /*!--------------------------------------------------------------------------
  558. CIpsmComponentData::OnInitializeNodeMgr
  559. -
  560. Author: KennT
  561. ---------------------------------------------------------------------------*/
  562. STDMETHODIMP
  563. CIpsmComponentData::OnInitializeNodeMgr
  564. (
  565. ITFSComponentData * pTFSCompData,
  566. ITFSNodeMgr * pNodeMgr
  567. )
  568. {
  569. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  570. // For now create a new node handler for each new node,
  571. // this is rather bogus as it can get expensive. We can
  572. // consider creating only a single node handler for each
  573. // node type.
  574. CIpsmRootHandler * pHandler = NULL;
  575. SPITFSNodeHandler spHandler;
  576. SPITFSNode spNode;
  577. HRESULT hr = hrOK;
  578. try
  579. {
  580. pHandler = new CIpsmRootHandler(pTFSCompData);
  581. // Do this so that it will get released correctly
  582. spHandler = pHandler;
  583. }
  584. catch(...)
  585. {
  586. hr = E_OUTOFMEMORY;
  587. }
  588. CORg( hr );
  589. // Create the root node for this sick puppy
  590. CORg( CreateContainerTFSNode(&spNode,
  591. &GUID_IpsmRootNodeType,
  592. pHandler,
  593. pHandler, /* result handler */
  594. pNodeMgr) );
  595. // Need to initialize the data for the root node
  596. pHandler->InitializeNode(spNode);
  597. CORg( pNodeMgr->SetRootNode(spNode) );
  598. m_spRootNode.Set(spNode);
  599. //TODO this should refer to ipsmsnap.chm
  600. pTFSCompData->SetHTMLHelpFileName(_T("ipsecconcepts.chm"));
  601. Error:
  602. return hr;
  603. }
  604. /*!--------------------------------------------------------------------------
  605. CIpsmComponentData::OnCreateComponent
  606. -
  607. Author: EricDav, KennT
  608. ---------------------------------------------------------------------------*/
  609. STDMETHODIMP
  610. CIpsmComponentData::OnCreateComponent
  611. (
  612. LPCOMPONENT *ppComponent
  613. )
  614. {
  615. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  616. ASSERT(ppComponent != NULL);
  617. HRESULT hr = hrOK;
  618. CIpsmComponent * pComp = NULL;
  619. try
  620. {
  621. pComp = new CIpsmComponent;
  622. }
  623. catch(...)
  624. {
  625. hr = E_OUTOFMEMORY;
  626. }
  627. if (FHrSucceeded(hr))
  628. {
  629. pComp->Construct(m_spNodeMgr,
  630. static_cast<IComponentData *>(this),
  631. m_spTFSComponentData);
  632. *ppComponent = static_cast<IComponent *>(pComp);
  633. }
  634. return hr;
  635. }
  636. /*!--------------------------------------------------------------------------
  637. CIpsmComponentData::GetCoClassID
  638. -
  639. Author: KennT
  640. ---------------------------------------------------------------------------*/
  641. STDMETHODIMP_(const CLSID *)
  642. CIpsmComponentData::GetCoClassID()
  643. {
  644. return &CLSID_IpsmSnapin;
  645. }
  646. /*!--------------------------------------------------------------------------
  647. CIpsmComponentData::OnCreateDataObject
  648. -
  649. Author: KennT
  650. ---------------------------------------------------------------------------*/
  651. STDMETHODIMP
  652. CIpsmComponentData::OnCreateDataObject
  653. (
  654. MMC_COOKIE cookie,
  655. DATA_OBJECT_TYPES type,
  656. IDataObject ** ppDataObject
  657. )
  658. {
  659. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  660. Assert(ppDataObject != NULL);
  661. CDataObject * pObject = NULL;
  662. SPIDataObject spDataObject;
  663. pObject = new CDataObject;
  664. spDataObject = pObject; // do this so that it gets released correctly
  665. Assert(pObject != NULL);
  666. // Save cookie and type for delayed rendering
  667. pObject->SetType(type);
  668. pObject->SetCookie(cookie);
  669. // Store the coclass with the data object
  670. pObject->SetClsid(*GetCoClassID());
  671. pObject->SetTFSComponentData(m_spTFSComponentData);
  672. return pObject->QueryInterface(IID_IDataObject,
  673. reinterpret_cast<void**>(ppDataObject));
  674. }
  675. ///////////////////////////////////////////////////////////////////////////////
  676. //// IPersistStream interface members
  677. STDMETHODIMP
  678. CIpsmComponentData::GetClassID
  679. (
  680. CLSID *pClassID
  681. )
  682. {
  683. ASSERT(pClassID != NULL);
  684. // Copy the CLSID for this snapin
  685. *pClassID = CLSID_IpsmSnapin;
  686. return hrOK;
  687. }
  688. STDMETHODIMP
  689. CIpsmComponentData::IsDirty()
  690. {
  691. HRESULT hr = hrFalse;
  692. if (m_spRootNode->GetData(TFS_DATA_DIRTY))
  693. {
  694. hr = hrOK;
  695. }
  696. return hr;
  697. }
  698. STDMETHODIMP
  699. CIpsmComponentData::Load
  700. (
  701. IStream *pStm
  702. )
  703. {
  704. HRESULT hr = hrOK;
  705. DWORD dwSavedVersion;
  706. CString str;
  707. int i, j;
  708. ASSERT(pStm);
  709. CStringArray strArrayName;
  710. CDWordArray dwArrayRefreshInterval;
  711. CDWordArray dwArrayOptions;
  712. CDWordArray dwArrayColumnInfo;
  713. ASSERT(pStm);
  714. CIpsmRootHandler * pRootHandler = GETHANDLER(CIpsmRootHandler, m_spRootNode);
  715. // set the mode for this stream
  716. XferStream xferStream(pStm, XferStream::MODE_READ);
  717. // read the version of the file format
  718. DWORD dwFileVersion;
  719. CORg(xferStream.XferDWORD(IPSMSTRM_TAG_VERSION, &dwFileVersion));
  720. if (dwFileVersion < IPSMSNAP_FILE_VERSION)
  721. {
  722. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  723. AfxMessageBox(IDS_ERR_OLD_CONSOLE_FILE);
  724. return hr;
  725. }
  726. // Read the version # of the admin tool
  727. CORg(xferStream.XferDWORD(IPSMSTRM_TAG_VERSIONADMIN, &dwSavedVersion));
  728. if (dwSavedVersion < gdwIpsmSnapVersion)
  729. {
  730. // File is an older version. Warn the user and then don't
  731. // load anything else
  732. Assert(FALSE);
  733. }
  734. // now read all of the server information
  735. CORg(xferStream.XferCStringArray(IPSMSTRM_TAG_SERVER_NAME, &strArrayName));
  736. CORg(xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval));
  737. CORg(xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_OPTIONS, &dwArrayOptions));
  738. // now load the column information
  739. for (i = 0; i < NUM_SCOPE_ITEMS; i++)
  740. {
  741. CORg(xferStream.XferDWORDArray(IPSMSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
  742. for (j = 0; j < MAX_COLUMNS; j++)
  743. {
  744. aColumnWidths[i][j] = dwArrayColumnInfo[j];
  745. }
  746. }
  747. // now create the servers based on the information
  748. for (i = 0; i < strArrayName.GetSize(); i++)
  749. {
  750. //
  751. // now create the server object
  752. //
  753. pRootHandler->AddServer(NULL,
  754. strArrayName[i],
  755. FALSE,
  756. dwArrayOptions[i],
  757. dwArrayRefreshInterval[i],
  758. FALSE,
  759. 0,
  760. 0);
  761. }
  762. Error:
  763. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  764. }
  765. STDMETHODIMP
  766. CIpsmComponentData::Save
  767. (
  768. IStream *pStm,
  769. BOOL fClearDirty
  770. )
  771. {
  772. HRESULT hr = hrOK;
  773. CStringArray strArrayName;
  774. CDWordArray dwArrayRefreshInterval;
  775. CDWordArray dwArrayOptions;
  776. CDWordArray dwArrayColumnInfo;
  777. ASSERT(pStm);
  778. // set the mode for this stream
  779. XferStream xferStream(pStm, XferStream::MODE_WRITE);
  780. CString str;
  781. // Write the version # of the file format
  782. DWORD dwFileVersion = IPSMSNAP_FILE_VERSION;
  783. xferStream.XferDWORD(IPSMSTRM_TAG_VERSION, &dwFileVersion);
  784. // Write the version # of the admin tool
  785. xferStream.XferDWORD(IPSMSTRM_TAG_VERSIONADMIN, &gdwIpsmSnapVersion);
  786. //
  787. // Build our array of servers
  788. //
  789. int nNumServers = 0, nVisibleCount = 0;
  790. hr = m_spRootNode->GetChildCount(&nVisibleCount, &nNumServers);
  791. strArrayName.SetSize(nNumServers);
  792. dwArrayRefreshInterval.SetSize(nNumServers);
  793. dwArrayOptions.SetSize(nNumServers);
  794. dwArrayColumnInfo.SetSize(MAX_COLUMNS);
  795. //
  796. // loop and save off all the server's attributes
  797. //
  798. SPITFSNodeEnum spNodeEnum;
  799. SPITFSNode spCurrentNode;
  800. ULONG nNumReturned = 0;
  801. int nCount = 0;
  802. m_spRootNode->GetEnum(&spNodeEnum);
  803. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  804. while (nNumReturned)
  805. {
  806. CIpsmServer * pServer = GETHANDLER(CIpsmServer, spCurrentNode);
  807. // query the server for it's options:
  808. // auto refresh
  809. dwArrayRefreshInterval[nCount] = pServer->GetAutoRefreshInterval();
  810. dwArrayOptions[nCount] = pServer->GetOptions();
  811. // put the information in our array
  812. strArrayName[nCount] = pServer->GetName();
  813. // go to the next node
  814. spCurrentNode.Release();
  815. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  816. nCount++;
  817. }
  818. // now write out all of the server information
  819. xferStream.XferCStringArray(IPSMSTRM_TAG_SERVER_NAME, &strArrayName);
  820. xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_REFRESH_INTERVAL, &dwArrayRefreshInterval);
  821. xferStream.XferDWORDArray(IPSMSTRM_TAG_SERVER_OPTIONS, &dwArrayOptions);
  822. // now save the column information
  823. for (int i = 0; i < NUM_SCOPE_ITEMS; i++)
  824. {
  825. for (int j = 0; j < MAX_COLUMNS; j++)
  826. {
  827. dwArrayColumnInfo[j] = aColumnWidths[i][j];
  828. }
  829. xferStream.XferDWORDArray(IPSMSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo);
  830. }
  831. if (fClearDirty)
  832. {
  833. m_spRootNode->SetData(TFS_DATA_DIRTY, FALSE);
  834. }
  835. return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE;
  836. }
  837. STDMETHODIMP
  838. CIpsmComponentData::GetSizeMax
  839. (
  840. ULARGE_INTEGER *pcbSize
  841. )
  842. {
  843. ASSERT(pcbSize);
  844. // Set the size of the string to be saved
  845. ULISet32(*pcbSize, 10000);
  846. return S_OK;
  847. }
  848. STDMETHODIMP
  849. CIpsmComponentData::InitNew()
  850. {
  851. return hrOK;
  852. }
  853. HRESULT
  854. CIpsmComponentData::FinalConstruct()
  855. {
  856. HRESULT hr = hrOK;
  857. hr = CComponentData::FinalConstruct();
  858. if (FHrSucceeded(hr))
  859. {
  860. m_spTFSComponentData->GetNodeMgr(&m_spNodeMgr);
  861. }
  862. return hr;
  863. }
  864. void
  865. CIpsmComponentData::FinalRelease()
  866. {
  867. CComponentData::FinalRelease();
  868. }