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; }
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); // } } } }
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; }
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; }
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; }
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; }