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; }
void CUnBindDlg::OnOK(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/) { UINT32 nDiskCount = 0; unsigned int i; NDASCOMM_CONNECTION_INFO *pConnectionInfo; CFindIfVisitor<TRUE> unitDiskFinder; CDiskObjectList listUnbind; // List of disks to unbind CDiskObjectList::iterator itr; CUnitDiskObjectPtr unitDisk; WTL::CString strMsg; WTL::CString strTitle; strTitle.LoadString(IDS_APPLICATION); BOOL bUnbindMirror; BOOL bReadyToUnbind; UINT32 BindResult; bUnbindMirror = (dynamic_cast<const CMirDiskObject*>(m_pDiskUnbind.get()) != NULL); // warning message strMsg.LoadString((bUnbindMirror) ? IDS_WARNING_UNBIND_MIR : IDS_WARNING_UNBIND); int id = MessageBox( strMsg, strTitle, MB_YESNO|MB_ICONEXCLAMATION ); if(IDYES != id) return; listUnbind = unitDiskFinder.FindIf( m_pDiskUnbind, IsUnitDisk); nDiskCount = listUnbind.size(); pConnectionInfo = new NDASCOMM_CONNECTION_INFO[nDiskCount]; ZeroMemory(pConnectionInfo, sizeof(NDASCOMM_CONNECTION_INFO) * nDiskCount); bReadyToUnbind = TRUE; for ( itr = listUnbind.begin(), i = 0; itr != listUnbind.end(); ++itr ) { if(!(*itr)->IsUnitDisk()) continue; unitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(*itr); ZeroMemory(&pConnectionInfo[i], sizeof(NDASCOMM_CONNECTION_INFO)); pConnectionInfo[i].address_type = NDASCOMM_CONNECTION_INFO_TYPE_ADDR_LPX; pConnectionInfo[i].login_type = NDASCOMM_LOGIN_TYPE_NORMAL; pConnectionInfo[i].UnitNo = unitDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber; pConnectionInfo[i].bWriteAccess = TRUE; pConnectionInfo[i].ui64OEMCode = NULL; pConnectionInfo[i].bSupervisor = FALSE; pConnectionInfo[i].protocol = NDASCOMM_TRANSPORT_LPX; CopyMemory(pConnectionInfo[i].AddressLPX, unitDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, LPXADDR_NODE_LENGTH); if(!(unitDisk->GetAccessMask() & GENERIC_WRITE)) { // "%1!s! does not have a write access privilege. You need to set write key to this NDAS device before this action." strMsg.FormatMessage(IDS_ERROR_NOT_REGISTERD_WRITE_FMT, unitDisk->GetTitle() ); MessageBox( strMsg, strTitle, MB_OK|MB_ICONERROR ); bReadyToUnbind = FALSE; } i++; } if(!bReadyToUnbind) { delete [] pConnectionInfo; EndDialog(IDCANCEL); } BindResult = NdasOpBind(i, pConnectionInfo,NMT_SINGLE); DWORD dwLastError = ::GetLastError(); m_unboundDisks = listUnbind; if(i == BindResult) { strMsg.LoadString( (bUnbindMirror) ? IDS_WARNING_UNBIND_AFTER_MIR : IDS_WARNING_UNBIND_AFTER); MessageBox( strMsg, strTitle, MB_OK|MB_ICONINFORMATION ); } else { for ( itr = listUnbind.begin(); itr != listUnbind.end(); ++itr ) { unitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(*itr); if(!BindResult) break; BindResult--; } ::SetLastError(dwLastError); switch(dwLastError) { case NDASCOMM_ERROR_RW_USER_EXIST: case NDASOP_ERROR_ALREADY_USED: case NDASOP_ERROR_DEVICE_FAIL: case NDASOP_ERROR_NOT_SINGLE_DISK: case NDASOP_ERROR_DEVICE_UNSUPPORTED: case NDASOP_ERROR_NOT_BOUND_DISK: // does not return this error strMsg.FormatMessage(IDS_BIND_FAIL_AT_SINGLE_NDAS_FMT, unitDisk->GetTitle()); break; default: strMsg.LoadString(IDS_BIND_FAIL); break; } ShowErrorMessageBox(IDS_MAINFRAME_SINGLE_ACCESS_FAIL); } CNdasHIXChangeNotify HixChangeNotify(pGetNdasHostGuid()); BOOL bResults = HixChangeNotify.Initialize(); if(bResults) { for(i = 0; i < BindResult; i++) { NDAS_UNITDEVICE_ID unitDeviceId; CopyMemory(unitDeviceId.DeviceId.Node, pConnectionInfo[i].AddressLPX, sizeof(unitDeviceId.DeviceId.Node)); unitDeviceId.UnitNo = pConnectionInfo[i].UnitNo; HixChangeNotify.Notify(unitDeviceId); } } delete [] pConnectionInfo; EndDialog(IDOK); }