CCommandSet CMirDiskUIHandler::GetCommandSet(CDiskObjectPtr obj) const { ATLASSERT( dynamic_cast<const CMirDiskObject*>(obj.get()) != NULL ); CCommandSet setCommand; BOOL bCanWrite; CMirDiskObjectPtr mirDisk = boost::dynamic_pointer_cast<CMirDiskObject>(obj); bCanWrite = mirDisk->GetAccessMask() & GENERIC_WRITE; setCommand.push_back( CCommand( IDM_TOOL_UNBIND, bCanWrite ) ); if(NMT_MIRROR == mirDisk->GetNDASMediaType()) { // migrate : mirror -> RAID 1 setCommand.push_back( CCommand( IDM_TOOL_MIGRATE, !mirDisk->IsBroken() && mirDisk->HasWriteAccess())); } else { // do not check IsDirty here (cause it takes some time) setCommand.push_back( CCommand( IDM_TOOL_SYNCHRONIZE, /* bCanWrite && */ mirDisk->IsDirty() && !mirDisk->IsBroken() && mirDisk->HasWriteAccess())); } return setCommand; }
BOOL CDiskObjectComposite::HasWriteAccess() { UINT32 iMediaType = NMT_INVALID; // return the first NDAS Media type of unit disk which is not NMT_INVALID const_iterator itr; for ( itr = begin(); itr != end(); ++itr ) { if(::IsEmptyDisk(*itr)) return FALSE; if(!(*itr)->IsUnitDisk()) { CMirDiskObjectPtr mirDisk = boost::dynamic_pointer_cast<CMirDiskObject>(*itr); if(mirDisk) { if(!mirDisk->HasWriteAccess()) return FALSE; } else { return FALSE; } } // if(2 != (*itr)->GetDiskCount()) // return FALSE; CUnitDiskObjectPtr unitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(*itr); if(!(unitDisk->GetAccessMask() & GENERIC_WRITE)) return FALSE; } return TRUE; }
CCommandSet CUnitDiskUIHandler::GetCommandSet(CDiskObjectPtr obj) const { ATLASSERT( dynamic_cast<CUnitDiskObject*>(obj.get()) != NULL); CCommandSet setCommand; CUnitDiskObjectPtr unitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(obj); CUnitDiskInfoHandlerPtr handler = unitDisk->GetInfoHandler(); BOOL bCanWrite; if ( handler->IsBound() ) { CDiskObjectPtr aggrRoot = unitDisk->GetParent(); if ( aggrRoot->IsRoot() ) { // This can occur when the tree is updated just after // the disk is bound. // This additional if code prevents error. setCommand.push_back( CCommand(IDM_TOOL_UNBIND) ); } else { while ( !aggrRoot->GetParent()->IsRoot() ) aggrRoot = aggrRoot->GetParent(); // To Unbind, we should have write privilege to all the disks in bind setCommand.push_back( CCommand(IDM_TOOL_UNBIND, aggrRoot->GetAccessMask() & GENERIC_WRITE) ); } } else { bCanWrite = unitDisk->GetAccessMask() & GENERIC_WRITE; setCommand.push_back( CCommand(IDM_TOOL_ADDMIRROR, bCanWrite) ); } if ( handler->IsMirrored() ) { CMirDiskObjectPtr parent = boost::dynamic_pointer_cast<CMirDiskObject>(unitDisk->GetParent()); if ( parent.get() != NULL ) { // To synchronize, we have write privilege to the two disks in mirroring setCommand.push_back( CCommand(IDM_TOOL_SYNCHRONIZE, (parent->GetAccessMask() & GENERIC_WRITE) && parent->IsDirty() && !parent->IsBroken() && parent->HasWriteAccess() ) ); } CDiskObjectPtr aggrRoot = unitDisk->GetParent(); if ( aggrRoot->IsRoot() ) { // This can occur when the tree is updated just after // the disk is bound. // This additional if code prevents error. setCommand.push_back( CCommand(IDM_TOOL_UNBIND) ); } else { while ( !aggrRoot->GetParent()->IsRoot() ) aggrRoot = aggrRoot->GetParent(); } } else if(NMT_RAID4 == handler->GetNDASMediaType()) { CRAID4DiskObjectPtr parent = boost::dynamic_pointer_cast<CRAID4DiskObject>(unitDisk->GetParent()); if ( parent.get() != NULL ) { // To synchronize, we have write privilege to the two disks in mirroring setCommand.push_back( CCommand(IDM_TOOL_SYNCHRONIZE, (parent->GetAccessMask() & GENERIC_WRITE) && parent->IsDirty() && !parent->IsBroken() ) ); } } if(unitDisk->IsUnitDisk()) { setCommand.push_back( CCommand(IDM_TOOL_SINGLE) ); } return setCommand; }