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.

628 lines
18 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved
  3. Module Name:
  4. ManVolLs.cpp
  5. Abstract:
  6. Node representing Managed Volumes as a whole.
  7. Author:
  8. Rohde Wakefield [rohde] 08-Aug-1997
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "WzMnVlLs.h" // managed Resource creation wizard
  13. #include "PrMrSts.h"
  14. #include "ManVolLs.h"
  15. int CUiManVolLst::m_nScopeCloseIcon = AddScopeImage( IDI_DEVLST );
  16. int CUiManVolLst::m_nScopeCloseIconX = AddScopeImage( IDI_DEVLSTX );
  17. int CUiManVolLst::m_nScopeOpenIcon = AddScopeImage( IDI_NODEOPENFOLDER );
  18. int CUiManVolLst::m_nScopeOpenIconX = CUiManVolLst::m_nScopeCloseIconX;
  19. int CUiManVolLst::m_nResultIcon = AddResultImage( IDI_DEVLST );
  20. int CUiManVolLst::m_nResultIconX = AddResultImage( IDI_DEVLSTX );
  21. /////////////////////////////////////////////////////////////////////////////
  22. //
  23. // CoComObjectRoot
  24. //
  25. /////////////////////////////////////////////////////////////////////////////
  26. //---------------------------------------------------------------------------
  27. //
  28. // FinalConstruct
  29. //
  30. // Initialize this level of the object hierarchy
  31. //
  32. HRESULT CUiManVolLst::FinalConstruct( )
  33. {
  34. WsbTraceIn( L"CUiManVolLst::FinalConstruct", L"" );
  35. m_rTypeGuid = &cGuidManVolLst;
  36. HRESULT hr = CSakNode::FinalConstruct( );
  37. m_bSupportsPropertiesSingle = TRUE;
  38. m_bSupportsPropertiesMulti = FALSE;
  39. m_bSupportsDeleteSingle = FALSE;
  40. m_bSupportsDeleteMulti = FALSE;
  41. m_bSupportsRefreshSingle = TRUE;
  42. m_bSupportsRefreshMulti = FALSE;
  43. m_bIsContainer = TRUE;
  44. m_bHasDynamicChildren = TRUE;
  45. // Toolbar values
  46. INT i = 0;
  47. #if 0 // MS does not want us to have schedule toolbar button
  48. m_ToolbarButtons[i].nBitmap = 0;
  49. m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_LIST_SCHED;
  50. m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_LIST_SCHED;
  51. m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_LIST_SCHED;
  52. i++;
  53. #endif
  54. m_ToolbarButtons[i].nBitmap = 0;
  55. m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_LIST_NEW;
  56. m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_LIST_NEW;
  57. m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_LIST_NEW;
  58. i++;
  59. m_ToolbarBitmap = IDB_TOOLBAR_VOLUME_LIST;
  60. m_cToolbarButtons = i;
  61. WsbTraceOut( L"CUiManVolLst::FinalConstruct", L"hr = <%ls>", WsbHrAsString( hr ) );
  62. return( hr );
  63. }
  64. //---------------------------------------------------------------------------
  65. //
  66. // FinalRelease
  67. //
  68. // Clean up this level of the object hierarchy
  69. //
  70. void CUiManVolLst::FinalRelease( )
  71. {
  72. WsbTraceIn( L"CUiManVolLst::FinalRelease", L"" );
  73. CSakNode::FinalRelease( );
  74. WsbTraceOut( L"CUiManVolLst::FinalRelease", L"" );
  75. }
  76. /////////////////////////////////////////////////////////////////////////////
  77. //
  78. // ISakNode
  79. //
  80. /////////////////////////////////////////////////////////////////////////////
  81. //---------------------------------------------------------------------------
  82. //
  83. // GetContextMenu
  84. //
  85. // Return an HMENU to be used for context menus on this node.
  86. // Set the state of the menus according to the engine state.
  87. //
  88. STDMETHODIMP
  89. CUiManVolLst::GetContextMenu( BOOL /* bMultiSelect */, HMENU* phMenu )
  90. {
  91. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  92. HRESULT hr = S_OK;
  93. try {
  94. LoadContextMenu( IDR_MANVOLLST, phMenu );
  95. CMenu* pRootMenu, *pNewMenu, *pTaskMenu;
  96. CMenu menu;
  97. menu.Attach( *phMenu );
  98. pRootMenu = menu.GetSubMenu( MENU_INDEX_ROOT );
  99. pNewMenu = menu.GetSubMenu( MENU_INDEX_NEW );
  100. pTaskMenu = menu.GetSubMenu( MENU_INDEX_TASK );
  101. //
  102. // If engine down, disable these items
  103. //
  104. if ( m_pSakSnapAsk->GetState() != S_OK ) {
  105. pNewMenu->EnableMenuItem( ID_MANVOLLST_NEW_MANVOL, MF_GRAYED | MF_BYCOMMAND );
  106. }
  107. menu.Detach();
  108. } WsbCatch( hr );
  109. return( hr );
  110. }
  111. //---------------------------------------------------------------------------
  112. //
  113. // InvokeCommand
  114. //
  115. // User has selected a command from the menu. Process it here.
  116. //
  117. STDMETHODIMP
  118. CUiManVolLst::InvokeCommand( SHORT sCmd, IDataObject* /* pDataObject */ )
  119. {
  120. WsbTraceIn( L"CUiManVolLst::InvokeCommand", L"sCmd = <%d>", sCmd );
  121. CString theString;
  122. HRESULT hr = S_OK;
  123. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  124. try {
  125. switch (sCmd) {
  126. case MMC_VERB_REFRESH:
  127. RefreshObject( );
  128. RefreshScopePane( );
  129. break;
  130. case ID_MANVOLLST_ROOT_MANVOL:
  131. case ID_MANVOLLST_NEW_MANVOL:
  132. {
  133. //
  134. // use wizard to create manage volume
  135. //
  136. CComObject<CWizManVolLst>* pWizard = new CComObject<CWizManVolLst>;
  137. WsbAffirmAlloc( pWizard );
  138. CComPtr<ISakWizard> pSakWizard = (ISakWizard*)pWizard;
  139. WsbAffirmHr( m_pSakSnapAsk->CreateWizard( pSakWizard ) );
  140. if( S_OK == pWizard->m_HrFinish ) {
  141. WsbAffirmHr( RefreshScopePane( ) );
  142. }
  143. break;
  144. }
  145. default:
  146. WsbThrow( S_FALSE );
  147. break;
  148. }
  149. } WsbCatch( hr );
  150. WsbTraceOut( L"CUiManVolLst::InvokeCommand", L"hr = <%ls>", WsbHrAsString( hr ) );
  151. return( hr );
  152. }
  153. HRESULT CUiManVolLst::SetupToolbar( IToolbar *pToolbar )
  154. {
  155. WsbTraceIn( L"CUiManVolLst::SetupToolbar", L"pToolbar = <0x%p>", pToolbar );
  156. HRESULT hr = S_OK;
  157. try {
  158. for( INT i = 0; i < m_cToolbarButtons; i++ ) {
  159. m_ToolbarButtons[i].fsState = (UCHAR)( ( S_OK == m_pSakSnapAsk->GetState( ) ) ? TBSTATE_ENABLED : 0 );
  160. }
  161. WsbAffirmHr( CSakNode::SetupToolbar( pToolbar ) );
  162. } WsbCatch( hr );
  163. WsbTraceOut( L"CUiManVolLst::SetupToolbar", L"hr = <%ls>", WsbHrAsString( hr ) );
  164. return hr;
  165. }
  166. HRESULT CUiManVolLst::OnToolbarButtonClick( IDataObject* /* pDataObject */, long cmdId )
  167. {
  168. WsbTraceIn( L"CUiManVolLst::OnToolbarButtonClick", L"cmdId = <%d>", cmdId );
  169. HRESULT hr = S_OK;
  170. try {
  171. switch ( cmdId ) {
  172. case TB_CMD_VOLUME_LIST_NEW:
  173. {
  174. //
  175. // use wizard to create manage volume
  176. //
  177. CComObject<CWizManVolLst>* pWizard = new CComObject<CWizManVolLst>;
  178. WsbAffirmAlloc( pWizard );
  179. CComPtr<ISakWizard> pSakWizard = (ISakWizard*)pWizard;
  180. WsbAffirmHr( m_pSakSnapAsk->CreateWizard( pSakWizard ) );
  181. if( S_OK == pWizard->m_HrFinish ) {
  182. WsbAffirmHr( RefreshScopePane() );
  183. }
  184. break;
  185. }
  186. }
  187. } WsbCatch( hr );
  188. WsbTraceOut( L"CUiManVolLst::OnToolbarButtonClick", L"hr = <%ls>", WsbHrAsString( hr ) );
  189. return( hr );
  190. }
  191. //---------------------------------------------------------------------------------
  192. //
  193. // RefreshObject
  194. //
  195. // Refresh data in the object. This function is used for data that can change
  196. // (for example, volume utilization).
  197. //
  198. STDMETHODIMP CUiManVolLst::RefreshObject ()
  199. {
  200. WsbTraceIn( L"CUiManVolLst::RefreshObject", L"" );
  201. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  202. HRESULT hr = S_OK;
  203. try {
  204. //
  205. // Get the server objects
  206. //
  207. m_pHsmServer.Release( );
  208. m_pFsaServer.Release( );
  209. m_pFsaFilter.Release( );
  210. m_pManResCollection.Release( );
  211. if( m_pSakSnapAsk->GetHsmServer( &m_pHsmServer ) == S_OK) {
  212. // Get the FsaServer object
  213. if ( m_pSakSnapAsk->GetFsaServer( &m_pFsaServer ) == S_OK) {
  214. // Get the Fsa Filter object
  215. WsbAffirmHr( m_pFsaServer->GetFilter( &m_pFsaFilter ) );
  216. // Tell FSA to rescan (updates properties)
  217. WsbAffirmHr( m_pFsaServer->ScanForResources( ) );
  218. // Get Managed Volumes collection from HSM server
  219. WsbAffirmHr( m_pHsmServer->GetManagedResources( &m_pManResCollection ) );
  220. }
  221. }
  222. } WsbCatch( hr );
  223. WsbTraceOut( L"CUiManVolLst::RefreshObject", L"hr = <%ls>", WsbHrAsString( hr ) );
  224. return( hr );
  225. }
  226. HRESULT CUiManVolLst::ShowManVolLstProperties (IDataObject *pDataObject, int initialPage)
  227. {
  228. WsbTraceIn( L"CUiManVolLst::ShowManVolLstProperties", L"initialPage = <%d>", initialPage );
  229. HRESULT hr = S_OK;
  230. try {
  231. CComPtr <ISakNode> pSakNode;
  232. WsbAffirmHr( _InternalQueryInterface( IID_ISakNode, (void **) &pSakNode ) );
  233. WsbAffirmHr( m_pSakSnapAsk->ShowPropertySheet( pSakNode, pDataObject, initialPage ) );
  234. } WsbCatch( hr );
  235. WsbTraceOut( L"CUiManVolLst::ShowManVolLstProperties", L"hr = <%ls>", WsbHrAsString( hr ) );
  236. return( hr );
  237. }
  238. //----------------------------------------------------------------------------
  239. //
  240. // AddPropertyPages
  241. //
  242. STDMETHODIMP
  243. CUiManVolLst::AddPropertyPages( RS_NOTIFY_HANDLE handle, IUnknown* pUnkPropSheetCallback, IEnumGUID *pEnumObjectId, IEnumUnknown *pEnumUnkNode )
  244. {
  245. WsbTraceIn( L"CUiManVolLst::AddPropertyPages", L"handle = <%ld>, pUnkPropSheetCallback = <0x%0.l8x>, pEnumObjectId = <0x%p>",
  246. handle, pUnkPropSheetCallback, pEnumObjectId );
  247. HRESULT hr = S_OK;
  248. try {
  249. //
  250. // Create an object to hold the pages
  251. //
  252. CUiManVolLstSheet *pManVolPropertySheet = new CUiManVolLstSheet;
  253. WsbAffirmAlloc( pManVolPropertySheet );
  254. WsbAffirmHr( pManVolPropertySheet->InitSheet(
  255. handle,
  256. pUnkPropSheetCallback,
  257. (CSakNode *) this,
  258. m_pSakSnapAsk,
  259. pEnumObjectId,
  260. pEnumUnkNode
  261. ) );
  262. //
  263. // Tell the object to add it's pages
  264. //
  265. WsbAffirmHr( pManVolPropertySheet->AddPropertyPages( ) );
  266. } WsbCatch ( hr );
  267. WsbTraceOut( L"CUiManVolLst::AddPropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) );
  268. return ( hr );
  269. }
  270. //---------------------------------------------------------------------------
  271. //
  272. // CreateChildren
  273. //
  274. // Create and initialize all the children of the Managed Resource List node.
  275. //
  276. STDMETHODIMP CUiManVolLst::CreateChildren( )
  277. {
  278. WsbTraceIn( L"CUiManVolLst::CreateChildren", L"" );
  279. // Initialize the children of this node (no recursion. Decendents of children
  280. // are NOT created here)
  281. CComPtr<IUnknown> pUnkChild; // IUnknown pointer to new child.
  282. CComPtr<ISakNode> pNode;
  283. HRESULT hr = S_OK;
  284. try {
  285. //
  286. // Get pointer to Hsm Managed Resource Collection object stored
  287. // in this UI node. This may be NULL in the case of the service
  288. // being down, in which case we don't want to do anything.
  289. //
  290. if( m_pManResCollection ) {
  291. ULONG count = 0; // number of managed Resources in server
  292. WsbAffirmHr( m_pManResCollection->GetEntries( &count ) );
  293. CComPtr<IUnknown> pUnkHsmManRes; // unknown pointer to Hsm volume
  294. for( int i = 0; i < (int)count; i++ ) {
  295. pUnkChild.Release( );
  296. pNode.Release( );
  297. pUnkHsmManRes.Release( );
  298. // Create a managed Resource UI node for each managed volume in the HsmServer.
  299. WsbAffirmHr( NewChild( cGuidManVol, &pUnkChild ) );
  300. WsbAffirmHr( RsQueryInterface( pUnkChild, ISakNode, pNode ) );
  301. WsbAffirmHr( m_pManResCollection->At( i, IID_IUnknown, (void**)&pUnkHsmManRes ) );
  302. // Initialize the child UI COM object, putting the Hsm managed Resource
  303. // object inside the UI object.
  304. WsbAffirmHr( pNode->InitNode( m_pSakSnapAsk, pUnkHsmManRes, this ) );
  305. // Add the child COM object to the parent's list of children.
  306. WsbAffirmHr( AddChild( pNode ) );
  307. }
  308. }
  309. } WsbCatch( hr );
  310. // Indicate that this node's children are valid and up-to-date (even if there ARE
  311. // no children - at least now we know it).
  312. m_bChildrenAreValid = TRUE;
  313. // indicate that this parent node needs to be re-enumerated
  314. m_bEnumState = FALSE;
  315. WsbTraceOut( L"CUiManVolLst::CreateChildren", L"hr = <%ls>", WsbHrAsString( hr ) );
  316. return( hr );
  317. }
  318. //---------------------------------------------------------------------------
  319. //
  320. // InitNode
  321. //
  322. // Initialize single COM object without using the registry. Derived
  323. // objects frequently augment this method by implementing it themselves.
  324. //
  325. STDMETHODIMP CUiManVolLst::InitNode(
  326. ISakSnapAsk* pSakSnapAsk,
  327. IUnknown* pHsmObj,
  328. ISakNode* pParent
  329. )
  330. {
  331. WsbTraceIn( L"CUiManVolLst::InitNode", L"pSakSnapAsk = <0x%p>, pHsmObj = <0x%p>, pParent = <0x%p>", pSakSnapAsk, pHsmObj, pParent );
  332. HRESULT hr = S_OK;
  333. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  334. try {
  335. WsbAffirmHr( CSakNode::InitNode( pSakSnapAsk, NULL, pParent ) );
  336. //
  337. // Set the object properties
  338. // Display Name
  339. //
  340. CString sDisplayName;
  341. sDisplayName.LoadString( IDS_MANVOLLST_DISPLAY_NAME );
  342. CWsbStringPtr szWsbDisplayName( sDisplayName );
  343. WsbAffirmHr( put_DisplayName( szWsbDisplayName ) );
  344. //
  345. // Description
  346. //
  347. CString sDescription;
  348. sDescription.LoadString( IDS_MANVOLLST_DESCRIPTION );
  349. CWsbStringPtr szWsbDescription( sDescription );
  350. WsbAffirmHr( put_Description( szWsbDescription ) );
  351. //
  352. // Set up the result view columns
  353. //
  354. WsbAffirmHr( SetChildProps( RS_STR_RESULT_PROPS_MANRESLST_IDS,
  355. IDS_RESULT_PROPS_MANRESLST_TITLES,
  356. IDS_RESULT_PROPS_MANRESLST_WIDTHS));
  357. WsbAffirmHr( RefreshObject( ) );
  358. } WsbCatch( hr );
  359. WsbTraceOut( L"CUiManVolLst::InitNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  360. return( hr );
  361. }
  362. STDMETHODIMP
  363. CUiManVolLst::TerminateNode(
  364. )
  365. /*++
  366. Routine Description:
  367. Free any interface connections or other resources
  368. that would prevent correct shutdown of node (would
  369. keep ref count from going to 0).
  370. Arguments:
  371. CopySet - copy set of interest.
  372. pszValue - return string representing the state.
  373. Return Value:
  374. S_OK - Handled.
  375. E_* - Some error occurred.
  376. --*/
  377. {
  378. WsbTraceIn( L"CUiManVolLst::TerminateNode", L"" );
  379. HRESULT hr = S_OK;
  380. try {
  381. //
  382. // Release any interface pointers kept so that circular references
  383. // are broken
  384. //
  385. m_pFsaServer.Release( );
  386. m_pManResCollection.Release( );
  387. m_pHsmServer.Release( );
  388. m_pFsaFilter.Release( );
  389. m_pSchedAgent.Release( );
  390. m_pTask.Release( );
  391. m_pTrigger.Release( );
  392. //
  393. // And call the base class for it's pieces
  394. //
  395. WsbAffirmHr( CSakNode::TerminateNode( ) );
  396. } WsbCatch( hr );
  397. WsbTraceOut( L"CUiManVolLst::TerminateNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  398. return( hr );
  399. }
  400. /////////////////////////////////////////////////////////////////////////////////////////
  401. //
  402. // class CUiManVolLstSheet
  403. //
  404. HRESULT CUiManVolLstSheet::AddPropertyPages ( )
  405. {
  406. WsbTraceIn( L"CUiManVolLstSheet::AddPropertyPages", L"" );
  407. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  408. HRESULT hr = S_OK;
  409. try {
  410. // --------------------- Statistics Page ----------------------------------
  411. // NOTE: We now use the same page as the volume property sheet !!
  412. CPrMrSts *pPropPageStatus = new CPrMrSts( TRUE );
  413. WsbAffirmAlloc( pPropPageStatus );
  414. AddPage( pPropPageStatus );
  415. // Add more pages here.
  416. // ....
  417. } WsbCatch( hr );
  418. WsbTraceOut( L"CUiManVolLstSheet::AddPropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) );
  419. return( hr );
  420. }
  421. HRESULT CUiManVolLstSheet::GetNextFsaResource ( int *pBookMark, IFsaResource **ppFsaResource )
  422. {
  423. WsbTraceIn( L"CUiManVolLstSheet::GetNextFsaResource", L"*pBookMark = <%d>", *pBookMark );
  424. HRESULT hr = S_OK;
  425. HRESULT hrInternal = S_OK;
  426. try {
  427. WsbAffirm ( *pBookMark >= 0, E_FAIL );
  428. CComPtr <IWsbIndexedCollection> pManResCollection;
  429. WsbAffirmHr( GetManResCollection( &pManResCollection ) );
  430. CComPtr <IHsmManagedResource> pHsmManRes;
  431. CComPtr <IUnknown> pUnkFsaRes;
  432. hr = pManResCollection->At(*pBookMark, IID_IHsmManagedResource, (void**) &pHsmManRes);
  433. if ( hr == S_OK ) {
  434. (*pBookMark)++;
  435. WsbAffirmHr( pHsmManRes->GetFsaResource( &pUnkFsaRes ));
  436. WsbAffirmHr( pUnkFsaRes->QueryInterface( IID_IFsaResource, (void**) ppFsaResource ) );
  437. }
  438. } WsbCatch (hr);
  439. WsbTraceOut( L"CUiManVolLstSheet::GetNextFsaResource", L"hr = <%ls>", WsbHrAsString( hr ) );
  440. return hr;
  441. }
  442. // This function is to be called from the page thread
  443. HRESULT CUiManVolLstSheet::GetManResCollection( IWsbIndexedCollection **ppManResCollection )
  444. {
  445. WsbTraceIn( L"CUiManVolLstSheet::GetManResCollection", L"" );
  446. HRESULT hr = S_OK;
  447. try {
  448. CComPtr <IHsmServer> pHsmServer;
  449. WsbAffirmHrOk( GetHsmServer( &pHsmServer ) );
  450. //
  451. // Get Managed Volumes collection from HSM server
  452. //
  453. WsbAffirmHr( pHsmServer->GetManagedResources( ppManResCollection ) );
  454. } WsbCatch( hr );
  455. WsbTraceOut( L"CUiManVolLstSheet::GetManResCollection", L"hr = <%ls>, *ppManResCollection = <0x%p>",
  456. WsbHrAsString( hr ), *ppManResCollection );
  457. return( hr );
  458. }