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.

4055 lines
96 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. CSakData.cpp
  5. Abstract:
  6. This component implements the IComponentData interface for
  7. the snapin. Primarily it is responsible for handling the
  8. scope view panes.
  9. Author:
  10. Rohde Wakefield [rohde] 04-Mar-1997
  11. Revision History:
  12. --*/
  13. #include "stdafx.h"
  14. #include "HsmConn.h"
  15. #include "CSakSnap.h"
  16. #include "CSakData.h"
  17. #include "ChooHsm.h"
  18. #include "WzQstart.h"
  19. UINT CSakData::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  20. UINT CSakData::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  21. UINT CSakData::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  22. UINT CSakData::m_cfClassId = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  23. UINT CSakData::m_cfObjectTypes = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  24. UINT CSakData::m_cfMultiSelect = RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
  25. UINT CSakData::m_nImageArray[RS_SCOPE_IMAGE_ARRAY_MAX];
  26. INT CSakData::m_nImageCount = 0;
  27. ///////////////////////////////////////////////////////////////////////
  28. // CSakData
  29. //
  30. // CSakData plays several roles in the snapin:
  31. //
  32. // 1) Provides the single entry into the HSM Admin Snapin by
  33. // implementing IComponentData
  34. //
  35. // 2) Provides the "Interface" for scopeview activities within MMC
  36. //
  37. // 3) Owns the node tree / objects
  38. //
  39. // 4) Provides a layer between MMC and the node objects
  40. //
  41. // 5) Act as its own data object for MMC's node manager,
  42. //
  43. // 6) Manages our portion of the MMC image lists.
  44. //
  45. ///////////////////////////////////////////////////////////////////////
  46. const CString CSakData::CParamParse::m_DsFlag = TEXT( "ds:" );
  47. void CSakData::CParamParse::ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL /* bLast */ )
  48. {
  49. CString cmdLine = lpszParam;
  50. WsbTraceIn( L"CSakData::CParamParse::ParseParam", L"cmdLine = \"%ls\"\n", (LPCTSTR)cmdLine );
  51. if( bFlag ) {
  52. // This is the "correct" code, but currently we don't get the DsFlag parameter
  53. // passed on the command line via Directory Services
  54. if( cmdLine.Left( m_DsFlag.GetLength( ) ) == m_DsFlag ) {
  55. CString dsToken;
  56. CWsbStringPtr computerName;
  57. dsToken = cmdLine.Mid( m_DsFlag.GetLength( ) );
  58. if( SUCCEEDED( HsmGetComputerNameFromADsPath( dsToken, &computerName ) ) ) {
  59. m_HsmName = computerName;
  60. m_ManageLocal = FALSE;
  61. m_PersistManageLocal = FALSE;
  62. m_SetHsmName = TRUE;
  63. m_SetManageLocal = TRUE;
  64. m_SetPersistManageLocal = TRUE;
  65. }
  66. }
  67. } else {
  68. // This code is our stopgap measure until Directory Services starts
  69. // working the way it should
  70. if( cmdLine.Left( 5 ) == TEXT("LDAP:") ) {
  71. CWsbStringPtr computerName;
  72. if( SUCCEEDED( HsmGetComputerNameFromADsPath( cmdLine, &computerName ) ) ) {
  73. WsbTrace(L"CSakData::CParamParse::ParseParam: computerName = \"%ls\"\n", (OLECHAR*)computerName);
  74. m_HsmName = computerName;
  75. m_ManageLocal = FALSE;
  76. m_PersistManageLocal = FALSE;
  77. m_SetHsmName = TRUE;
  78. m_SetManageLocal = TRUE;
  79. m_SetPersistManageLocal = TRUE;
  80. }
  81. }
  82. }
  83. WsbTraceOut( L"CSakData::CParamParse::ParseParam", L"" );
  84. }
  85. HRESULT
  86. CSakData::FinalConstruct(
  87. void
  88. )
  89. /*++
  90. Routine Description:
  91. Called during initial CSakData construction to initialize members.
  92. Arguments:
  93. none.
  94. Return Value:
  95. S_OK - Initialized correctly.
  96. E_xxxxxxxxxxx - Failure occurred.
  97. --*/
  98. {
  99. WsbTraceIn( L"CSakData::FinalConstruct", L"" );
  100. HRESULT hr = S_OK;
  101. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  102. try {
  103. //
  104. // Init values
  105. //
  106. m_ManageLocal = FALSE;
  107. m_PersistManageLocal = TRUE;
  108. m_IsDirty = TRUE;
  109. m_State = FALSE;
  110. m_FirstTime = TRUE;
  111. m_Disabled = FALSE;
  112. m_RootNodeInitialized = FALSE;
  113. m_HrRmsConnect = S_FALSE;
  114. //
  115. // Create the hidden window so we can post messages back to self
  116. //
  117. m_pWnd = new CSakDataWnd;
  118. WsbAffirmPointer( m_pWnd );
  119. WsbAffirmStatus( m_pWnd->Create( this ) );
  120. //
  121. // Finally do low level ATL construct
  122. //
  123. WsbAffirmHr( CComObjectRoot::FinalConstruct( ) );
  124. } WsbCatch( hr );
  125. WsbTraceOut( L"CSakData::FinalConstruct", L"hr = <%ls>", WsbHrAsString( hr ) );
  126. return( hr );
  127. }
  128. void
  129. CSakData::FinalRelease(
  130. void
  131. )
  132. /*++
  133. Routine Description:
  134. Called on final release in order to clean up all members.
  135. Arguments:
  136. none.
  137. Return Value:
  138. none.
  139. --*/
  140. {
  141. WsbTraceIn( L"CSakData::FinalRelease", L"" );
  142. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  143. HRESULT hr = S_OK;
  144. try {
  145. if( m_pWnd ) {
  146. m_pWnd->DestroyWindow( );
  147. m_pWnd = 0;
  148. }
  149. } WsbCatch( hr );
  150. WsbTraceOut( L"CSakData::FinalRelease", L"" );
  151. }
  152. ///////////////////////////////////////////////////////////////////////
  153. // IComponentData //
  154. ///////////////////////////////////////////////////////////////////////
  155. STDMETHODIMP
  156. CSakData::Initialize(
  157. IN IUnknown * pUnk
  158. )
  159. /*++
  160. Routine Description:
  161. Called when the user first adds a snapin.
  162. Arguments:
  163. pUnk - Base IUnknown of console
  164. Return Value:
  165. S_OK - Correctly initialized.
  166. E_xxxxxxxxxxx - Unable to initialize.
  167. --*/
  168. {
  169. WsbTraceIn( L"CSakData::Initialize", L"pUnk = <0x%p>", pUnk );
  170. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  171. HRESULT hr = S_OK;
  172. try {
  173. //
  174. // validity check on parameters
  175. //
  176. WsbAffirmPointer( pUnk );
  177. //
  178. // QI and Save interfaces
  179. //
  180. WsbAffirmHr( RsQueryInterface( pUnk, IConsole, m_pConsole ) );
  181. WsbAffirmHr( RsQueryInterface( pUnk, IConsoleNameSpace, m_pNameSpace ) );
  182. //
  183. // Get the scope image list only and store it in the snapin.
  184. // It is AddRef'ed by the console
  185. //
  186. WsbAffirmHr( m_pConsole->QueryScopeImageList( &m_pImageScope ) );
  187. // Create the root node (make sure not already set)
  188. WsbAffirmPointer( !m_pRootNode );
  189. WsbAffirmHr( m_pRootNode.CoCreateInstance( CLSID_CUiHsmCom ) );
  190. //
  191. // If the Hsm name has not been set (by choose Hsm),
  192. // do not initialize the node here. Allow
  193. // IPersistStream::Load to initialize it, or to be grabbed
  194. // from the extension's parent
  195. //
  196. if( m_ManageLocal || ( m_HsmName != "" ) ) {
  197. //
  198. // Make sure no changes from command line
  199. //
  200. InitFromCommandLine( );
  201. //
  202. // Set the Hsm name in sakData and HsmCom objectds
  203. //
  204. WsbAffirmHr( InitializeRootNode( ) );
  205. }
  206. WsbAffirmHr( OnAddImages() );
  207. } WsbCatch( hr);
  208. WsbTraceOut( L"CSakData::Initialize", L"hr = <%ls>", WsbHrAsString( hr ) );
  209. return( hr );
  210. }
  211. STDMETHODIMP
  212. CSakData::Notify(
  213. IN IDataObject* pDataObject,
  214. IN MMC_NOTIFY_TYPE event,
  215. IN LPARAM arg,
  216. IN LPARAM param
  217. )
  218. /*++
  219. Routine Description:
  220. Handle user clicks on nodes in the treeview, along with other
  221. MMC notices.
  222. Arguments:
  223. pDataObject - Data Object for which event occured
  224. event - The event type
  225. arg, param - Info for event (depend on type)
  226. Return Value:
  227. S_OK - Notification handled without error.
  228. E_xxxxxxxxxxx - Unable to register server.
  229. --*/
  230. {
  231. WsbTraceIn( L"CSakData::Notify", L"pDataObject = <0x%p>, event = <%ls>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, RsNotifyEventAsString( event ), arg, arg, param, param );
  232. HRESULT hr = S_OK;
  233. try {
  234. switch( event ) {
  235. //
  236. // This node was selected or deselected in the scope pane (the user clicked
  237. // on the expansion/contraction button)
  238. //
  239. case MMCN_EXPAND:
  240. WsbAffirmHr( OnFolder(pDataObject, arg, param) );
  241. break;
  242. //
  243. // This node was expanded or contracted in the scope pane (the user
  244. // clicked on the actual node
  245. //
  246. case MMCN_SHOW:
  247. WsbAffirmHr( OnShow( pDataObject, arg, param ) );
  248. break;
  249. // Not implemented
  250. case MMCN_SELECT:
  251. WsbAffirmHr( OnSelect( pDataObject, arg, param ) );
  252. break;
  253. // Not implemented
  254. case MMCN_MINIMIZED:
  255. WsbAffirmHr( OnMinimize( pDataObject, arg, param ) );
  256. break;
  257. case MMCN_ADD_IMAGES:
  258. WsbAffirmHr( OnAddImages() );
  259. break;
  260. case MMCN_PROPERTY_CHANGE:
  261. {
  262. CComPtr<ISakNode> pNode;
  263. WsbAffirmHr( GetBaseHsmFromCookie( (MMC_COOKIE) param, &pNode ) );
  264. WsbAffirmHr( UpdateAllViews( pNode ) );
  265. }
  266. break;
  267. case MMCN_CONTEXTHELP:
  268. WsbAffirmHr( OnContextHelp( pDataObject, arg, param ) );
  269. break;
  270. case MMCN_REMOVE_CHILDREN:
  271. WsbAffirmHr( OnRemoveChildren( pDataObject ) );
  272. break;
  273. // Note - Future expansion of notify types possible
  274. default:
  275. break;
  276. }
  277. } WsbCatch( hr );
  278. WsbTraceOut( L"CSakData::Notify", L"hr = <%ls>", WsbHrAsString( hr ) );
  279. return( hr );
  280. }
  281. STDMETHODIMP
  282. CSakData::Destroy(
  283. void
  284. )
  285. /*++
  286. Routine Description:
  287. Called to force the release of any owned objects and
  288. to clear all views.
  289. Arguments:
  290. none.
  291. Return Value:
  292. S_OK - Correctly tore down.
  293. E_xxxxxxxxxxx - Failure occurred (not meaningful).
  294. --*/
  295. {
  296. WsbTraceIn( L"CSakData::Destroy", L"" );
  297. HRESULT hr = S_OK;
  298. try {
  299. // Release the interfaces that we QI'ed
  300. if( m_pConsole != NULL ) {
  301. //
  302. // Tell the console to release the header control interface
  303. //
  304. m_pNameSpace.Release();
  305. m_pImageScope.Release();
  306. //
  307. // Release the IConsole interface last
  308. //
  309. m_pConsole.Release();
  310. }
  311. // Recursive delete list of UI nodes, including the root node.
  312. if( m_pRootNode ) {
  313. m_pRootNode->DeleteAllChildren( );
  314. m_pRootNode->TerminateNode( );
  315. m_pRootNode.Release( );
  316. }
  317. m_pHsmServer.Release( );
  318. m_pFsaServer.Release( );
  319. m_pRmsServer.Release( );
  320. } WsbCatch( hr );
  321. WsbTraceOut( L"CSakData::Destroy", L"hr = <%ls>", WsbHrAsString( hr ) );
  322. return( hr );
  323. }
  324. STDMETHODIMP
  325. CSakData::QueryDataObject(
  326. IN MMC_COOKIE cookie,
  327. IN DATA_OBJECT_TYPES type,
  328. OUT IDataObject** ppDataObject
  329. )
  330. /*++
  331. Routine Description:
  332. Called by the console when it needs data for a particular node.
  333. Since each node is a data object, its IDataObject interface is
  334. simply returned. The console will later pass in this dataobject to
  335. SakSnap help it establish the context under which it is being called.
  336. Arguments:
  337. cookie - Node which is being queried.
  338. type - The context under which a dataobject is being requested.
  339. ppDataObject - returned data object.
  340. Return Value:
  341. S_OK - Data Object found and returned.
  342. E_xxxxxxxxxxx - Failure occurred.
  343. --*/
  344. {
  345. WsbTraceIn( L"CSakData::QueryDataObject", L"cookie = <0x%p>, type = <%d>, ppDataObject = <0x%p>", cookie, type, ppDataObject );
  346. HRESULT hr = S_OK;
  347. try {
  348. //
  349. // We return ourself if needing a root for the node manager
  350. //
  351. if( ( ( 0 == cookie ) || ( EXTENSION_RS_FOLDER_PARAM == cookie ) ) && ( CCT_SNAPIN_MANAGER == type ) ) {
  352. WsbAffirmHr( _InternalQueryInterface( IID_IDataObject, (void**)ppDataObject ) );
  353. } else {
  354. WsbAffirmHr( GetDataObjectFromCookie ( cookie, ppDataObject ) );
  355. WsbAffirmHr( SetContextType( *ppDataObject, type ) );
  356. }
  357. } WsbCatch ( hr )
  358. WsbTraceOut( L"CSakData::QueryDataObject", L"hr = <%ls>, *ppDataObject = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppDataObject ) );
  359. return ( hr );
  360. }
  361. STDMETHODIMP
  362. CSakData::CompareObjects(
  363. IN IDataObject* pDataObjectA,
  364. IN IDataObject* pDataObjectB
  365. )
  366. /*++
  367. Routine Description:
  368. Compare data objects for MMC
  369. Arguments:
  370. pDataObjectA, - Data object refering to node.
  371. pDataObjectB
  372. Return Value:
  373. S_OK - Objects represent the same node.
  374. S_FALSE - Objects do not represent the same node.
  375. E_xxxxxxxxxxx - Failure occurred.
  376. --*/
  377. {
  378. WsbTraceIn( L"CSakData::CompareObjects", L"pDataObjectA = <0x%p>, pDataObjectB = <0x%p>", pDataObjectA, pDataObjectB );
  379. HRESULT hr = S_OK;
  380. try {
  381. WsbAssertPointer ( pDataObjectA );
  382. WsbAssertPointer ( pDataObjectB );
  383. //
  384. // Since only one dataobject exists for any given node,
  385. // the QI's for IUnknown should match. (object identity)
  386. //
  387. CComPtr<IUnknown> pUnkA, pUnkB;
  388. WsbAssertHr( RsQueryInterface( pDataObjectA, IUnknown, pUnkA ) );
  389. WsbAssertHr( RsQueryInterface( pDataObjectB, IUnknown, pUnkB ) );
  390. if ( (IUnknown*)pUnkA != (IUnknown*)pUnkB ) {
  391. hr = S_FALSE;
  392. }
  393. } WsbCatch( hr );
  394. WsbTraceOut( L"CSakData::CompareObjects", L"hr = <%ls>", WsbHrAsString( hr ) );
  395. return ( hr );
  396. }
  397. STDMETHODIMP
  398. CSakData::CreateComponent(
  399. OUT IComponent** ppComponent
  400. )
  401. /*++
  402. Routine Description:
  403. Creates a new Component object for MMC - our
  404. CSakSnap object.
  405. Arguments:
  406. ppComponent - Return value of the Component.
  407. Return Value:
  408. S_OK - Created successfully.
  409. E_xxxxxxxxxxx - Failure occurred.
  410. --*/
  411. {
  412. WsbTraceIn( L"CSakData::CreateComponent", L"ppComponent = <0x%p>", ppComponent );
  413. HRESULT hr = S_OK;
  414. try {
  415. WsbAffirmPointer( ppComponent );
  416. //
  417. // Create the Snapin Component as C++ object so we can init.
  418. //
  419. CSakSnap * pSnapin = new CComObject<CSakSnap>;
  420. WsbAffirmPointer( pSnapin );
  421. //
  422. // Following code is based on ATL's CreateInstance
  423. //
  424. pSnapin->SetVoid( NULL );
  425. pSnapin->InternalFinalConstructAddRef();
  426. HRESULT hRes = pSnapin->FinalConstruct();
  427. pSnapin->InternalFinalConstructRelease();
  428. if( FAILED( hRes ) ) {
  429. delete pSnapin;
  430. pSnapin = NULL;
  431. WsbThrow( hRes );
  432. }
  433. //
  434. // And QI for right interface
  435. //
  436. WsbAffirmHr ( pSnapin->_InternalQueryInterface( IID_IComponent, (void**)ppComponent ) );
  437. //
  438. // Initialize internal pointer to CSakData
  439. //
  440. pSnapin->m_pSakData = this;
  441. } WsbCatch( hr );
  442. WsbTraceOut( L"CSakData::CreateComponent", L"hr = <%ls>, *ppComponent = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppComponent ) );
  443. return( hr );
  444. }
  445. STDMETHODIMP
  446. CSakData::GetDisplayInfo(
  447. IN OUT SCOPEDATAITEM* pScopeItem
  448. )
  449. /*++
  450. Routine Description:
  451. When MMC is told to call back concerning scope items,
  452. we receive a call here to fill in missing information.
  453. Currently we do not use this capability.
  454. Arguments:
  455. pScopeItem - SCOPEDATAITEM structure representing state of the node
  456. in the scope treeview.
  457. Return Value:
  458. S_OK - Struct filled in.
  459. E_xxxxxxxxxxx - Failure occurred.
  460. --*/
  461. {
  462. static CWsbStringPtr tmpString;
  463. WsbTraceIn( L"CSakData::GetDisplayInfo", L"cookie = <0x%p>, pScopeItem->mask = <0x%p>", pScopeItem->lParam, pScopeItem->mask );
  464. HRESULT hr = S_OK;
  465. try {
  466. CComPtr<ISakNode> pNode;
  467. CComPtr<ISakNodeProp> pNodeProp;
  468. WsbAffirmHr( GetBaseHsmFromCookie( pScopeItem->lParam, &pNode ) );
  469. WsbAffirmHr( pNode.QueryInterface( &pNodeProp ) );
  470. if( pScopeItem->mask & SDI_IMAGE ) {
  471. WsbAffirmHr( pNode->GetScopeOpenIcon( m_State, &pScopeItem->nImage ) );
  472. }
  473. if( SDI_STR & pScopeItem->mask ) {
  474. //
  475. // Go to the node and get the display name.
  476. // Following the example of the snapin framework, we
  477. // copy the name into a static string pointer and
  478. // return a pointer to this.
  479. //
  480. CWsbBstrPtr bstr;
  481. WsbAffirmHr( pNodeProp->get_DisplayName( &bstr ) );
  482. tmpString = bstr;
  483. pScopeItem->displayname = tmpString;
  484. }
  485. } WsbCatch( hr );
  486. WsbTraceOut( L"CSakData::GetDisplayInfo", L"hr = <%ls>, pScopeItem->displayname = <%ls>", WsbHrAsString( hr ), (SDI_STR & pScopeItem->mask) ? pScopeItem->displayname : L"N/A" );
  487. return( hr );
  488. }
  489. ///////////////////////////////////////////////////////////////////////
  490. // IExtendPropertySheet //
  491. ///////////////////////////////////////////////////////////////////////
  492. STDMETHODIMP
  493. CSakData::CreatePropertyPages(
  494. IN IPropertySheetCallback* pPropSheetCallback,
  495. IN RS_NOTIFY_HANDLE handle,
  496. IN IDataObject* pDataObject
  497. )
  498. /*++
  499. Routine Description:
  500. Console calls this when it is building a property sheet to
  501. show for a node. It is also called for the data object given
  502. to represent the snapin to the snapin manager, and should
  503. show the initial selection page at that point.
  504. Arguments:
  505. pPropSheetCallback - MMC interface to use to add page.
  506. handle - Handle to MMC to use to add the page.
  507. pDataObject - Data object refering to node.
  508. Return Value:
  509. S_OK - Pages added.
  510. E_xxxxxxxxxxx - Failure occurred.
  511. --*/
  512. {
  513. WsbTraceIn( L"CSakData::CreatePropertyPages", L"pPropSheetCallback = <0x%p>, handle = <0x%p>, pDataObject = <0x%p>", pPropSheetCallback, handle, pDataObject );
  514. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  515. HRESULT hr = S_OK;
  516. try {
  517. //
  518. // Confirm parameters.
  519. //
  520. WsbAffirmPointer( pPropSheetCallback );
  521. // WsbAffirmPointer( handle ); // Can be zero
  522. WsbAffirmPointer( pDataObject );
  523. //
  524. // If DataObject is CSakData, we need to present user
  525. // with page for machine. Do this by checking for
  526. // support of IComponentData interface.
  527. //
  528. CComPtr<IComponentData> pData;
  529. CComPtr<ISakWizard> pWizard;
  530. if( SUCCEEDED( RsQueryInterface( pDataObject, IComponentData, pData ) ) ) {
  531. //
  532. // Create the Hsm Choose property page.
  533. //
  534. HPROPSHEETPAGE hPage = 0; // Windows property page handle
  535. CChooseHsmDlg * pChooseDlg = new CChooseHsmDlg( );
  536. WsbAffirmPointer( pChooseDlg );
  537. pChooseDlg->m_hConsoleHandle = handle;
  538. pChooseDlg->m_pHsmName = &m_HsmName;
  539. pChooseDlg->m_pManageLocal = &m_ManageLocal;
  540. WsbAffirmHr( MMCPropPageCallback( &(pChooseDlg->m_psp) ) );
  541. hPage = CreatePropertySheetPage( &pChooseDlg->m_psp );
  542. WsbAffirmPointer( hPage );
  543. pPropSheetCallback->AddPage( hPage );
  544. } else if( SUCCEEDED( RsQueryInterface( pDataObject, ISakWizard, pWizard ) ) ) {
  545. WsbAffirmHr( pWizard->AddWizardPages( handle, pPropSheetCallback, this ) );
  546. } else {
  547. //
  548. // Get node out of the dataobject.
  549. //
  550. CComPtr<ISakNode> pNode;
  551. CComPtr<IEnumGUID> pEnumObjectId;
  552. CComPtr<IEnumUnknown> pEnumUnkNode;
  553. //
  554. // Get the base hsm pointer depending on the data object type
  555. //
  556. WsbAffirmHr( GetBaseHsmFromDataObject( pDataObject, &pNode, &pEnumObjectId, &pEnumUnkNode ) );
  557. //
  558. // Tell the node to add its property pages. pEnumObjectId will be NULL if
  559. // we are processing single-select.
  560. //
  561. WsbAffirmHr( pNode->AddPropertyPages( handle, pPropSheetCallback, pEnumObjectId, pEnumUnkNode ) );
  562. }
  563. } WsbCatch ( hr );
  564. WsbTraceOut( L"CSakData::CreatePropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) );
  565. return ( hr );
  566. }
  567. STDMETHODIMP
  568. CSakData::QueryPagesFor(
  569. IN IDataObject* pDataObject
  570. )
  571. /*++
  572. Routine Description:
  573. This method is called by MMC when it wants to find out if this node
  574. supports property pages. The answer is yes if:
  575. 1) The MMC context is either for the scope pane or result pane, AND
  576. 2) The node actually DOES have property pages.
  577. OR
  578. 1) The Data Object is acquired by the snapin manager.
  579. OR
  580. 1) It is a wizard data object
  581. Return S_OK if it DOES have pages, and S_FALSE if it does NOT have pages.
  582. Arguments:
  583. pDataObject - Data object refering to node.
  584. Return Value:
  585. S_OK - Pages exist.
  586. S_FALSE - No property pages.
  587. E_xxxxxxxxxxx - Failure occurred.
  588. --*/
  589. {
  590. WsbTraceIn( L"CSakData::QueryPagesFor", L"pDataObject = <0x%p>", pDataObject );
  591. HRESULT hr = S_FALSE;
  592. try {
  593. //
  594. // Confirm parameter.
  595. //
  596. WsbAffirmPointer( pDataObject );
  597. //
  598. // If DataObject is CSakData, we need to present user
  599. // with page for machine. Do this by checking for
  600. // support of IComponentData interface, which is only
  601. // supported by CSakData.
  602. //
  603. CComPtr<IComponentData> pData;
  604. CComPtr<ISakWizard> pWizard;
  605. if( SUCCEEDED( RsQueryInterface( pDataObject, IComponentData, pData ) ) ||
  606. SUCCEEDED( RsQueryInterface( pDataObject, ISakWizard, pWizard ) ) ) {
  607. hr = S_OK;
  608. } else {
  609. //
  610. // Get node out of the dataobject.
  611. //
  612. CComPtr<ISakNode> pBaseHsm;
  613. WsbAffirmHr( GetBaseHsmFromDataObject( pDataObject, &pBaseHsm ) );
  614. //
  615. // Ask the node if it has property pages.
  616. // Ensure we did not get an error.
  617. //
  618. hr = pBaseHsm->SupportsProperties( FALSE );
  619. WsbAffirmHr( hr );
  620. }
  621. } WsbCatch ( hr );
  622. WsbTraceOut( L"CSakData::QueryPagesFor", L"hr = <%ls>", WsbHrAsString( hr ) );
  623. return( hr );
  624. }
  625. ///////////////////////////////////////////////////////////////////////
  626. // IDataObject methods
  627. ///////////////////////////////////////////////////////////////////////
  628. STDMETHODIMP
  629. CSakData::GetDataHere(
  630. IN LPFORMATETC lpFormatetc,
  631. IN LPSTGMEDIUM lpMedium
  632. )
  633. /*++
  634. Routine Description:
  635. Retrieve information FROM the dataobject and put INTO lpMedium.
  636. Arguments:
  637. lpFormatetc - Format to retreive.
  638. lpMedium - Storage to put information into.
  639. Return Value:
  640. S_OK - Storage filled in.
  641. E_xxxxxxxxxxx - Failure occurred.
  642. --*/
  643. {
  644. WsbTraceIn( L"CSakData::GetDataHere", L"lpFormatetc->cfFormat = <%ls>", RsClipFormatAsString( lpFormatetc->cfFormat ) );
  645. HRESULT hr = DV_E_CLIPFORMAT;
  646. //
  647. // Based on the CLIPFORMAT write data to "lpMedium" in the correct format.
  648. //
  649. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  650. //
  651. // clip format is the Display Name
  652. //
  653. if( cf == m_cfDisplayName ) {
  654. hr = RetrieveDisplayName( lpMedium );
  655. }
  656. //
  657. // clip format is the Node Type
  658. //
  659. else if( cf == m_cfNodeType ) {
  660. hr = RetrieveNodeTypeData( lpMedium );
  661. }
  662. //
  663. // clip format is the Node Type
  664. //
  665. else if( cf == m_cfNodeTypeString ) {
  666. hr = RetrieveNodeTypeStringData( lpMedium );
  667. }
  668. //
  669. // clip format is the ClassId
  670. //
  671. else if( cf == m_cfClassId ) {
  672. hr = RetrieveClsid( lpMedium );
  673. }
  674. WsbTraceOut( L"CSakData::GetDataHere", L"hr = <%ls>", WsbHrAsString( hr ) );
  675. return( hr );
  676. }
  677. STDMETHODIMP
  678. CSakData::SetData(
  679. IN LPFORMATETC lpFormatetc,
  680. IN LPSTGMEDIUM /*lpMedium*/,
  681. IN BOOL /*fRelease*/
  682. )
  683. /*++
  684. Routine Description:
  685. Put data INTO a dataobject FROM the information in the lpMedium.
  686. We do not allow any data to be set.
  687. Arguments:
  688. lpFormatetc - Format to set.
  689. lpMedium - Storage to get information from.
  690. fRelease - Indicates who owns storage after call.
  691. Return Value:
  692. S_OK - Storage retreived.
  693. E_xxxxxxxxxxx - Failure occurred.
  694. --*/
  695. {
  696. WsbTraceIn( L"CSakData::SetData", L"lpFormatetc->cfFormat = <%ls>", RsClipFormatAsString( lpFormatetc->cfFormat ) );
  697. HRESULT hr = DV_E_CLIPFORMAT;
  698. WsbTraceOut( L"CSakData::SetData", L"hr = <%ls>", WsbHrAsString( hr ) );
  699. return( hr );
  700. }
  701. ///////////////////////////////////////////////////////////////////////
  702. // Note - CSakData does not implement these
  703. ///////////////////////////////////////////////////////////////////////
  704. STDMETHODIMP CSakData::GetData(LPFORMATETC lpFormatetcIn, LPSTGMEDIUM /*lpMedium*/)
  705. {
  706. WsbTraceIn( L"CSakData::GetData", L"lpFormatetc->cfFormat = <%ls>", RsClipFormatAsString( lpFormatetcIn->cfFormat ) );
  707. HRESULT hr = E_NOTIMPL;
  708. WsbTraceOut( L"CSakData::GetData", L"hr = <%ls>", WsbHrAsString( hr ) );
  709. return( hr );
  710. }
  711. STDMETHODIMP CSakData::EnumFormatEtc(DWORD /*dwDirection*/, LPENUMFORMATETC* /*ppEnumFormatEtc*/)
  712. {
  713. WsbTraceIn( L"CSakData::EnumFormatEtc", L"" );
  714. HRESULT hr = E_NOTIMPL;
  715. WsbTraceOut( L"CSakData::EnumFormatEtc", L"hr = <%ls>", WsbHrAsString( hr ) );
  716. return( hr );
  717. }
  718. HRESULT
  719. CSakData::RetrieveDisplayName(
  720. OUT LPSTGMEDIUM lpMedium
  721. )
  722. /*++
  723. Routine Description:
  724. Retrieve from a dataobject with the display named used in the scope pane
  725. Arguments:
  726. lpMedium - Storage to set information into.
  727. Return Value:
  728. S_OK - Storage set.
  729. E_xxxxxxxxxxx - Failure occurred.
  730. --*/
  731. {
  732. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  733. HRESULT hr = S_OK;
  734. try {
  735. //
  736. // Load the name the data object
  737. //
  738. CString fullTitle;
  739. if( m_ManageLocal ) {
  740. fullTitle.LoadString( IDS_MANAGE_LOCAL );
  741. } else if( !m_HsmName.IsEmpty( ) ) {
  742. AfxFormatString1( fullTitle, IDS_HSM_NAME_PREFIX, m_HsmName );
  743. } else {
  744. fullTitle = HSMADMIN_NO_HSM_NAME;
  745. }
  746. WsbAffirmHr( Retrieve( fullTitle, ((wcslen( fullTitle ) + 1) * sizeof(wchar_t)), lpMedium ) );
  747. } WsbCatch( hr );
  748. return( hr );
  749. }
  750. HRESULT
  751. CSakData::RetrieveNodeTypeData(
  752. LPSTGMEDIUM lpMedium
  753. )
  754. /*++
  755. Routine Description:
  756. Retrieve from a dataobject with the NodeType (GUID) data in it.
  757. Arguments:
  758. lpMedium - Storage to set information into.
  759. Return Value:
  760. S_OK - Storage set.
  761. E_xxxxxxxxxxx - Failure occurred.
  762. --*/
  763. {
  764. return Retrieve( (const void*)(&cGuidHsmCom), sizeof(GUID), lpMedium );
  765. }
  766. HRESULT
  767. CSakData::RetrieveClsid(
  768. LPSTGMEDIUM lpMedium
  769. )
  770. /*++
  771. Routine Description:
  772. Retrieve from a dataobject with the CLSID data in it.
  773. Arguments:
  774. lpMedium - Storage to set information into.
  775. Return Value:
  776. S_OK - Storage set.
  777. E_xxxxxxxxxxx - Failure occurred.
  778. --*/
  779. {
  780. GUID guid = GetCoClassID();
  781. return Retrieve( (const void*) &guid, sizeof(CLSID), lpMedium );
  782. }
  783. HRESULT
  784. CSakData::RetrieveNodeTypeStringData(
  785. LPSTGMEDIUM lpMedium
  786. )
  787. /*++
  788. Routine Description:
  789. Retrieve from a dataobject with the node type object in GUID string format
  790. Arguments:
  791. lpMedium - Storage to set information into.
  792. Return Value:
  793. S_OK - Storage set.
  794. E_xxxxxxxxxxx - Failure occurred.
  795. --*/
  796. {
  797. CWsbStringPtr guidString = cGuidHsmCom;
  798. return Retrieve( guidString, ((wcslen( guidString ) + 1 ) * sizeof(wchar_t)), lpMedium );
  799. }
  800. HRESULT
  801. CSakData::Retrieve(
  802. IN const void* pBuffer,
  803. IN DWORD len,
  804. OUT LPSTGMEDIUM lpMedium)
  805. /*++
  806. Routine Description:
  807. Retrieve FROM a dataobject INTO a lpMedium. The data object can be one of
  808. several types of data in it (nodetype, nodetype string, display name).
  809. This function moves data from pBuffer to the lpMedium->hGlobal
  810. Arguments:
  811. pBuffer - Buffer to copy contents out of.
  812. len - Length of buffer in bytes.
  813. lpMedium - Storage to set information into.
  814. Return Value:
  815. S_OK - Storage set.
  816. E_xxxxxxxxxxx - Failure occurred.
  817. --*/
  818. {
  819. HRESULT hr = S_OK;
  820. try {
  821. //
  822. // Check Parameters
  823. //
  824. WsbAffirmPointer( pBuffer );
  825. WsbAffirmPointer( lpMedium );
  826. WsbAffirm( lpMedium->tymed == TYMED_HGLOBAL, E_FAIL );
  827. //
  828. // Create the stream on the hGlobal passed in. When we write to the stream,
  829. // it simultaneously writes to the hGlobal the same information.
  830. //
  831. CComPtr<IStream> lpStream;
  832. WsbAffirmHr( CreateStreamOnHGlobal( lpMedium->hGlobal, FALSE, &lpStream ) );
  833. //
  834. // Write 'len' number of bytes from pBuffer into the stream. When we write
  835. // to the stream, it simultaneously writes to the global memory we
  836. // associated it with above.
  837. //
  838. ULONG numBytesWritten;
  839. WsbAffirmHr( lpStream->Write( pBuffer, len, &numBytesWritten ) );
  840. } WsbCatch( hr );
  841. return( hr );
  842. }
  843. ///////////////////////////////////////////////////////////////////////
  844. // ISakSnapAsk
  845. ///////////////////////////////////////////////////////////////////////
  846. STDMETHODIMP
  847. CSakData::GetHsmName(
  848. OUT OLECHAR ** pszName OPTIONAL
  849. )
  850. /*++
  851. Routine Description:
  852. Retrieves the IUnknown pointer of a UI node given the node type.
  853. This will return the first node found of this type.
  854. Arguments:
  855. pszName - Return of the name of the computer (can be NULL).
  856. Return Value:
  857. S_OK - Managing remote machine - computer name given.
  858. S_FALSE - Managing local machine - *pszName set to local name.
  859. --*/
  860. {
  861. WsbTraceIn( L"CSakData::GetHsmName", L"pszName = <0x%p>", pszName );
  862. HRESULT hr = S_OK;
  863. try {
  864. CWsbStringPtr name = m_HsmName;
  865. if( m_ManageLocal ) {
  866. hr = S_FALSE;
  867. }
  868. if( pszName ) {
  869. WsbAffirmHr( name.GiveTo( pszName ) );
  870. }
  871. } WsbCatch( hr );
  872. WsbTraceOut( L"CSakData::GetHsmName", L"hr = <%ls>, *pszName = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pszName ) );
  873. return( hr );
  874. }
  875. STDMETHODIMP
  876. CSakData::GetNodeOfType(
  877. IN REFGUID nodetype,
  878. OUT ISakNode** ppNode
  879. )
  880. /*++
  881. Routine Description:
  882. Retrieves the IUnknown pointer of a UI node given the node type.
  883. This will return the first node found of this type.
  884. Arguments:
  885. nodetype - The GUID node type to look for.
  886. ppUiNode - returned IUnknown interface.
  887. Return Value:
  888. S_OK - Found.
  889. S_FALSE - No Error, not found.
  890. E_UNEXPECTED - Some error occurred.
  891. --*/
  892. {
  893. WsbTraceIn( L"CSakData::GetNodeOfType", L"nodetype = <%ls>, ppUiNode = <0x%p>", WsbGuidAsString( nodetype ), ppNode );
  894. HRESULT hr = S_OK;
  895. try {
  896. //
  897. // Verify Params
  898. //
  899. WsbAffirmPointer( ppNode );
  900. *ppNode = NULL;
  901. //
  902. // Call on base node to search down the node tree.
  903. // Save result, verify no error
  904. //
  905. CComPtr<ISakNode> pBaseHsm;
  906. WsbAffirmHr( m_pRootNode.QueryInterface( &pBaseHsm ) );
  907. hr = pBaseHsm->FindNodeOfType( nodetype, ppNode );
  908. WsbAffirmHr( hr );
  909. } WsbCatch( hr );
  910. WsbTraceOut( L"CSakData::GetNodeOfType", L"hr = <%ls>, *ppNode = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppNode ) );
  911. return( hr );
  912. }
  913. STDMETHODIMP
  914. CSakData::GetHsmServer(
  915. OUT IHsmServer** ppHsmServer
  916. )
  917. /*++
  918. Routine Description:
  919. Retrieve an interface pointer to the HSM server the snapin
  920. is managing.
  921. Arguments:
  922. ppHsmServer - returned HSM server interface pointer.
  923. Return Value:
  924. S_OK - Return fine.
  925. E_UNEXPECTED - Some error occurred.
  926. --*/
  927. {
  928. WsbTraceIn( L"CSakData::GetHsmServer", L"ppHsmServer = <0x%p>", ppHsmServer );
  929. HRESULT hr = S_OK;
  930. try {
  931. //
  932. // Check Params
  933. //
  934. WsbAffirmPointer( ppHsmServer );
  935. *ppHsmServer = 0;
  936. WsbAffirmHrOk( AffirmServiceConnection( HSMCONN_TYPE_HSM ) );
  937. //
  938. // The connection should now be valid
  939. //
  940. WsbAffirmPointer( m_pHsmServer );
  941. //
  942. // Return the connection to the caller
  943. //
  944. m_pHsmServer.CopyTo( ppHsmServer );
  945. } WsbCatch( hr );
  946. WsbTraceOut( L"CSakData::GetHsmServer", L"hr = <%ls>, *ppHsmServer = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppHsmServer ) );
  947. return( hr );
  948. }
  949. STDMETHODIMP
  950. CSakData::GetRmsServer(
  951. OUT IRmsServer** ppRmsServer
  952. )
  953. /*++
  954. Routine Description:
  955. Retrieve an interface pointer to the RMS server the snapin
  956. is managing.
  957. Arguments:
  958. ppRmsServer - returned HSM server interface pointer.
  959. Return Value:
  960. S_OK - Return fine.
  961. E_UNEXPECTED - Some error occurred.
  962. --*/
  963. {
  964. WsbTraceIn( L"CSakData::GetRmsServer", L"ppRmsServer = <0x%p>", ppRmsServer );
  965. HRESULT hr = S_OK;
  966. try {
  967. //
  968. // Check Params
  969. //
  970. WsbAffirmPointer( ppRmsServer );
  971. *ppRmsServer = 0;
  972. WsbAffirmHrOk( AffirmServiceConnection( HSMCONN_TYPE_RMS ) );
  973. //
  974. // We should now be connected
  975. //
  976. WsbAffirmPointer( m_pRmsServer );
  977. m_pRmsServer.CopyTo( ppRmsServer );
  978. } WsbCatch ( hr );
  979. WsbTraceOut( L"CSakData::GetRmsServer", L"hr = <%ls>, *ppRmsServer = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppRmsServer ) );
  980. return( hr );
  981. }
  982. STDMETHODIMP
  983. CSakData::GetFsaServer(
  984. OUT IFsaServer** ppFsaServer
  985. )
  986. /*++
  987. Routine Description:
  988. Retrieve an interface pointer to the Fsa server the snapin
  989. is managing.
  990. Arguments:
  991. ppFsaServer - returned HSM server interface pointer.
  992. Return Value:
  993. S_OK - Return fine.
  994. E_UNEXPECTED - Some error occurred.
  995. --*/
  996. {
  997. WsbTraceIn( L"CSakData::GetFsaServer", L"ppFsaServer = <0x%p>", ppFsaServer );
  998. HRESULT hr = S_OK;
  999. try {
  1000. //
  1001. // Check Params
  1002. //
  1003. WsbAffirmPointer( ppFsaServer );
  1004. *ppFsaServer = 0;
  1005. WsbAffirmHrOk( AffirmServiceConnection( HSMCONN_TYPE_FSA ) );
  1006. WsbAffirmPointer( m_pFsaServer );
  1007. m_pFsaServer.CopyTo( ppFsaServer );
  1008. } WsbCatch ( hr );
  1009. WsbTraceOut( L"CSakData::GetFsaServer", L"hr = <%ls>, *ppFsaServer = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppFsaServer ) );
  1010. return( hr );
  1011. }
  1012. STDMETHODIMP
  1013. CSakData::ShowPropertySheet(
  1014. IN ISakNode* pNode,
  1015. IN IDataObject* pDataObject,
  1016. IN INT initialPage
  1017. )
  1018. /*++
  1019. Routine Description:
  1020. Create a property sheet for this node with the given page displayed
  1021. on top
  1022. Arguments:
  1023. pNode - node to show property sheet for
  1024. initialPage - 0 based index of initial page to show
  1025. Return Value:
  1026. S_OK - Return fine.
  1027. E_UNEXPECTED - Some error occurred.
  1028. --*/
  1029. {
  1030. WsbTraceIn( L"CSakData::ShowPropertySheet", L"pNode = <0x%p>, initialPage = <%d>", pNode, initialPage );
  1031. HRESULT hr = S_OK;
  1032. HRESULT hrInternal = S_OK;
  1033. try {
  1034. WsbAffirmPointer( pNode );
  1035. //
  1036. // Get the property sheet provider interface from IConsole
  1037. //
  1038. CComPtr <IPropertySheetProvider> pProvider;
  1039. WsbAffirmHr( m_pConsole.QueryInterface( &pProvider ) );
  1040. //
  1041. // Get the component data pointer
  1042. //
  1043. CComPtr <IComponent> pComponent;
  1044. pComponent = (IComponent *) this;
  1045. //
  1046. // If the sheet is already loaded, just show it
  1047. //
  1048. hrInternal = pProvider->FindPropertySheet( 0, pComponent, pDataObject );
  1049. if( hrInternal != S_OK ) {
  1050. //
  1051. // Not loaded, create it
  1052. //
  1053. CComPtr<ISakNodeProp> pNodeProp;
  1054. WsbAffirmHr( RsQueryInterface( pNode, ISakNodeProp, pNodeProp ) );
  1055. CWsbBstrPtr pszName;
  1056. WsbAffirmHr( pNodeProp->get_DisplayName( &pszName ) );
  1057. //
  1058. // If multiselect, append ellipses
  1059. //
  1060. if( IsDataObjectMultiSelect( pDataObject ) == S_OK ) {
  1061. pszName.Append( L", ...");
  1062. }
  1063. //
  1064. // Create the property sheet
  1065. //
  1066. WsbAffirmHr( pProvider->CreatePropertySheet (pszName, TRUE, 0, pDataObject, 0 ) );
  1067. //
  1068. // Tell the IComponentData interface to add pages
  1069. //
  1070. CComPtr <IUnknown> pUnkComponentData;
  1071. pUnkComponentData = (IUnknown *) (IComponentData*) this;
  1072. WsbAffirmHr( pProvider->AddPrimaryPages( pUnkComponentData, TRUE, 0, TRUE ) );
  1073. WsbAffirmHr( pProvider->Show( 0, initialPage ) );
  1074. }
  1075. } WsbCatch ( hr );
  1076. WsbTraceOut( L"CSakData::ShowPropertySheet", L"hr = <%ls>", WsbHrAsString( hr ) );
  1077. return( hr );
  1078. }
  1079. STDMETHODIMP
  1080. CSakData::RefreshNode(
  1081. IN ISakNode* pNode
  1082. )
  1083. /*++
  1084. Routine Description:
  1085. Refresh scope pane from this node on down
  1086. Arguments:
  1087. pNode - node to refresh
  1088. Return Value:
  1089. S_OK - Return fine.
  1090. E_UNEXPECTED - Some error occurred.
  1091. --*/
  1092. {
  1093. WsbTraceIn( L"CSakData::RefreshNode", L"pNode = <0x%p>", pNode );
  1094. HRESULT hr = S_OK;
  1095. try {
  1096. WsbAffirmPointer( m_pWnd->GetSafeHwnd( ) );
  1097. //
  1098. // Post it to handle later
  1099. //
  1100. MMC_COOKIE cookie;
  1101. WsbAffirmHr( GetCookieFromBaseHsm( pNode, &cookie ) );
  1102. m_pWnd->PostRefreshNode( cookie );
  1103. } WsbCatch ( hr );
  1104. WsbTraceOut( L"CSakData::RefreshNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  1105. return( hr );
  1106. }
  1107. HRESULT
  1108. CSakData::InternalRefreshNode(
  1109. IN MMC_COOKIE Cookie
  1110. )
  1111. /*++
  1112. Routine Description:
  1113. Refresh scope pane from this node on down.
  1114. Arguments:
  1115. pNode - node to refresh
  1116. Return Value:
  1117. S_OK - Return fine.
  1118. E_UNEXPECTED - Some error occurred.
  1119. --*/
  1120. {
  1121. WsbTraceIn( L"CSakData::InternalRefreshNode", L"Cookie = <0x%p>", Cookie );
  1122. HRESULT hr = S_OK;
  1123. try {
  1124. //
  1125. // Decode the node, make sure still exists
  1126. //
  1127. CComPtr<ISakNode> pNode;
  1128. WsbAffirmHr( GetBaseHsmFromCookie( Cookie, &pNode ) );
  1129. //
  1130. // Recursively update tree
  1131. //
  1132. WsbAffirmHr( RefreshNodeEx( pNode ) );
  1133. } WsbCatch ( hr );
  1134. WsbTraceOut( L"CSakData::InternalRefreshNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  1135. return( hr );
  1136. }
  1137. HRESULT
  1138. CSakData::RefreshNodeEx(
  1139. IN ISakNode* pNode
  1140. )
  1141. /*++
  1142. Routine Description:
  1143. Refresh scope pane from this node on down. This is recursively called.
  1144. Arguments:
  1145. pNode - node to refresh
  1146. Return Value:
  1147. S_OK - Return fine.
  1148. E_UNEXPECTED - Some error occurred.
  1149. --*/
  1150. {
  1151. WsbTraceIn( L"CSakData::RefreshNodeEx", L"pNode = <0x%p>", pNode );
  1152. HRESULT hr = S_OK;
  1153. try {
  1154. //
  1155. // Refresh this node
  1156. //
  1157. WsbAffirmHr( pNode->RefreshObject( ) );
  1158. //
  1159. // Refresh Icon and Text if container
  1160. //
  1161. if( S_OK == pNode->IsContainer( ) ) {
  1162. SCOPEDATAITEM sdi;
  1163. ZeroMemory( &sdi, sizeof sdi );
  1164. sdi.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  1165. WsbAffirmHr( pNode->GetScopeID( &sdi.ID ) );
  1166. sdi.displayname = MMC_CALLBACK;
  1167. WsbAffirmHr( pNode->GetScopeCloseIcon( m_State, &sdi.nImage ) );
  1168. WsbAffirmHr( pNode->GetScopeOpenIcon( m_State, &sdi.nOpenImage ) );
  1169. WsbAffirmHr( m_pNameSpace->SetItem( &sdi ) );
  1170. }
  1171. //
  1172. // If this is a container with dynamic children, then we
  1173. // want to just cause our contents to be recreated
  1174. //
  1175. if( S_OK == pNode->HasDynamicChildren( ) ) {
  1176. WsbAffirmHr( FreeEnumChildren( pNode ) );
  1177. WsbAffirmHr( pNode->InvalidateChildren() )
  1178. WsbAffirmHr( EnsureChildrenAreCreated( pNode ) );
  1179. HSCOPEITEM scopeID;
  1180. WsbAffirmHr( pNode->GetScopeID( &scopeID ) );
  1181. WsbAffirmHr( EnumScopePane( pNode, (HSCOPEITEM)( scopeID ) ) );
  1182. } else {
  1183. //
  1184. // Loop over the children and call
  1185. //
  1186. CComPtr<IEnumUnknown> pEnum;
  1187. if( ( pNode->EnumChildren( &pEnum ) ) == S_OK ) {
  1188. CComPtr<ISakNode> pChildNode;
  1189. CComPtr<IUnknown> pUnk;
  1190. while( S_OK == pEnum->Next( 1, &pUnk, NULL ) ) {
  1191. WsbAffirmHr( pUnk.QueryInterface( &pChildNode ) );
  1192. WsbAffirmHr( RefreshNodeEx( pChildNode ) );
  1193. //
  1194. // must release even for smart pointer because of re-assign.
  1195. //
  1196. pChildNode.Release( );
  1197. pUnk.Release( );
  1198. }
  1199. }
  1200. }
  1201. } WsbCatch ( hr );
  1202. WsbTraceOut( L"CSakData::RefreshNodeEx", L"hr = <%ls>", WsbHrAsString( hr ) );
  1203. return( hr );
  1204. }
  1205. HRESULT
  1206. CSakData::InternalUpdateAllViews(
  1207. IN MMC_COOKIE Cookie
  1208. )
  1209. /*++
  1210. Routine Description:
  1211. Calls MMC to update all views
  1212. Arguments:
  1213. pUnkNode - node to refresh
  1214. Return Value:
  1215. S_OK - Return fine.
  1216. E_UNEXPECTED - Some error occurred.
  1217. --*/
  1218. {
  1219. WsbTraceIn( L"CSakData::InternalUpdateAllViews", L"Cookie = <0x%p>", Cookie );
  1220. HRESULT hr = S_OK;
  1221. try {
  1222. //
  1223. // Decode the node
  1224. //
  1225. CComPtr <IDataObject> pDataObject;
  1226. WsbAffirmHr( GetDataObjectFromCookie( Cookie, &pDataObject ) );
  1227. //
  1228. // Call MMC
  1229. //
  1230. WsbAffirmHr( m_pConsole->UpdateAllViews( pDataObject, 0L, 0L ) );
  1231. } WsbCatch ( hr );
  1232. WsbTraceOut( L"CSakData::InternalUpdateAllViews", L"hr = <%ls>", WsbHrAsString( hr ) );
  1233. return( hr );
  1234. }
  1235. STDMETHODIMP
  1236. CSakData::UpdateAllViews (
  1237. IN ISakNode* pNode
  1238. )
  1239. /*++
  1240. Routine Description:
  1241. Calls MMC to update all views
  1242. Arguments:
  1243. pUnkNode - node to refresh
  1244. Return Value:
  1245. S_OK - Return fine.
  1246. E_UNEXPECTED - Some error occurred.
  1247. --*/
  1248. {
  1249. WsbTraceIn( L"CSakData::UpdateAllViews", L"pNode = <0x%p>", pNode );
  1250. HRESULT hr = S_OK;
  1251. try {
  1252. WsbAffirmPointer( m_pWnd->GetSafeHwnd( ) );
  1253. //
  1254. // Post it to handle later
  1255. //
  1256. MMC_COOKIE cookie;
  1257. WsbAffirmHr( GetCookieFromBaseHsm( pNode, &cookie ) );
  1258. m_pWnd->PostUpdateAllViews( cookie );
  1259. } WsbCatch ( hr );
  1260. WsbTraceOut( L"CSakData::UpdateAllViews", L"hr = <%ls>", WsbHrAsString( hr ) );
  1261. return( hr );
  1262. }
  1263. ///////////////////////////////////////////////////////////////////////
  1264. // Node type manipulation routines
  1265. ///////////////////////////////////////////////////////////////////////
  1266. HRESULT
  1267. CSakData::GetBaseHsmFromDataObject (
  1268. IN IDataObject *pDataObject,
  1269. OUT ISakNode **ppBaseHsm,
  1270. OUT IEnumGUID **ppEnumObjectId,
  1271. OUT IEnumUnknown **ppEnumUnkNode
  1272. )
  1273. /*++
  1274. Routine Description:
  1275. Retrieves the ISakNode for the object referenced by the
  1276. given data object.
  1277. Arguments:
  1278. pDataObject - identifies the node to be worked on.
  1279. ppBaseHSM - returned IBaseHSM interface.
  1280. ppEnumObjectId - returned interface to enumeration of object Ids. Can be NULL.
  1281. Return Value:
  1282. S_OK - Node found and returned.
  1283. E_UNEXPECTED - Some error occurred.
  1284. --*/
  1285. {
  1286. WsbTraceIn( L"CSakData::GetBaseHsmFromDataObject",
  1287. L"pDataObject = <0x%p>, ppBaseHsm = <0x%p>, ppEnumObjectId = <0x%p>",
  1288. pDataObject, ppBaseHsm, ppEnumObjectId );
  1289. HRESULT hr = S_OK;
  1290. try {
  1291. *ppBaseHsm = 0;
  1292. if ( ppEnumObjectId ) *ppEnumObjectId = NULL;
  1293. //
  1294. // Get the base hsm pointer depending on the data object type
  1295. //
  1296. if (IsDataObjectMs( pDataObject ) == S_OK) {
  1297. WsbAffirmHr( GetBaseHsmFromMsDataObject( pDataObject, ppBaseHsm, ppEnumObjectId, ppEnumUnkNode ) );
  1298. } else if (IsDataObjectOt( pDataObject ) == S_OK) {
  1299. WsbAffirmHr( GetBaseHsmFromOtDataObject( pDataObject, ppBaseHsm, ppEnumObjectId, ppEnumUnkNode ) );
  1300. } else { // Assume single select
  1301. WsbAffirmPointer( pDataObject );
  1302. WsbAffirmHr( RsQueryInterface2( pDataObject, ISakNode, ppBaseHsm ) );
  1303. }
  1304. } WsbCatch ( hr );
  1305. WsbTraceOut( L"CSakData::GetBaseHsmFromDataObject", L"hr = <%ls>, *ppBaseHsm = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppBaseHsm ) );
  1306. return ( hr );
  1307. }
  1308. HRESULT
  1309. CSakData::GetBaseHsmFromMsDataObject (
  1310. IN IDataObject *pDataObject,
  1311. OUT ISakNode **ppBaseHsm,
  1312. OUT IEnumGUID **ppEnumObjectId,
  1313. OUT IEnumUnknown **ppEnumUnkNode
  1314. )
  1315. /*++
  1316. Routine Description:
  1317. Retrieves the ISakNode for the object referenced by the
  1318. given data object.
  1319. Arguments:
  1320. pDataObject - identifies the node to be worked on.
  1321. ppBaseHSM - returned IBaseHSM interface.
  1322. Return Value:
  1323. S_OK - Node found and returned.
  1324. E_UNEXPECTED - Some error occurred.
  1325. --*/
  1326. {
  1327. WsbTraceIn( L"CSakData::GetBaseHsmFromMsDataObject", L"pDataObject = <0x%p>, ppBaseHsm = <0x%p>", pDataObject, ppBaseHsm );
  1328. HRESULT hr = S_OK;
  1329. try {
  1330. // We've got an MMC mutli-select data object. Get the first
  1331. // data object from it's array of data objects
  1332. FORMATETC fmt = {(CLIPFORMAT)m_cfMultiSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  1333. STGMEDIUM stgm = {TYMED_HGLOBAL, NULL};
  1334. WsbAffirmHr ( pDataObject->GetData( &fmt, &stgm ) == S_OK );
  1335. DWORD count;
  1336. memcpy( &count, stgm.hGlobal, sizeof (DWORD) );
  1337. if ( count > 0 ) {
  1338. //
  1339. // The following code is admittedly UGLY
  1340. // We have a data stream where we need to skip past the
  1341. // first DWORD count and grab an interface pointer.
  1342. // Other snapins code does it as follows:
  1343. // IDataObject * pDO;
  1344. // memcpy( &pDO, (DWORD *) stgm.hGlobal + 1, sizeof(IDataObject*) );
  1345. //
  1346. // However, since this code does an indirect cast (via memcpy)
  1347. // from DWORD to IDataObject*, and does not keep a true reference
  1348. // on the interface pointer, we will use a smart pointer.
  1349. // The (DWORD*) and +1 operation bump our pointer past the count.
  1350. // We then need to grab the next bytes in the buffer and use them
  1351. // as a IDataObject *.
  1352. //
  1353. CComPtr<IDataObject> pOtDataObject;
  1354. pOtDataObject = *( (IDataObject**)( (DWORD *) stgm.hGlobal + 1 ) );
  1355. //
  1356. // Note: When we can be extended we need to check to see if this is one of ours
  1357. //
  1358. WsbAffirmHr( GetBaseHsmFromOtDataObject ( pOtDataObject, ppBaseHsm, ppEnumObjectId, ppEnumUnkNode ) );
  1359. }
  1360. } WsbCatch ( hr );
  1361. WsbTraceOut( L"CSakData::GetBaseHsmFromMsDataObject", L"hr = <%ls>, *ppBaseHsm = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppBaseHsm ) );
  1362. return ( hr );
  1363. }
  1364. HRESULT
  1365. CSakData::GetBaseHsmFromOtDataObject (
  1366. IN IDataObject *pDataObject,
  1367. OUT ISakNode **ppBaseHsm,
  1368. OUT IEnumGUID **ppEnumObjectId,
  1369. OUT IEnumUnknown **ppEnumUnkNode
  1370. )
  1371. /*++
  1372. Routine Description:
  1373. Retrieves the ISakNode for the object referenced by the
  1374. given data object.
  1375. Arguments:
  1376. pDataObject - identifies the node to be worked on.
  1377. ppBaseHSM - returned IBaseHSM interface.
  1378. Return Value:
  1379. S_OK - Node found and returned.
  1380. E_UNEXPECTED - Some error occurred.
  1381. --*/
  1382. {
  1383. WsbTraceIn( L"CSakData::GetBaseHsmFromOtDataObject", L"pDataObject = <0x%p>, ppBaseHsm = <0x%p>", pDataObject, ppBaseHsm );
  1384. HRESULT hr = S_OK;
  1385. try {
  1386. // we've got an object types mutli-select data object. Get the first node selected
  1387. // from the data object.
  1388. CComPtr<IMsDataObject> pMsDataObject;
  1389. CComPtr<IUnknown> pUnkNode;
  1390. CComPtr<IEnumUnknown> pEnumUnkNode;
  1391. CComPtr<ISakNode> pNode;
  1392. WsbAffirmHr( RsQueryInterface( pDataObject, IMsDataObject, pMsDataObject ) );
  1393. WsbAffirmHr( pMsDataObject->GetNodeEnumerator( &pEnumUnkNode ) );
  1394. WsbAffirmHr( pEnumUnkNode->Next( 1, &pUnkNode, NULL ) );
  1395. WsbAffirmHr( pUnkNode.QueryInterface( &pNode ) );
  1396. WsbAffirmHr( pEnumUnkNode->Reset() ); // This enumeration is passed on, so we must reset it
  1397. if( ppBaseHsm ) {
  1398. pNode.CopyTo( ppBaseHsm );
  1399. }
  1400. if( ppEnumObjectId ) {
  1401. pMsDataObject->GetObjectIdEnumerator( ppEnumObjectId );
  1402. }
  1403. if( ppEnumUnkNode ) {
  1404. pEnumUnkNode.CopyTo( ppEnumUnkNode );
  1405. }
  1406. } WsbCatch ( hr );
  1407. WsbTraceOut( L"CSakData::GetBaseHsmFromOtDataObject", L"hr = <%ls>, *ppBaseHsm = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppBaseHsm ) );
  1408. return ( hr );
  1409. }
  1410. HRESULT
  1411. CSakData::GetDataObjectFromBaseHsm (
  1412. IN ISakNode * pBaseHsm,
  1413. OUT IDataObject* *ppDataObject
  1414. )
  1415. /*++
  1416. Routine Description:
  1417. Retrieves the dataobject for the object referenced by the
  1418. given IBaseHSM.
  1419. Arguments:
  1420. pBaseHsm - identifies the node to be worked on.
  1421. ppDataObject - returned IDataObject interface.
  1422. Return Value:
  1423. S_OK - Node found and returned.
  1424. E_UNEXPECTED - Some error occurred.
  1425. --*/
  1426. {
  1427. WsbTraceIn( L"CSakData::GetDataObjectFromBaseHsm", L"pBaseHsm = <0x%p>, ppDataObject = <0x%p>", pBaseHsm, ppDataObject );
  1428. HRESULT hr = S_OK;
  1429. try {
  1430. *ppDataObject = 0;
  1431. if( pBaseHsm ) {
  1432. WsbAffirmHr( RsQueryInterface2( pBaseHsm, IDataObject, ppDataObject ) );
  1433. }
  1434. } WsbCatch ( hr );
  1435. WsbTraceOut( L"CSakData::GetDataObjectFromBaseHsm", L"hr = <%ls>, *ppDataObject = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppDataObject ) );
  1436. return ( hr );
  1437. }
  1438. HRESULT
  1439. CSakData::GetBaseHsmFromCookie (
  1440. IN MMC_COOKIE Cookie,
  1441. OUT ISakNode ** ppBaseHsm
  1442. )
  1443. /*++
  1444. Routine Description:
  1445. Retrieves the ISakNode for the object referenced by the
  1446. given cookie.
  1447. Arguments:
  1448. Cookie - identifies the node to be worked on.
  1449. ppBaseHsm - returned ISakNode interface.
  1450. Return Value:
  1451. S_OK - Node found and returned.
  1452. E_UNEXPECTED - Some error occurred.
  1453. --*/
  1454. {
  1455. WsbTraceIn( L"CSakData::GetBaseHsmFromCookie", L"Cookie = <0x%p>, ppBaseHsm = <0x%p>", Cookie, ppBaseHsm );
  1456. HRESULT hr = S_OK;
  1457. try {
  1458. //
  1459. // Cookies are pointers to CSakDataNodePrivate classes, which
  1460. // contain smart pointers to their nodes.
  1461. // NULL cookie means root snapin.
  1462. //
  1463. if( ( 0 == Cookie ) || ( EXTENSION_RS_FOLDER_PARAM == Cookie ) ) {
  1464. WsbAffirmHr( GetCookieFromBaseHsm( m_pRootNode, &Cookie ) );
  1465. }
  1466. WsbAffirmPointer( Cookie );
  1467. CSakDataNodePrivate* pNodePriv = (CSakDataNodePrivate*)Cookie;
  1468. WsbAffirmHr( CSakDataNodePrivate::Verify( pNodePriv ) );
  1469. WsbAffirmHr( pNodePriv->m_pNode.QueryInterface( ppBaseHsm ) );
  1470. } WsbCatch( hr );
  1471. WsbTraceOut( L"CSakData::GetBaseHsmFromCookie", L"hr = <%ls>, *ppBaseHsm = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppBaseHsm ) );
  1472. return ( hr );
  1473. }
  1474. HRESULT
  1475. CSakData::GetCookieFromBaseHsm (
  1476. IN ISakNode * pNode,
  1477. OUT MMC_COOKIE * pCookie
  1478. )
  1479. /*++
  1480. Routine Description:
  1481. Retrieves the cookie for the object referenced by the
  1482. given IBaseHSM.
  1483. Arguments:
  1484. pBaseHsm - identifies the node to be worked on.
  1485. pCookie - returned Cookie.
  1486. Return Value:
  1487. S_OK - Node found and returned.
  1488. E_UNEXPECTED - Some error occurred.
  1489. --*/
  1490. {
  1491. WsbTraceIn( L"CSakData::GetCookieFromBaseHsm", L"pNode = <0x%p>, pCookie = <0x%p>", pNode, pCookie );
  1492. HRESULT hr = S_OK;
  1493. try {
  1494. WsbAffirmPointer( pNode );
  1495. //
  1496. // Ask the node for our private data back
  1497. //
  1498. RS_PRIVATE_DATA data;
  1499. WsbAffirmHr( pNode->GetPrivateData( &data ) );
  1500. if( !data ) {
  1501. CSakDataNodePrivate *pNodePriv = new CSakDataNodePrivate( pNode );
  1502. WsbAffirmAlloc( pNodePriv );
  1503. WsbAffirmHr( pNode->GetPrivateData( &data ) );
  1504. }
  1505. WsbAffirmHr( CSakDataNodePrivate::Verify( (CSakDataNodePrivate*)data ) );
  1506. *pCookie = (MMC_COOKIE)data;
  1507. } WsbCatch( hr );
  1508. WsbTraceOut( L"CSakData::GetCookieFromBaseHsm", L"hr = <%ls>, *pCookie = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)pCookie ) );
  1509. return( hr );
  1510. }
  1511. HRESULT
  1512. CSakData::GetDataObjectFromCookie (
  1513. IN MMC_COOKIE Cookie,
  1514. OUT IDataObject **ppDataObject
  1515. )
  1516. /*++
  1517. Routine Description:
  1518. Retrieves the IDataObject for the object referenced by the
  1519. given cookie.
  1520. Arguments:
  1521. Cookie - identifies the node to be worked on.
  1522. ppDataObject - returned IDataObject interface.
  1523. Return Value:
  1524. S_OK - Node found and returned.
  1525. E_UNEXPECTED - Some error occurred.
  1526. --*/
  1527. {
  1528. WsbTraceIn( L"CSakData::GetDataObjectFromCookie", L"Cookie = <0x%p>, ppDataObject = <0x%p>", Cookie, ppDataObject );
  1529. HRESULT hr = S_OK;
  1530. try {
  1531. //
  1532. // Check Params
  1533. //
  1534. WsbAffirmPointer( ppDataObject );
  1535. //
  1536. // Use GetBaseHsmFromCookie to resolve to node object
  1537. //
  1538. CComPtr<ISakNode> pNode;
  1539. WsbAffirmHr( GetBaseHsmFromCookie( Cookie, &pNode ) );
  1540. WsbAffirmPointer( pNode );
  1541. WsbAffirmHr( RsQueryInterface2( pNode, IDataObject, ppDataObject ) );
  1542. } WsbCatch( hr );
  1543. WsbTraceOut( L"CSakData::GetDataObjectFromCookie", L"hr = <%ls>, *ppDataObject = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppDataObject ) );
  1544. return( hr );
  1545. }
  1546. HRESULT
  1547. CSakData::SetContextType(
  1548. IDataObject* pDataObject,
  1549. DATA_OBJECT_TYPES type
  1550. )
  1551. /*++
  1552. Routine Description:
  1553. Set the MMC context type in the data object for later retrieval by any method
  1554. which receives this dataobject (CCT_SNAPIN_MANAGER, CCT_SCOPE, CCT_RESULT, etc).
  1555. Arguments:
  1556. pDataObject - identifies the node to be worked on.
  1557. Return Value:
  1558. S_OK - Node found and returned.
  1559. E_UNEXPECTED - Some error occurred.
  1560. --*/
  1561. {
  1562. WsbTraceIn( L"CSakData::SetContextType", L"pDataObject = <0x%p>, type = <%d>", pDataObject, type );
  1563. // Prepare structures to store an HGLOBAL from the dataobject.
  1564. // Allocate memory for the stream which will contain the SakSnap GUID.
  1565. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  1566. FORMATETC formatetc = { (CLIPFORMAT)CSakNode::m_cfInternal, NULL,
  1567. DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  1568. HRESULT hr = S_OK;
  1569. try {
  1570. // Allocate space in which to place the data
  1571. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, sizeof(INTERNAL));
  1572. WsbAffirm( stgmedium.hGlobal != NULL, E_POINTER );
  1573. // Put the data into the global memory. This is what will eventually be
  1574. // copied down into the member variables of the dataobject, itself.
  1575. memcpy(&stgmedium.hGlobal, &type, sizeof(type));
  1576. // Copy this data into the dataobject.
  1577. WsbAffirmHr( pDataObject->SetData(&formatetc, &stgmedium, FALSE ));
  1578. } WsbCatch( hr );
  1579. WsbTraceOut( L"CSakData::SetContextType", L"hr = <%ls>", WsbHrAsString( hr ) );
  1580. return( hr );
  1581. }
  1582. HRESULT
  1583. CSakData::InitializeRootNode(
  1584. void
  1585. )
  1586. /*++
  1587. Routine Description:
  1588. The initialization of the root node is separate in order to
  1589. allow reconnect multiple times (as needed). This is the
  1590. implementation of initialization.
  1591. Arguments:
  1592. pDataObject - identifies the node to be worked on.
  1593. Return Value:
  1594. S_OK - Node found and returned.
  1595. E_UNEXPECTED - Some error occurred.
  1596. --*/
  1597. {
  1598. WsbTraceIn( L"CSakData::InitializeRootNode", L"" );
  1599. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  1600. HRESULT hr = S_OK;
  1601. try {
  1602. // Make sure the computer name is set in CSakdata if we are managing the local
  1603. // Hsm
  1604. if( m_ManageLocal ) {
  1605. WCHAR computerName[ MAX_COMPUTERNAME_LENGTH + 1 ];
  1606. DWORD dw = MAX_COMPUTERNAME_LENGTH + 1;
  1607. WsbAffirmStatus(GetComputerName( computerName, &dw ));
  1608. m_HsmName = computerName;
  1609. }
  1610. //
  1611. // Initialize the static root node (no recursion. Descendants are NOT created here)
  1612. //
  1613. WsbAffirmPointer( m_pRootNode );
  1614. WsbAffirmHr( m_pRootNode->InitNode( (ISakSnapAsk*)this, NULL, NULL ) );
  1615. //
  1616. // Set the Display Name in the object
  1617. //
  1618. CString fullTitle;
  1619. if( IsPrimaryImpl( ) ) {
  1620. //
  1621. // We're standalone, so show the targeted server
  1622. //
  1623. if( m_ManageLocal ) {
  1624. fullTitle.LoadString( IDS_MANAGE_LOCAL );
  1625. } else if( !m_HsmName.IsEmpty( ) ) {
  1626. AfxFormatString1( fullTitle, IDS_HSM_NAME_PREFIX, m_HsmName );
  1627. } else {
  1628. fullTitle = HSMADMIN_NO_HSM_NAME;
  1629. }
  1630. } else {
  1631. //
  1632. // We're an extension, so just show app name
  1633. //
  1634. fullTitle.LoadString( AFX_IDS_APP_TITLE );
  1635. }
  1636. // Put the displayname
  1637. CComPtr <ISakNodeProp> pRootNodeProp;
  1638. WsbAffirmHr( RsQueryInterface( m_pRootNode, ISakNodeProp, pRootNodeProp ) );
  1639. WsbAffirmHr( pRootNodeProp->put_DisplayName( (LPWSTR)(LPCWSTR) fullTitle ) );
  1640. WsbAffirmHr( m_pRootNode->RefreshObject() );
  1641. } WsbCatch( hr );
  1642. WsbTraceOut( L"CSakData::InitializeRootNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  1643. return( hr );
  1644. }
  1645. HRESULT
  1646. CSakData::AffirmServiceConnection(
  1647. INT ConnType
  1648. )
  1649. /*++
  1650. Routine Description:
  1651. Validates that the connection to the requested HSM service is still valid. If not,
  1652. attempts to reconnect to the service.
  1653. Arguments:
  1654. ConnType - type of service connection being checked
  1655. Return Value:
  1656. S_OK - Node created and bound to server.
  1657. S_FALSE - Service has not yet been setup or stopped.
  1658. E_UNEXPECTED - Some error occurred.
  1659. --*/
  1660. {
  1661. WsbTraceIn( L"CSakData::AffirmServiceConnection", L"" );
  1662. HRESULT hr = S_OK;
  1663. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  1664. BOOL previouslyConnected = ( GetState() == S_OK );
  1665. BOOL firstTime = m_FirstTime;
  1666. CString szMessage;
  1667. CWsbStringPtr computerName;
  1668. try {
  1669. //
  1670. // Handle this first so reentrancy is not a problem
  1671. //
  1672. if( m_FirstTime ) {
  1673. m_FirstTime = FALSE;
  1674. }
  1675. WsbAffirmHr( WsbGetComputerName( computerName ) );
  1676. //
  1677. // See if snapin is supposed to be disabled. If so, then
  1678. // don't do anything.
  1679. //
  1680. if( m_Disabled ) {
  1681. WsbThrow( RS_E_DISABLED );
  1682. }
  1683. //
  1684. // We want to avoid starting the services if they are stopped.
  1685. // So, check the service state before continuing.
  1686. //
  1687. HRESULT hrCheck;
  1688. {
  1689. //
  1690. // Potentially a long operation - show wait cursor if possible
  1691. //
  1692. CWaitCursor waitCursor;
  1693. hrCheck = WsbCheckService( m_HsmName, APPID_RemoteStorageEngine );
  1694. }
  1695. if( S_FALSE == hrCheck ) {
  1696. //
  1697. // Engine service is not running
  1698. //
  1699. WsbThrow( S_FALSE );
  1700. } else if( ( HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) == hrCheck ) ||
  1701. ( E_ACCESSDENIED == hrCheck ) ) {
  1702. //
  1703. // Engine is not installed (or at least we can't check
  1704. // because local privs don't allow, but may on a different
  1705. // server)
  1706. //
  1707. // If we are set to "Manage Local" then we will provide the
  1708. // opportunity to look at a different machine
  1709. //
  1710. if( firstTime && m_ManageLocal ) {
  1711. //
  1712. // If we get back "File not found" then the engine was
  1713. // not installed, so we need to ask for a different machine
  1714. // to administer
  1715. //
  1716. hrCheck = RetargetSnapin( );
  1717. WsbAffirmHrOk( hrCheck );
  1718. } else {
  1719. //
  1720. // we want to return the true error if access is denied
  1721. // and can't retarget to another machine without same error
  1722. //
  1723. if( E_ACCESSDENIED == hrCheck ) {
  1724. WsbThrow( hrCheck );
  1725. } else {
  1726. WsbThrow( RS_E_NOT_INSTALLED );
  1727. }
  1728. }
  1729. }
  1730. //
  1731. // Is the current connection still valid?
  1732. // Test the connection. If it's OK, return it. If not,
  1733. // re-establish the connection.
  1734. //
  1735. HRESULT hrConnected = VerifyConnection( ConnType );
  1736. WsbAffirmHr( hrConnected );
  1737. //
  1738. // If it looks like we're not connected, then connect
  1739. //
  1740. if( S_FALSE == hrConnected ) {
  1741. //
  1742. // Connect to engine first and see if we are setup.
  1743. // Don't process any further if not setup.
  1744. //
  1745. WsbAffirmHr( RawConnect( HSMCONN_TYPE_HSM ) );
  1746. HRESULT hrSetup = RsIsRemoteStorageSetupEx( m_pHsmServer );
  1747. WsbAffirmHr( hrSetup );
  1748. if( S_FALSE == hrSetup ) {
  1749. //
  1750. // Not setup - see if we are local
  1751. //
  1752. if( computerName.IsEqual( m_HsmName ) && firstTime ) {
  1753. hrSetup = RunSetupWizard( m_pHsmServer );
  1754. }
  1755. //
  1756. // By this point, if hrSetup is not S_OK,
  1757. // we are not configured.
  1758. //
  1759. if( S_OK != hrSetup ) {
  1760. WsbThrow( RS_E_NOT_CONFIGURED );
  1761. }
  1762. }
  1763. //
  1764. // At this point we should be setup and ready to connect
  1765. //
  1766. WsbAffirmHrOk( RawConnect( ConnType ) );
  1767. }
  1768. //
  1769. // We're connected
  1770. //
  1771. SetState( TRUE );
  1772. } WsbCatchAndDo( hr,
  1773. //
  1774. // Need to decide if we should ignore the error or not.
  1775. // Note that even if the error is ignored here, its
  1776. // returned still to the caller
  1777. //
  1778. BOOL ignoreError = FALSE;
  1779. //
  1780. // if RMS error of not ready, and we received this last time RMS
  1781. // connection was made, ignore the error.
  1782. //
  1783. if( HSMCONN_TYPE_RMS == ConnType ) {
  1784. HRESULT hrPrevConnect = m_HrRmsConnect;
  1785. m_HrRmsConnect = hr;
  1786. if( ( RsIsRmsErrorNotReady( hr ) == S_OK ) &&
  1787. ( RsIsRmsErrorNotReady( hrPrevConnect ) == S_OK ) ) {
  1788. ignoreError = TRUE;
  1789. }
  1790. }
  1791. if( !ignoreError ) {
  1792. //
  1793. // Set up state conditions before anything else
  1794. //
  1795. ClearConnections( );
  1796. SetState( FALSE );
  1797. //
  1798. // If we were previously connected or this is the first connect,
  1799. // report the error
  1800. //
  1801. if( previouslyConnected || firstTime ) {
  1802. //
  1803. // Temporarily set to disable so we don't recurse when dialog is up
  1804. //
  1805. BOOL disabled = m_Disabled;
  1806. m_Disabled = TRUE;
  1807. CString msg;
  1808. switch( hr ) {
  1809. case S_OK:
  1810. //
  1811. // Connected OK - no error
  1812. //
  1813. break;
  1814. case RS_E_DISABLED:
  1815. //
  1816. // Disabled - just ignore
  1817. //
  1818. break;
  1819. case S_FALSE:
  1820. //
  1821. // Service not running
  1822. //
  1823. AfxFormatString1( msg, IDS_ERR_SERVICE_NOT_RUNNING, m_HsmName );
  1824. AfxMessageBox( msg, RS_MB_ERROR );
  1825. break;
  1826. case RS_E_NOT_CONFIGURED:
  1827. //
  1828. // If remote, let user know it needs to be set up locally
  1829. //
  1830. if( ! computerName.IsEqual( m_HsmName ) ) {
  1831. AfxFormatString1( msg, IDS_ERR_SERVICE_NOT_SETUP_REMOTE, m_HsmName );
  1832. AfxMessageBox( msg, RS_MB_ERROR );
  1833. }
  1834. break;
  1835. case RS_E_NOT_INSTALLED:
  1836. //
  1837. // Give indication of where this can be setup
  1838. //
  1839. AfxFormatString1( msg, IDS_ERR_SERVICE_NOT_INSTALLED, m_HsmName );
  1840. AfxMessageBox( msg, RS_MB_ERROR );
  1841. break;
  1842. case RS_E_CANCELLED:
  1843. //
  1844. // User cancelled - there's no error to notify
  1845. //
  1846. break;
  1847. default:
  1848. //
  1849. // Report the error
  1850. //
  1851. AfxFormatString1( msg, IDS_ERR_SERVICE_NOT_CONNECTING, m_HsmName );
  1852. AfxMessageBox( msg, RS_MB_ERROR );
  1853. if( HSMCONN_TYPE_RMS == ConnType ) {
  1854. disabled = TRUE;
  1855. }
  1856. }
  1857. //
  1858. // Restore disabledness
  1859. //
  1860. m_Disabled = disabled;
  1861. }
  1862. }
  1863. );
  1864. //
  1865. // Need to track RMS connections separately
  1866. //
  1867. if( HSMCONN_TYPE_RMS == ConnType ) {
  1868. m_HrRmsConnect = hr;
  1869. }
  1870. //
  1871. // If our state of "Connection" changed, cause a refresh
  1872. //
  1873. BOOL connected = ( GetState() == S_OK );
  1874. if( ( connected != previouslyConnected ) && ( ! firstTime ) ) {
  1875. RefreshNode( m_pRootNode );
  1876. }
  1877. WsbTraceOut( L"CSakData::AffirmServiceConnection", L"hr = <%ls>", WsbHrAsString( hr ) );
  1878. return( hr );
  1879. }
  1880. HRESULT
  1881. CSakData::VerifyConnection(
  1882. INT ConnType
  1883. )
  1884. /*++
  1885. Routine Description:
  1886. Verify whether the indicated connection is still good or not.
  1887. Does not attempt to reconnect.
  1888. Arguments:
  1889. ConnType - type of service connection being checked
  1890. Return Value:
  1891. S_OK - Connected.
  1892. S_FALSE - Not connected.
  1893. E_* - Error occurred while checking
  1894. --*/
  1895. {
  1896. WsbTraceIn( L"CSakData::VerifyConnection", L"" );
  1897. HRESULT hr = S_FALSE;
  1898. try {
  1899. switch( ConnType ) {
  1900. case HSMCONN_TYPE_HSM:
  1901. if( m_pHsmServer ) {
  1902. GUID id;
  1903. WsbAffirmHr( m_pHsmServer->GetID( &id ) );
  1904. hr = S_OK;
  1905. }
  1906. break;
  1907. case HSMCONN_TYPE_RMS:
  1908. if( m_pRmsServer ) {
  1909. WsbAffirmHr( m_pRmsServer->IsReady( ) );
  1910. hr = S_OK;
  1911. }
  1912. break;
  1913. case HSMCONN_TYPE_FSA:
  1914. if( m_pFsaServer ) {
  1915. CWsbStringPtr pszName;
  1916. WsbAffirmHr( m_pFsaServer->GetName( &pszName, 0 ) );
  1917. hr = S_OK;
  1918. }
  1919. break;
  1920. }
  1921. } WsbCatchAndDo( hr,
  1922. ClearConnections( );
  1923. );
  1924. WsbTraceOut( L"CSakData::VerifyConnection", L"hr = <%ls>", WsbHrAsString( hr ) );
  1925. return( hr );
  1926. }
  1927. HRESULT
  1928. CSakData::RawConnect(
  1929. INT ConnType
  1930. )
  1931. /*++
  1932. Routine Description:
  1933. Do low level connection to service specified
  1934. Arguments:
  1935. ConnType - type of service connection
  1936. Return Value:
  1937. S_OK - Connected.
  1938. E_* - Error occurred while checking
  1939. --*/
  1940. {
  1941. WsbTraceIn( L"CSakData::RawConnect", L"" );
  1942. HRESULT hr = S_OK;
  1943. try {
  1944. //
  1945. // Potentially a long operation - show wait cursor if possible
  1946. //
  1947. CWaitCursor waitCursor;
  1948. switch( ConnType ) {
  1949. case HSMCONN_TYPE_HSM:
  1950. if( ! m_pHsmServer ) {
  1951. WsbAffirmHr( HsmConnectFromName( HSMCONN_TYPE_HSM, m_HsmName, IID_IHsmServer, (void**)&m_pHsmServer ) );
  1952. }
  1953. break;
  1954. case HSMCONN_TYPE_RMS:
  1955. if( ! m_pRmsServer ) {
  1956. CComPtr<IHsmServer> pHsm;
  1957. WsbAffirmHr( HsmConnectFromName( HSMCONN_TYPE_HSM, m_HsmName, IID_IHsmServer, (void**)&pHsm ) );
  1958. WsbAffirmPointer(pHsm);
  1959. WsbAffirmHr(pHsm->GetHsmMediaMgr(&m_pRmsServer));
  1960. WsbAffirmHrOk( VerifyConnection( HSMCONN_TYPE_RMS ) );
  1961. }
  1962. break;
  1963. case HSMCONN_TYPE_FSA:
  1964. if( ! m_pFsaServer ) {
  1965. CWsbStringPtr LogicalName( m_HsmName );
  1966. //
  1967. // FSA confuses things by having a
  1968. // extra level for the "type"
  1969. //
  1970. LogicalName.Append( "\\NTFS" );
  1971. WsbAffirmHr( HsmConnectFromName( HSMCONN_TYPE_FSA, LogicalName, IID_IFsaServer, (void**)&m_pFsaServer ) );
  1972. }
  1973. break;
  1974. }
  1975. } WsbCatch( hr );
  1976. WsbTraceOut( L"CSakData::RawConnect", L"hr = <%ls>", WsbHrAsString( hr ) );
  1977. return( hr );
  1978. }
  1979. HRESULT
  1980. CSakData::ClearConnections(
  1981. )
  1982. /*++
  1983. Routine Description:
  1984. Clear cached connections
  1985. Arguments:
  1986. none.
  1987. Return Value:
  1988. S_OK - Cleared.
  1989. E_* - Error occurred while checking
  1990. --*/
  1991. {
  1992. WsbTraceIn( L"CSakData::ClearConnections", L"" );
  1993. HRESULT hr = S_OK;
  1994. try {
  1995. m_pHsmServer = 0;
  1996. m_pRmsServer = 0;
  1997. m_pFsaServer = 0;
  1998. } WsbCatch( hr );
  1999. WsbTraceOut( L"CSakData::ClearConnections", L"hr = <%ls>", WsbHrAsString( hr ) );
  2000. return( hr );
  2001. }
  2002. HRESULT
  2003. CSakData::RunSetupWizard(
  2004. IHsmServer * pServer
  2005. )
  2006. /*++
  2007. Routine Description:
  2008. Run the setup wizard
  2009. Handles disabling / enabling as needed
  2010. Arguments:
  2011. pServer - interface to engine
  2012. Return Value:
  2013. S_OK - Setup Correctly.
  2014. S_FALSE - Canceled
  2015. E_* - Error occurred while setting up
  2016. --*/
  2017. {
  2018. WsbTraceIn( L"CSakData::RunSetupWizard", L"" );
  2019. HRESULT hr = S_OK;
  2020. try {
  2021. //
  2022. // use wizard to create manage volume
  2023. //
  2024. CComObject<CQuickStartWizard>* pWizard = new CComObject<CQuickStartWizard>;
  2025. WsbAffirmAlloc( pWizard );
  2026. CComPtr<ISakWizard> pSakWizard = (ISakWizard*)pWizard;
  2027. WsbAffirmHr( CreateWizard( pSakWizard ) );
  2028. //
  2029. // RS_E_CANCELED indicates canceled, and FAILEd indicates error.
  2030. // If so, then throw "Not set up"
  2031. //
  2032. if( S_OK != pWizard->m_HrFinish ) {
  2033. WsbThrow( S_FALSE );
  2034. }
  2035. WsbAffirmHrOk( RsIsRemoteStorageSetupEx( pServer ) );
  2036. } WsbCatch( hr );
  2037. WsbTraceOut( L"CSakData::RunSetupWizard", L"hr = <%ls>", WsbHrAsString( hr ) );
  2038. return( hr );
  2039. }
  2040. HRESULT
  2041. CSakData::RetargetSnapin(
  2042. )
  2043. /*++
  2044. Routine Description:
  2045. Run the small choose server dialog
  2046. Arguments:
  2047. none.
  2048. Return Value:
  2049. S_OK - Setup Correctly.
  2050. S_FALSE - Canceled
  2051. E_* - Error occurred while changing
  2052. --*/
  2053. {
  2054. WsbTraceIn( L"CSakData::RetargetSnapin", L"" );
  2055. HRESULT hr = S_OK;
  2056. try {
  2057. if( IsPrimaryImpl( ) ) {
  2058. //
  2059. // Bring up dialog
  2060. //
  2061. CChooseHsmQuickDlg dlg;
  2062. dlg.m_pHsmName = &m_HsmName;
  2063. if( IDOK == dlg.DoModal( ) ) {
  2064. m_PersistManageLocal = FALSE;
  2065. m_ManageLocal = FALSE;
  2066. //
  2067. // We want the name shown to be accurate, regardless
  2068. // of whether they targetted to a valid machine.
  2069. // So, re-initialize the root node before going
  2070. // any further.
  2071. //
  2072. WsbAffirmHr( InitializeRootNode( ) );
  2073. //
  2074. // Make sure we hook up OK. If not, just disable
  2075. // Note that since we set "First" flag at beginning
  2076. // of the block, this will not endlessly recurse
  2077. //
  2078. hr = AffirmServiceConnection( HSMCONN_TYPE_HSM );
  2079. if( FAILED( hr ) ) {
  2080. Disable( );
  2081. WsbThrow( hr );
  2082. }
  2083. } else {
  2084. //
  2085. // They canceled out, so just disable
  2086. //
  2087. Disable( );
  2088. WsbThrow( RS_E_CANCELLED );
  2089. }
  2090. } else {
  2091. //
  2092. // As extension we don't allow retargeting, so we just disable
  2093. //
  2094. Disable( );
  2095. WsbThrow( S_FALSE );
  2096. }
  2097. } WsbCatch( hr );
  2098. WsbTraceOut( L"CSakData::RetargetSnapin", L"hr = <%ls>", WsbHrAsString( hr ) );
  2099. return( hr );
  2100. }
  2101. HRESULT
  2102. CSakData::CreateChildNodes(
  2103. ISakNode* pParentNode
  2104. )
  2105. /*++
  2106. Routine Description:
  2107. Create and initialize the children of an existing COM parent. Currently, this
  2108. initialization is being done from HSM object.
  2109. Arguments:
  2110. pNode - The node to create the children of.
  2111. Return Value:
  2112. S_OK - Children created.
  2113. E_UNEXPECTED - Some error occurred.
  2114. --*/
  2115. {
  2116. WsbTraceIn( L"CSakData::CreateChildNodes", L"pParentNode = <0x%p>", pParentNode );
  2117. HRESULT hr = S_OK;
  2118. try {
  2119. //
  2120. // Initialize the child nodes - first delete existing children from UI,
  2121. // then initialize new children into UI. No recursion. Decendents are
  2122. // NOT created here.
  2123. //
  2124. CComPtr<ISakNode> pNode;
  2125. WsbAffirmHr( RsQueryInterface( pParentNode, ISakNode, pNode ) );
  2126. WsbAffirmHr( pNode->DeleteAllChildren( ) );
  2127. WsbAffirmHr( pNode->CreateChildren( ) );
  2128. } WsbCatch( hr );
  2129. WsbTraceOut( L"CSakData::CreateChildNodes", L"hr = <%ls>", WsbHrAsString( hr ) );
  2130. return( hr );
  2131. }
  2132. HRESULT
  2133. CSakData::FreeEnumChildren(
  2134. ISakNode* pParentNode
  2135. )
  2136. /*++
  2137. Routine Description:
  2138. Recursively (bottom-up) free the SCOPEDATAITEM children of the pParent
  2139. enumerated node
  2140. Arguments:
  2141. pParentNode - identifies the node to be worked on.
  2142. Return Value:
  2143. S_OK - Children freed successfully.
  2144. E_UNEXPECTED - Some error occurred.
  2145. --*/
  2146. {
  2147. WsbTraceIn( L"CSakData::FreeEnumChildren", L"pParentNode = <0x%p>", pParentNode );
  2148. HRESULT hr = S_OK;
  2149. try {
  2150. HSCOPEITEM scopeIDParent;
  2151. pParentNode->GetScopeID( &scopeIDParent );
  2152. WsbAffirm( scopeIDParent > 0, E_FAIL )
  2153. WsbAffirmHr( m_pNameSpace->DeleteItem( scopeIDParent, FALSE ) );
  2154. pParentNode->SetEnumState( FALSE );
  2155. } WsbCatch (hr);
  2156. WsbTraceOut( L"CSakData::FreeEnumChildren", L"hr = <%ls>", WsbHrAsString( hr ) );
  2157. return( hr );
  2158. }
  2159. /////////////////////////////////////////////////////////////////////////////////////////
  2160. //
  2161. // IPersistStream implementation
  2162. //
  2163. STDMETHODIMP
  2164. CSakData::Save(
  2165. IStream *pStm,
  2166. BOOL fClearDirty
  2167. )
  2168. /*++
  2169. Routine Description:
  2170. Save the information we need to reconstruct the root node in the
  2171. supplied stream.
  2172. Arguments:
  2173. pStm I: Console-supplied stream
  2174. fClearDirty I: The console tells us to clear our dirty flag
  2175. Return Value:
  2176. S_OK - Saved successfully.
  2177. E_* - Some error occurred.
  2178. --*/
  2179. {
  2180. WsbTraceIn( L"CSakData::Save", L"pStm = <0x%p>, fClearDirty", pStm, WsbBoolAsString( fClearDirty ) );
  2181. HRESULT hr = S_OK;
  2182. try {
  2183. ULONG version = HSMADMIN_CURRENT_VERSION;
  2184. WsbAffirmHr( WsbSaveToStream( pStm, version ) );
  2185. if( m_PersistManageLocal ) {
  2186. WsbAffirmHr( WsbSaveToStream( pStm, m_ManageLocal ) );
  2187. CWsbStringPtr pHsmName( m_HsmName );
  2188. WsbAffirmHr( WsbSaveToStream( pStm, pHsmName ) );
  2189. } else {
  2190. WsbAffirmHr( WsbSaveToStream( pStm, (BOOL)TRUE ) );
  2191. CWsbStringPtr pHsmName( "" );
  2192. WsbAffirmHr( WsbSaveToStream( pStm, pHsmName ) );
  2193. }
  2194. // Set the dirty flag
  2195. if( fClearDirty ) ClearDirty( );
  2196. } WsbCatch( hr );
  2197. WsbTraceOut( L"CSakData::Save", L"hr = <%ls>", WsbHrAsString( hr ) );
  2198. return( hr );
  2199. }
  2200. STDMETHODIMP
  2201. CSakData::Load(
  2202. IStream *pStm
  2203. )
  2204. /*++
  2205. Routine Description:
  2206. Load the information we need to reconstruct the root node from the
  2207. supplied stream.
  2208. Arguments:
  2209. pStm IConsole-supplied stream
  2210. Return Value:
  2211. S_OK - Saved successfully.
  2212. E_* - Some error occurred.
  2213. --*/
  2214. {
  2215. WsbTraceIn( L"CSakData::Load", L"pStm = <0x%p>", pStm );
  2216. HRESULT hr = S_OK;
  2217. try {
  2218. ULONG version = 0;
  2219. WsbAffirmHr( WsbLoadFromStream( pStm, &version ) );
  2220. WsbAssert( ( version == 1 ), E_FAIL );
  2221. // Get the flag for local or named HSM
  2222. WsbLoadFromStream( pStm, &m_ManageLocal );
  2223. CWsbStringPtr pHsmName;
  2224. // Get the HSM name ("" for local HSM)
  2225. WsbLoadFromStream( pStm, &pHsmName, 0 );
  2226. m_HsmName = pHsmName;
  2227. // Grab any options from the command line after loading
  2228. InitFromCommandLine( );
  2229. // Set the Hsm name in SakData and HsmCom objects
  2230. WsbAffirmHr( InitializeRootNode() );
  2231. ClearDirty();
  2232. } WsbCatch (hr);
  2233. WsbTraceOut( L"CSakData::Load", L"hr = <%ls>", WsbHrAsString( hr ) );
  2234. return( hr );
  2235. }
  2236. STDMETHODIMP
  2237. CSakData::IsDirty(
  2238. void
  2239. )
  2240. /*++
  2241. Routine Description:
  2242. The console asks us if we are dirty.
  2243. Arguments:
  2244. None
  2245. Return Value:
  2246. S_OK - Dirty.
  2247. S_FALSE - Not Dirty.
  2248. --*/
  2249. {
  2250. WsbTraceIn( L"CSakData::IsDirty", L"" );
  2251. HRESULT hr = ThisIsDirty() ? S_OK : S_FALSE;
  2252. WsbTraceOut( L"CSakData::IsDirty", L"hr = <%ls>", WsbHrAsString( hr ) );
  2253. return( hr );
  2254. }
  2255. HRESULT
  2256. CSakData::GetSizeMax(
  2257. ULARGE_INTEGER * /*pcbSize*/
  2258. )
  2259. /*++
  2260. Routine Description:
  2261. Not currently used by the console
  2262. Arguments:
  2263. pcbSize
  2264. Return Value:
  2265. E_NOTIMPL
  2266. --*/
  2267. {
  2268. WsbTraceIn( L"CSakData::GetSizeMax", L"" );
  2269. HRESULT hr = E_NOTIMPL;
  2270. WsbTraceOut( L"CSakData::GetSizeMax", L"hr = <%ls>", WsbHrAsString( hr ) );
  2271. return( hr );
  2272. }
  2273. STDMETHODIMP
  2274. CSakData::GetClassID(
  2275. CLSID *pClassID
  2276. )
  2277. /*++
  2278. Routine Description:
  2279. Not currently used by the console
  2280. Arguments:
  2281. pClassID - The class ID for the snapin
  2282. Return Value:
  2283. S_OK
  2284. --*/
  2285. {
  2286. WsbTraceIn( L"CSakData::GetClassID", L"pClassID = <0x%p>", pClassID );
  2287. HRESULT hr = S_OK;
  2288. *pClassID = CLSID_HsmAdmin;
  2289. WsbTraceOut( L"CSakData::GetClassID", L"hr = <%ls>, *pClassID = <%ls>", WsbHrAsString( hr ), WsbPtrToGuidAsString( pClassID ) );
  2290. return( hr );
  2291. }
  2292. /////////////////////////////////////////////////////////////////////////////
  2293. //
  2294. // Adds images to the consoles image list from the static array
  2295. //
  2296. HRESULT CSakData::OnAddImages()
  2297. {
  2298. HRESULT hr = S_OK;
  2299. HICON hIcon;
  2300. try {
  2301. //
  2302. // Put the images from the static array into the image list
  2303. // for the scope pane
  2304. //
  2305. for( INT i = 0; i < m_nImageCount; i++ ) {
  2306. // Load the icon using the resource Id stored in the
  2307. // static array and get the handle.
  2308. hIcon = LoadIcon( _Module.m_hInst,
  2309. MAKEINTRESOURCE( m_nImageArray [i] ) );
  2310. // Add to the Console's Image list
  2311. WsbAffirmHr( m_pImageScope->ImageListSetIcon( (RS_WIN32_HANDLE*)hIcon, i ) );
  2312. }
  2313. } WsbCatch (hr);
  2314. return hr;
  2315. }
  2316. //////////////////////////////////////////////////////////////////////////////////
  2317. //
  2318. // Description: Add the supplied resource ID to the list of resource IDs for
  2319. // the scope pane. Returns the index into the array.
  2320. //
  2321. INT CSakData::AddImage( UINT rId )
  2322. {
  2323. INT nIndex = -1;
  2324. if (CSakData::m_nImageCount < RS_SCOPE_IMAGE_ARRAY_MAX) {
  2325. CSakData::m_nImageArray[CSakData::m_nImageCount] = rId;
  2326. nIndex = CSakData::m_nImageCount;
  2327. CSakData::m_nImageCount++;
  2328. }
  2329. return nIndex;
  2330. }
  2331. void CSakData::SetState (BOOL State)
  2332. {
  2333. m_State = State;
  2334. }
  2335. STDMETHODIMP
  2336. CSakData::GetState ()
  2337. {
  2338. return ((m_State) ? S_OK : S_FALSE);
  2339. }
  2340. STDMETHODIMP
  2341. CSakData::Disable(
  2342. IN BOOL Disable
  2343. )
  2344. {
  2345. WsbTraceIn( L"CSakData::Disable", L"Disable = <%ls>", WsbBoolAsString( Disable ) );
  2346. HRESULT hr = S_OK;
  2347. m_Disabled = Disable ? TRUE : FALSE; // Force values to TRUE or FALSE
  2348. //
  2349. // Make sure state is correct as well
  2350. //
  2351. if( Disable ) {
  2352. SetState( FALSE );
  2353. }
  2354. WsbTraceOut( L"CSakData::Disable", L"hr = <%ls>", WsbHrAsString( hr ) );
  2355. return( hr );
  2356. }
  2357. STDMETHODIMP
  2358. CSakData::IsDisabled(
  2359. )
  2360. {
  2361. WsbTraceIn( L"CSakData::IsDisabled", L"" );
  2362. HRESULT hr = m_Disabled ? S_OK : S_FALSE;
  2363. WsbTraceOut( L"CSakData::IsDisabled", L"hr = <%ls>", WsbHrAsString( hr ) );
  2364. return( hr );
  2365. }
  2366. // Is the dataobject either type of multi-select dataobject?
  2367. HRESULT
  2368. CSakData::IsDataObjectMultiSelect ( IDataObject *pDataObject )
  2369. {
  2370. HRESULT hr = S_OK;
  2371. WsbTraceThreadOff( );
  2372. hr = ( ( (IsDataObjectOt( pDataObject ) ) == S_OK ) ||
  2373. ( (IsDataObjectMs( pDataObject ) ) == S_OK ) ) ? S_OK : S_FALSE;
  2374. WsbTraceThreadOn( );
  2375. return( hr );
  2376. }
  2377. // Is the dataobject an Object Types dataobject?
  2378. HRESULT
  2379. CSakData::IsDataObjectOt ( IDataObject *pDataObject )
  2380. {
  2381. HRESULT hr = S_FALSE;
  2382. WsbTraceThreadOff( );
  2383. // Is this a mutli-select data object?
  2384. FORMATETC fmt = {(CLIPFORMAT)m_cfObjectTypes, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  2385. STGMEDIUM stgm = {TYMED_HGLOBAL, NULL};
  2386. if ( pDataObject->GetData( &fmt, &stgm ) == S_OK ) {
  2387. hr = S_OK;
  2388. }
  2389. ReleaseStgMedium( &stgm );
  2390. WsbTraceThreadOn( );
  2391. return( hr );
  2392. }
  2393. // Is the dataobject a Mutli-Select dataobject?
  2394. HRESULT
  2395. CSakData::IsDataObjectMs ( IDataObject *pDataObject )
  2396. {
  2397. HRESULT hr = S_FALSE;
  2398. WsbTraceThreadOff( );
  2399. // Is this a mutli-select data object?
  2400. FORMATETC fmt = {(CLIPFORMAT)m_cfMultiSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  2401. STGMEDIUM stgm = {TYMED_HGLOBAL, NULL};
  2402. if ( pDataObject->GetData( &fmt, &stgm ) == S_OK ) {
  2403. hr = S_OK;
  2404. }
  2405. ReleaseStgMedium( &stgm );
  2406. WsbTraceThreadOn( );
  2407. return( hr );
  2408. }
  2409. #if 0
  2410. HRESULT CSakData::SaveColumnWidths( USHORT listCtrlId, CListCtrl *pListCtrl )
  2411. {
  2412. WsbTraceIn( L"CSakData::SaveColumnWidths", L"pNode = <0x%p>", pNode );
  2413. HRESULT hr = S_OK;
  2414. HRESULT hrInternal;
  2415. UINT columnWidth;
  2416. GUID nodeTypeGuid;
  2417. BOOL exists = FALSE;
  2418. UINT updateIndex;
  2419. UINT col;
  2420. try {
  2421. WsbAssertPointer( pListCtrl );
  2422. // Search to see if the listCtrlId already has an entry
  2423. for( INT index = 0; index < m_cListViewWidths; index++ ) {
  2424. if ( m_ListViewWidths[ index ].listCtrlId == listCtrlId ) {
  2425. updateIndex = index;
  2426. exists = TRUE;
  2427. }
  2428. }
  2429. if ( !exists ) {
  2430. // Create a new entry
  2431. WsbAssert( m_cListViewWidths < BHSM_MAX_NODE_TYPES - 1, E_FAIL );
  2432. updateIndex = m_cListViewWidths;
  2433. m_ListViewWidths[ updateIndex ].listCtrlId = listCtrlId;
  2434. m_cListViewWidths++;
  2435. }
  2436. // Now set the column widths
  2437. col = 0;
  2438. hrInternal = S_OK;
  2439. while( hrInternal == S_OK ) {
  2440. hrInternal = pListCtrl->GetColumnWidth( col, &columnWidth );
  2441. if (hrInternal == S_OK) {
  2442. m_ListViewWidths[ updateIndex ].columnWidths[ col ] = columnWidth;
  2443. col++;
  2444. }
  2445. }
  2446. // if we failed totally to get column widths, don't wipe out the previous value
  2447. if ( col > 0 ) {
  2448. m_ListViewWidths[ updateIndex ].colCount = col;
  2449. }
  2450. } WsbCatch (hr);
  2451. WsbTraceOut( L"CSakData::SaveColumnWidths", L"hr = <%ls>", WsbHrAsString( hr ) );
  2452. return hr;
  2453. }
  2454. HRESULT CSakData::GetSavedColumnWidths( USHORT listCtrlId, CListCtrl *pListCtrl )
  2455. {
  2456. WsbTraceIn( L"CSakData::SaveColumnWidths", L"pNode = <0x%p>", pNode );
  2457. HRESULT hr = S_OK;
  2458. GUID nodeTypeGuid;
  2459. BOOL exists = FALSE;
  2460. INT col;
  2461. try {
  2462. WsbAssertPointer( pNode );
  2463. // Search to see if the listCtrlId already has an entry
  2464. for ( INT index = 0; index < m_cListViewWidths; index++ ) {
  2465. if ( m_ListViewWidths[ index ].listCtrlId == listCtrlId ) {
  2466. for ( col = 0; col < m_ListViewWidths[ index ].colCount; col++) {
  2467. // Return the column widths
  2468. pColumnWidths[ col ] = m_ListViewWidths[ index ].columnWidths[ col ];
  2469. }
  2470. *pColCount = m_ListViewWidths[ index ].colCount;
  2471. exists = TRUE;
  2472. }
  2473. }
  2474. if ( !exists ) {
  2475. return WSB_E_NOTFOUND;
  2476. }
  2477. } WsbCatch (hr);
  2478. WsbTraceOut( L"CSakData::SaveColumnWidths", L"hr = <%ls>", WsbHrAsString( hr ) );
  2479. return hr;
  2480. }
  2481. #endif
  2482. void
  2483. CSakData::InitFromCommandLine(
  2484. void
  2485. )
  2486. /*++
  2487. Routine Description:
  2488. Retreive the command line info and fill in appropriate fields.
  2489. Arguments:
  2490. none.
  2491. Return Value:
  2492. none.
  2493. --*/
  2494. {
  2495. WsbTraceIn( L"CSakData::InitFromCommandLine", L"" );
  2496. g_App.ParseCommandLine( m_Parse );
  2497. if( m_Parse.m_SetManageLocal ) m_ManageLocal = m_Parse.m_ManageLocal;
  2498. if( m_Parse.m_SetHsmName ) m_HsmName = m_Parse.m_HsmName;
  2499. if( m_Parse.m_SetPersistManageLocal ) m_PersistManageLocal = m_Parse.m_PersistManageLocal;
  2500. }
  2501. /////////////////////////////////////////////////////////////////////////////
  2502. // CSakDataWnd
  2503. BOOL
  2504. CSakDataWnd::Create(
  2505. CSakData * pSakData
  2506. )
  2507. {
  2508. WsbTraceIn( L"CSakDataWnd::Create", L"" );
  2509. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  2510. m_pSakData = pSakData;
  2511. BOOL retval = CWnd::CreateEx( 0, AfxRegisterWndClass( 0 ), _T("RSAdmin MsgWnd"), WS_OVERLAPPED, 0, 0, 0, 0, 0, 0 );
  2512. WsbTraceOut( L"CSakDataWnd::Create", L"retval = <%ls>", WsbBoolAsString( retval ) );
  2513. return( retval );
  2514. }
  2515. void
  2516. CSakDataWnd::PostNcDestroy(
  2517. )
  2518. {
  2519. WsbTraceIn( L"CSakDataWnd::PostNcDestroy", L"" );
  2520. AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
  2521. CWnd::PostNcDestroy( );
  2522. //
  2523. // Cleanup object
  2524. //
  2525. delete this;
  2526. WsbTraceOut( L"CSakDataWnd::PostNcDestroy", L"" );
  2527. }
  2528. BEGIN_MESSAGE_MAP(CSakDataWnd, CWnd)
  2529. //{{AFX_MSG_MAP(CSakDataWnd)
  2530. // NOTE - the ClassWizard will add and remove mapping macros here.
  2531. //}}AFX_MSG_MAP
  2532. ON_MESSAGE( WM_SAKDATA_UPDATE_ALL_VIEWS, OnUpdateAllViews )
  2533. ON_MESSAGE( WM_SAKDATA_REFRESH_NODE, OnRefreshNode )
  2534. END_MESSAGE_MAP()
  2535. /////////////////////////////////////////////////////////////////////////////
  2536. // CSakDataWnd message handlers
  2537. LONG
  2538. CSakDataWnd::OnUpdateAllViews(
  2539. IN UINT,
  2540. IN LONG lParam )
  2541. {
  2542. WsbTraceIn( L"CSakDataWnd::OnUpdateAllViews", L"" );
  2543. HRESULT hr = S_OK;
  2544. try {
  2545. //
  2546. // Call the internal update
  2547. //
  2548. WsbAffirmHr( m_pSakData->InternalUpdateAllViews( (MMC_COOKIE)lParam ) );
  2549. } WsbCatch( hr );
  2550. WsbTraceOut( L"CSakDataWnd::OnUpdateAllViews", L"" );
  2551. return( 0 );
  2552. }
  2553. void
  2554. CSakDataWnd::PostUpdateAllViews(
  2555. IN MMC_COOKIE Cookie
  2556. )
  2557. {
  2558. WsbTraceIn( L"CSakDataWnd::PostUpdateAllViews", L"" );
  2559. PostMessage( WM_SAKDATA_UPDATE_ALL_VIEWS, 0, Cookie );
  2560. WsbTraceOut( L"CSakDataWnd::PostUpdateAllViews", L"" );
  2561. }
  2562. LONG
  2563. CSakDataWnd::OnRefreshNode(
  2564. IN UINT,
  2565. IN LONG lParam )
  2566. {
  2567. WsbTraceIn( L"CSakDataWnd::OnRefreshNode", L"" );
  2568. HRESULT hr = S_OK;
  2569. try {
  2570. //
  2571. // Call the internal update
  2572. //
  2573. WsbAffirmHr( m_pSakData->InternalRefreshNode( (MMC_COOKIE)lParam ) );
  2574. } WsbCatch( hr );
  2575. WsbTraceOut( L"CSakDataWnd::OnRefreshNode", L"" );
  2576. return( 0 );
  2577. }
  2578. void
  2579. CSakDataWnd::PostRefreshNode(
  2580. IN MMC_COOKIE Cookie
  2581. )
  2582. {
  2583. WsbTraceIn( L"CSakDataWnd::PostRefreshNode", L"" );
  2584. PostMessage( WM_SAKDATA_REFRESH_NODE, 0, Cookie );
  2585. WsbTraceOut( L"CSakDataWnd::PostRefreshNode", L"" );
  2586. }
  2587. ULONG
  2588. CSakData::InternalAddRef(
  2589. )
  2590. {
  2591. WsbTraceIn( L"CSakData::InternalAddRef", L"" );
  2592. ULONG retval = CComObjectRoot::InternalAddRef( );
  2593. WsbTraceOut( L"CSakData::InternalAddRef", L"retval = <%lu>", retval );
  2594. return( retval );
  2595. }
  2596. ULONG
  2597. CSakData::InternalRelease(
  2598. )
  2599. {
  2600. WsbTraceIn( L"CSakData::InternalRelease", L"" );
  2601. ULONG retval = CComObjectRoot::InternalRelease( );
  2602. WsbTraceOut( L"CSakData::InternalRelease", L"retval = <%lu>", retval );
  2603. return( retval );
  2604. }
  2605. STDMETHODIMP
  2606. CSakData::GetHelpTopic(
  2607. LPOLESTR* pTopic
  2608. )
  2609. {
  2610. WsbTraceIn( L"CSakData::GetHelpTopic", L"" );
  2611. HRESULT hr = S_OK;
  2612. try {
  2613. WsbAffirmPointer( pTopic );
  2614. *pTopic = 0;
  2615. CWsbStringPtr topic;
  2616. WsbAffirmHr( topic.LoadFromRsc( _Module.m_hInst, IDS_HELPFILE ) );
  2617. #if 1 // Hopefully temporary hack since MMC can't find the help directory
  2618. WsbAffirmHr( topic.Prepend( L"\\help\\" ) );
  2619. CWsbStringPtr winDir;
  2620. WsbAffirmHr( winDir.Alloc( RS_WINDIR_SIZE ) );
  2621. WsbAffirmStatus( ::GetWindowsDirectory( (WCHAR*)winDir, RS_WINDIR_SIZE ) != 0 );
  2622. WsbAffirmHr( topic.Prepend( winDir ) );
  2623. #endif
  2624. WsbAffirmHr( topic.GiveTo( pTopic ) );
  2625. } WsbCatch( hr );
  2626. WsbTraceOut( L"CSakData::GetHelpTopic", L"hr = <%ls>, *pTopic = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pTopic ) );
  2627. return( hr );
  2628. }
  2629. STDMETHODIMP
  2630. CSakData::GetLinkedTopics(
  2631. LPOLESTR* pTopic
  2632. )
  2633. {
  2634. WsbTraceIn( L"CSakData::GetLinkedTopics", L"" );
  2635. HRESULT hr = S_OK;
  2636. try {
  2637. WsbAffirmPointer( pTopic );
  2638. *pTopic = 0;
  2639. CWsbStringPtr topic;
  2640. WsbAffirmHr( topic.LoadFromRsc( _Module.m_hInst, IDS_HELPFILELINK ) );
  2641. #if 1 // Hopefully temporary hack since MMC can't find the help directory
  2642. WsbAffirmHr( topic.Prepend( L"\\help\\" ) );
  2643. CWsbStringPtr winDir;
  2644. WsbAffirmHr( winDir.Alloc( RS_WINDIR_SIZE ) );
  2645. WsbAffirmStatus( ::GetWindowsDirectory( (WCHAR*)winDir, RS_WINDIR_SIZE ) != 0 );
  2646. WsbAffirmHr( topic.Prepend( winDir ) );
  2647. #endif
  2648. WsbAffirmHr( topic.GiveTo( pTopic ) );
  2649. } WsbCatch( hr );
  2650. WsbTraceOut( L"CSakData::GetLinkedTopics", L"hr = <%ls>, *pTopic = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pTopic ) );
  2651. return( hr );
  2652. }
  2653. STDMETHODIMP
  2654. CSakData::CreateWizard(
  2655. IN ISakWizard * pWizard
  2656. )
  2657. {
  2658. WsbTraceIn( L"CSakData::CreateWizard", L"" );
  2659. HRESULT hr = S_OK;
  2660. try {
  2661. WsbAffirmPointer( pWizard );
  2662. //
  2663. // Need to get prop sheet privider and create wizard
  2664. //
  2665. CComPtr<IPropertySheetProvider> pProvider;
  2666. WsbAffirmHr( m_pConsole.QueryInterface( &pProvider ) );
  2667. //
  2668. // Create it
  2669. //
  2670. CWsbStringPtr pszName;
  2671. WsbAffirmHr( pWizard->GetTitle( &pszName ) );
  2672. //
  2673. // Create the property sheet
  2674. //
  2675. CComPtr<IDataObject> pDataObject;
  2676. WsbAffirmHr( RsQueryInterface( pWizard, IDataObject, pDataObject ) );
  2677. WsbAffirmHr( pProvider->CreatePropertySheet( pszName, FALSE, 0, pDataObject, MMC_PSO_NEWWIZARDTYPE ) );
  2678. //
  2679. // Tell the IComponentData interface to add pages
  2680. //
  2681. CComPtr <IUnknown> pUnkComponentData;
  2682. pUnkComponentData = (IUnknown *) (IComponentData*) this;
  2683. WsbAffirmHr( pProvider->AddPrimaryPages( pUnkComponentData, TRUE, 0, TRUE ) );
  2684. //
  2685. // And show it
  2686. //
  2687. HWND mainWnd;
  2688. WsbAffirmHr( m_pConsole->GetMainWindow( &mainWnd ) );
  2689. WsbAffirmHr( pProvider->Show( reinterpret_cast<RS_WIN32_HANDLE>(mainWnd), 0 ) );
  2690. } WsbCatch( hr );
  2691. WsbTraceOut( L"CSakData::CreateWizard", L"hr = <%ls>", WsbHrAsString( hr ) );
  2692. return( hr );
  2693. }
  2694. STDMETHODIMP
  2695. CSakData::GetWatermarks(
  2696. IN LPDATAOBJECT pDataObject,
  2697. OUT HBITMAP* pWatermark,
  2698. OUT HBITMAP* pHeader,
  2699. OUT HPALETTE* pPalette,
  2700. OUT BOOL* pStretch
  2701. )
  2702. {
  2703. WsbTraceIn( L"CSakData::GetWatermarks", L"" );
  2704. HRESULT hr = S_OK;
  2705. try {
  2706. //
  2707. // Need to get the ISakWizard interface to do actual work
  2708. //
  2709. CComPtr<ISakWizard> pWizard;
  2710. WsbAffirmHr( RsQueryInterface( pDataObject, ISakWizard, pWizard ) );
  2711. //
  2712. // And make the call
  2713. //
  2714. WsbAffirmHr( pWizard->GetWatermarks( pWatermark, pHeader, pPalette, pStretch ) );
  2715. } WsbCatch( hr );
  2716. WsbTraceOut( L"CSakData::GetWatermarks", L"" );
  2717. return( hr );
  2718. }
  2719. CSakDataNodePrivate::CSakDataNodePrivate( ISakNode* pNode )
  2720. {
  2721. m_pNode = pNode;
  2722. RS_PRIVATE_DATA data = (RS_PRIVATE_DATA)this;
  2723. if( SUCCEEDED( pNode->SetPrivateData( data ) ) ) {
  2724. m_Magic = RS_NODE_MAGIC_GOOD;
  2725. } else {
  2726. m_Magic = RS_NODE_MAGIC_DEFUNCT;
  2727. }
  2728. }
  2729. CSakDataNodePrivate::~CSakDataNodePrivate( )
  2730. {
  2731. m_Magic = RS_NODE_MAGIC_DEFUNCT;
  2732. if( m_pNode ) {
  2733. m_pNode->SetPrivateData( 0 );
  2734. }
  2735. }
  2736. HRESULT CSakDataNodePrivate::Verify( CSakDataNodePrivate* pNodePriv )
  2737. {
  2738. HRESULT hr = E_POINTER;
  2739. if( !IsBadWritePtr( pNodePriv, sizeof( CSakDataNodePrivate ) ) ) {
  2740. if( RS_NODE_MAGIC_GOOD == pNodePriv->m_Magic ) {
  2741. hr = S_OK;
  2742. }
  2743. }
  2744. return( hr );
  2745. }