Esempio n. 1
0
BOOL
CNdasAutoRegister::ProcessRegister(
	CONST NDAS_DEVICE_ID& deviceId, 
	ACCESS_MASK autoRegAccess)
{
	CNdasDeviceRegistrar* pRegistrar = pGetNdasDeviceRegistrar();
	CRefObjPtr<CNdasDevice> pExistingDevice = pRegistrar->Find(deviceId);
	if (NULL != pExistingDevice.p) {
		return TRUE;
	}

	CRefObjPtr<CNdasDevice> pDevice = pRegistrar->Register(deviceId, TRUE, TRUE);
	if (NULL == pDevice.p) {
		return FALSE;
	}

	pDevice->SetGrantedAccess(autoRegAccess);

	BOOL fSuccess = pDevice->Enable(TRUE);
	if (!fSuccess) {
		DBGPRT_ERR(_FT("Enable failed: "));
	}

	TCHAR szName[MAX_NDAS_DEVICE_NAME_LEN + 1];
	HRESULT hr = ::StringCchPrintf(szName, MAX_NDAS_DEVICE_NAME_LEN + 1,
		_T("NDAS Device A%04d"), pDevice->GetSlotNo());
	_ASSERTE(SUCCEEDED(hr));

	pDevice->SetName(szName);

	return TRUE;
}
Esempio n. 2
0
ACCESS_MASK 
CNdasLogicalDevice::GetAllowingAccess()
{
	ximeta::CAutoLock autolock(this);
	if (0 == GetUnitDeviceCount()) {
		return 0x00000000L;
	}

	ACCESS_MASK access(0xFFFFFFFFL);
	//
	// Any single missing entry will revoke all accesses
	//
	for (DWORD i = 0; i < GetUnitDeviceCount(); ++i) {

		CRefObjPtr<CNdasUnitDevice> pUnitDevice = GetUnitDevice(i);

		if (NULL == pUnitDevice.p) {
			return 0x00000000L;
		}

		access &= pUnitDevice->GetAllowingAccess();
	}

	return access;
}
Esempio n. 3
0
BOOL
CNdasLogicalDevice::IsVolatile()
{
	ximeta::CAutoLock autolock(this);

	DWORD nUnitDevices = GetUnitDeviceCount();
	for (DWORD i = 0; i < nUnitDevices; ++i)
	{
		CRefObjPtr<CNdasUnitDevice> pUnitDevice = GetUnitDevice(i);
		// Unit Device can be null
		if (NULL == pUnitDevice.p) continue;

		CRefObjPtr<CNdasDevice> pDevice = pUnitDevice->GetParentDevice();
		// If unit device is not null, parent device cannot be null
		_ASSERTE(NULL != pDevice.p);

		if (pDevice->IsVolatile())
		{
			// If any single device is volatile, then it's volatile.
			return TRUE;
		}
	}
	// Otherwise, we don't consider it volatile.
	return FALSE;
}
Esempio n. 4
0
CNdasLogicalDevice* 
CNdasLogicalDeviceManager::Register(CNdasUnitDevice& unitDevice)
{
	ximeta::CAutoLock autolock(this);

	CONST NDAS_LOGICALDEVICE_GROUP& ldGroup = unitDevice.GetLDGroup();
	DWORD ldSequence = unitDevice.GetLDSequence();

	CNdasLogicalDevice* pLogDevice = NULL;
	LDGroupMap::iterator itr = m_LDGroupMap.find(ldGroup);

	if (itr == m_LDGroupMap.end()) {
		//
		// New Logical Device Instance
		//
		NDAS_LOGICALDEVICE_ID id = cpAllocateID();
		if (0 == id) {
			// SLOT FULL
			::SetLastError(NDASSVC_ERROR_LOGICALDEVICE_SLOT_FULL);
			return NULL;
		}

		pLogDevice = new CNdasLogicalDevice(id, ldGroup);
		if (NULL == pLogDevice) {
			::SetLastError(ERROR_OUTOFMEMORY);
			return NULL;
		}
		BOOL fSuccess = pLogDevice->Initialize();
		if (!fSuccess) {
			delete pLogDevice;
			return NULL;
		}
		pLogDevice->AddRef(); // internal pointer reference
		m_LDGroupMap.insert(LDGroupMap::value_type(ldGroup, pLogDevice));
		m_LDIDMap.insert(LDIDMap::value_type(id, pLogDevice));

		CRefObjPtr<CNdasDevice> pDevice = unitDevice.GetParentDevice();
		_ASSERTE(NULL != pDevice.p);
		if (pDevice->IsAutoRegistered()) {
			pLogDevice->SetMountOnReady(pDevice->GetGrantedAccess());
			// auto registered devices always ignore RiskyMountFlag
			pLogDevice->SetRiskyMountFlag(FALSE);
		}

	} else {
		pLogDevice = itr->second;
	}

	BOOL fSuccess = pLogDevice->AddUnitDevice(unitDevice);
	_ASSERTE(fSuccess);
	if (!fSuccess) {
		return NULL;
	}

	if (NULL != pLogDevice) pLogDevice->AddRef(); // external pointer reference
	return pLogDevice;
}
Esempio n. 5
0
static void 
CheckUnitDeviceOnUnmount(CNdasUnitDevice* pUnitDevice)
{
	if (pUnitDevice) 
	{
		CRefObjPtr<CNdasDevice> pDevice = pUnitDevice->GetParentDevice();
		if (NULL != pDevice.p) 
		{
			(VOID) pDevice->UpdateDeviceInfo();
		}
	}
}
Esempio n. 6
0
VOID 
CNdasLogicalDevice::SetStatus(NDAS_LOGICALDEVICE_STATUS newStatus)
{
	ximeta::CAutoLock autolock(this);

	//
	// Ignore duplicate status change
	//
	if (m_status == newStatus) {
		return;
	}

	NDAS_LOGICALDEVICE_STATUS oldStatus = m_status;

	BOOL fValid = pCheckStatusValidity(m_status, newStatus);
	_ASSERTE(fValid);

	m_status = newStatus;

	// Update Unit Device Status
	for (DWORD i = 0; i < GetUnitDeviceCount(); ++i) {

		CRefObjPtr<CNdasUnitDevice> pUnitDevice = GetUnitDevice(i);

		if (NULL == pUnitDevice.p) {
			DBGPRT_ERR(_FT("Unit Device %s is not found.\n"),
				CNdasUnitDeviceId(GetUnitDeviceID(i)).ToString());
			continue;
		}

		//
		// TODO: Create a status updater with observer
		//

		switch (m_status) {
		case NDAS_LOGICALDEVICE_STATUS_MOUNTED:
		case NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING:
		case NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING:
			pUnitDevice->SetStatus(NDAS_UNITDEVICE_STATUS_MOUNTED);
			break;
		default:
			// otherwise
			pUnitDevice->SetStatus(NDAS_UNITDEVICE_STATUS_NOT_MOUNTED);
		}

	}
	
	// publish a status change event
	(VOID) pGetNdasEventPublisher()->
		LogicalDeviceStatusChanged(m_logicalDeviceId, oldStatus, newStatus);

}
Esempio n. 7
0
const NDAS_CONTENT_ENCRYPT* 
CNdasLogicalDevice::GetContentEncrypt()
{
	CRefObjPtr<CNdasUnitDevice> pPrimaryUnitDevice = GetUnitDevice(0);
	if (NULL == pPrimaryUnitDevice.p)
	{
		return NULL;
	}

	if (NDAS_UNITDEVICE_TYPE_DISK != pPrimaryUnitDevice->GetType())
	{
		return NULL;
	}

	CNdasUnitDiskDevice* pUnitDiskDevice = 
		reinterpret_cast<CNdasUnitDiskDevice*>(pPrimaryUnitDevice.p);

	m_contentEncrypt = pUnitDiskDevice->GetEncryption();

	return &m_contentEncrypt;
}
Esempio n. 8
0
BOOL
CNdasLogicalDeviceManager::Unregister(CNdasUnitDevice& unitDevice)
{
	ximeta::CAutoLock autolock(this);

	CRefObjPtr<CNdasLogicalDevice> pLogDevice = unitDevice.GetLogicalDevice();
	if (NULL == pLogDevice.p) {
		return FALSE;
	}

	DWORD ldSequence = unitDevice.GetLDSequence();
	pLogDevice->RemoveUnitDevice(unitDevice);

	if (pLogDevice->GetUnitDeviceInstanceCount() == 0) {

		NDAS_LOGICALDEVICE_ID id = pLogDevice->GetLogicalDeviceId();

		LDGroupMap::size_type ldg_erased = 
			m_LDGroupMap.erase(pLogDevice->GetLDGroup());
		_ASSERTE(1 == ldg_erased);

		LDIDMap::size_type id_erased = 
			m_LDIDMap.erase(id);
		_ASSERTE(1 == id_erased);
		
		pLogDevice->Release();

		BOOL fSuccess = cpDeallocateID(id);
		_ASSERTE(fSuccess);
	}

	return TRUE;
}
Esempio n. 9
0
DWORD
CNdasLogicalDevice::cpGetMaxRequestBlocks()
{
	ximeta::CAutoLock autolock(this);

	//
	// MaxRequestBlock is a NDAS Device's dependent property
	// So we only have to look at NDAS devices
	//

	DWORD dwMaxRequestBlocks(0);

	for (DWORD i = 0; i < GetUnitDeviceCount(); i++) 
	{
		CRefObjPtr<CNdasUnitDevice> pUnitDevice = GetUnitDevice(i);
		if (NULL == pUnitDevice.p) 
		{
			return 0;
		}

		if (0 == i) 
		{
			dwMaxRequestBlocks = pUnitDevice->GetOptimalMaxRequestBlock();
		}
		else
		{
			dwMaxRequestBlocks = 
				min(dwMaxRequestBlocks, pUnitDevice->GetOptimalMaxRequestBlock());
		}

	}

	m_dwCurrentMRB = dwMaxRequestBlocks;
	return dwMaxRequestBlocks;

}
Esempio n. 10
0
BOOL 
CNdasLogicalDevice::PlugIn(ACCESS_MASK requestingAccess)
{
	ximeta::CAutoLock autolock(this);

	BOOL fPSWriteShare = IsPSWriteShareCapable();

	BOOL fSuccess = cpCheckPlugInCondition(requestingAccess);
	if (!fSuccess) 
	{
		return FALSE;
	}

	//
	// Plug In
	// - NDAS Controller
	//
	CRefObjPtr<CNdasUnitDevice> pPrimaryUnitDevice = GetUnitDevice(0);

	if (NULL == pPrimaryUnitDevice.p) 
	{
		SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER);
		::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_MEMBER_MISSING);
		return FALSE;
	}

	CRefObjPtr<CNdasDevice> pDevice = pPrimaryUnitDevice->GetParentDevice();
	if (NULL == pDevice.p) 
	{
		SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER);
		::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_MEMBER_MISSING);
	}

	//
	// Max DVD Instance (Global Instance) Constraint
	//
	// Do not allow local host to have multiple DVD devices
	// with Write Access.
	// I-O Data's request?
	//
