/*++ © 1998 Seagate Software, Inc. All rights reserved Module Name: ManVol.cpp Abstract: Managed Volume node implementation. Author: Rohde Wakefield [rohde] 08-Aug-1997 Revision History: --*/ #include "stdafx.h" #include #include "ManVol.h" #include "PrMrSts.h" #include "PrMrIe.h" #include "WzUnmang.h" int CUiManVol::m_nResultIcon = AddResultImage( IDI_NODEMANVOL ); int CUiManVol::m_nResultIconX = AddResultImage( IDI_NODEMANVOLX ); int CUiManVol::m_nResultIconD = AddResultImage( IDI_NODEMANVOLD ); // Not used int CUiManVol::m_nScopeCloseIcon = AddScopeImage( IDI_NODEMANVOL ); int CUiManVol::m_nScopeCloseIconX = AddScopeImage( IDI_NODEMANVOLX ); int CUiManVol::m_nScopeOpenIcon = CUiManVol::m_nScopeCloseIcon; int CUiManVol::m_nScopeOpenIconX = CUiManVol::m_nScopeCloseIconX; UINT CUiManVol::m_ObjectTypes = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT); UINT CUiManVol::m_MultiSelect = RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS); ///////////////////////////////////////////////////////////////////////////// // // CoComObjectRoot // ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- // // FinalConstruct // // Initialize this level of the object hierarchy // HRESULT CUiManVol::FinalConstruct( ) { WsbTraceIn( L"CUiManVol::FinalConstruct", L"" ); m_rTypeGuid = &cGuidManVol; HRESULT hr = CSakNode::FinalConstruct( ); m_bSupportsPropertiesSingle = TRUE; m_bSupportsPropertiesMulti = TRUE; m_bSupportsDeleteSingle = FALSE; m_bSupportsDeleteMulti = FALSE; m_bSupportsRefreshSingle = TRUE; m_bSupportsRefreshMulti = FALSE; m_bIsContainer = FALSE; m_pFsaResource = NULL; m_HrAvailable = S_FALSE; // Toolbar values INT i = 0; #if 0 // MS does not want these toolbar buttons to show up m_ToolbarButtons[i].nBitmap = 0; m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_SETTINGS; m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_SETTINGS; m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_SETTINGS; i++; m_ToolbarButtons[i].nBitmap = 1; m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_TOOLS; m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_TOOLS; m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_TOOLS; i++; m_ToolbarButtons[i].nBitmap = 2; m_ToolbarButtons[i].idCommand = TB_CMD_VOLUME_RULES; m_ToolbarButtons[i].idButtonText = IDS_TB_TEXT_VOLUME_RULES; m_ToolbarButtons[i].idTooltipText = IDS_TB_TIP_VOLUME_RULES; i++; #endif m_ToolbarBitmap = IDB_TOOLBAR_VOLUME; m_cToolbarButtons = i; WsbTraceOut( L"CUiManVol::FinalConstruct", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } //--------------------------------------------------------------------------- // // FinalRelease // // Clean up this level of the object hierarchy // void CUiManVol::FinalRelease( ) { WsbTraceIn( L"CUiManVol::FinalRelease", L"" ); CSakNode::FinalRelease( ); WsbTraceOut( L"CUiManVol::FinalRelease", L"" ); } ///////////////////////////////////////////////////////////////////////////// // // ISakNode // ///////////////////////////////////////////////////////////////////////////// //--------------------------------------------------------------------------- // // GetContextMenu // // Return an HMENU to be used for context menus on this node. // STDMETHODIMP CUiManVol::GetContextMenu( BOOL bMultiSelect, HMENU* phMenu ) { WsbTraceIn( L"CUiManVol::GetContextMenu", L"" ); AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = S_OK; try { WsbAffirmPointer( m_pFsaResource ); LoadContextMenu( IDR_MANVOL, phMenu ); CMenu* pRootMenu; CMenu* pTaskMenu; CMenu menu; menu.Attach( *phMenu ); pRootMenu = menu.GetSubMenu( MENU_INDEX_ROOT ); pTaskMenu = menu.GetSubMenu( MENU_INDEX_TASK ); // // If multi-select, disable these items // // // else if engine down or resource is being unmanaged, or appears to be missing // (formatted new?), disable these items // BOOL bState = ( m_pSakSnapAsk->GetState( ) == S_OK ); BOOL bDeletePending = ( m_pFsaResource->IsDeletePending( ) == S_OK ); BOOL bAvailable = ( IsAvailable( ) == S_OK ); if( bMultiSelect ) { pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_RULES, MF_GRAYED | MF_BYCOMMAND ); pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_REMOVE, MF_GRAYED | MF_BYCOMMAND ); } else { pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_LEVELS, MF_BYCOMMAND | ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) ); pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_TASKS, MF_BYCOMMAND | ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) ); pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_RULES, MF_BYCOMMAND | ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) ); pRootMenu->EnableMenuItem( ID_MANVOL_ROOT_REMOVE, MF_BYCOMMAND | ( ( !bState || bDeletePending ) ? MF_GRAYED : MF_ENABLED ) ); pTaskMenu->EnableMenuItem( ID_MANVOL_ROOT_TOOLS_COPY, MF_BYCOMMAND | ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) ); pTaskMenu->EnableMenuItem( ID_MANVOL_ROOT_TOOLS_VALIDATE, MF_BYCOMMAND | ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) ); pTaskMenu->EnableMenuItem( ID_MANVOL_ROOT_TOOLS_CREATE_FREESPACE, MF_BYCOMMAND | ( ( !bState || bDeletePending || !bAvailable ) ? MF_GRAYED : MF_ENABLED ) ); } menu.Detach( ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::GetContextMenu", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } //--------------------------------------------------------------------------- // // InvokeCommand // // User has selected a command from the menu. Process it here. // STDMETHODIMP CUiManVol::InvokeCommand( SHORT sCmd, IDataObject* pDataObject ) { WsbTraceIn( L"CUiManVol::InvokeCommand", L"sCmd = <%d>", sCmd ); CString theString; HRESULT hr = S_OK; AFX_MANAGE_STATE(AfxGetStaticModuleState()); try { WsbAffirmPointer( m_pFsaResource ); if( S_OK != m_pFsaResource->IsDeletePending( ) ) { switch( sCmd ) { case ID_MANVOL_ROOT_REMOVE: // // Should not be called for multi-select // RemoveObject(); break; case ID_MANVOL_ROOT_LEVELS: case ID_MANVOL_TASK_LEVELS: ShowManVolProperties( pDataObject, 1 ); break; case ID_MANVOL_ROOT_RULES: case ID_MANVOL_TASK_RULES: // // Should not be called for multi-select // ShowManVolProperties( pDataObject, 2 ); break; case ID_MANVOL_ROOT_TOOLS_COPY : HandleTask( pDataObject, HSM_JOB_DEF_TYPE_MANAGE ); break; case ID_MANVOL_ROOT_TOOLS_VALIDATE : HandleTask( pDataObject, HSM_JOB_DEF_TYPE_VALIDATE ); break; case ID_MANVOL_ROOT_TOOLS_CREATE_FREESPACE : HandleTask( pDataObject, HSM_JOB_DEF_TYPE_TRUNCATE ); break; default: break; } } else { CString message; AfxFormatString1( message, IDS_ERR_VOLUME_DELETE_PENDING, m_szName ); AfxMessageBox( message, RS_MB_ERROR ); } } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::InvokeCommand", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CUiManVol::OnToolbarButtonClick( IDataObject *pDataObject, long cmdId ) { WsbTraceIn( L"CUiManVol::OnToolbarButtonClick", L"cmdId = <%d>", cmdId ); HRESULT hr = S_OK; try { WsbAffirmPointer( m_pFsaResource ); if( S_OK != m_pFsaResource->IsDeletePending( ) ) { try { switch( cmdId ) { case TB_CMD_VOLUME_SETTINGS: ShowManVolProperties( pDataObject, 1 ); break; case TB_CMD_VOLUME_TOOLS: ShowManVolProperties( pDataObject, 2 ); break; case TB_CMD_VOLUME_RULES: ShowManVolProperties( pDataObject, 3 ); break; } } WsbCatch( hr ); } else { CString message; AfxFormatString1( message, IDS_ERR_VOLUME_DELETE_PENDING, m_szName ); AfxMessageBox( message, RS_MB_ERROR ); } } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::OnToolbarButtonClick", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CUiManVol::ShowManVolProperties( IDataObject *pDataObject, int initialPage ) { WsbTraceIn( L"CUiManVol::ShowManVolProperties", L"initialPage = <%d>", initialPage ); HRESULT hr = S_OK; try { CComPtr pSakNode; WsbAffirmHr( _InternalQueryInterface( IID_ISakNode, (void **) &pSakNode ) ); WsbAffirmHr( m_pSakSnapAsk->ShowPropertySheet( pSakNode, pDataObject, initialPage ) ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::ShowManVolProperties", L"hr = <%ls>", WsbHrAsString( hr ) ); return hr; } HRESULT CUiManVol::CreateAndRunManVolJob( HSM_JOB_DEF_TYPE jobType ) { WsbTraceIn( L"CUiManVol::CreateAndRunManVolJob", L"jobType = <0x%p>", jobType ); HRESULT hr = 0; try { WsbAffirmPointer( m_pFsaResource ); // // Get a pointer to the FsaResource interface // CComPtr pHsmServer; WsbAffirmHrOk( m_pSakSnapAsk->GetHsmServer( &pHsmServer ) ); RsCreateAndRunFsaJob( jobType, pHsmServer, m_pFsaResource ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::CreateAndRunManVolJob", L"hr = <%ls>", WsbHrAsString( hr ) ); return hr; } HRESULT CUiManVol::HandleTask( IDataObject * pDataObject, HSM_JOB_DEF_TYPE jobType ) { WsbTraceIn( L"CUiManVol::HandleTask", L"pDataObject = <0x%p>, jobType = <0x%p>", pDataObject, jobType ); HRESULT hr = 0; try { UINT nMsgId = 0; CComPtr pHsmServer; WsbAffirmHrOk( m_pSakSnapAsk->GetHsmServer( &pHsmServer ) ); // // Submit jobs for all selected FsaResource's // if ( IsDataObjectMultiSelect( pDataObject ) == S_OK ) { CComPtr pOtDataObject; if ( IsDataObjectMs( pDataObject ) == S_OK ) { WsbAffirmHr( GetOtFromMs( pDataObject, &pOtDataObject ) ); } else { pOtDataObject = pDataObject; } // Get a pointer to a FsaResource attribute out of the data ULONG nElem = 1; CComPtr pMsDataObject; CComPtr pUnkNode; CComPtr pEnumUnkNode; WsbAffirmHr( pOtDataObject.QueryInterface( &pMsDataObject ) ); WsbAffirmHr( pMsDataObject->GetNodeEnumerator( &pEnumUnkNode ) ); // Prompt the user that we are about to submit the jobs. CString tempString; UINT msgId = 0; WsbAffirmHr( GetTaskTypeMessageId( jobType, TRUE, &msgId ) ); CWsbStringPtr computerName; WsbAffirmHr( pHsmServer->GetName( &computerName ) ); CString message; AfxFormatString1( message, msgId, computerName ); tempString.LoadString( IDS_RUN_JOB_MULTI2 ); message += tempString; if ( AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 ) == IDOK ) { while ( pEnumUnkNode->Next( nElem, &pUnkNode, NULL ) == S_OK ) { CComPtr pNode; WsbAffirmHr( pUnkNode.QueryInterface( &pNode ) ); pUnkNode.Release(); CComPtr pUnk; WsbAffirmHr( pNode->GetHsmObj( &pUnk ) ); CComPtr pManRes; WsbAffirmHr( pUnk.QueryInterface( &pManRes ) ); // // Then Get Coresponding FSA resource // CComPtr pUnkFsaRes; WsbAffirmHr( pManRes->GetFsaResource( &pUnkFsaRes ) ); CComPtr pFsaResource; WsbAffirmHr( pUnkFsaRes.QueryInterface( &pFsaResource ) ); RsCreateAndRunFsaJob( jobType, pHsmServer, pFsaResource, FALSE ); } } } else { WsbAffirmPointer( m_pFsaResource ); // Prompt the user that we are about to submit the jobs. UINT msgId = 0; WsbAffirmHr( GetTaskTypeMessageId( jobType, FALSE, &msgId ) ); CWsbStringPtr computerName; WsbAffirmHr( pHsmServer->GetName( &computerName ) ); CString message; AfxFormatString1( message, msgId, computerName ); CString jobName; WsbAffirmHr( RsCreateJobName( jobType, m_pFsaResource, jobName ) ); CString tempString; AfxFormatString1( tempString, IDS_MONITOR_TASK, jobName ); message += tempString; if ( AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 ) == IDOK ) { RsCreateAndRunFsaJob( jobType, pHsmServer, m_pFsaResource, FALSE ); } } } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::HandleTask", L"hr = <%ls>", WsbHrAsString( hr ) ); return hr; } HRESULT CUiManVol::GetTaskTypeMessageId( HSM_JOB_DEF_TYPE jobType, BOOL multiSelect, UINT* msgId ) { WsbTraceIn( L"CUiManVol::GetTaskTypeMessageId", L"jobType = <%d>, msgId = <%d>, multiSelect = <%d>", jobType, msgId, multiSelect ); HRESULT hr = 0; try { WsbAffirmPointer( msgId ); switch ( jobType ) { case HSM_JOB_DEF_TYPE_MANAGE : if ( multiSelect ) *msgId = IDS_RUN_MULTI_COPY_JOBS; else *msgId = IDS_RUN_COPY_JOB; break; case HSM_JOB_DEF_TYPE_VALIDATE : if ( multiSelect ) *msgId = IDS_RUN_MULTI_VALIDATE_JOBS; else *msgId = IDS_RUN_VALIDATE_JOB; break; case HSM_JOB_DEF_TYPE_TRUNCATE : if ( multiSelect ) *msgId = IDS_RUN_MULTI_CFS_JOBS; else *msgId = IDS_RUN_CFS_JOB; break; default: break; } } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::GetTaskTypeMessageId", L"jobType = <%d>, msgId = <%d>, multiSelect = <%d>", jobType, msgId, multiSelect ); return hr; } // Is the dataobject either type of multi-select dataobject? HRESULT CUiManVol::IsDataObjectMultiSelect ( IDataObject *pDataObject ) { HRESULT hr = S_OK; hr = ( ( (IsDataObjectOt( pDataObject ) ) == S_OK ) || ( (IsDataObjectMs( pDataObject ) ) == S_OK ) ) ? S_OK : S_FALSE; return hr; } // Is the dataobject an Object Types dataobject? HRESULT CUiManVol::IsDataObjectOt ( IDataObject *pDataObject ) { HRESULT hr = S_FALSE; // Is this a mutli-select data object? FORMATETC fmt = {(CLIPFORMAT)m_ObjectTypes, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; STGMEDIUM stgm = {TYMED_HGLOBAL, NULL}; if ( pDataObject->GetData( &fmt, &stgm ) == S_OK ) { hr = S_OK; } ReleaseStgMedium( &stgm ); return hr; } // Is the dataobject a Mutli-Select dataobject? HRESULT CUiManVol::IsDataObjectMs ( IDataObject *pDataObject ) { HRESULT hr = S_FALSE; // Is this a mutli-select data object? FORMATETC fmt = {(CLIPFORMAT)m_MultiSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; STGMEDIUM stgm = {TYMED_HGLOBAL, NULL}; if ( pDataObject->GetData( &fmt, &stgm ) == S_OK ) { hr = S_OK; } ReleaseStgMedium( &stgm ); return hr; } HRESULT CUiManVol::GetOtFromMs( IDataObject * pDataObject, IDataObject ** ppOtDataObject ) { WsbTraceIn( L"CUiManVol::GetOtFromMs", L"pDataObject = <0x%p>, ppOtDataObject = <0x%p>", pDataObject, ppOtDataObject ); HRESULT hr = S_OK; try { // We've got an MMC mutli-select data object. Get the first // data object from it's array of data objects FORMATETC fmt = {(CLIPFORMAT)m_MultiSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; STGMEDIUM stgm = {TYMED_HGLOBAL, NULL}; WsbAffirmHr ( pDataObject->GetData( &fmt, &stgm ) == S_OK ); DWORD count; memcpy( &count, stgm.hGlobal, sizeof (DWORD) ); if ( count > 0 ) { // // The following code is admittedly UGLY // We have a data stream where we need to skip past the // first DWORD count and grab an interface pointer. // Other snapins code does it as follows: // IDataObject * pDO; // memcpy( &pDO, (DWORD *) stgm.hGlobal + 1, sizeof(IDataObject*) ); // // However, since this code does an indirect cast (via memcpy) // from DWORD to IDataObject*, and does not keep a true reference // on the interface pointer, we will use a smart pointer. // The (DWORD*) and +1 operation bump our pointer past the count. // We then need to grab the next bytes in the buffer and use them // as a IDataObject *. // CComPtr pOtDataObject; pOtDataObject = *( (IDataObject**)( (DWORD *) stgm.hGlobal + 1 ) ); WsbAffirmHr( pOtDataObject->QueryInterface( IID_IDataObject, (void**) ppOtDataObject ) ); } ReleaseStgMedium( &stgm ); } WsbCatch ( hr ); WsbTraceOut( L"CUiManVol::GetOtFromMs", L"pDataObject = <0x%p>, ppOtDataObject = <0x%p>", pDataObject, ppOtDataObject ); return ( hr ); } STDMETHODIMP CUiManVol::AddPropertyPages( RS_NOTIFY_HANDLE handle, IUnknown* pUnkPropSheetCallback, IEnumGUID *pEnumObjectId, IEnumUnknown *pEnumUnkNode ) { WsbTraceIn( L"CUiManVol::AddPropertyPages", L"handle = <%ld>, pUnkPropSheetCallback = <0x%0.l8x>, pEnumObjectId = <0x%p>", handle, pUnkPropSheetCallback, pEnumObjectId ); HRESULT hr = S_OK; try { // // Make sure we can still contact the engine before doing this // If not running, we shouldn't even exist so update parent // CComPtr pHsmServer; HRESULT hrRunning = m_pSakSnapAsk->GetHsmServer( &pHsmServer ); if( S_FALSE == hrRunning ) { m_pSakSnapAsk->UpdateAllViews( m_pParent ); } WsbAffirmHrOk( hrRunning ); // // Create an object to hold the pages // CUiManVolSheet *pManVolPropertySheet = new CUiManVolSheet; WsbAffirmAlloc( pManVolPropertySheet ); WsbAffirmHr( pManVolPropertySheet->InitSheet( handle, pUnkPropSheetCallback, this, m_pSakSnapAsk, pEnumObjectId, pEnumUnkNode ) ); // // Tell the object to add it's pages // WsbAffirmHr( pManVolPropertySheet->AddPropertyPages( ) ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::AddPropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } //--------------------------------------------------------------------------- // // InitNode // // Initialize single COM object. Derived objects frequently augment this // method by implementing it themselves. // STDMETHODIMP CUiManVol::InitNode( ISakSnapAsk* pSakSnapAsk, IUnknown* pHsmObj, ISakNode* pParent ) { WsbTraceIn( L"CUiManVol::InitNode", L"pSakSnapAsk = <0x%p>, pHsmObj = <0x%p>, pParent = <0x%p>", pSakSnapAsk, pHsmObj, pParent ); HRESULT hr = S_OK; try { WsbAffirmHr( CSakNode::InitNode( pSakSnapAsk, pHsmObj, pParent )); // // Get the Fsa object pointer // CComQIPtr pHsmManRes = m_pHsmObj; WsbAffirmPointer( pHsmManRes ); CComPtr pUnkFsaRes; WsbAffirmHr( pHsmManRes->GetFsaResource( &pUnkFsaRes ) ); m_pFsaResource.Release( ); WsbAffirmHr( RsQueryInterface( pUnkFsaRes, IFsaResource, m_pFsaResource ) ); // // Get and save the unique Id for this volume // WsbAffirmHr( m_pFsaResource->GetIdentifier( &m_ObjectId ) ); // // Set up the connection point // CSakNode::SetConnection( pUnkFsaRes ); // // Set object properties // RefreshObject(); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::InitNode", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } STDMETHODIMP CUiManVol::TerminateNode( ) /*++ Routine Description: Free any interface connections or other resources that would prevent correct shutdown of node (would keep ref count from going to 0). Arguments: CopySet - copy set of interest. pszValue - return string representing the state. Return Value: S_OK - Handled. E_* - Some error occurred. --*/ { WsbTraceIn( L"CUiManVol::TerminateNode", L"" ); HRESULT hr = S_OK; try { // // Release any interface pointers kept so that circular references // are broken // m_pFsaResource.Release( ); // // call the base class for it's pieces // CSakNode::TerminateNode( ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::TerminateNode", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CUiManVol::RemoveObject() { WsbTraceIn( L"CUiManVol::RemoveObject", L"" ); AFX_MANAGE_STATE(AfxGetStaticModuleState()); HRESULT hr = S_OK; try { // // use wizard to create manage volume // CComObject* pWizard = new CComObject; WsbAffirmAlloc( pWizard ); WsbAffirmHr( pWizard->SetNode( this ) ); CComPtr pSakWizard = (ISakWizard*)pWizard; WsbAffirmHr( m_pSakSnapAsk->CreateWizard( pSakWizard ) ); // // Refresh will take place when called back from FSA // } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::RemoveObject", L"hr = <%ls>", WsbHrAsString( hr ) ); return hr; } //--------------------------------------------------------------------------------- // // RefreshObject // // Refresh data in the object. This function is used for data that can change // (for example, volume utilization). // // STDMETHODIMP CUiManVol::RefreshObject() { WsbTraceIn( L"CUiManVol::RefreshObject", L"" ); HRESULT hr = S_OK; ULONG hsmLevel = 0; LONGLONG fileSize = 0; BOOL isRelative = TRUE; // assumed to be TRUE FILETIME accessTime; UINT accessTimeDays; LONGLONG total = 0; LONGLONG free = 0; LONGLONG premigrated = 0; LONGLONG truncated = 0; int percent; CString sFormat; try { WsbAffirmPointer( m_pFsaResource ); // Get and format the volume name and label CString addString; WsbAffirmHr( RsGetVolumeDisplayName( m_pFsaResource, addString ) ); WsbAffirmHr( put_DisplayName( (LPTSTR)(LPCTSTR)addString ) ); WsbAffirmHr( RsGetVolumeSortKey( m_pFsaResource, addString ) ); WsbAffirmHr( put_DisplayName_SortKey( (LPTSTR)(LPCTSTR)addString ) ); // Get level settings WsbAffirmHr( m_pFsaResource->GetHsmLevel( &hsmLevel ) ); put_DesiredFreeSpaceP( hsmLevel / FSA_HSMLEVEL_1 ); WsbAffirmHr( m_pFsaResource->GetManageableItemLogicalSize( &fileSize ) ); put_MinFileSizeKb( (LONG) (fileSize / 1024) ); // Show KBytes WsbAffirmHr( m_pFsaResource->GetManageableItemAccessTime( &isRelative, &accessTime ) ); WsbAssert( isRelative, E_FAIL ); // We only do relative time // Convert FILETIME to days LONGLONG temp = WSB_FT_TICKS_PER_DAY; accessTimeDays = (UINT) ( WsbFTtoLL( accessTime ) / temp ); if (accessTimeDays > 999 ) { accessTimeDays = 0; } put_AccessDays( accessTimeDays ); // Get statistics WsbAffirmHr( m_pFsaResource->GetSizes( &total, &free, &premigrated, &truncated ) ); percent = (int) ( ( free * 100 ) / total ); put_FreeSpaceP( percent ); put_Capacity( total ); put_FreeSpace( free ); put_Premigrated( premigrated ); put_Truncated( truncated ); put_IsAvailable( IsAvailable( ) == S_OK ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::RefreshObject", L"hr = <%ls>", WsbHrAsString( hr ) ); return hr; } //----------------------------------------------------------------------------- // // get and put functions for object properties // HRESULT CUiManVol::put_DesiredFreeSpaceP( int percent ) { m_DesiredFreeSpaceP = percent; return S_OK; } HRESULT CUiManVol::put_MinFileSizeKb( LONG minFileSizeKb ) { m_MinFileSizeKb = minFileSizeKb; return S_OK; } HRESULT CUiManVol::put_AccessDays( int accessTimeDays ) { m_AccessDays = accessTimeDays; return S_OK; } HRESULT CUiManVol::put_FreeSpaceP( int percent ) { m_FreeSpaceP = percent; return S_OK; } HRESULT CUiManVol::put_Capacity( LONGLONG capacity ) { m_Capacity = capacity; return S_OK; } HRESULT CUiManVol::put_FreeSpace( LONGLONG freeSpace ) { m_FreeSpace = freeSpace; return S_OK; } HRESULT CUiManVol::put_Premigrated( LONGLONG premigrated ) { m_Premigrated = premigrated; return S_OK; } HRESULT CUiManVol::put_Truncated( LONGLONG truncated ) { m_Truncated = truncated; return S_OK; } STDMETHODIMP CUiManVol::get_DesiredFreeSpaceP( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { CString sFormat; WCHAR buffer[256]; // Format the byte value RsGuiFormatLongLong4Char( ( m_Capacity / (LONGLONG)100 ) * (LONGLONG)(m_DesiredFreeSpaceP), sFormat ); // Format the percent value _itow( m_DesiredFreeSpaceP, buffer, 10 ); sFormat = sFormat + L" (" + buffer + L"%)"; // Allocate the string *pszValue = SysAllocString( sFormat ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_DesiredFreeSpaceP_SortKey( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { *pszValue = SysAlloc64BitSortKey( ( m_Capacity / (LONGLONG)100 ) * (LONGLONG)(m_DesiredFreeSpaceP) ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_MinFileSizeKb( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { WCHAR buffer[256]; // Format the value _ltow( m_MinFileSizeKb, buffer, 10 ); wcscat( buffer, L"KB" ); // Allocate the string *pszValue = SysAllocString( buffer ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_AccessDays( BSTR *pszValue ) { HRESULT hr = S_OK; WCHAR buffer[256]; AFX_MANAGE_STATE(AfxGetStaticModuleState()); try { if( S_OK == IsAvailable( ) ) { // Format the value _itow( m_AccessDays, buffer, 10 ); CString sDays; sDays.LoadString( IDS_DAYS ); wcscat( buffer, L" " ); wcscat( buffer, sDays ); // Allocate the string *pszValue = SysAllocString( buffer ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_FreeSpaceP( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { WCHAR buffer[256]; // Format the value _itow( m_FreeSpaceP, buffer, 10 ); wcscat( buffer, L"%" ); // Allocate the string *pszValue = SysAllocString( buffer ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_Capacity( BSTR *pszValue ) { WsbTraceIn( L"CUiManVol::get_Capacity", L"" ); HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { CString sFormat; // Format the value WsbAffirmHr( RsGuiFormatLongLong4Char( m_Capacity, sFormat ) ); // Allocate the string *pszValue = SysAllocString( sFormat ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::get_Capacity", L"hr = <%ls>, *pszValue = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pszValue ) ); return( hr ); } STDMETHODIMP CUiManVol::get_Capacity_SortKey( BSTR *pszValue ) { WsbTraceIn( L"CUiManVol::get_Capacity_SortKey", L"" ); HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { *pszValue = SysAlloc64BitSortKey( m_Capacity ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::get_Capacity_SortKey", L"hr = <%ls>, *pszValue = <%ls>", WsbHrAsString( hr ), WsbPtrToStringAsString( pszValue ) ); return( hr ); } STDMETHODIMP CUiManVol::get_FreeSpace( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { CString sFormat; WCHAR buffer[256]; // Format the byte value WsbAffirmHr( RsGuiFormatLongLong4Char( m_FreeSpace, sFormat ) ); // Format the percent value _itow( m_FreeSpaceP, buffer, 10 ); sFormat = sFormat + L" (" + buffer + L"%)"; // Allocate the string *pszValue = SysAllocString( sFormat ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_FreeSpace_SortKey( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { *pszValue = SysAlloc64BitSortKey( m_FreeSpace ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_Premigrated( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { CString sFormat; // Format the value WsbAffirmHr( RsGuiFormatLongLong4Char( m_Premigrated, sFormat ) ); // Allocate the string *pszValue = SysAllocString( sFormat ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } STDMETHODIMP CUiManVol::get_Truncated( BSTR *pszValue ) { HRESULT hr = S_OK; try { if( S_OK == IsAvailable( ) ) { CString sFormat; // Format the value WsbAffirmHr( RsGuiFormatLongLong4Char( m_Truncated, sFormat ) ); // Allocate the string *pszValue = SysAllocString( sFormat ); } else { *pszValue = SysAllocString( L"" ); } WsbAffirmAlloc( *pszValue ); } WsbCatch( hr ); return( hr ); } ///////////////////////////////////////////////////////////////////////////////////////// // // class CUiManVolSheet // HRESULT CUiManVolSheet::AddPropertyPages( ) { WsbTraceIn( L"CUiManVolSheet::AddPropertyPages", L"" ); HRESULT hr = S_OK; try { AFX_MANAGE_STATE( AfxGetStaticModuleState() ); // //----------------------------------------------------------- // Create the Hsm Statistics property page. // CPrMrSts *pPropPageStatus = new CPrMrSts(); WsbAffirmAlloc( pPropPageStatus ); AddPage( pPropPageStatus ); // //---------------------------------------------------------- // Create the Hsm levels property page. // CPrMrLvl *pPropPageLevels = new CPrMrLvl(); WsbAffirmAlloc( pPropPageLevels ); AddPage( pPropPageLevels ); if( IsMultiSelect() != S_OK ) { // //---------------------------------------------------------- // Create the Hsm Include/Exclude property page. // CPrMrIe *pPropPageIncExc = new CPrMrIe(); WsbAffirmAlloc( pPropPageIncExc ); AddPage( pPropPageIncExc ); } } WsbCatch( hr ); WsbTraceOut( L"CUiManVolSheet::AddPropertyPages", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CUiManVolSheet::GetNextFsaResource( int *pBookMark, IFsaResource **ppFsaResource ) { WsbTraceIn( L"CUiManVolSheet::GetNextFsaResource", L"*pBookMark = <%ld>", WsbPtrToLongAsString( (LONG*)pBookMark ) ); HRESULT hr = S_OK; GUID objectId; try { WsbAffirmPointer( pBookMark ); WsbAffirm( *pBookMark >= 0, E_FAIL ); // // Get the Fsa Server so we can get Fsa Resources // CComPtr pFsaServer; WsbAffirmHr( GetFsaServer( &pFsaServer ) ); if( *pBookMark <= m_ObjectIdList.GetUpperBound( ) ) { objectId = m_ObjectIdList[ *pBookMark ]; (*pBookMark)++; WsbAffirmHr( pFsaServer->FindResourceById( objectId, ppFsaResource ) ); } else { hr = S_FALSE; } } WsbCatch( hr ); WsbTraceOut( L"CUiManVolSheet::GetNextFsaResource", L"hr = <%ls>", WsbHrAsString( hr ) ); return hr; } STDMETHODIMP CUiManVol::GetResultIcon( IN BOOL bOK, OUT int* pIconIndex ) { WsbTraceIn( L"CUiManVol::GetResultIcon", L"" ); HRESULT hr = S_OK; try { WsbAffirmPointer( m_pFsaResource ); if( S_OK == IsAvailable( ) ) { // // Check to make sure it's not deleted (or being deleted) // If so, put on the X // bOK = ( S_FALSE == m_pFsaResource->IsDeletePending( ) && S_OK == m_pFsaResource->IsManaged( ) ); WsbAffirmHr( CSakNodeImpl::GetResultIcon( bOK, pIconIndex ) ); } else { *pIconIndex = m_nResultIconD; } } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::GetResultIcon", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } STDMETHODIMP CUiManVol::SupportsProperties( BOOL bMultiSelect ) { WsbTraceIn( L"CUiManVol::SupportsProperties", L"" ); HRESULT hr = S_OK; try { WsbAffirmPointer( m_pFsaResource ); if( !bMultiSelect && ( S_OK == m_pFsaResource->IsDeletePending( ) || S_OK != IsAvailable( ) ) ) { hr = S_FALSE; } else { hr = CSakNode::SupportsProperties( bMultiSelect ); } } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::SupportsProperties", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } STDMETHODIMP CUiManVol::SupportsRefresh( BOOL bMultiSelect ) { WsbTraceIn( L"CUiManVol::SupportsRefresh", L"" ); HRESULT hr = S_OK; try { WsbAffirmPointer( m_pFsaResource ); if( !bMultiSelect && S_OK == m_pFsaResource->IsDeletePending( ) ) { hr = S_FALSE; } else { hr = CSakNode::SupportsRefresh( bMultiSelect ); } } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::SupportsRefresh", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } STDMETHODIMP CUiManVol::IsValid( void ) { WsbTraceIn( L"CUiManVol::IsValid", L"" ); HRESULT hr = S_OK; try { WsbAffirmPointer( m_pFsaResource ); // // Still valid if managed. // WsbAffirmHrOk( m_pFsaResource->IsManaged( ) ); } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::IsValid", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CUiManVol::IsAvailable( void ) { WsbTraceIn( L"CUiManVol::IsAvailable", L"" ); HRESULT hr = S_FALSE; try { WsbAffirmPointer( m_pFsaResource ); // // Under certain circumstances we can't get a good answer back, so // we have to rely on the last answer we got. // HRESULT hrAvailable = m_pFsaResource->IsAvailable( ); if( RPC_E_CANTCALLOUT_ININPUTSYNCCALL == hrAvailable ) { hrAvailable = m_HrAvailable; } hr = hrAvailable; m_HrAvailable = hrAvailable; } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::IsAvailable", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CUiManVol::put_IsAvailable( BOOL Available ) { WsbTraceIn( L"CUiManVol::put_IsAvailable", L"Available = <%ls>", WsbBoolAsString( Available ) ); HRESULT hr = S_FALSE; try { m_HrAvailable = Available ? S_OK : S_FALSE; } WsbCatch( hr ); WsbTraceOut( L"CUiManVol::put_IsAvailable", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); }