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.

1499 lines
39 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved
  3. Module Name:
  4. ManVol.cpp
  5. Abstract:
  6. Managed Volume node implementation.
  7. Author:
  8. Rohde Wakefield [rohde] 08-Aug-1997
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include <mstask.h>
  13. #include "ManVol.h"
  14. #include "PrMrSts.h"
  15. #include "PrMrIe.h"
  16. #include "WzUnmang.h"
  17. int CUiManVol::m_nResultIcon = AddResultImage( IDI_NODEMANVOL );
  18. int CUiManVol::m_nResultIconX = AddResultImage( IDI_NODEMANVOLX );
  19. int CUiManVol::m_nResultIconD = AddResultImage( IDI_NODEMANVOLD );
  20. // Not used
  21. int CUiManVol::m_nScopeCloseIcon = AddScopeImage( IDI_NODEMANVOL );
  22. int CUiManVol::m_nScopeCloseIconX = AddScopeImage( IDI_NODEMANVOLX );
  23. int CUiManVol::m_nScopeOpenIcon = CUiManVol::m_nScopeCloseIcon;
  24. int CUiManVol::m_nScopeOpenIconX = CUiManVol::m_nScopeCloseIconX;
  25. UINT CUiManVol::m_ObjectTypes = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
  26. UINT CUiManVol::m_MultiSelect = RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
  27. /////////////////////////////////////////////////////////////////////////////
  28. //
  29. // CoComObjectRoot
  30. //
  31. /////////////////////////////////////////////////////////////////////////////
  32. //---------------------------------------------------------------------------
  33. //
  34. // FinalConstruct
  35. //
  36. // Initialize this level of the object hierarchy
  37. //
  38. HRESULT CUiManVol::FinalConstruct( )
  39. {
  40. WsbTraceIn( L"CUiManVol::FinalConstruct", L"" );
  41. m_rTypeGuid = &cGuidManVol;
  42. HRESULT hr = CSakNode::FinalConstruct( );
  43. m_bSupportsPropertiesSingle = TRUE;
  44. m_bSupportsPropertiesMulti = TRUE;
  45. m_bSupportsDeleteSingle = FALSE;
  46. m_bSupportsDeleteMulti = FALSE;
  47. m_bSupportsRefreshSingle = TRUE;
  48. m_bSupportsRefreshMulti = FALSE;
  49. m_bIsContainer = FALSE;
  50. m_pFsaResource = NULL;
  51. m_HrAvailable = S_FALSE;
  52. // Toolbar values
  53. INT i = 0;
  54. #if 0 // MS does not want these toolbar buttons to show up
  55. m_ToolbarButtons[i].nBitmap = 0;
  56. m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_SETTINGS;
  57. m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_SETTINGS;
  58. m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_SETTINGS;
  59. i++;
  60. m_ToolbarButtons[i].nBitmap = 1;
  61. m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_TOOLS;
  62. m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_TOOLS;
  63. m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_TOOLS;
  64. i++;
  65. m_ToolbarButtons[i].nBitmap = 2;
  66. m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_RULES;
  67. m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_RULES;
  68. m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_RULES;
  69. i++;
  70. #endif
  71. m_ToolbarBitmap = IDB_TOOLBAR_VOLUME;
  72. m_cToolbarButtons = i;
  73. WsbTraceOut( L"CUiManVol::FinalConstruct", L"hr = <%ls>", WsbHrAsString( hr ) );
  74. return( hr );
  75. }
  76. //---------------------------------------------------------------------------
  77. //
  78. // FinalRelease
  79. //
  80. // Clean up this level of the object hierarchy
  81. //
  82. void CUiManVol::FinalRelease( )
  83. {
  84. WsbTraceIn( L"CUiManVol::FinalRelease", L"" );
  85. CSakNode::FinalRelease( );
  86. WsbTraceOut( L"CUiManVol::FinalRelease", L"" );
  87. }
  88. /////////////////////////////////////////////////////////////////////////////
  89. //
  90. // ISakNode
  91. //
  92. /////////////////////////////////////////////////////////////////////////////
  93. //---------------------------------------------------------------------------
  94. //
  95. // GetContextMenu
  96. //
  97. // Return an HMENU to be used for context menus on this node.
  98. //
  99. STDMETHODIMP
  100. CUiManVol::GetContextMenu( BOOL bMultiSelect, HMENU* phMenu )
  101. {
  102. WsbTraceIn( L"CUiManVol::GetContextMenu", L"" );
  103. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  104. HRESULT hr = S_OK;
  105. try {
  106. WsbAffirmPointer( m_pFsaResource );
  107. LoadContextMenu( IDR_MANVOL, phMenu );
  108. CMenu* pRootMenu;
  109. CMenu* pTaskMenu;
  110. CMenu menu;
  111. menu.Attach( *phMenu );
  112. pRootMenu = menu.GetSubMenu( MENU_INDEX_ROOT );
  113. pTaskMenu = menu.GetSubMenu( MENU_INDEX_TASK );
  114. //
  115. // If multi-select, disable these items
  116. //
  117. //
  118. // else if engine down or resource is being unmanaged, or appears to be missing
  119. // (formatted new?), disable these items
  120. //
  121. BOOL bState = ( m_pSakSnapAsk->GetState( ) == S_OK );
  122. BOOL bDeletePending = ( m_pFsaResource->IsDeletePending( ) == S_OK );
  123. BOOL bAvailable = ( IsAvailable( ) == S_OK );
  124. if( bMultiSelect ) {
  125. pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_RULES, MF_GRAYED | MF_BYCOMMAND );
  126. pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_REMOVE, MF_GRAYED | MF_BYCOMMAND );
  127. }
  128. else {
  129. pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_LEVELS, MF_BYCOMMAND |
  130. ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) );
  131. pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_TASKS, MF_BYCOMMAND |
  132. ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) );
  133. pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_RULES, MF_BYCOMMAND |
  134. ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) );
  135. pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_REMOVE, MF_BYCOMMAND |
  136. ( ( !bState || bDeletePending ) ? MF_GRAYED : MF_ENABLED ) );
  137. pTaskMenu->EnableMenuItem( ID_MANVOL_ROOT_TOOLS_COPY, MF_BYCOMMAND |
  138. ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) );
  139. pTaskMenu->EnableMenuItem( ID_MANVOL_ROOT_TOOLS_VALIDATE, MF_BYCOMMAND |
  140. ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) );
  141. pTaskMenu->EnableMenuItem( ID_MANVOL_ROOT_TOOLS_CREATE_FREESPACE, MF_BYCOMMAND |
  142. ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) );
  143. }
  144. menu.Detach( );
  145. } WsbCatch( hr );
  146. WsbTraceOut( L"CUiManVol::GetContextMenu", L"hr = <%ls>", WsbHrAsString( hr ) );
  147. return( hr );
  148. }
  149. //---------------------------------------------------------------------------
  150. //
  151. // InvokeCommand
  152. //
  153. // User has selected a command from the menu. Process it here.
  154. //
  155. STDMETHODIMP
  156. CUiManVol::InvokeCommand( SHORT sCmd, IDataObject* pDataObject )
  157. {
  158. WsbTraceIn( L"CUiManVol::InvokeCommand", L"sCmd = <%d>", sCmd );
  159. CString theString;
  160. HRESULT hr = S_OK;
  161. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  162. try {
  163. WsbAffirmPointer( m_pFsaResource );
  164. if( S_OK != m_pFsaResource->IsDeletePending( ) ) {
  165. switch( sCmd ) {
  166. case ID_MANVOL_ROOT_REMOVE:
  167. //
  168. // Should not be called for multi-select
  169. //
  170. RemoveObject();
  171. break;
  172. case ID_MANVOL_ROOT_LEVELS:
  173. case ID_MANVOL_TASK_LEVELS:
  174. ShowManVolProperties( pDataObject, 1 );
  175. break;
  176. case ID_MANVOL_ROOT_RULES:
  177. case ID_MANVOL_TASK_RULES:
  178. //
  179. // Should not be called for multi-select
  180. //
  181. ShowManVolProperties( pDataObject, 2 );
  182. break;
  183. case ID_MANVOL_ROOT_TOOLS_COPY :
  184. HandleTask( pDataObject, HSM_JOB_DEF_TYPE_MANAGE );
  185. break;
  186. case ID_MANVOL_ROOT_TOOLS_VALIDATE :
  187. HandleTask( pDataObject, HSM_JOB_DEF_TYPE_VALIDATE );
  188. break;
  189. case ID_MANVOL_ROOT_TOOLS_CREATE_FREESPACE :
  190. HandleTask( pDataObject, HSM_JOB_DEF_TYPE_TRUNCATE );
  191. break;
  192. default:
  193. break;
  194. }
  195. } else {
  196. CString message;
  197. AfxFormatString1( message, IDS_ERR_VOLUME_DELETE_PENDING, m_szName );
  198. AfxMessageBox( message, RS_MB_ERROR );
  199. }
  200. } WsbCatch( hr );
  201. WsbTraceOut( L"CUiManVol::InvokeCommand", L"hr = <%ls>", WsbHrAsString( hr ) );
  202. return( hr );
  203. }
  204. HRESULT CUiManVol::OnToolbarButtonClick( IDataObject *pDataObject, long cmdId )
  205. {
  206. WsbTraceIn( L"CUiManVol::OnToolbarButtonClick", L"cmdId = <%d>", cmdId );
  207. HRESULT hr = S_OK;
  208. try {
  209. WsbAffirmPointer( m_pFsaResource );
  210. if( S_OK != m_pFsaResource->IsDeletePending( ) ) {
  211. try {
  212. switch( cmdId ) {
  213. case TB_CMD_VOLUME_SETTINGS:
  214. ShowManVolProperties( pDataObject, 1 );
  215. break;
  216. case TB_CMD_VOLUME_TOOLS:
  217. ShowManVolProperties( pDataObject, 2 );
  218. break;
  219. case TB_CMD_VOLUME_RULES:
  220. ShowManVolProperties( pDataObject, 3 );
  221. break;
  222. }
  223. } WsbCatch( hr );
  224. } else {
  225. CString message;
  226. AfxFormatString1( message, IDS_ERR_VOLUME_DELETE_PENDING, m_szName );
  227. AfxMessageBox( message, RS_MB_ERROR );
  228. }
  229. } WsbCatch( hr );
  230. WsbTraceOut( L"CUiManVol::OnToolbarButtonClick", L"hr = <%ls>", WsbHrAsString( hr ) );
  231. return( hr );
  232. }
  233. HRESULT CUiManVol::ShowManVolProperties( IDataObject *pDataObject, int initialPage )
  234. {
  235. WsbTraceIn( L"CUiManVol::ShowManVolProperties", L"initialPage = <%d>", initialPage );
  236. HRESULT hr = S_OK;
  237. try {
  238. CComPtr<ISakNode> pSakNode;
  239. WsbAffirmHr( _InternalQueryInterface( IID_ISakNode, (void **) &pSakNode ) );
  240. WsbAffirmHr( m_pSakSnapAsk->ShowPropertySheet( pSakNode, pDataObject, initialPage ) );
  241. } WsbCatch( hr );
  242. WsbTraceOut( L"CUiManVol::ShowManVolProperties", L"hr = <%ls>", WsbHrAsString( hr ) );
  243. return hr;
  244. }
  245. HRESULT CUiManVol::CreateAndRunManVolJob( HSM_JOB_DEF_TYPE jobType )
  246. {
  247. WsbTraceIn( L"CUiManVol::CreateAndRunManVolJob", L"jobType = <0x%p>", jobType );
  248. HRESULT hr = 0;
  249. try {
  250. WsbAffirmPointer( m_pFsaResource );
  251. //
  252. // Get a pointer to the FsaResource interface
  253. //
  254. CComPtr<IHsmServer> pHsmServer;
  255. WsbAffirmHrOk( m_pSakSnapAsk->GetHsmServer( &pHsmServer ) );
  256. RsCreateAndRunFsaJob( jobType, pHsmServer, m_pFsaResource );
  257. } WsbCatch( hr );
  258. WsbTraceOut( L"CUiManVol::CreateAndRunManVolJob", L"hr = <%ls>", WsbHrAsString( hr ) );
  259. return hr;
  260. }
  261. HRESULT CUiManVol::HandleTask( IDataObject * pDataObject, HSM_JOB_DEF_TYPE jobType )
  262. {
  263. WsbTraceIn( L"CUiManVol::HandleTask", L"pDataObject = <0x%p>, jobType = <0x%p>", pDataObject, jobType );
  264. HRESULT hr = 0;
  265. try {
  266. UINT nMsgId = 0;
  267. CComPtr<IHsmServer> pHsmServer;
  268. WsbAffirmHrOk( m_pSakSnapAsk->GetHsmServer( &pHsmServer ) );
  269. //
  270. // Submit jobs for all selected FsaResource's
  271. //
  272. if ( IsDataObjectMultiSelect( pDataObject ) == S_OK )
  273. {
  274. CComPtr<IDataObject> pOtDataObject;
  275. if ( IsDataObjectMs( pDataObject ) == S_OK ) {
  276. WsbAffirmHr( GetOtFromMs( pDataObject, &pOtDataObject ) );
  277. }
  278. else {
  279. pOtDataObject = pDataObject;
  280. }
  281. // Get a pointer to a FsaResource attribute out of the data
  282. ULONG nElem = 1;
  283. CComPtr<IMsDataObject> pMsDataObject;
  284. CComPtr<IUnknown> pUnkNode;
  285. CComPtr<IEnumUnknown> pEnumUnkNode;
  286. WsbAffirmHr( pOtDataObject.QueryInterface( &pMsDataObject ) );
  287. WsbAffirmHr( pMsDataObject->GetNodeEnumerator( &pEnumUnkNode ) );
  288. // Prompt the user that we are about to submit the jobs.
  289. CString tempString;
  290. UINT msgId = 0;
  291. WsbAffirmHr( GetTaskTypeMessageId( jobType, TRUE, &msgId ) );
  292. CWsbStringPtr computerName;
  293. WsbAffirmHr( pHsmServer->GetName( &computerName ) );
  294. CString message;
  295. AfxFormatString1( message, msgId, computerName );
  296. tempString.LoadString( IDS_RUN_JOB_MULTI2 );
  297. message += tempString;
  298. if ( AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 ) == IDOK )
  299. {
  300. while ( pEnumUnkNode->Next( nElem, &pUnkNode, NULL ) == S_OK )
  301. {
  302. CComPtr<ISakNode> pNode;
  303. WsbAffirmHr( pUnkNode.QueryInterface( &pNode ) );
  304. pUnkNode.Release();
  305. CComPtr<IUnknown> pUnk;
  306. WsbAffirmHr( pNode->GetHsmObj( &pUnk ) );
  307. CComPtr<IHsmManagedResource> pManRes;
  308. WsbAffirmHr( pUnk.QueryInterface( &pManRes ) );
  309. //
  310. // Then Get Coresponding FSA resource
  311. //
  312. CComPtr<IUnknown> pUnkFsaRes;
  313. WsbAffirmHr( pManRes->GetFsaResource( &pUnkFsaRes ) );
  314. CComPtr<IFsaResource> pFsaResource;
  315. WsbAffirmHr( pUnkFsaRes.QueryInterface( &pFsaResource ) );
  316. RsCreateAndRunFsaJob( jobType, pHsmServer, pFsaResource, FALSE );
  317. }
  318. }
  319. }
  320. else
  321. {
  322. WsbAffirmPointer( m_pFsaResource );
  323. // Prompt the user that we are about to submit the jobs.
  324. UINT msgId = 0;
  325. WsbAffirmHr( GetTaskTypeMessageId( jobType, FALSE, &msgId ) );
  326. CWsbStringPtr computerName;
  327. WsbAffirmHr( pHsmServer->GetName( &computerName ) );
  328. CString message;
  329. AfxFormatString1( message, msgId, computerName );
  330. CString jobName;
  331. WsbAffirmHr( RsCreateJobName( jobType, m_pFsaResource, jobName ) );
  332. CString tempString;
  333. AfxFormatString1( tempString, IDS_MONITOR_TASK, jobName );
  334. message += tempString;
  335. if ( AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 ) == IDOK ) {
  336. RsCreateAndRunFsaJob( jobType, pHsmServer, m_pFsaResource, FALSE );
  337. }
  338. }
  339. } WsbCatch( hr );
  340. WsbTraceOut( L"CUiManVol::HandleTask", L"hr = <%ls>", WsbHrAsString( hr ) );
  341. return hr;
  342. }
  343. HRESULT
  344. CUiManVol::GetTaskTypeMessageId( HSM_JOB_DEF_TYPE jobType, BOOL multiSelect, UINT* msgId ) {
  345. WsbTraceIn( L"CUiManVol::GetTaskTypeMessageId", L"jobType = <%d>, msgId = <%d>, multiSelect = <%d>", jobType, msgId, multiSelect );
  346. HRESULT hr = 0;
  347. try {
  348. WsbAffirmPointer( msgId );
  349. switch ( jobType ) {
  350. case HSM_JOB_DEF_TYPE_MANAGE :
  351. if ( multiSelect )
  352. *msgId = IDS_RUN_MULTI_COPY_JOBS;
  353. else
  354. *msgId = IDS_RUN_COPY_JOB;
  355. break;
  356. case HSM_JOB_DEF_TYPE_VALIDATE :
  357. if ( multiSelect )
  358. *msgId = IDS_RUN_MULTI_VALIDATE_JOBS;
  359. else
  360. *msgId = IDS_RUN_VALIDATE_JOB;
  361. break;
  362. case HSM_JOB_DEF_TYPE_TRUNCATE :
  363. if ( multiSelect )
  364. *msgId = IDS_RUN_MULTI_CFS_JOBS;
  365. else
  366. *msgId = IDS_RUN_CFS_JOB;
  367. break;
  368. default:
  369. break;
  370. }
  371. } WsbCatch( hr );
  372. WsbTraceOut( L"CUiManVol::GetTaskTypeMessageId", L"jobType = <%d>, msgId = <%d>, multiSelect = <%d>", jobType, msgId, multiSelect );
  373. return hr;
  374. }
  375. // Is the dataobject either type of multi-select dataobject?
  376. HRESULT
  377. CUiManVol::IsDataObjectMultiSelect ( IDataObject *pDataObject )
  378. {
  379. HRESULT hr = S_OK;
  380. hr = ( ( (IsDataObjectOt( pDataObject ) ) == S_OK ) ||
  381. ( (IsDataObjectMs( pDataObject ) ) == S_OK ) ) ? S_OK : S_FALSE;
  382. return hr;
  383. }
  384. // Is the dataobject an Object Types dataobject?
  385. HRESULT
  386. CUiManVol::IsDataObjectOt ( IDataObject *pDataObject )
  387. {
  388. HRESULT hr = S_FALSE;
  389. // Is this a mutli-select data object?
  390. FORMATETC fmt = {(CLIPFORMAT)m_ObjectTypes, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  391. STGMEDIUM stgm = {TYMED_HGLOBAL, NULL};
  392. if ( pDataObject->GetData( &fmt, &stgm ) == S_OK ) {
  393. hr = S_OK;
  394. }
  395. ReleaseStgMedium( &stgm );
  396. return hr;
  397. }
  398. // Is the dataobject a Mutli-Select dataobject?
  399. HRESULT
  400. CUiManVol::IsDataObjectMs ( IDataObject *pDataObject )
  401. {
  402. HRESULT hr = S_FALSE;
  403. // Is this a mutli-select data object?
  404. FORMATETC fmt = {(CLIPFORMAT)m_MultiSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  405. STGMEDIUM stgm = {TYMED_HGLOBAL, NULL};
  406. if ( pDataObject->GetData( &fmt, &stgm ) == S_OK ) {
  407. hr = S_OK;
  408. }
  409. ReleaseStgMedium( &stgm );
  410. return hr;
  411. }
  412. HRESULT
  413. CUiManVol::GetOtFromMs( IDataObject * pDataObject, IDataObject ** ppOtDataObject )
  414. {
  415. WsbTraceIn( L"CUiManVol::GetOtFromMs", L"pDataObject = <0x%p>, ppOtDataObject = <0x%p>", pDataObject, ppOtDataObject );
  416. HRESULT hr = S_OK;
  417. try {
  418. // We've got an MMC mutli-select data object. Get the first
  419. // data object from it's array of data objects
  420. FORMATETC fmt = {(CLIPFORMAT)m_MultiSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  421. STGMEDIUM stgm = {TYMED_HGLOBAL, NULL};
  422. WsbAffirmHr ( pDataObject->GetData( &fmt, &stgm ) == S_OK );
  423. DWORD count;
  424. memcpy( &count, stgm.hGlobal, sizeof (DWORD) );
  425. if ( count > 0 ) {
  426. //
  427. // The following code is admittedly UGLY
  428. // We have a data stream where we need to skip past the
  429. // first DWORD count and grab an interface pointer.
  430. // Other snapins code does it as follows:
  431. // IDataObject * pDO;
  432. // memcpy( &pDO, (DWORD *) stgm.hGlobal + 1, sizeof(IDataObject*) );
  433. //
  434. // However, since this code does an indirect cast (via memcpy)
  435. // from DWORD to IDataObject*, and does not keep a true reference
  436. // on the interface pointer, we will use a smart pointer.
  437. // The (DWORD*) and +1 operation bump our pointer past the count.
  438. // We then need to grab the next bytes in the buffer and use them
  439. // as a IDataObject *.
  440. //
  441. CComPtr<IDataObject> pOtDataObject;
  442. pOtDataObject = *( (IDataObject**)( (DWORD *) stgm.hGlobal + 1 ) );
  443. WsbAffirmHr( pOtDataObject->QueryInterface( IID_IDataObject, (void**) ppOtDataObject ) );
  444. }
  445. ReleaseStgMedium( &stgm );
  446. } WsbCatch ( hr );
  447. WsbTraceOut( L"CUiManVol::GetOtFromMs", L"pDataObject = <0x%p>, ppOtDataObject = <0x%p>", pDataObject, ppOtDataObject );
  448. return ( hr );
  449. }
  450. STDMETHODIMP
  451. CUiManVol::AddPropertyPages( RS_NOTIFY_HANDLE handle, IUnknown* pUnkPropSheetCallback, IEnumGUID *pEnumObjectId, IEnumUnknown *pEnumUnkNode )
  452. {
  453. WsbTraceIn( L"CUiManVol::AddPropertyPages", L"handle = <%ld>, pUnkPropSheetCallback = <0x%0.l8x>, pEnumObjectId = <0x%p>",
  454. handle, pUnkPropSheetCallback, pEnumObjectId );
  455. HRESULT hr = S_OK;
  456. try {
  457. //
  458. // Make sure we can still contact the engine before doing this
  459. // If not running, we shouldn't even exist so update parent
  460. //
  461. CComPtr<IHsmServer> pHsmServer;
  462. HRESULT hrRunning = m_pSakSnapAsk->GetHsmServer( &pHsmServer );
  463. if( S_FALSE == hrRunning ) {
  464. m_pSakSnapAsk->UpdateAllViews( m_pParent );
  465. }
  466. WsbAffirmHrOk( hrRunning );
  467. //
  468. // Create an object to hold the pages
  469. //
  470. CUiManVolSheet *pManVolPropertySheet = new CUiManVolSheet;
  471. WsbAffirmAlloc( pManVolPropertySheet );
  472. WsbAffirmHr( pManVolPropertySheet->InitSheet(
  473. handle,
  474. pUnkPropSheetCallback,
  475. this,
  476. m_pSakSnapAsk,
  477. pEnumObjectId,
  478. pEnumUnkNode
  479. ) );
  480. //
  481. // Tell the object to add it's pages
  482. //
  483. WsbAffirmHr( pManVolPropertySheet->AddPropertyPages( ) );
  484. } WsbCatch( hr );
  485. WsbTraceOut( L"CUiManVol::AddPropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) );
  486. return( hr );
  487. }
  488. //---------------------------------------------------------------------------
  489. //
  490. // InitNode
  491. //
  492. // Initialize single COM object. Derived objects frequently augment this
  493. // method by implementing it themselves.
  494. //
  495. STDMETHODIMP CUiManVol::InitNode(
  496. ISakSnapAsk* pSakSnapAsk,
  497. IUnknown* pHsmObj,
  498. ISakNode* pParent
  499. )
  500. {
  501. WsbTraceIn( L"CUiManVol::InitNode", L"pSakSnapAsk = <0x%p>, pHsmObj = <0x%p>, pParent = <0x%p>", pSakSnapAsk, pHsmObj, pParent );
  502. HRESULT hr = S_OK;
  503. try {
  504. WsbAffirmHr( CSakNode::InitNode( pSakSnapAsk, pHsmObj, pParent ));
  505. //
  506. // Get the Fsa object pointer
  507. //
  508. CComQIPtr<IHsmManagedResource, &IID_IHsmManagedResource> pHsmManRes = m_pHsmObj;
  509. WsbAffirmPointer( pHsmManRes );
  510. CComPtr<IUnknown> pUnkFsaRes;
  511. WsbAffirmHr( pHsmManRes->GetFsaResource( &pUnkFsaRes ) );
  512. m_pFsaResource.Release( );
  513. WsbAffirmHr( RsQueryInterface( pUnkFsaRes, IFsaResource, m_pFsaResource ) );
  514. //
  515. // Get and save the unique Id for this volume
  516. //
  517. WsbAffirmHr( m_pFsaResource->GetIdentifier( &m_ObjectId ) );
  518. //
  519. // Set up the connection point
  520. //
  521. CSakNode::SetConnection( pUnkFsaRes );
  522. //
  523. // Set object properties
  524. //
  525. RefreshObject();
  526. } WsbCatch( hr );
  527. WsbTraceOut( L"CUiManVol::InitNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  528. return( hr );
  529. }
  530. STDMETHODIMP
  531. CUiManVol::TerminateNode(
  532. )
  533. /*++
  534. Routine Description:
  535. Free any interface connections or other resources
  536. that would prevent correct shutdown of node (would
  537. keep ref count from going to 0).
  538. Arguments:
  539. CopySet - copy set of interest.
  540. pszValue - return string representing the state.
  541. Return Value:
  542. S_OK - Handled.
  543. E_* - Some error occurred.
  544. --*/
  545. {
  546. WsbTraceIn( L"CUiManVol::TerminateNode", L"" );
  547. HRESULT hr = S_OK;
  548. try {
  549. //
  550. // Release any interface pointers kept so that circular references
  551. // are broken
  552. //
  553. m_pFsaResource.Release( );
  554. //
  555. // call the base class for it's pieces
  556. //
  557. CSakNode::TerminateNode( );
  558. } WsbCatch( hr );
  559. WsbTraceOut( L"CUiManVol::TerminateNode", L"hr = <%ls>", WsbHrAsString( hr ) );
  560. return( hr );
  561. }
  562. HRESULT
  563. CUiManVol::RemoveObject()
  564. {
  565. WsbTraceIn( L"CUiManVol::RemoveObject", L"" );
  566. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  567. HRESULT hr = S_OK;
  568. try {
  569. //
  570. // use wizard to create manage volume
  571. //
  572. CComObject<CUnmanageWizard>* pWizard = new CComObject<CUnmanageWizard>;
  573. WsbAffirmAlloc( pWizard );
  574. WsbAffirmHr( pWizard->SetNode( this ) );
  575. CComPtr<ISakWizard> pSakWizard = (ISakWizard*)pWizard;
  576. WsbAffirmHr( m_pSakSnapAsk->CreateWizard( pSakWizard ) );
  577. //
  578. // Refresh will take place when called back from FSA
  579. //
  580. } WsbCatch( hr );
  581. WsbTraceOut( L"CUiManVol::RemoveObject", L"hr = <%ls>", WsbHrAsString( hr ) );
  582. return hr;
  583. }
  584. //---------------------------------------------------------------------------------
  585. //
  586. // RefreshObject
  587. //
  588. // Refresh data in the object. This function is used for data that can change
  589. // (for example, volume utilization).
  590. //
  591. //
  592. STDMETHODIMP
  593. CUiManVol::RefreshObject()
  594. {
  595. WsbTraceIn( L"CUiManVol::RefreshObject", L"" );
  596. HRESULT hr = S_OK;
  597. ULONG hsmLevel = 0;
  598. LONGLONG fileSize = 0;
  599. BOOL isRelative = TRUE; // assumed to be TRUE
  600. FILETIME accessTime;
  601. UINT accessTimeDays;
  602. LONGLONG total = 0;
  603. LONGLONG free = 0;
  604. LONGLONG premigrated = 0;
  605. LONGLONG truncated = 0;
  606. int percent;
  607. CString sFormat;
  608. try {
  609. WsbAffirmPointer( m_pFsaResource );
  610. // Get and format the volume name and label
  611. CString addString;
  612. WsbAffirmHr( RsGetVolumeDisplayName( m_pFsaResource, addString ) );
  613. WsbAffirmHr( put_DisplayName( (LPTSTR)(LPCTSTR)addString ) );
  614. WsbAffirmHr( RsGetVolumeSortKey( m_pFsaResource, addString ) );
  615. WsbAffirmHr( put_DisplayName_SortKey( (LPTSTR)(LPCTSTR)addString ) );
  616. // Get level settings
  617. WsbAffirmHr( m_pFsaResource->GetHsmLevel( &hsmLevel ) );
  618. put_DesiredFreeSpaceP( hsmLevel / FSA_HSMLEVEL_1 );
  619. WsbAffirmHr( m_pFsaResource->GetManageableItemLogicalSize( &fileSize ) );
  620. put_MinFileSizeKb( (LONG) (fileSize / 1024) ); // Show KBytes
  621. WsbAffirmHr( m_pFsaResource->GetManageableItemAccessTime( &isRelative, &accessTime ) );
  622. WsbAssert( isRelative, E_FAIL ); // We only do relative time
  623. // Convert FILETIME to days
  624. LONGLONG temp = WSB_FT_TICKS_PER_DAY;
  625. accessTimeDays = (UINT) ( WsbFTtoLL( accessTime ) / temp );
  626. if (accessTimeDays > 999 ) {
  627. accessTimeDays = 0;
  628. }
  629. put_AccessDays( accessTimeDays );
  630. // Get statistics
  631. WsbAffirmHr( m_pFsaResource->GetSizes( &total, &free, &premigrated, &truncated ) );
  632. percent = (int) ( ( free * 100 ) / total );
  633. put_FreeSpaceP( percent );
  634. put_Capacity( total );
  635. put_FreeSpace( free );
  636. put_Premigrated( premigrated );
  637. put_Truncated( truncated );
  638. put_IsAvailable( IsAvailable( ) == S_OK );
  639. } WsbCatch( hr );
  640. WsbTraceOut( L"CUiManVol::RefreshObject", L"hr = <%ls>", WsbHrAsString( hr ) );
  641. return hr;
  642. }
  643. //-----------------------------------------------------------------------------
  644. //
  645. // get and put functions for object properties
  646. //
  647. HRESULT CUiManVol::put_DesiredFreeSpaceP( int percent )
  648. {
  649. m_DesiredFreeSpaceP = percent;
  650. return S_OK;
  651. }
  652. HRESULT CUiManVol::put_MinFileSizeKb( LONG minFileSizeKb )
  653. {
  654. m_MinFileSizeKb = minFileSizeKb;
  655. return S_OK;
  656. }
  657. HRESULT CUiManVol::put_AccessDays( int accessTimeDays )
  658. {
  659. m_AccessDays = accessTimeDays;
  660. return S_OK;
  661. }
  662. HRESULT CUiManVol::put_FreeSpaceP( int percent )
  663. {
  664. m_FreeSpaceP = percent;
  665. return S_OK;
  666. }
  667. HRESULT CUiManVol::put_Capacity( LONGLONG capacity )
  668. {
  669. m_Capacity = capacity;
  670. return S_OK;
  671. }
  672. HRESULT CUiManVol::put_FreeSpace( LONGLONG freeSpace )
  673. {
  674. m_FreeSpace = freeSpace;
  675. return S_OK;
  676. }
  677. HRESULT CUiManVol::put_Premigrated( LONGLONG premigrated )
  678. {
  679. m_Premigrated = premigrated;
  680. return S_OK;
  681. }
  682. HRESULT CUiManVol::put_Truncated( LONGLONG truncated )
  683. {
  684. m_Truncated = truncated;
  685. return S_OK;
  686. }
  687. STDMETHODIMP CUiManVol::get_DesiredFreeSpaceP( BSTR *pszValue )
  688. {
  689. HRESULT hr = S_OK;
  690. try {
  691. if( S_OK == IsAvailable( ) ) {
  692. CString sFormat;
  693. WCHAR buffer[256];
  694. // Format the byte value
  695. RsGuiFormatLongLong4Char( ( m_Capacity / (LONGLONG)100 ) * (LONGLONG)(m_DesiredFreeSpaceP), sFormat );
  696. // Format the percent value
  697. _itow( m_DesiredFreeSpaceP, buffer, 10 );
  698. sFormat = sFormat + L" (" + buffer + L"%)";
  699. // Allocate the string
  700. *pszValue = SysAllocString( sFormat );
  701. } else {
  702. *pszValue = SysAllocString( L"" );
  703. }
  704. WsbAffirmAlloc( *pszValue );
  705. } WsbCatch( hr );
  706. return( hr );
  707. }
  708. STDMETHODIMP CUiManVol::get_DesiredFreeSpaceP_SortKey( BSTR *pszValue )
  709. {
  710. HRESULT hr = S_OK;
  711. try {
  712. if( S_OK == IsAvailable( ) ) {
  713. *pszValue = SysAlloc64BitSortKey( ( m_Capacity / (LONGLONG)100 ) * (LONGLONG)(m_DesiredFreeSpaceP) );
  714. } else {
  715. *pszValue = SysAllocString( L"" );
  716. }
  717. WsbAffirmAlloc( *pszValue );
  718. } WsbCatch( hr );
  719. return( hr );
  720. }
  721. STDMETHODIMP CUiManVol::get_MinFileSizeKb( BSTR *pszValue )
  722. {
  723. HRESULT hr = S_OK;
  724. try {
  725. if( S_OK == IsAvailable( ) ) {
  726. WCHAR buffer[256];
  727. // Format the value
  728. _ltow( m_MinFileSizeKb, buffer, 10 );
  729. wcscat( buffer, L"KB" );
  730. // Allocate the string
  731. *pszValue = SysAllocString( buffer );
  732. } else {
  733. *pszValue = SysAllocString( L"" );
  734. }
  735. WsbAffirmAlloc( *pszValue );
  736. } WsbCatch( hr );
  737. return( hr );
  738. }
  739. STDMETHODIMP CUiManVol::get_AccessDays( BSTR *pszValue )
  740. {
  741. HRESULT hr = S_OK;
  742. WCHAR buffer[256];
  743. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  744. try {
  745. if( S_OK == IsAvailable( ) ) {
  746. // Format the value
  747. _itow( m_AccessDays, buffer, 10 );
  748. CString sDays;
  749. sDays.LoadString( IDS_DAYS );
  750. wcscat( buffer, L" " );
  751. wcscat( buffer, sDays );
  752. // Allocate the string
  753. *pszValue = SysAllocString( buffer );
  754. } else {
  755. *pszValue = SysAllocString( L"" );
  756. }
  757. WsbAffirmAlloc( *pszValue );
  758. } WsbCatch( hr );
  759. return( hr );
  760. }
  761. STDMETHODIMP CUiManVol::get_FreeSpaceP( BSTR *pszValue )
  762. {
  763. HRESULT hr = S_OK;
  764. try {
  765. if( S_OK == IsAvailable( ) ) {
  766. WCHAR buffer[256];
  767. // Format the value
  768. _itow( m_FreeSpaceP, buffer, 10 );
  769. wcscat( buffer, L"%" );
  770. // Allocate the string
  771. *pszValue = SysAllocString( buffer );
  772. } else {
  773. *pszValue = SysAllocString( L"" );
  774. }
  775. WsbAffirmAlloc( *pszValue );
  776. } WsbCatch( hr );
  777. return( hr );
  778. }
  779. STDMETHODIMP CUiManVol::get_Capacity( BSTR *pszValue )
  780. {
  781. WsbTraceIn( L"CUiManVol::get_Capacity", L"" );
  782. HRESULT hr = S_OK;
  783. try {
  784. if( S_OK == IsAvailable( ) ) {
  785. CString sFormat;
  786. // Format the value
  787. WsbAffirmHr( RsGuiFormatLongLong4Char( m_Capacity, sFormat ) );
  788. // Allocate the string
  789. *pszValue = SysAllocString( sFormat );
  790. } else {
  791. *pszValue = SysAllocString( L"" );
  792. }
  793. WsbAffirmAlloc( *pszValue );
  794. } WsbCatch( hr );
  795. WsbTraceOut( L"CUiManVol::get_Capacity", L"hr = <%ls>, *pszValue = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pszValue ) );
  796. return( hr );
  797. }
  798. STDMETHODIMP CUiManVol::get_Capacity_SortKey( BSTR *pszValue )
  799. {
  800. WsbTraceIn( L"CUiManVol::get_Capacity_SortKey", L"" );
  801. HRESULT hr = S_OK;
  802. try {
  803. if( S_OK == IsAvailable( ) ) {
  804. *pszValue = SysAlloc64BitSortKey( m_Capacity );
  805. } else {
  806. *pszValue = SysAllocString( L"" );
  807. }
  808. WsbAffirmAlloc( *pszValue );
  809. } WsbCatch( hr );
  810. WsbTraceOut( L"CUiManVol::get_Capacity_SortKey", L"hr = <%ls>, *pszValue = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pszValue ) );
  811. return( hr );
  812. }
  813. STDMETHODIMP CUiManVol::get_FreeSpace( BSTR *pszValue )
  814. {
  815. HRESULT hr = S_OK;
  816. try {
  817. if( S_OK == IsAvailable( ) ) {
  818. CString sFormat;
  819. WCHAR buffer[256];
  820. // Format the byte value
  821. WsbAffirmHr( RsGuiFormatLongLong4Char( m_FreeSpace, sFormat ) );
  822. // Format the percent value
  823. _itow( m_FreeSpaceP, buffer, 10 );
  824. sFormat = sFormat + L" (" + buffer + L"%)";
  825. // Allocate the string
  826. *pszValue = SysAllocString( sFormat );
  827. } else {
  828. *pszValue = SysAllocString( L"" );
  829. }
  830. WsbAffirmAlloc( *pszValue );
  831. } WsbCatch( hr );
  832. return( hr );
  833. }
  834. STDMETHODIMP CUiManVol::get_FreeSpace_SortKey( BSTR *pszValue )
  835. {
  836. HRESULT hr = S_OK;
  837. try {
  838. if( S_OK == IsAvailable( ) ) {
  839. *pszValue = SysAlloc64BitSortKey( m_FreeSpace );
  840. } else {
  841. *pszValue = SysAllocString( L"" );
  842. }
  843. WsbAffirmAlloc( *pszValue );
  844. } WsbCatch( hr );
  845. return( hr );
  846. }
  847. STDMETHODIMP CUiManVol::get_Premigrated( BSTR *pszValue )
  848. {
  849. HRESULT hr = S_OK;
  850. try {
  851. if( S_OK == IsAvailable( ) ) {
  852. CString sFormat;
  853. // Format the value
  854. WsbAffirmHr( RsGuiFormatLongLong4Char( m_Premigrated, sFormat ) );
  855. // Allocate the string
  856. *pszValue = SysAllocString( sFormat );
  857. } else {
  858. *pszValue = SysAllocString( L"" );
  859. }
  860. WsbAffirmAlloc( *pszValue );
  861. } WsbCatch( hr );
  862. return( hr );
  863. }
  864. STDMETHODIMP CUiManVol::get_Truncated( BSTR *pszValue )
  865. {
  866. HRESULT hr = S_OK;
  867. try {
  868. if( S_OK == IsAvailable( ) ) {
  869. CString sFormat;
  870. // Format the value
  871. WsbAffirmHr( RsGuiFormatLongLong4Char( m_Truncated, sFormat ) );
  872. // Allocate the string
  873. *pszValue = SysAllocString( sFormat );
  874. } else {
  875. *pszValue = SysAllocString( L"" );
  876. }
  877. WsbAffirmAlloc( *pszValue );
  878. } WsbCatch( hr );
  879. return( hr );
  880. }
  881. /////////////////////////////////////////////////////////////////////////////////////////
  882. //
  883. // class CUiManVolSheet
  884. //
  885. HRESULT CUiManVolSheet::AddPropertyPages( )
  886. {
  887. WsbTraceIn( L"CUiManVolSheet::AddPropertyPages", L"" );
  888. HRESULT hr = S_OK;
  889. try {
  890. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  891. //
  892. //-----------------------------------------------------------
  893. // Create the Hsm Statistics property page.
  894. //
  895. CPrMrSts *pPropPageStatus = new CPrMrSts();
  896. WsbAffirmAlloc( pPropPageStatus );
  897. AddPage( pPropPageStatus );
  898. //
  899. //----------------------------------------------------------
  900. // Create the Hsm levels property page.
  901. //
  902. CPrMrLvl *pPropPageLevels = new CPrMrLvl();
  903. WsbAffirmAlloc( pPropPageLevels );
  904. AddPage( pPropPageLevels );
  905. if( IsMultiSelect() != S_OK ) {
  906. //
  907. //----------------------------------------------------------
  908. // Create the Hsm Include/Exclude property page.
  909. //
  910. CPrMrIe *pPropPageIncExc = new CPrMrIe();
  911. WsbAffirmAlloc( pPropPageIncExc );
  912. AddPage( pPropPageIncExc );
  913. }
  914. } WsbCatch( hr );
  915. WsbTraceOut( L"CUiManVolSheet::AddPropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) );
  916. return( hr );
  917. }
  918. HRESULT CUiManVolSheet::GetNextFsaResource( int *pBookMark, IFsaResource **ppFsaResource )
  919. {
  920. WsbTraceIn( L"CUiManVolSheet::GetNextFsaResource", L"*pBookMark = <%ld>", WsbPtrToLongAsString( (LONG*)pBookMark ) );
  921. HRESULT hr = S_OK;
  922. GUID objectId;
  923. try {
  924. WsbAffirmPointer( pBookMark );
  925. WsbAffirm( *pBookMark >= 0, E_FAIL );
  926. //
  927. // Get the Fsa Server so we can get Fsa Resources
  928. //
  929. CComPtr <IFsaServer> pFsaServer;
  930. WsbAffirmHr( GetFsaServer( &pFsaServer ) );
  931. if( *pBookMark <= m_ObjectIdList.GetUpperBound( ) ) {
  932. objectId = m_ObjectIdList[ *pBookMark ];
  933. (*pBookMark)++;
  934. WsbAffirmHr( pFsaServer->FindResourceById( objectId, ppFsaResource ) );
  935. } else {
  936. hr = S_FALSE;
  937. }
  938. } WsbCatch( hr );
  939. WsbTraceOut( L"CUiManVolSheet::GetNextFsaResource", L"hr = <%ls>", WsbHrAsString( hr ) );
  940. return hr;
  941. }
  942. STDMETHODIMP
  943. CUiManVol::GetResultIcon(
  944. IN BOOL bOK,
  945. OUT int* pIconIndex
  946. )
  947. {
  948. WsbTraceIn( L"CUiManVol::GetResultIcon", L"" );
  949. HRESULT hr = S_OK;
  950. try {
  951. WsbAffirmPointer( m_pFsaResource );
  952. if( S_OK == IsAvailable( ) ) {
  953. //
  954. // Check to make sure it's not deleted (or being deleted)
  955. // If so, put on the X
  956. //
  957. bOK = ( S_FALSE == m_pFsaResource->IsDeletePending( ) && S_OK == m_pFsaResource->IsManaged( ) );
  958. WsbAffirmHr( CSakNodeImpl<CUiManVol>::GetResultIcon( bOK, pIconIndex ) );
  959. } else {
  960. *pIconIndex = m_nResultIconD;
  961. }
  962. } WsbCatch( hr );
  963. WsbTraceOut( L"CUiManVol::GetResultIcon", L"hr = <%ls>", WsbHrAsString( hr ) );
  964. return( hr );
  965. }
  966. STDMETHODIMP
  967. CUiManVol::SupportsProperties(
  968. BOOL bMultiSelect
  969. )
  970. {
  971. WsbTraceIn( L"CUiManVol::SupportsProperties", L"" );
  972. HRESULT hr = S_OK;
  973. try {
  974. WsbAffirmPointer( m_pFsaResource );
  975. if( !bMultiSelect &&
  976. ( S_OK == m_pFsaResource->IsDeletePending( ) || S_OK != IsAvailable( ) ) ) {
  977. hr = S_FALSE;
  978. } else {
  979. hr = CSakNode::SupportsProperties( bMultiSelect );
  980. }
  981. } WsbCatch( hr );
  982. WsbTraceOut( L"CUiManVol::SupportsProperties", L"hr = <%ls>", WsbHrAsString( hr ) );
  983. return( hr );
  984. }
  985. STDMETHODIMP CUiManVol::SupportsRefresh( BOOL bMultiSelect )
  986. {
  987. WsbTraceIn( L"CUiManVol::SupportsRefresh", L"" );
  988. HRESULT hr = S_OK;
  989. try {
  990. WsbAffirmPointer( m_pFsaResource );
  991. if( !bMultiSelect && S_OK == m_pFsaResource->IsDeletePending( ) ) {
  992. hr = S_FALSE;
  993. } else {
  994. hr = CSakNode::SupportsRefresh( bMultiSelect );
  995. }
  996. } WsbCatch( hr );
  997. WsbTraceOut( L"CUiManVol::SupportsRefresh", L"hr = <%ls>", WsbHrAsString( hr ) );
  998. return( hr );
  999. }
  1000. STDMETHODIMP CUiManVol::IsValid( void )
  1001. {
  1002. WsbTraceIn( L"CUiManVol::IsValid", L"" );
  1003. HRESULT hr = S_OK;
  1004. try {
  1005. WsbAffirmPointer( m_pFsaResource );
  1006. //
  1007. // Still valid if managed.
  1008. //
  1009. WsbAffirmHrOk( m_pFsaResource->IsManaged( ) );
  1010. } WsbCatch( hr );
  1011. WsbTraceOut( L"CUiManVol::IsValid", L"hr = <%ls>", WsbHrAsString( hr ) );
  1012. return( hr );
  1013. }
  1014. HRESULT CUiManVol::IsAvailable( void )
  1015. {
  1016. WsbTraceIn( L"CUiManVol::IsAvailable", L"" );
  1017. HRESULT hr = S_FALSE;
  1018. try {
  1019. WsbAffirmPointer( m_pFsaResource );
  1020. //
  1021. // Under certain circumstances we can't get a good answer back, so
  1022. // we have to rely on the last answer we got.
  1023. //
  1024. HRESULT hrAvailable = m_pFsaResource->IsAvailable( );
  1025. if( RPC_E_CANTCALLOUT_ININPUTSYNCCALL == hrAvailable ) {
  1026. hrAvailable = m_HrAvailable;
  1027. }
  1028. hr = hrAvailable;
  1029. m_HrAvailable = hrAvailable;
  1030. } WsbCatch( hr );
  1031. WsbTraceOut( L"CUiManVol::IsAvailable", L"hr = <%ls>", WsbHrAsString( hr ) );
  1032. return( hr );
  1033. }
  1034. HRESULT CUiManVol::put_IsAvailable( BOOL Available )
  1035. {
  1036. WsbTraceIn( L"CUiManVol::put_IsAvailable", L"Available = <%ls>", WsbBoolAsString( Available ) );
  1037. HRESULT hr = S_FALSE;
  1038. try {
  1039. m_HrAvailable = Available ? S_OK : S_FALSE;
  1040. } WsbCatch( hr );
  1041. WsbTraceOut( L"CUiManVol::put_IsAvailable", L"hr = <%ls>", WsbHrAsString( hr ) );
  1042. return( hr );
  1043. }