#if NDAS_FEATURE_DONOT_ALLOW_MULTIPLE_DVD_RW_INSTANCES
	if (NDAS_LOGICALDEVICE_TYPE_DVD == GetType()) 
	{
		fSuccess = cpCheckPlugInCondForDVD(requestingAccess);
		if (!fSuccess) 
		{
			// SetLastError is set by the pCheckPlugInCondForDVD
			return FALSE;
		}
	}
#endif

	//
	// Resetting an event always succeeds if the handle is valid
	//
	fSuccess = ::ResetEvent(m_hDisconnectedEvent);
	_ASSERTE(fSuccess);

	fSuccess = ::ResetEvent(m_hAlarmEvent);
	_ASSERTE(fSuccess);

	//
	// Add Target
	// - Add a disk device to the NDAS controller
	//

	SIZE_T cbAddTargetDataSize =  
		sizeof(LANSCSI_ADD_TARGET_DATA) - sizeof(LSBUS_UNITDISK) +
		GetUnitDeviceCount() * sizeof(LSBUS_UNITDISK);

	PLANSCSI_ADD_TARGET_DATA pAddTargetData = 
		(PLANSCSI_ADD_TARGET_DATA) ::HeapAlloc(
		::GetProcessHeap(),
		HEAP_ZERO_MEMORY,
		cbAddTargetDataSize);

	if (NULL == pAddTargetData) 
	{
		// TODO: Out of memory
		return FALSE;
	}

	// automatically free the heap when it goes out of the scope
	AutoProcessHeap autoHeap = pAddTargetData;

	UCHAR ucTargetType = pConvertToLSBusTargetType(m_logicalDeviceGroup.Type);

	pAddTargetData->ulSize = cbAddTargetDataSize;
	pAddTargetData->ulSlotNo = m_NdasScsiLocation.SlotNo;
	pAddTargetData->ulTargetBlocks = 0; // initialization and will be added
	pAddTargetData->DesiredAccess = requestingAccess;
	pAddTargetData->ulNumberOfUnitDiskList = GetUnitDeviceCount();
	pAddTargetData->ucTargetType = ucTargetType;

	// if PSWriteShare is not capable, we should specify the LUROption
	// to turn off the PSWriteShare explicitly.


	DWORD dwLUROptions = 0;
	{
		BOOL fConfigured = _NdasSystemCfg.GetValueEx(
			_T("ndassvc"),
			_T("LUROptions"),
			&dwLUROptions);
		if (!fConfigured) 
		{
			// revert to default for safety
			dwLUROptions = 0; 
		}
	}

	if (!fPSWriteShare)
	{
		dwLUROptions |= LUROPTION_OFF_WRITESHARE_PS;
		dwLUROptions &= ~(LUROPTION_ON_WRITESHARE_PS);
	}

	pAddTargetData->LurOptions = dwLUROptions;


	// Set Content Encryption from the primary unit device
	// (Only for Disk Devices)
	if (NDAS_UNITDEVICE_TYPE_DISK == pPrimaryUnitDevice->GetType()) 
	{
		
		CNdasUnitDiskDevice* pUnitDiskDevice = 
			reinterpret_cast<CNdasUnitDiskDevice*>(pPrimaryUnitDevice.p);

		CONST NDAS_CONTENT_ENCRYPT& encrypt = pUnitDiskDevice->GetEncryption();

		pAddTargetData->CntEcrKeyLength = encrypt.KeyLength;
		pAddTargetData->CntEcrMethod = encrypt.Method;
		::CopyMemory(
			pAddTargetData->CntEcrKey,
			encrypt.Key,
			encrypt.KeyLength);

	}

	if (NDASSCSI_TYPE_DISK_RAID1 == ucTargetType ||
		NDASSCSI_TYPE_DISK_RAID4 == ucTargetType)
	{
		CNdasUnitDiskDevice* pUnitDiskDevice = 
			reinterpret_cast<CNdasUnitDiskDevice*>(pPrimaryUnitDevice.p);
		_ASSERTE(NULL != pUnitDiskDevice->GetAddTargetInfo());

		::CopyMemory(
			&pAddTargetData->RAID_Info,
			pUnitDiskDevice->GetAddTargetInfo(),
			sizeof(INFO_RAID));

		if (0 == pAddTargetData->RAID_Info.SectorsPerBit) {
			::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_INVALID_BIND_INFORMATION);
			return FALSE;
		}
	}

	for (DWORD i = 0; i < GetUnitDeviceCount(); ++i) {

		CRefObjPtr<CNdasUnitDevice> pUnitDevice = GetUnitDevice(i);
		if (NULL == pUnitDevice.p) 
		{
			SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER);
			::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_MEMBER_MISSING);
			return FALSE;
		}

		CRefObjPtr<CNdasDevice> pDevice = pUnitDevice->GetParentDevice();
		_ASSERTE(NULL != pDevice.p);

		PLSBUS_UNITDISK pud = &pAddTargetData->UnitDiskList[i];

		::CopyMemory(
			pud->Address.Node, 
			pDevice->GetRemoteLpxAddress().Node, 
			sizeof(pud->Address.Node));

		pud->Address.Port = htons(NDAS_DEVICE_LPX_PORT);

		C_ASSERT(
			sizeof(pud->NICAddr.Node) ==
			sizeof(pDevice->GetLocalLpxAddress().Node));

		::CopyMemory(
			pud->NICAddr.Node, 
			pDevice->GetLocalLpxAddress().Node, 
			sizeof(pud->NICAddr.Node));

		pud->NICAddr.Port = htons(0); // should be zero

		pud->iUserID = pUnitDevice->GetDeviceUserID(requestingAccess);
		pud->iPassword = pUnitDevice->GetDevicePassword();

		pud->ulUnitBlocks = pUnitDevice->GetUserBlockCount();
		pud->ulPhysicalBlocks = pUnitDevice->GetPhysicalBlockCount();
		pud->ucUnitNumber = pUnitDevice->GetUnitNo();
		pud->ucHWType = pDevice->GetHWType();
		pud->ucHWVersion = pDevice->GetHWVersion();
		pud->IsWANConnection = FALSE;

		//
		// Set Reconnect Retry Count, Retry Interval
		// if overridden by the user
		//
		// default:
		// ReconnTrial = 19, ReconnInterval = 3000
		//
		// reddotnet: (will be set by the installer)
		// ReconnTrial = 2, ReconnInterval = 3000
		//
		{
			BOOL fOverride = FALSE;
			BOOL fConfigured = _NdasSystemCfg.GetValueEx(
				_T("ndassvc"),
				_T("OverrideLogDevReconnect"),
				&fOverride);
			if (!fConfigured)
			{
				fOverride = FALSE;
			}

			if (fOverride)
			{
				static const DWORD LOGDEV_RECONNECT_DEFAULT = 19;
				static const DWORD LOGDEV_RECONNECT_MAX = 19;
				DWORD dwReconnect = LOGDEV_RECONNECT_DEFAULT;
				fConfigured = _NdasSystemCfg.GetValueEx(
					_T("ndassvc"),
					_T("LogDevReconnect"),
					&dwReconnect);
				if (!fConfigured || dwReconnect > LOGDEV_RECONNECT_MAX)
				{
					dwReconnect = LOGDEV_RECONNECT_DEFAULT;
				}

				static const DWORD LOGDEV_RECONNECT_INTERVAL_DEFAULT = 3000;
				static const DWORD LOGDEV_RECONNECT_INTERVAL_MAX = 60000;
				DWORD dwReconnectInterval = LOGDEV_RECONNECT_INTERVAL_DEFAULT;
				fConfigured = _NdasSystemCfg.GetValueEx(
					_T("ndassvc"),
					_T("LogDevReconnectInterval"),
					&dwReconnectInterval);
				if (!fConfigured || dwReconnectInterval > LOGDEV_RECONNECT_INTERVAL_MAX)
				{
					dwReconnectInterval = LOGDEV_RECONNECT_INTERVAL_DEFAULT;
				}

				pud->LurnOptions |= LURNOPTION_SET_RECONNECTION;
				pud->ReconnTrial = dwReconnect;
				pud->ReconnInterval = dwReconnectInterval;
			}
		}
		
		//
		// Add Target Info
		//
