Beispiel #1
0
BOOL CNdasEventMonitor::OnLogicalDeviceDisconnected(DWORD nWaitIndex)
{
	ximeta::CAutoLock autolock(this);

	PCNdasLogicalDevice pLogDevice = NULL;

	if (nWaitIndex < m_vLogDevices.size()) {
		pLogDevice = m_vLogDevices[nWaitIndex];
	} else {
		_ASSERTE(FALSE);
		return TRUE;
	}

	if (NULL == pLogDevice) {
		_ASSERTE(FALSE);
		return TRUE;
	}

	CNdasScsiLocation location = pLogDevice->GetNdasScsiLocation();

	DPInfo(_FT("Disconnect Event from %s: %s\n"),
		location.ToString(),
		pLogDevice->ToString());

	//
	// reset the event to prevent consecutive same event pulse
	//
	BOOL fSuccess = ::ResetEvent(pLogDevice->GetDisconnectEvent());
	_ASSERTE(fSuccess);

	CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();

	NDAS_LOGICALDEVICE_ID logicalDeviceId = pLogDevice->GetLogicalDeviceId();

	(VOID) pEventPublisher->LogicalDeviceDisconnected(logicalDeviceId);

	pLogDevice->OnDisconnected();

	return TRUE;
}
Beispiel #2
0
void NdasLogicalDeviceStatusCheck(CNdasLogicalDevice* pLogDevice)
{
	//
	// Clear the risky mount flag 
	// in LOGICALDEVICE_RISK_MOUNT_INTERVAL after mounting
	//

	if (pLogDevice->IsRiskyMount() && 0 != pLogDevice->GetMountTick()) {
		DWORD dwBiased = ::GetTickCount() - pLogDevice->GetMountTick();
		//
		// In case of rollover (in 19 days),
		// it is safe to clear that flag.
		// This is not a strict time tick check
		//
		if (dwBiased > CNdasEventMonitor::LOGICALDEVICE_RISK_MOUNT_INTERVAL) {
			pLogDevice->SetRiskyMountFlag(FALSE);
		}
	}

	//
	// During mount pending, NDAS SCSI is not available until the user
	// accept the warning message of non-signed driver
	//
	// This may cause the logical device being unmounted. 
	//

	if (NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING == pLogDevice->GetStatus() ||
		NDAS_LOGICALDEVICE_STATUS_MOUNTED == pLogDevice->GetStatus() ||
		NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING == pLogDevice->GetStatus())
	{

		CNdasScsiLocation location = pLogDevice->GetNdasScsiLocation();

		BOOL fAlive, fAdapterError;

		BOOL fSuccess = ::LsBusCtlQueryNodeAlive(
			location.SlotNo, 
			&fAlive, 
			&fAdapterError);

		//
		// if LsBusCtlQueryNodeAlive fails, 
		// there may be no lanscsibus device instance...
		//

		if (!fSuccess) {

			DBGPRT_ERR_EX(_FT("LsBusCtlQueryNodeAlive at %s failed: "), location.ToString());

		} else {

			if (!fAlive) {
				pLogDevice->OnDeviceStatusFailure();
			}

//			if (fAdapterError) {
//				DBGPRT_ERR_EX(_FT("LsBusCtlQueryNodeAlive reported an adapter error.\n"));
//				pLogDevice->SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_FROM_DRIVER);
//			}

		}

	}

}
Beispiel #3
0
BOOL 
CNdasEventMonitor::OnLogicalDeviceAlarmed(DWORD nWaitIndex)
{
	ximeta::CAutoLock autolock(this);

	PCNdasLogicalDevice pLogDevice = NULL;

	if (nWaitIndex < m_vLogDevices.size()) {
		pLogDevice = m_vLogDevices[nWaitIndex];
	} else {
		_ASSERTE(FALSE);
		return FALSE;
	}

	if (NULL == pLogDevice) {
		_ASSERTE(FALSE);
		return FALSE;
	}

	CNdasScsiLocation ndasScsiLocation = pLogDevice->GetNdasScsiLocation();

	DPInfo(_FT("Alarm Event from %s: %s\n"),
		ndasScsiLocation.ToString(),
		pLogDevice->ToString());

	if (ndasScsiLocation.IsInvalid()) {
		DBGPRT_ERR(_FT("Invalid SCSI Location\n"));
		_ASSERTE(FALSE);
		return FALSE;
	}

	//
	// reset the event to prevent consecutive same event pulse
	//
	// should return TRUE
	BOOL fSuccess = ::ResetEvent(pLogDevice->GetAlarmEvent());
	_ASSERTE(fSuccess);

	ULONG ulAdapterStatus;

	fSuccess = ::LsBusCtlQueryStatus(
		ndasScsiLocation.SlotNo,
		&ulAdapterStatus);

	if (!fSuccess) {
		DPErrorEx(_FT("Unable to get alarm status, Ignored: "));
		return TRUE;
	}

	if(pLogDevice->GetAdapterStatus() != ulAdapterStatus)
	{
		pLogDevice->SetAdapterStatus(ulAdapterStatus);

		CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();

		(VOID) pEventPublisher->LogicalDeviceAlarmed(pLogDevice->GetLogicalDeviceId(), ulAdapterStatus);
	}

	if(ADAPTERINFO_ISSTATUSFLAG(ulAdapterStatus, ADAPTERINFO_STATUSFLAG_MEMBER_FAULT))
		pLogDevice->SetAllUnitDevicesFault();

	return TRUE;
}
Beispiel #4
0
BOOL 
CNdasEventMonitor::OnLogicalDeviceAlarmed(DWORD nWaitIndex)
{
	ximeta::CAutoLock autolock(this);

	CNdasLogicalDevice* pLogDevice = NULL;

	if (nWaitIndex < m_vLogDevices.size()) {
		pLogDevice = m_vLogDevices[nWaitIndex];
	} else {
		_ASSERTE(FALSE);
		return FALSE;
	}

	if (NULL == pLogDevice) {
		_ASSERTE(FALSE);
		return FALSE;
	}

	CNdasScsiLocation ndasScsiLocation = pLogDevice->GetNdasScsiLocation();

	DBGPRT_INFO(_FT("Alarm Event from %s: %s\n"),
		ndasScsiLocation.ToString(),
		pLogDevice->ToString());

	if (ndasScsiLocation.IsInvalid()) {
		DBGPRT_ERR(_FT("Invalid SCSI Location\n"));
		_ASSERTE(FALSE);
		return FALSE;
	}

	//
	// reset the event to prevent consecutive same event pulse
	//
	// should return TRUE
	BOOL fSuccess = ::ResetEvent(pLogDevice->GetAlarmEvent());
	_ASSERTE(fSuccess);

	ULONG ulAdapterStatus;

	fSuccess = ::LsBusCtlQueryStatus(
		ndasScsiLocation.SlotNo,
		&ulAdapterStatus);

	if (!fSuccess) {
		DBGPRT_ERR_EX(_FT("(%s) query status failed on alarm, ignored: "), 
			ndasScsiLocation.ToString());
		return TRUE;
	}

	DBGPRT_INFO(_FT("(%s) alarmed %08X.\n"), 
		ndasScsiLocation.ToString(), ulAdapterStatus);

	// Determine whether an alarm will be issued.
	// Only viable alarm will be published
	if(pIsViableAlarmStatus(pLogDevice->GetAdapterStatus(), ulAdapterStatus))
	{
		CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();
		(VOID) pEventPublisher->LogicalDeviceAlarmed(
			pLogDevice->GetLogicalDeviceId(), pGetSignificatAlarm(pLogDevice->GetAdapterStatus(), ulAdapterStatus));
	}

	pLogDevice->SetAdapterStatus(ulAdapterStatus);

	return TRUE;
}
Beispiel #5
0
LRESULT 
CNdasServiceDeviceEventHandler::
OnCdRomDeviceInterfaceArrival(
	PDEV_BROADCAST_DEVICEINTERFACE pdbhdr)
{
	XTLTRACE2(TCPnp, TLInfo, 
		"OnCdRomDeviceInterfaceArrival: %ls\n", pdbhdr->dbcc_name);

	XTL::AutoFileHandle hDevice = ::CreateFile(
		(LPCTSTR)pdbhdr->dbcc_name,
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		0,
		NULL);

	if (hDevice.IsInvalid()) 
	{
		//
		// TODO: Set Logical Device Status to 
		// LDS_MOUNT_PENDING -> LDS_UNMOUNTED
		// and Set LDS_ERROR? However, which one?
		//
		XTLTRACE2_ERR(TCPnp, TLError, 
			"CreateFile(%ls) failed.\n", (LPCTSTR) pdbhdr->dbcc_name);

		return TRUE;
	}

	// Disks and CDROMs can be treated as same for querying scsi address 
	CNdasScsiLocation ndasScsiLocation;
	if (!pGetNdasScsiLocationForDisk(hDevice, &ndasScsiLocation)) 
	{
		XTLTRACE2_ERR(TCPnp, TLWarning, 
			"pGetNdasScsiLocationForCDROM(%p) failed.\n", hDevice);
		XTLTRACE2(TCPnp, TLWarning, 
			"May not be NDAS logical device. Ignoring.\n");
		return TRUE;
	}

	XTLTRACE2(TCPnp, TLInfo,
		"NDAS Logical Device at %ls.\n", 
		ndasScsiLocation.ToString());

	//
	// we are to set the logical device status 
	// from MOUNT_PENDING -> MOUNTED
	//

	CNdasLogicalDevicePtr pLogDevice = pGetNdasLogicalDevice(ndasScsiLocation);
	if (CNdasLogicalDeviceNullPtr == pLogDevice) 
	{
		// unknown NDAS logical device
		XTLTRACE2(TCPnp, TLWarning, 
			"No Logical device at %ls found in LDM.\n", 
			ndasScsiLocation.ToString());
		return TRUE;
	}

	pLogDevice->OnMounted();


	//
	// Device Notification
	//

	bool result = AddDeviceNotificationHandle(
		hDevice, 
		DeviceNotifyData(DeviceNotifyData::DNTCdRom, ndasScsiLocation));

	if (!result)
	{
		XTLTRACE2_ERR(TCPnp, TLWarning, 
			"Registering CDROM device handle %p for notification failed.\n", hDevice);
	}
	else
	{
		XTLTRACE2(TCPnp, TLInfo, 
			"CDROM Device handle %p is registered for notification.\n", hDevice);
	}

	return TRUE;
}
Beispiel #6
0
LRESULT 
CNdasServiceDeviceEventHandler::
OnDiskDeviceInterfaceArrival(
	PDEV_BROADCAST_DEVICEINTERFACE pdbhdr)
{
	XTLTRACE2(TCPnp, TLInfo, 
		"OnDiskDeviceInterfaceArrival: %ls\n", pdbhdr->dbcc_name);

	XTL::AutoFileHandle hDisk = ::CreateFile(
		reinterpret_cast<LPCTSTR>(pdbhdr->dbcc_name),
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		0,
		NULL);

	if (hDisk.IsInvalid()) 
	{
		//
		// TODO: Set Logical Device Status to 
		// LDS_MOUNT_PENDING -> LDS_UNMOUNTED
		// and Set LDS_ERROR? However, which one?
		//
		XTLTRACE2_ERR(TCPnp, TLError, "CreateFile(%ls) failed.\n", (LPCTSTR) pdbhdr->dbcc_name);
		return TRUE;
	}

	CNdasScsiLocation ndasScsiLocation;
	if (!pGetNdasScsiLocationForDisk(hDisk, &ndasScsiLocation)) 
	{
		XTLTRACE2_ERR(TCPnp, TLWarning, 
			"pGetNdasScsiLocationForDisk(%p) failed.\n", hDisk);
		XTLTRACE2(TCPnp, TLWarning, 
			"May not be NDAS logical device. Ignoring.\n");
		return TRUE;
	}

	XTLTRACE2(TCPnp, TLInfo,
		"NDAS Logical Device Slot No: %ls.\n", 
		ndasScsiLocation.ToString());

	//
	// we are to set the logical device status 
	// from MOUNT_PENDING -\> MOUNTED
	//

	//////////////////////////////////////////////////////////////////////
	// minimum access
	//////////////////////////////////////////////////////////////////////

	CNdasLogicalDevicePtr pLogDevice = pGetNdasLogicalDevice(ndasScsiLocation);
	if (CNdasLogicalDeviceNullPtr == pLogDevice) 
	{
		// unknown NDAS logical device
		XTLTRACE2(TCPnp, TLWarning, 
			"No Logical device at %ls found in LDM.\n", 
			ndasScsiLocation.ToString());
		return TRUE;
	}

	pLogDevice->OnMounted();


// TODO: by configuration!
#ifdef NDAS_FEATURE_DISABLE_WRITE_CACHE
	fSuccess = sysutil::DisableDiskWriteCache(hDisk);
	if (!fSuccess) 
	{
		XTLTRACE2_ERR(TCPnp, TLWarning, "DisableDiskWriteCache failed.\n");
	}
	else 
	{
		XTLTRACE2(TCPnp, TLInfo, "Disk Write Cache disabled successfully.\n");
	}
#endif

	//////////////////////////////////////////////////////////////////////
	// Set HotplugInfo
	//////////////////////////////////////////////////////////////////////

#ifdef NDAS_FEATURE_USE_HOTPLUG_POLICY
	pSetDiskHotplugInfoByPolicy(hDisk);
#endif

	//////////////////////////////////////////////////////////////////////
	// Registers Device Notification
	//////////////////////////////////////////////////////////////////////

	bool result = AddDeviceNotificationHandle(
		hDisk, 
		DeviceNotifyData(DeviceNotifyData::DNTDisk, ndasScsiLocation));

	if (!result)
	{
		XTLTRACE2_ERR(TCPnp, TLWarning, 
			"Registering disk device handle %p for notification failed.\n", hDisk);
	}
	else
	{
		XTLTRACE2(TCPnp, TLInfo, 
			"Disk device handle %p is registered for notification.\n", hDisk);
	}

	//////////////////////////////////////////////////////////////////////
	
	return TRUE;
}