VOID CNdasDevice::SetGrantedAccess(ACCESS_MASK access) { ximeta::CAutoLock autolock(this); // only GENERIC_READ and GENERIC_WRITE are acceptable m_grantedAccess = (access & (GENERIC_READ | GENERIC_WRITE)); const DWORD cbData = sizeof(m_grantedAccess) + sizeof(m_deviceId); BYTE lpbData[cbData] = {0}; ::CopyMemory(lpbData, &m_grantedAccess, sizeof(m_grantedAccess)); ::CopyMemory(lpbData + sizeof(m_grantedAccess), &m_deviceId, sizeof(m_deviceId)); BOOL fSuccess = _NdasSystemCfg.SetSecureValueEx( m_szCfgContainer, TEXT("GrantedAccess"), lpbData, cbData); if (!fSuccess) { DBGPRT_WARN_EX(_FT("Writing device access to the registry failed at %s.\n"), m_szCfgContainer); } (VOID) pGetNdasEventPublisher()->DevicePropertyChanged(m_dwSlotNo); }
VOID CNdasDevice::SetName(LPCTSTR szName) { ximeta::CAutoLock autolock(this); HRESULT hr = ::StringCchCopy( m_szDeviceName, MAX_NDAS_DEVICE_NAME_LEN, szName); _ASSERTE(SUCCEEDED(hr)); BOOL fSuccess = _NdasSystemCfg.SetValueEx( m_szCfgContainer, TEXT("DeviceName"), szName); if (!fSuccess) { DBGPRT_WARN_EX( _FT("Writing device name entry to the registry failed at %s.\n"), m_szCfgContainer); } CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher(); (VOID) pEventPublisher->DevicePropertyChanged(m_dwSlotNo); }
VOID CNdasDevice::ChangeStatus(NDAS_DEVICE_STATUS newStatus) { ximeta::CAutoLock autolock(this); if (m_status == newStatus) { return; } NDAS_DEVICE_STATUS oldStatus = m_status; // // clear failure count for every status change // m_dwCommFailureCount = 0; switch (newStatus) { case NDAS_DEVICE_STATUS_DISABLED: { pGetNdasDeviceHeartbeatListner()->Detach(this); pGetNdasEventMonitor()->Detach(this); DestroyAllUnitDevices(); } break; case NDAS_DEVICE_STATUS_CONNECTED: { pGetNdasEventMonitor()->Attach(this); } break; case NDAS_DEVICE_STATUS_DISCONNECTED: { // // Detaching from the Monitor will be done at OnStatusCheck // by returning TRUE to detach this device from the monitor // pGetNdasDeviceHeartbeatListner()->Attach(this); DestroyAllUnitDevices(); } break; default: _ASSERTE(FALSE); } DBGPRT_INFO(_FT("%s status changed %s to %s\n"), ToString(), NdasDeviceStatusString(m_status), NdasDeviceStatusString(newStatus)); m_status = newStatus; (VOID) pGetNdasEventPublisher()-> DeviceStatusChanged(m_dwSlotNo, oldStatus, newStatus); return; }
void CNdasEventMonitor::OnLogicalDeviceAlarmedByPnP( __in INdasLogicalUnit* pNdasLogicalUnit, __in ULONG NewAdapterStatus) { NDAS_LOCATION ndasLocation; COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Alarm Event, ndasLocation=%08X, logicalUnit=%p\n", ndasLocation, pNdasLogicalUnit); if (0 == ndasLocation) { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Invalid SCSI Location\n"); XTLASSERT(FALSE); return; } XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Logical device alarmed by PnP, ndasLocation=%08X, adapterStatus=%08X.\n", ndasLocation, NewAdapterStatus); // Determine whether an alarm will be issued. // Only viable alarm will be published ULONG currentAdapterStatus; COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(¤tAdapterStatus)); if (pIsViableAlarmStatus(currentAdapterStatus, NewAdapterStatus)) { CNdasEventPublisher& epub = pGetNdasEventPublisher(); if (ADAPTERINFO_ISSTATUS(NewAdapterStatus, NDASSCSI_ADAPTER_STATUS_STOPPED) && ADAPTERINFO_ISSTATUSFLAG(NewAdapterStatus, NDAS_DEVICE_ALARM_STATUSFLAG_ABNORMAL_TERMINAT)) { // // Notify abnormal removal of the LU device. // OnLogicalDeviceDisconnected(pNdasLogicalUnit); } else { NDAS_LOGICALDEVICE_ID logicalUnitId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId)); (void) epub.LogicalDeviceAlarmed( logicalUnitId, pGetSignificantAlarm(currentAdapterStatus, NewAdapterStatus)); } } COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(NewAdapterStatus)); }
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); }
VOID CNdasDevice::SetName(LPCTSTR szName) { ximeta::CAutoLock autolock(this); HRESULT hr = ::StringCchCopy( m_szDeviceName, MAX_NDAS_DEVICE_NAME_LEN, szName); _ASSERTE(SUCCEEDED(hr)); (VOID) SetConfigValue(_T("DeviceName"), szName); (VOID) pGetNdasEventPublisher()->DevicePropertyChanged(m_dwSlotNo); }
VOID CNdasDevice::SetGrantedAccess(ACCESS_MASK access) { ximeta::CAutoLock autolock(this); // only GENERIC_READ and GENERIC_WRITE are acceptable m_grantedAccess = (access & (GENERIC_READ | GENERIC_WRITE)); const DWORD cbData = sizeof(m_grantedAccess) + sizeof(m_deviceId); BYTE lpbData[cbData] = {0}; ::CopyMemory(lpbData, &m_grantedAccess, sizeof(m_grantedAccess)); ::CopyMemory(lpbData + sizeof(m_grantedAccess), &m_deviceId, sizeof(m_deviceId)); (VOID) SetConfigValueSecure(_T("GrantedAccess"), lpbData, cbData); (VOID) pGetNdasEventPublisher()->DevicePropertyChanged(m_dwSlotNo); }
void CNdasEventMonitor::OnLogicalDeviceDisconnected( INdasLogicalUnit* pNdasLogicalUnit) { NDAS_LOCATION location; COMVERIFY(pNdasLogicalUnit->get_Id(&location)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Disconnect Event, ndasLocation=%d, logicalUnit=%p\n", location, pNdasLogicalUnit); NDAS_LOGICALDEVICE_ID logicalDeviceId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalDeviceId)); CNdasEventPublisher& epub = pGetNdasEventPublisher(); (void) epub.LogicalDeviceDisconnected(logicalDeviceId); CComQIPtr<INdasLogicalUnitPnpSink> pNdasLogicalUnitPnpSink(pNdasLogicalUnit); pNdasLogicalUnitPnpSink->OnDisconnected(); }
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 CNdasEventMonitor::OnLogicalDeviceAlarmed(INdasLogicalUnit* pNdasLogicalUnit) { NDAS_LOCATION ndasLocation; COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation)); NDAS_LOGICALUNIT_ADDRESS ndasLogicalUnitAddress; COMVERIFY(pNdasLogicalUnit->get_LogicalUnitAddress(&ndasLogicalUnitAddress)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Alarm Event, ndasLocation=%d, logicalUnit=%p\n", ndasLocation, pNdasLogicalUnit); if (0 == ndasLocation) { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Invalid SCSI Location\n"); XTLASSERT(FALSE); return; } ULONG newAdapterStatus; while(TRUE) { BOOL success = ::NdasBusCtlQueryEvent( ndasLocation, &newAdapterStatus); if (!success) { if (::GetLastError() == ERROR_NO_MORE_ITEMS) { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "No more events, ignored, ndasLocation=%d\n", ndasLocation); } else { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Query status failed on alarm, ignored, ndasLocation=%d\n", ndasLocation); } return; } XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Logical device alarmed, ndasLocation=%d, adapterStatus=%08X.\n", ndasLocation, newAdapterStatus); // Determine whether an alarm will be issued. // Only viable alarm will be published ULONG currentAdapterStatus; COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(¤tAdapterStatus)); if (pIsViableAlarmStatus(currentAdapterStatus, newAdapterStatus)) { CNdasEventPublisher& epub = pGetNdasEventPublisher(); NDAS_LOGICALDEVICE_ID logicalUnitId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId)); (void) epub.LogicalDeviceAlarmed( logicalUnitId, pGetSignificantAlarm(currentAdapterStatus, newAdapterStatus)); } COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(newAdapterStatus)); if (!ADAPTERINFO_ISSTATUSFLAG( newAdapterStatus, NDASSCSI_ADAPTER_STATUSFLAG_NEXT_EVENT_EXIST)) { break; } } }
// // Remove the unit device ID from the list // BOOL CNdasLogicalDevice::RemoveUnitDevice(CNdasUnitDevice& unitDevice) { ximeta::CAutoLock autolock(this); DWORD ldSequence = unitDevice.GetLDSequence(); _ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices); if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) { DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence); return FALSE; } _ASSERTE(&unitDevice == m_pUnitDevices[ldSequence]); if (&unitDevice != m_pUnitDevices[ldSequence]) { DBGPRT_ERR(_FT("Unit device in sequence (%d) is not occupied.\n"), ldSequence); return FALSE; } m_pUnitDevices[ldSequence]->Release(); m_pUnitDevices[ldSequence] = NULL; // // Workaround for Fault-tolerant Mode // -> Even if the logical device is incomplete, // Mounted Logical Device Location should be intact // if it is mounted // if (NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING == GetStatus() || NDAS_LOGICALDEVICE_STATUS_MOUNTED == GetStatus() || NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING == GetStatus()) { --m_nUnitDeviceInstances; return TRUE; } if (IsComplete()) { CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager(); pLdm->UnregisterNdasScsiLocation(m_NdasScsiLocation); } --m_nUnitDeviceInstances; // // Deallocation NDAS SCSI Location when the fist unit device is removed // if (0 == ldSequence) { cpDeallocateNdasScsiLocation(); } // // Publish Event // CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher(); (VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId); // // Set Device Error // SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER); return TRUE; }
// // Set the unit device ID at a sequence // to a unit device member ID list // BOOL CNdasLogicalDevice::AddUnitDevice(CNdasUnitDevice& unitDevice) { ximeta::CAutoLock autolock(this); BOOL fSuccess; DWORD ldSequence = unitDevice.GetLDSequence(); _ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices); if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) { DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence); return FALSE; } _ASSERTE(NULL == m_pUnitDevices[ldSequence]); if (NULL != m_pUnitDevices[ldSequence]) { DBGPRT_ERR(_FT("Sequence (%d) is already occupied.\n"), ldSequence); return FALSE; } _ASSERTE(NULL == m_pUnitDevices[ldSequence]); m_pUnitDevices[ldSequence] = &unitDevice; m_pUnitDevices[ldSequence]->AddRef(); ++m_nUnitDeviceInstances; _ASSERTE( m_nUnitDeviceInstances >= 0 && m_nUnitDeviceInstances <= GetUnitDeviceCount() ); if (m_nUnitDeviceInstances < GetUnitDeviceCount()) { SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER); } else { SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_NONE); } // // Allocate NDAS SCSI Location when the first unit device is // available // if (0 == ldSequence) { cpAllocateNdasScsiLocation(); } if (IsComplete()) { CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager(); pLdm->RegisterNdasScsiLocation(m_NdasScsiLocation, *this); } if (IsComplete()) { // // Reconciliation Support // BOOL bAlive, bAdapterError; fSuccess = ::LsBusCtlQueryNodeAlive( m_NdasScsiLocation.SlotNo, &bAlive, &bAdapterError); // // Reconciliation // if (fSuccess && bAlive) { ReconcileFromNdasBus(); } } else if (IsComplete() && m_fMountOnReady) { // // Boot-time Plug In Support // if ((m_mountOnReadyAccess & GetAllowingAccess()) == m_mountOnReadyAccess) { (VOID) PlugIn(m_mountOnReadyAccess); } else if ((GENERIC_READ & GetAllowingAccess()) && m_fReducedMountOnReadyAccess) { (VOID) PlugIn(GENERIC_READ); } } DBGPRT_INFO(_FT("Added %s to Logical Device %s\n"), unitDevice.ToString(), this->ToString()); CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher(); (VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId); return TRUE; }
STDMETHODIMP CNdasDeviceRegistrar::Deregister(INdasDevice* pNdasDevice) { NDAS_DEVICE_ID ndasDeviceId; HRESULT hr; COMVERIFY(hr = pNdasDevice->get_NdasDeviceId(&ndasDeviceId)); if (FAILED(hr)) { return hr; } DWORD slotNo; COMVERIFY(hr = pNdasDevice->get_SlotNo(&slotNo)); XTLASSERT(0 != slotNo); NDAS_DEVICE_STATUS status; COMVERIFY(pNdasDevice->get_Status(&status)); if (NDAS_DEVICE_STATUS_DISABLED != status) { return NDASSVC_ERROR_CANNOT_UNREGISTER_ENABLED_DEVICE; } CAutoLock<CLock> autolock(&m_DataLock); XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Unregister device %s\n", CNdasDeviceId(ndasDeviceId).ToStringA()); bool found = false; size_t count = m_NdasDevices.GetCount(); for (size_t i = 0; i < count; ++i) { CComPtr<INdasDevice> p = m_NdasDevices.GetAt(i); if (p == pNdasDevice) { m_NdasDevices.RemoveAt(i); found = true; break; } } if (!found) { return NDASSVC_ERROR_DEVICE_ENTRY_NOT_FOUND; } DeviceIdMap::iterator itrId = m_deviceIdMap.find(ndasDeviceId); ATLASSERT(m_deviceIdMap.end() != itrId); DeviceSlotMap::iterator itrSlot = m_deviceSlotMap.find(slotNo); ATLASSERT(m_deviceSlotMap.end() != itrSlot); m_deviceIdMap.erase(itrId); m_deviceSlotMap.erase(itrSlot); m_slotbit[slotNo] = false; XTL::CStaticStringBuffer<30> containerName(_T("Devices\\%04d"), slotNo); BOOL success = _NdasSystemCfg.DeleteContainer(containerName, TRUE); if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Deleting registration entry from the registry failed at %ls, error=0x%X\n", containerName, GetLastError()); } autolock.Release(); (void) pGetNdasEventPublisher().DeviceEntryChanged(); return S_OK; }
STDMETHODIMP CNdasDeviceRegistrar::Register( __in_opt DWORD SlotNo, __in const NDAS_DEVICE_ID& DeviceId, __in DWORD RegFlags, __in_opt const NDASID_EXT_DATA* NdasIdExtension, __in BSTR Name, __in ACCESS_MASK GrantedAccess, __in_opt const NDAS_OEM_CODE* NdasOemCode, __deref_out INdasDevice** ppNdasDevice) { HRESULT hr; *ppNdasDevice = 0; NDAS_DEVICE_ID ndasDeviceId = DeviceId; // // this will lock this class from here // and releases the lock when the function returns; // CAutoLock<CLock> autolock(&m_DataLock); XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Registering device %s at slot %d\n", CNdasDeviceId(DeviceId).ToStringA(), SlotNo); if (NULL == NdasIdExtension) { NdasIdExtension = &NDAS_ID_EXTENSION_DEFAULT; } // // Only DEFAULT and SEAGATE are currently implemented // if (NDAS_VID_SEAGATE != NdasIdExtension->VID && NDAS_VID_WINDWOS_RO != NdasIdExtension->VID && NDAS_VID_DEFAULT != NdasIdExtension->VID) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Unknown Vendor ID=0x%02X\n", NdasIdExtension->VID); hr = NDASSVC_ERROR_UNKNOWN_VENDOR_ID; return hr; } ndasDeviceId.VID = NdasIdExtension->VID; // If SlotNo is zero, automatically assign it. // check slot number if (0 == SlotNo) { SlotNo = pLookupEmptySlot(); if (0 == SlotNo) { return NDASSVC_ERROR_DEVICE_ENTRY_SLOT_FULL; } } else if (SlotNo > MAX_SLOT_NUMBER) { return NDASSVC_ERROR_INVALID_SLOT_NUMBER; } // check and see if the slot is occupied if (m_slotbit[SlotNo]) { return NDASSVC_ERROR_SLOT_ALREADY_OCCUPIED; } // find an duplicate address { CComPtr<INdasDevice> pExistingDevice; if (SUCCEEDED(get_NdasDevice(&ndasDeviceId, &pExistingDevice))) { return NDASSVC_ERROR_DUPLICATE_DEVICE_ENTRY; } } // register CComObject<CNdasDevice>* pNdasDeviceInstance; hr = CComObject<CNdasDevice>::CreateInstance(&pNdasDeviceInstance); if (FAILED(hr)) { return hr; } hr = pNdasDeviceInstance->Initialize( SlotNo, ndasDeviceId, RegFlags, NdasIdExtension); if (FAILED(hr)) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Device initialization failed, error=0x%X\n", GetLastError()); return hr; } CComPtr<INdasDevice> pNdasDevice(pNdasDeviceInstance); COMVERIFY(pNdasDevice->put_Name(Name)); COMVERIFY(pNdasDevice->put_GrantedAccess(GrantedAccess)); if (NdasOemCode) { COMVERIFY(pNdasDevice->put_OemCode(NdasOemCode)); } m_slotbit[SlotNo] = true; bool insertResult; m_NdasDevices.Add(pNdasDevice); XTLVERIFY( m_deviceSlotMap.insert(std::make_pair(SlotNo, pNdasDevice)).second ); //DeviceSlotMap::value_type(SlotNo, pNdasDevice)).second; XTLVERIFY( m_deviceIdMap.insert(std::make_pair(ndasDeviceId, pNdasDevice)).second ); //DeviceIdMap::value_type(ndasDeviceId, pNdasDevice)).second; XTLASSERT(m_deviceSlotMap.size() == m_deviceIdMap.size()); // // When NdasIdExtension is NULL, NDAS_ID_EXTENSION_DEFAULT is assigned already // if (RegFlags & NDAS_DEVICE_REG_FLAG_VOLATILE) { } else { BOOL success; XTL::CStaticStringBuffer<30> containerName(_T("Devices\\%04d"), SlotNo); if (0 != memcmp(&NDAS_ID_EXTENSION_DEFAULT, NdasIdExtension, sizeof(NDASID_EXT_DATA))) { NDAS_DEVICE_ID_REG_DATA regData = {0}; regData.DeviceId = ndasDeviceId; regData.NdasIdExtension = *NdasIdExtension; success = _NdasSystemCfg.SetSecureValueEx( containerName, _T("DeviceID2"), ®Data, sizeof(regData)); } else { success = _NdasSystemCfg.SetSecureValueEx( containerName, _T("DeviceID"), &ndasDeviceId, sizeof(ndasDeviceId)); } if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Writing registration entry to the registry failed at %ls, error=0x%X\n", containerName.ToString(), GetLastError()); } success = _NdasSystemCfg.SetSecureValueEx( containerName, _T("RegFlags"), &RegFlags, sizeof(RegFlags)); if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Writing registration entry to the registry failed at %ls, error=0x%X\n", containerName.ToString(), GetLastError()); } } BOOL publishEvent = !m_fBootstrapping; autolock.Release(); // // During bootstrapping, we do not publish this event // Bootstrap process will publish an event later // if (publishEvent) { (void) pGetNdasEventPublisher().DeviceEntryChanged(); } *ppNdasDevice = pNdasDevice.Detach(); return S_OK; }
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; }
PCNdasDevice CNdasDeviceRegistrar::Register(const NDAS_DEVICE_ID& DeviceId, DWORD dwSlotNo) { // // this will lock this class from here // and releases the lock when the function returns; // ximeta::CAutoLock autolock(this); DPInfo(_FT("Registering device %s at slot %d\n"), LPCTSTR(CNdasDeviceId(DeviceId)), dwSlotNo); // check slot number if (dwSlotNo < 1 || dwSlotNo > m_dwMaxSlotNo) { ::SetLastError(NDASHLPSVC_ERROR_INVALID_SLOT_NUMBER); return NULL; } // check and see if the slot is occupied if (m_pbSlotOccupied[dwSlotNo]) { ::SetLastError(NDASHLPSVC_ERROR_SLOT_ALREADY_OCCUPIED); return NULL; } // find an duplicate address if (NULL != Find(DeviceId)) { ::SetLastError(NDASHLPSVC_ERROR_DUPLICATE_DEVICE_ENTRY); return NULL; } // register PCNdasDevice pDevice = new CNdasDevice(dwSlotNo, DeviceId); if (NULL == pDevice) { // memory allocation failed // No need to set error here! return NULL; } pDevice->AddRef(); BOOL fSuccess = pDevice->Initialize(); if (!fSuccess) { // DebugPrintError((ERROR_T("Device initialization failed!"))); pDevice->Release(); return NULL; } m_pbSlotOccupied[dwSlotNo] = TRUE; bool insertResult; insertResult = m_deviceSlotMap.insert(DeviceSlotMap::value_type(dwSlotNo, pDevice)).second; _ASSERTE(insertResult == true); insertResult = m_deviceIdMap.insert(DeviceIdMap::value_type(DeviceId, pDevice)).second; _ASSERTE(insertResult == true); _ASSERTE(m_deviceSlotMap.size() == m_deviceIdMap.size()); TCHAR szContainer[30]; HRESULT hr = ::StringCchPrintf(szContainer, 30, TEXT("Devices\\%04d"), dwSlotNo); _ASSERT(SUCCEEDED(hr)); fSuccess = _NdasSystemCfg.SetSecureValueEx( szContainer, _T("DeviceId"), &DeviceId, sizeof(DeviceId)); if (!fSuccess) { DPWarningEx( _FT("Writing registration entry to the registry failed at %s.\n"), szContainer); } // // During bootstrapping, we do not publish this event // Bootstrapper will do this later. // if (!m_fBootstrapping) { CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher(); (VOID) pEventPublisher->DeviceEntryChanged(); } return pDevice; }