/*
		if (NDASSCSI_TYPE_DISK_RAID1 == ucTargetType) {

			CNdasUnitDiskDevice* pUnitDiskDevice = 
				reinterpret_cast<CNdasUnitDiskDevice*>(pUnitDevice.p);
			_ASSERTE(NULL != pUnitDiskDevice->GetAddTargetInfo());

			::CopyMemory(
				&pud->RAID_Info,
				pUnitDiskDevice->GetAddTargetInfo(),
				sizeof(INFO_RAID));

			if (0 == pud->RAID_Info.SectorsPerBit) {
				::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_INVALID_BIND_INFORMATION);
				return FALSE;
			}
		}
		else if(NDASSCSI_TYPE_DISK_RAID4 == ucTargetType) {

			CNdasUnitDiskDevice* pUnitDiskDevice = 
				reinterpret_cast<CNdasUnitDiskDevice*>(pUnitDevice.p);
			_ASSERTE(NULL != pUnitDiskDevice->GetAddTargetInfo());

			::CopyMemory(
				&pud->RAID_Info,
				pUnitDiskDevice->GetAddTargetInfo(),
				sizeof(INFO_RAID));

			if (0 == pud->RAID_Info.SectorsPerBit) {
				::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_INVALID_BIND_INFORMATION);
				return FALSE;
			}
		}
*/

		if (NDAS_UNITDEVICE_TYPE_DISK == pUnitDevice->GetType()) 
		{
			CNdasUnitDiskDevice* pUnitDiskDevice =
				reinterpret_cast<CNdasUnitDiskDevice*>(pUnitDevice.p);

			//
			// check if last DIB information is same with current one
			//
			if(!pUnitDiskDevice->HasSameDIBInfo())
			{
				pDevice->InvalidateUnitDevice(pUnitDevice->GetUnitNo());
				::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_MODIFIED_BIND_INFORMATION);
				return FALSE;
			}

			//
			// check if bitmap status in RAID 1, 4. Do not plug in
			//
