コード例 #1
0
ファイル: ndaspnp.cpp プロジェクト: tigtigtig/ndas4windows
LRESULT 
CNdasServiceDeviceEventHandler::
OnDeviceHandleQueryRemoveFailed(
	PDEV_BROADCAST_HANDLE pdbch)
{
	XTLTRACE2(TCPnp, TLInfo, 
		"OnDeviceHandleQueryRemoveFailed: Device Handle %p, Notify Handle %p\n", 
		pdbch->dbch_handle,
		pdbch->dbch_hdevnotify);

	DeviceNotifyData notifyData;
	if (!FindDeviceHandle(pdbch->dbch_hdevnotify, notifyData))
	{
		XTLTRACE2(TCPnp, TLInfo, "Notify Handle is not registered.\n");
		return TRUE;
	}

	XTLTRACE2(TCPnp, TLInfo, 
		"LogDeviceSlotNo %ls, Type %d\n", 
		CNdasScsiLocation(notifyData.NdasScsiLocation).ToString(), 
		DeviceNotifyDataTypeString(notifyData.Type));

	//
	// DEVNOTIFYINFO_TYPE_STORAGEPORT is the only notification we are 
	// interested in. However, when a CDROM device attached to the storage port,
	// the storage port device notification for QueryRemoveFailed is not
	// sent to us. So, we also need to handle CD-ROM.
	// 
	// Do not worry about redundant calls to pLogDevice->OnUnmountFailed().
	// It only cares if NDAS_LOGICALDEVICE_STATUS is UNMOUNT_PENDING,
	// which means backup calls will be ignored.
	//
	switch (notifyData.Type)
	{
	case DeviceNotifyData::DNTStoragePort:
	case DeviceNotifyData::DNTCdRom:
	case DeviceNotifyData::DNTDisk:
		{
			CNdasLogicalDevicePtr pLogDevice = 
				pGetNdasLogicalDevice(notifyData.NdasScsiLocation);
			if (CNdasLogicalDeviceNullPtr == pLogDevice) 
			{
				XTLTRACE2(TCPnp, TLWarning, 
					"Logical Device not found at %ls.\n", 
					CNdasScsiLocation(notifyData.NdasScsiLocation).ToString());
				return TRUE;
			}
			pLogDevice->OnUnmountFailed();
		}
		break;
	default:
		break;
	}
	return TRUE;
}
コード例 #2
0
ファイル: ndaslogdev.cpp プロジェクト: yzx65/ndas4windows
BOOL
CNdasLogicalDevice::Unplug()
{
	BOOL fSuccess(FALSE);

	ximeta::CAutoLock autolock(this);

	DBGPRT_INFO(_FT("Unplugging %s\n"), ToString());

	if (m_status == NDAS_LOGICALDEVICE_STATUS_NOT_INITIALIZED) 
	{
		::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_INITIALIZED);
		return FALSE;
	}

	if (m_status != NDAS_LOGICALDEVICE_STATUS_MOUNTED &&
		m_status != NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING &&
		m_status != NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING) 
	{
		::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_MOUNTED);
		return FALSE;
	}

	//
	// Remove target ejects the disk and the volume.
	//

	fSuccess = LsBusCtlRemoveTarget(m_NdasScsiLocation.SlotNo);
	if (!fSuccess) {
		DBGPRT_WARN_EX(_FT("LsBusCtlRemoveTarget failed: "));
	}

	// Intentional break
	::Sleep(100);

	//
	// BUG:
	// What happened when RemoveTarget succeeded and 
	// Unplugging LANSCSI port is failed?
	//

	fSuccess = LsBusCtlUnplug(m_NdasScsiLocation.SlotNo);
	if (!fSuccess) 
	{
		DBGPRT_ERR_EX(_FT("LsBusCtlUnplug failed: "));
		// last error from lsbusctl unplug
		return FALSE;
	}

	//
	// Change the status to unmounted
	//
	SetStatus(NDAS_LOGICALDEVICE_STATUS_UNMOUNTED);

	DBGPRT_INFO(_FT("Unplugged successfully at slot %s.\n"),
		CNdasScsiLocation(m_NdasScsiLocation).ToString());

	return TRUE;

}
コード例 #3
0
ファイル: ndaslogdevman.cpp プロジェクト: yzx65/ndas4windows
BOOL
CNdasLogicalDeviceManager::UnregisterNdasScsiLocation(
	CONST NDAS_SCSI_LOCATION& location)
{
	ximeta::CAutoLock autolock(this);

	LocationMap::size_type nErased = m_NdasScsiLocationMap.erase(location);
	if (1 != nErased) {
		DBGPRT_WARN(
			_FT("NdasScsiLocation not registered at %s"), 
			CNdasScsiLocation(location).ToString());
	}
	_ASSERTE(1 == nErased);

	return (1 == nErased);
}
コード例 #4
0
BOOL
CNdasLogicalDevice::Recover()
{
	BOOL fSuccess(FALSE);

	ximeta::CAutoLock autolock(this);

	DBGPRT_INFO(_FT("Recovering %s\n"), ToString());

	switch(GetType())
	{
	case NDAS_LOGICALDEVICE_TYPE_DISK_RAID1:
	case NDAS_LOGICALDEVICE_TYPE_DISK_RAID4:
		break;
	default:
		return FALSE;
	}

	if (m_status == NDAS_LOGICALDEVICE_STATUS_NOT_INITIALIZED) {
		::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_INITIALIZED);
		return FALSE;
	}

	if (m_status != NDAS_LOGICALDEVICE_STATUS_MOUNTED) 
	{
		::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_MOUNTED);
		return FALSE;
	}

	// Do not recover if any NDAS unit device is not alive
	DWORD ldSequence = 0;
	for(ldSequence = 0; ldSequence < m_logicalDeviceGroup.nUnitDevices; ldSequence++)
	{
		if(NDAS_UNITDEVICE_STATUS_MOUNTED != m_pUnitDevices[ldSequence]->GetStatus())
		{
			::SetLastError(NDASHLPSVC_ERROR_NDAS_UNITDEVICE_NOT_MOUNTED);
			return FALSE;
		}
	}

	if(IsAnyUnitDevicesFault())
	{
		::SetLastError(NDASHLPSVC_ERROR_NDAS_UNITDEVICE_NOT_MOUNTED);
		return FALSE;
	}

	ULONG ulStatus;

	fSuccess = ::LsBusCtlQueryStatus(		
		m_NdasScsiLocation.SlotNo,
		&ulStatus);

	if (!fSuccess) {
		DBGPRT_ERR_EX(_FT("Unable to get status"));
		return FALSE;
	}

	// Do not recover if NDAS logical device is not under emergency
	// Do not recover if NDAS logical device is already recovering
	if(!ADAPTERINFO_ISSTATUSFLAG(ulStatus, ADAPTERINFO_STATUSFLAG_MEMBER_FAULT))
	{
		DBGPRT_ERR_EX(_FT("Not in emergency mode or already recovering"));
		return FALSE;
	}


	//
	// LsBusCtl is overhauled only to use SlotNo for RemoveTargetData
	//

	//
	// Remove target ejects the disk and the volume.
	//

	fSuccess = LsBusCtlRecoverTarget(m_NdasScsiLocation.SlotNo);
	if (!fSuccess) {
		DBGPRT_WARN_EX(_FT("LsBusCtlRemoveTarget failed: "));
	}

	DBGPRT_INFO(_FT("Started recovering successfully at slot %s.\n"),
		CNdasScsiLocation(m_NdasScsiLocation).ToString());

	return TRUE;

}
コード例 #5
0
ファイル: ndaspnp.cpp プロジェクト: tigtigtig/ndas4windows
LRESULT 
CNdasServiceDeviceEventHandler::
OnDeviceHandleRemoveComplete(
	PDEV_BROADCAST_HANDLE pdbch)
{
	//
	// Device Handle Remove Complete is called on Surprise Removal
	//

	XTLTRACE2(TCPnp, TLInfo, 
		"OnDeviceHandleRemoveComplete: Device Handle %p, Notify Handle %p\n",
		pdbch->dbch_handle, pdbch->dbch_hdevnotify);

	DeviceNotifyData notifyData;
	if (!FindDeviceHandle(pdbch->dbch_hdevnotify, notifyData))
	{
		XTLTRACE2(TCPnp, TLInfo, "Notify Handle is not registered.\n");
		return TRUE;
	}

	// Erase from the map
	XTLVERIFY(1 == m_DevNotifyMap.erase(pdbch->dbch_hdevnotify));

	BOOL fSuccess = ::UnregisterDeviceNotification(pdbch->dbch_hdevnotify);
	if (!fSuccess) 
	{
		XTLTRACE2(TCPnp, TLWarning, 
			"Unregistering a device notification to %p failed.\n",
			pdbch->dbch_hdevnotify);
	}

	switch (notifyData.Type)
	{
	case DeviceNotifyData::DNTStoragePort:
		{
			//
			// Remove removal is completed for NDAS SCSI Controller
			//
			CNdasLogicalDevicePtr pLogDevice = 
				pGetNdasLogicalDevice(notifyData.NdasScsiLocation);
			if (CNdasLogicalDeviceNullPtr == pLogDevice) 
			{
				XTLTRACE2(TCPnp, TLWarning, 
					"Logical Device not found at %ls.\n", 
					CNdasScsiLocation(notifyData.NdasScsiLocation).ToString());
			}
			else
			{
				pLogDevice->OnUnmounted();
			}
		}
		break;
	case DeviceNotifyData::DNTDisk:
		{
			XTLTRACE2(TCPnp, TLInfo, 
				"Disk Remove Complete(%ls)\n", 
				CNdasScsiLocation(notifyData.NdasScsiLocation).ToString());
		}
		break;
	case DeviceNotifyData::DNTCdRom:
		{
			XTLTRACE2(TCPnp, TLInfo, 
				"CDROM Remove Complete(%ls)\n", 
				CNdasScsiLocation(notifyData.NdasScsiLocation).ToString());
		}
		break;
	case DeviceNotifyData::DNTVolume:
		{
			XTLTRACE2(TCPnp, TLInfo, 
				"Volume Remove Complete(%ls)\n", 
				CNdasScsiLocation(notifyData.NdasScsiLocation).ToString());
		}
		break;
	default:
		// We do not care about other types at this time.
		break;
	}

	return TRUE;
}