Example #1
0
void CNBListViewCtrl::AddDiskObjectList(CDiskObjectList disks)
{
	CDiskObjectList::iterator itr;
	for ( itr = disks.begin(); itr != disks.end(); ++itr )
		AddDiskObject( *itr );
	SortItems();
}
Example #2
0
CDiskObjectList CLanUnitDiskObject::UnBind(CDiskObjectPtr _this)
{
	ATLASSERT( this == _this.get() );
	CDiskObjectList listUnbound;

	// If the disk is aggregated, the MBR block of the disk should be cleaned
	// to prevent unexpected behavior of disks after unbinding.
	CDataSector dataSector( SECTOR_MBR_COUNT );
	dataSector.SetLocation( 0 );
	if ( m_pHandler->IsBoundAndNotSingleMirrored() )
	{
		try{
			dataSector.WriteAccept( &m_session );
		}
		catch( CNDASException &e )
		{
			NDAS_THROW_EXCEPTION_CHAIN_STR(
				CDiskException,
				CDiskException::ERROR_FAIL_TO_INITIALIZE,
				_T("Fail to clean MBR"),
				e);
		}
	}

	// Clear bind information
	m_pHandler->UnBind(
		boost::dynamic_pointer_cast<CUnitDiskObject>(_this)
		);

	listUnbound.push_back(_this);
	return listUnbound;
}
Example #3
0
void CNBListViewCtrl::SelectDiskObjectList(CDiskObjectList disks)
{
	CDiskObjectList::iterator itr;
	for ( itr = disks.begin(); itr != disks.end(); ++itr )
		SelectDiskObject( *itr );

}
Example #4
0
CDiskObjectList CNBListViewCtrl::GetDiskObjectList()
{
	int nCount = CListViewCtrl::GetItemCount();
	CDiskObjectList diskList;
	for ( int i=0; i < nCount; i++ )
	{
		diskList.push_back( m_mapObject[CListViewCtrl::GetItemData(i)] );
	}
	return diskList;
}
Example #5
0
void CSelectDiskDlg::OnOK(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/)
{
	CDiskObjectList listSelected;// = m_wndListSingle.GetSelectedDiskObjectList();
	if ( listSelected.size() == 0 )
		// TODO : Display message to select
		return;
	ATLASSERT( listSelected.size() == 1 );
	m_pSelectedDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(listSelected.front());
	// Check if the selected disk's size is not smaller than the source disk's size
	EndDialog(IDOK);
}
Example #6
0
CDiskObjectList CDiskObjectComposite::UnBind(CDiskObjectPtr _this)
{
	ATLASSERT( this == _this.get() );
	CDiskObjectList unboundDisks;
	CDiskObjectList::iterator itr;
	for ( itr = begin(); itr != end(); ++itr )
	{
		CDiskObjectList subUnboundDisks = (*itr)->UnBind(*itr);
		unboundDisks.splice(  
			unboundDisks.end(), 
			subUnboundDisks
			);
	}
	return unboundDisks;
}
Example #7
0
CDiskObjectList CNBListViewCtrl::GetSelectedDiskObjectList()
{
	int nCount = CListViewCtrl::GetSelectedCount();
	int nItem;
	CDiskObjectList selectDiskList;

	nItem = -1;
	for ( int i=0; i < nCount; i++ )
	{
		nItem = CListViewCtrl::GetNextItem( nItem, LVNI_SELECTED );
		selectDiskList.push_back( m_mapObject[CListViewCtrl::GetItemData(nItem)] );
	}

	return selectDiskList;
}
Example #8
0
void CUnBindDlg::SetDiskToUnbind(CDiskObjectPtr obj)
{
	 m_pDiskUnbind = obj; 

	CFindIfVisitor<TRUE> unitDiskFinder;
	CDiskObjectList listUnbind;	// List of disks to unbind
	listUnbind = unitDiskFinder.FindIf( m_pDiskUnbind, IsUnitDisk);
	
	//
	// Data is deleted only when the disks are aggregated
	// Thus, change message if they are not.
	//
	CUnitDiskObjectPtr unitDisk = 
		boost::dynamic_pointer_cast<CUnitDiskObject>(listUnbind.front());
	if ( unitDisk->GetInfoHandler()->IsBoundAndNotSingleMirrored() )
	{
		IDD = IDD_UNBIND_MIRROR;
	}
}
Example #9
0
void CSelectMirDlg::OnOK(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/)
{
	CDiskObjectList listSelected = m_wndListSingle.GetSelectedDiskObjectList();
	if ( listSelected.size() == 0 )
		// TODO : Display message to select
		return;
	ATLASSERT( listSelected.size() == 1 );
	m_pSelectedDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(listSelected.front());
	// Check if the selected disk's size is not smaller than the source disk's size
	if ( m_pSelectedDisk->GetInfoHandler()->GetUserSectorCount() 
		< m_pSourceDisk->GetInfoHandler()->GetUserSectorCount() )
	{
		MessageBox(
			_T("A disk cannot be mirrored by a smaller disk."), 
			_T(PROGRAM_TITLE), 
			MB_OK
			);
		return;
	}
	// FIXME : Confirmation would be necessary.
	EndDialog(IDOK);
}
Example #10
0
BOOL CMirDiskUIHandler::OnSynchronize(CDiskObjectPtr obj) const
{
	ATLASSERT( dynamic_cast<CMirDiskObject*>(obj.get()) != NULL );
	
	CMirDiskObjectPtr mirDisk = 
		boost::dynamic_pointer_cast<CMirDiskObject>(obj);
	CUnitDiskObjectPtr sourceDisk, destDisk;
	BOOL bFirstDefected, bSecondDefected;
	BOOL bResults;
	
	bResults = mirDisk->GetDirtyDiskStatus(&bFirstDefected, &bSecondDefected);
	if(!bResults)
		return FALSE;

	// check dirty status here
//	ATLASSERT( mirDisk->GetDirtyDiskCount() > 0 );
	if ( !bFirstDefected && !bSecondDefected)
	{
		WTL::CString strMsg;
		strMsg.LoadString(IDS_WARNING_NOT_NEED_RECOVER );
		WTL::CString strTitle;
		strTitle.LoadString(IDS_APPLICATION);
		MessageBox( 
			::GetFocus(),
			strMsg,
			strTitle,
			MB_OK | MB_ICONERROR
			);
		return TRUE;
	}
	
	//
	// Select the source disk and the dest disk
	//
	if ( bFirstDefected && bSecondDefected)
	{
		CSelectDiskDlg dlgSelect(IDD_SELSOURCE);
		CDiskObjectList listDisks;
		listDisks.push_back( mirDisk->front() );
		listDisks.push_back( mirDisk->back() );
		dlgSelect.SetSingleDisks( listDisks );
		if ( dlgSelect.DoModal() != IDOK )
			return TRUE;
		sourceDisk = dlgSelect.GetSelectedDisk();
		if ( sourceDisk == mirDisk->front() )
			destDisk = 
				boost::dynamic_pointer_cast<CUnitDiskObject>(mirDisk->back());
		else
			destDisk = 
				boost::dynamic_pointer_cast<CUnitDiskObject>(mirDisk->front());
	}
	else
	{
		if (bFirstDefected)
		{
			sourceDisk = 
				/*boost::dynamic_pointer_cast<CUnitDiskObject>*/ (mirDisk->SecondDisk());
			destDisk = 
			/*boost::dynamic_pointer_cast<CUnitDiskObject>*/ (mirDisk->FirstDisk());
		}
		else if (bSecondDefected )
		{
			sourceDisk = 
				/*boost::dynamic_pointer_cast<CUnitDiskObject>*/ (mirDisk->FirstDisk());
			destDisk = 
				/*boost::dynamic_pointer_cast<CUnitDiskObject>*/ (mirDisk->SecondDisk());
		}
		else
		{
			return FALSE;
		}
	}

	//
	// Synchronize
	//

	CRecoverDlg dlgRecover(FALSE, IDS_LOGDEV_TYPE_DISK_RAID1, IDS_RECOVERDLG_TASK_RECOVER);

	dlgRecover.SetMemberDevice(destDisk);
	dlgRecover.DoModal();

	CNdasHIXChangeNotify HixChangeNotify(pGetNdasHostGuid());
	bResults = HixChangeNotify.Initialize();
	if(bResults)
	{
		NDAS_UNITDEVICE_ID unitDeviceId;

		CopyMemory(unitDeviceId.DeviceId.Node,
			sourceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
			sizeof(unitDeviceId.DeviceId.Node));
		unitDeviceId.UnitNo = 
			sourceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
		HixChangeNotify.Notify(unitDeviceId);

		CopyMemory(unitDeviceId.DeviceId.Node,
			destDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
			sizeof(unitDeviceId.DeviceId.Node));
		unitDeviceId.UnitNo = 
			destDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
		HixChangeNotify.Notify(unitDeviceId);
	}
	

	return TRUE;
}
Example #11
0
void CMainFrame::OnRepair(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/)
{
#ifdef __NEVER_DEFINED__
	BOOL bResults;
	BOOL bReturn = FALSE;

	int iItemSelected = m_viewTreeList.GetSelectedItemData();
	if (-1 == iItemSelected)
	{
		
		return;
	}
	
	CDiskObjectPtr obj = m_mapObject[iItemSelected];


	if( dynamic_cast<CDiskObjectComposite *>(obj.get()) == NULL )
	{
		
		return;
	}

	CDiskObjectCompositePtr DiskObjectComposite =
		boost::dynamic_pointer_cast<CDiskObjectComposite>(obj);

	if(!((NMT_RAID1 == DiskObjectComposite->GetNDASMediaType() ||
		NMT_RAID4 == DiskObjectComposite->GetNDASMediaType()) &&
		1 == DiskObjectComposite->GetMissingMemberCount()))
	{
		
		// TODO : No disk is available
		CString strMsg;
		strMsg.LoadString( IDS_MAINFRAME_NOT_READY_REPAIR );
		CString strTitle;
		strTitle.LoadString(IDS_APPLICATION);
		MessageBox(
			strMsg,
			strTitle, 
			MB_OK | MB_ICONERROR
			);
		return;
	}		


	CSelectDiskDlg dlgSelect(IDD_REPAIR);
	CDiskObjectList singleDisks;
	CFindIfVisitor<FALSE> singleDiskFinder;
	singleDisks = singleDiskFinder.FindIf(m_pRoot, IsWritableUnitDisk);

	if ( singleDisks.size() == 0 )
	{
		
		// TODO : No disk is available
		CString strMsg;
		strMsg.LoadString( IDS_MAINFRAME_NO_DISK_REPAIR );
		CString strTitle;
		strTitle.LoadString(IDS_APPLICATION);
		MessageBox(
			strMsg,
			strTitle, 
			MB_OK | MB_ICONWARNING
			);
		return;
	}

	dlgSelect.SetSingleDisks(singleDisks);

	if ( dlgSelect.DoModal() != IDOK )
		return;

	CUnitDiskObjectPtr replaceDisk, sourceDisk;
	sourceDisk = DiskObjectComposite->GetAvailableUnitDisk();
	replaceDisk = dlgSelect.GetSelectedDisk();

	if(NULL == sourceDisk.get())
		return;
	
	NDASCOMM_CONNECTION_INFO ci, ciReplace;

	ZeroMemory(&ci, sizeof(NDASCOMM_CONNECTION_INFO));
	ci.Size = sizeof(NDASCOMM_CONNECTION_INFO);
	ci.AddressType = NDASCOMM_CIT_DEVICE_ID;
	ci.LoginType = NDASCOMM_LOGIN_TYPE_NORMAL;
	ci.UnitNo = sourceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
	ci.WriteAccess = TRUE;
	ci.Protocol = NDASCOMM_TRANSPORT_LPX;
	CopyMemory(
		ci.DeviceId.Node, 
		sourceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
		sizeof(ci.DeviceId.Node));

	ZeroMemory(&ciReplace, sizeof(NDASCOMM_CONNECTION_INFO));
	ciReplace.Size = sizeof(NDASCOMM_CONNECTION_INFO);
	ciReplace.AddressType = NDASCOMM_CIT_DEVICE_ID;
	ciReplace.LoginType = NDASCOMM_LOGIN_TYPE_NORMAL;
	ciReplace.UnitNo = replaceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
	ciReplace.WriteAccess = TRUE;
	ciReplace.Protocol = NDASCOMM_TRANSPORT_LPX;
	CopyMemory(
		ciReplace.DeviceId.Node,
		replaceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
		sizeof(ciReplace.DeviceId.Node));

	AutoCursor l_auto_cursor(IDC_WAIT);
	bResults = NdasOpRepair(&ci, &ciReplace);
	l_auto_cursor.Release();

	if(!bResults)
	{
		CString strMsg;

		DWORD dwLastError = ::GetLastError();
		strMsg.LoadString(IDS_REPAIR_FAIL);

		ShowErrorMessageBox(strMsg);

		return;
	}

	CNdasHIXChangeNotify HixChangeNotify(pGetNdasHostGuid());
	bResults = HixChangeNotify.Initialize();
	if(bResults)
	{
		CUnitDiskObjectPtr UnitDiskObjectPtr;
		NDAS_UNITDEVICE_ID unitDeviceId;

		CDiskObjectComposite::const_iterator itr;
		for ( itr = DiskObjectComposite->begin(); itr != DiskObjectComposite->end(); ++itr )
		{
			if((dynamic_cast<CEmptyDiskObject*>((*itr).get()) != NULL))
				continue;

			UnitDiskObjectPtr = 
				boost::dynamic_pointer_cast<CUnitDiskObject>(*itr);

			CopyMemory(unitDeviceId.DeviceId.Node, 
				UnitDiskObjectPtr->GetLocation()->GetUnitDiskLocation()->MACAddr, 
				sizeof(unitDeviceId.DeviceId.Node));
			unitDeviceId.UnitNo = 
				UnitDiskObjectPtr->GetLocation()->GetUnitDiskLocation()->UnitNumber;
			HixChangeNotify.Notify(unitDeviceId);
		}

		CopyMemory(unitDeviceId.DeviceId.Node, 
			replaceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, 
			sizeof(unitDeviceId.DeviceId.Node));
		unitDeviceId.UnitNo = 
			replaceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
		HixChangeNotify.Notify(unitDeviceId);
	}


	CRecoverDlg dlgRecover(
		TRUE, 
        (NMT_RAID1 == DiskObjectComposite->GetNDASMediaType()) ?
		IDS_LOGDEV_TYPE_DISK_RAID1 : IDS_LOGDEV_TYPE_DISK_RAID4,
		IDS_RECOVERDLG_TASK_REPAIR);

	dlgRecover.SetMemberDevice(sourceDisk);
	dlgRecover.DoModal();

	OnRefreshStatus(NULL, NULL, NULL);
#endif
	
	return;
}
Example #12
0
void CMainFrame::OnAddMirror(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/)
{
	ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus);

	CTreeItem itemSelected = m_view.GetSelectedItem();

	if ( itemSelected.IsNull() )
	{
		LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus);
		return;
	}

	CDiskObjectList singleDisks;
	CUnitDiskObjectPtr  sourceDisk;
	sourceDisk = 
		boost::dynamic_pointer_cast<CUnitDiskObject>(
			m_mapObject[m_view.GetItemData(itemSelected)]
			);
	ATLASSERT( sourceDisk.get() != NULL );

	CFindIfVisitor<FALSE> singleDiskFinder;
	singleDisks = singleDiskFinder.FindIf(m_pRoot, IsWritableUnitDisk);
	singleDisks.remove( sourceDisk );
	if ( singleDisks.size() == 0 )
	{
		LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus);
		// TODO : No disk is available
		WTL::CString strMsg;
		strMsg.LoadString( IDS_MAINFRAME_NO_DISK_TO_MIRROR );
		WTL::CString strTitle;
		strTitle.LoadString(IDS_APPLICATION);
		MessageBox(
			strMsg,
			strTitle, 
			MB_OK | MB_ICONWARNING
			);
		return;
	}

	DWORD UnitNo = 0;
	CSelectMirDlg dlgSelDisk(IDD_ADDMIR);
	dlgSelDisk.SetSingleDisks( singleDisks );
	dlgSelDisk.SetSourceDisk( sourceDisk );
	if ( dlgSelDisk.DoModal() == IDOK )
	{
		CUnitDiskObjectPtr mirDisk = dlgSelDisk.GetSelectedDisk();

		// Bind & Synchronize 
		NDAS_CONNECTION_INFO ConnectionInfo[2];

		ZeroMemory(&ConnectionInfo[0], sizeof(NDAS_CONNECTION_INFO));

		ConnectionInfo[0].type = NDAS_CONNECTION_INFO_TYPE_MAC_ADDRESS;
		ConnectionInfo[0].UnitNo = sourceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
		ConnectionInfo[0].bWriteAccess = TRUE;
		ConnectionInfo[0].ui64OEMCode = NULL;
		ConnectionInfo[0].protocol = IPPROTO_LPXTCP;
		CopyMemory(ConnectionInfo[0].MacAddress, 
				sourceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
			LPXADDR_NODE_LENGTH);

		ZeroMemory(&ConnectionInfo[1], sizeof(NDAS_CONNECTION_INFO));

		ConnectionInfo[1].type = NDAS_CONNECTION_INFO_TYPE_MAC_ADDRESS;
		ConnectionInfo[1].UnitNo = mirDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
		ConnectionInfo[1].bWriteAccess = TRUE;
		ConnectionInfo[1].ui64OEMCode = NULL;
		ConnectionInfo[1].protocol = IPPROTO_LPXTCP;
		CopyMemory(ConnectionInfo[1].MacAddress, 
			mirDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
			LPXADDR_NODE_LENGTH);

		UINT32 BindResult = NdasOpBind(
			2,
			ConnectionInfo,
			NMT_SAFE_RAID1);

		if(2 != BindResult)
		{
	LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus);

			WTL :: CString strMsg;

			DWORD dwLastError = ::GetLastError();

			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:
				strMsg.FormatMessage(IDS_BIND_FAIL_AT_SINGLE_NDAS_FMT, 
					(BindResult == 0) ? sourceDisk->GetTitle() : mirDisk->GetTitle());
				break;
			default:
				strMsg.LoadString(IDS_BIND_FAIL);
				break;
	}

			ShowErrorMessageBox(strMsg);

		return;
	}

		CNdasHIXChangeNotify HixChangeNotify(pGetNdasHostGuid());
		BOOL bResults = HixChangeNotify.Initialize();
		if(bResults)
		{
			NDAS_UNITDEVICE_ID unitDeviceId;

			CopyMemory(unitDeviceId.DeviceId.Node, 
				sourceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, 
				sizeof(unitDeviceId.DeviceId.Node));
			unitDeviceId.UnitNo = 
				sourceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
			HixChangeNotify.Notify(unitDeviceId);

			CopyMemory(unitDeviceId.DeviceId.Node, 
				mirDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, 
				sizeof(unitDeviceId.DeviceId.Node));
			unitDeviceId.UnitNo = 
				mirDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
			HixChangeNotify.Notify(unitDeviceId);
		}

		CRecoverDlg dlgRecover(TRUE, IDS_LOGDEV_TYPE_DISK_RAID1, IDS_RECOVERDLG_TASK_ADD_MIRROR);

		dlgRecover.SetMemberDevice(mirDisk);
		dlgRecover.DoModal();

		OnRefreshStatus(NULL, NULL, NULL);
	}

	LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus);
}
Example #13
0
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);
}