#ifdef __DO_NOT_MOUNT_CORRUPTED_RAID__ // now driver supports recover on mount
			if (NDAS_UNITDEVICE_DISK_TYPE_RAID1 == pUnitDiskDevice->GetSubType().DiskDeviceType ||
				NDAS_UNITDEVICE_DISK_TYPE_RAID4 == pUnitDiskDevice->GetSubType().DiskDeviceType)
			{
				if (!pUnitDiskDevice->IsBitmapClean()) 
				{
					::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_CORRUPTED_BIND_INFORMATION);
					return FALSE;
				}
			}
#endif
			//
			// Done checking plug in condition
			//
		}
	}

	//
	// Check Multiple Write Access Compatibility
	//
	if (GENERIC_WRITE & requestingAccess) 
	{
		DWORD dwMaxNDFSCompatCheck = 1;

		if (m_fDisconnected)
		{
			// On disconnection (other than power failure), 
			// they may exist an inactive R/W connection at the NDAS device. 
			// In such case, no host will reply to NDFS Compatibility Check.
			// As an workaround for that we try NDFS Compatibility Check 
			// more than once if failed.
			static const DWORD MAX_NDFS_COMPAT_CHECK_DEFAULT = 10;
			static const DWORD MAX_NDFS_COMPAT_CHECK_MAX = 60;

			fSuccess = _NdasSystemCfg.GetValueEx(
				_T("ndassvc"), 
				_T("MaxWriteAccessCheck"),
				&dwMaxNDFSCompatCheck);

			if (!fSuccess || dwMaxNDFSCompatCheck > MAX_NDFS_COMPAT_CHECK_MAX)
			{
				dwMaxNDFSCompatCheck = MAX_NDFS_COMPAT_CHECK_DEFAULT;
			}

		}

		for (DWORD i = 0; i < dwMaxNDFSCompatCheck; ++i)
		{
			fSuccess = IsWriteAccessAllowed(fPSWriteShare, pPrimaryUnitDevice);
			if (fSuccess) 
			{
				break;
			}
		}

		if (!fSuccess)
		{
			return FALSE;
		}
	}
		

	// After this, we used up a Disconnected flag, so we can clear it.
	m_fDisconnected = FALSE;

	pAddTargetData->ulTargetBlocks = GetUserBlockCount();
	DWORD dwMaxRequestBlocksPerUnit = cpGetMaxRequestBlocks();
	DWORD dwMaxRequestBlocks;

	// use max of MBR
	switch(GetType())
	{
	case NDAS_LOGICALDEVICE_TYPE_DISK_RAID0:
		dwMaxRequestBlocks = dwMaxRequestBlocksPerUnit * GetUnitDeviceCountInRaid();
		break;
	case NDAS_LOGICALDEVICE_TYPE_DISK_RAID4:
		dwMaxRequestBlocks = dwMaxRequestBlocksPerUnit * (GetUnitDeviceCountInRaid() -1);
		break;
	default:
		dwMaxRequestBlocks = dwMaxRequestBlocksPerUnit;
		break;
	}

	DBGPRT_INFO(
		_FT("LsBusCtlPlugInEx2(SlotNo %d, MaxReqBlock %d, DisEvt %p, RecEvt %p).)\n"),
		m_NdasScsiLocation.SlotNo, 
		dwMaxRequestBlocks, 
		m_hDisconnectedEvent, 
		m_hAlarmEvent);

	SetReconnectFlag(FALSE);

	BOOL fVolatileRegister = IsVolatile();

	fSuccess = LsBusCtlPlugInEx2(
		m_NdasScsiLocation.SlotNo,
		dwMaxRequestBlocks,
		m_hDisconnectedEvent,
		m_hAlarmEvent,
		fVolatileRegister);

	if (!fSuccess) 
	{
		DBGPRT_ERR_EX(_FT("LsBusCtlPlugInEx2 failed: \n"));
		_ASSERTE(fSuccess && "PlugIn failure");
		return FALSE;
	}

	DBGPRT_INFO(_FT("LsBusCtlPluginEx succeeded.\n"));

	BEGIN_DBGPRT_BLOCK_INFO()
		DBGPRT_INFO(_FT("LsBusCtlAddTarget(pAddTargetData)\n"));
		DPType(XDebug::OL_INFO, pAddTargetData, cbAddTargetDataSize);
	END_DBGPRT_BLOCK()

	fSuccess = LsBusCtlAddTarget(pAddTargetData);
	if (!fSuccess) 
	{
		DBGPRT_ERR_EX(_FT("AddTarget failed.\n"));
		::Sleep(1000);
		LsBusCtlEject(m_NdasScsiLocation.SlotNo);
		_ASSERTE(fSuccess);
		return FALSE;
	}

	DBGPRT_INFO(_FT("LsBusCtlAddTarget succeeded.\n"));

	//
	// Set the status
	//

	SetMountedAccess(requestingAccess);

	//
	// Set the status as pending, actual mount completion is
	// reported from PNP event handler to call OnMounted()
	// to complete this process
	//

	SetStatus(NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING);

	//
	// Attach or detach from the event monitor
	//

	CNdasEventMonitor* pEventMon = pGetNdasEventMonitor();
	pEventMon->Attach(this);

	DBGPRT_INFO(_FT("Plugged in successfully at %s.\n"), m_NdasScsiLocation.ToString());

	return TRUE;
}
Esempio n. 11
0
DWORD 
CNdasLogicalDevice::GetUserBlockCount()
{
	ximeta::CAutoLock autolock(this);

	if (!IsComplete()) 
	{
		return 0;
	}

	if (!IS_NDAS_LOGICALDEVICE_TYPE_DISK_GROUP(m_logicalDeviceGroup.Type)) 
	{
		_ASSERTE(1 == GetUnitDeviceCount());
		CRefObjPtr<CNdasUnitDevice> pUnitDevice = GetUnitDevice(0);
		_ASSERTE(NULL != pUnitDevice.p);
		if (NULL == pUnitDevice.p) 
		{
			return 0;
		}
		return pUnitDevice->GetUserBlockCount();
	}

	DWORD dwBlocks = 0;
	for (DWORD i = 0; i < GetUnitDeviceCount(); i++) 
	{

		CRefObjPtr<CNdasUnitDevice> pUnitDevice = GetUnitDevice(i);
		_ASSERTE(NULL != pUnitDevice.p);
		if (NULL == pUnitDevice.p) 
		{
			return 0;
		}

		_ASSERTE(pUnitDevice->GetType() == NDAS_UNITDEVICE_TYPE_DISK);

		CNdasUnitDiskDevice* pUnitDisk = 
			reinterpret_cast<CNdasUnitDiskDevice*>(pUnitDevice.p);

		// dwBlocks += pUnitDisk->GetBlocks();

		_ASSERTE(IS_NDAS_LOGICALDEVICE_TYPE_DISK_GROUP(m_logicalDeviceGroup.Type));

		switch (m_logicalDeviceGroup.Type) 
		{
		case NDAS_LOGICALDEVICE_TYPE_DISK_MIRRORED:
			if (0 == i) 
			{
				dwBlocks = pUnitDisk->GetUserBlockCount();
			}
			break;
		case NDAS_LOGICALDEVICE_TYPE_DISK_AGGREGATED:
		case NDAS_LOGICALDEVICE_TYPE_DISK_RAID0:
			dwBlocks += pUnitDisk->GetUserBlockCount();
			break;
		case NDAS_LOGICALDEVICE_TYPE_DISK_RAID1:
			if (i % 2) 
			{
				dwBlocks += pUnitDisk->GetUserBlockCount();
			}
			break;
		case NDAS_LOGICALDEVICE_TYPE_DISK_RAID4:
			if (i != GetUnitDeviceCount() - 1) 
			{
				//
				// do not count parity disk
				//
				dwBlocks += pUnitDisk->GetUserBlockCount();
			}
			break;
		case NDAS_LOGICALDEVICE_TYPE_DISK_SINGLE:
			dwBlocks = pUnitDisk->GetUserBlockCount();
			break;
		default: 
			// not implemented yet : DVD, VDVD, MO, FLASH ...
			_ASSERTE(FALSE);
			break;
		}

	}

	return dwBlocks;

}