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(NDASHLPSVC_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(); m_LDGroupMap.insert(LDGroupMap::value_type(ldGroup, pLogDevice)); m_LDIDMap.insert(LDIDMap::value_type(id, pLogDevice)); CNdasDevice* pDevice = unitDevice.GetParentDevice(); 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; } pLogDevice->AddRef(); return pLogDevice; }
CNdasDeviceRegistrar::~CNdasDeviceRegistrar() { delete [] m_pbSlotOccupied; DeviceSlotMap::iterator itr = m_deviceSlotMap.begin(); for(; itr != m_deviceSlotMap.end(); itr++) { CNdasDevice* pDevice = itr->second; pDevice->Release(); } m_deviceSlotMap.clear(); m_deviceIdMap.clear(); DBGPRT_TRACE(_FT("dtor\n")); }
static NDAS_UNITDEVICE_ID pCreateUnitDeviceId(CNdasDevice& dev, DWORD unitNo) { NDAS_UNITDEVICE_ID deviceID = {dev.GetDeviceId(), unitNo}; return deviceID; }
// not used at this time (reserved for the future use) void CNdasDeviceRegistrar::pDeleteAutoRegistered( const DeviceSlotMap::value_type& entry) { DWORD dwSlotNo = entry.first; CNdasDevice* pDevice = entry.second; if (pDevice->IsAutoRegistered()) { TCHAR szContainer[30]; HRESULT hr = ::StringCchPrintf( szContainer, 30, _T("Devices\\%04d"), dwSlotNo); _ASSERT(SUCCEEDED(hr)); BOOL fSuccess = _NdasSystemCfg.DeleteContainer(szContainer, TRUE); } }
DWORD CNdasEventMonitor::OnTaskStart() { BOOL bTerminateThread(FALSE); // 15 sec = 10,000,000 nanosec // negative value means relative time LARGE_INTEGER liDueTime; liDueTime.QuadPart = - 10 * 1000 * 1000; BOOL fSuccess = ::SetWaitableTimer( m_hHeartbeatMonitorTimer, &liDueTime, HEARTBEAT_MONITOR_INTERVAL, NULL, NULL, FALSE); if (!fSuccess) { DBGPRT_ERR_EX(_FT("Setting waitable timer failed: ")); } do { // // Lock against m_vLogDevice set change // this->Lock(); DWORD dwLogDevices = m_vLogDevices.size(); DWORD dwHandles = 3 + 2 * dwLogDevices; HANDLE* hWaitingHandles = new HANDLE[dwHandles]; hWaitingHandles[0] = m_hTaskTerminateEvent; hWaitingHandles[1] = m_hLogDeviceSetChangeEvent; hWaitingHandles[2] = m_hHeartbeatMonitorTimer; CNdasLogicalDeviceVector::const_iterator itr = m_vLogDevices.begin(); for (DWORD i = 3; itr != m_vLogDevices.end(); ++itr, ++i) { CNdasLogicalDevice* pLogDevice = *itr; hWaitingHandles[i] = pLogDevice->GetDisconnectEvent(); hWaitingHandles[dwLogDevices + i] = pLogDevice->GetAlarmEvent(); } this->Unlock(); fSuccess = ::ResetEvent(m_hLogDeviceSetChangeEvent); _ASSERTE(fSuccess); BOOL bResetLogDeviceSet(FALSE); do { DWORD dwWaitResult = ::WaitForMultipleObjects( dwHandles, hWaitingHandles, FALSE, INFINITE); if (WAIT_OBJECT_0 == dwWaitResult) { // // Terminate Thread Event // bTerminateThread = TRUE; } else if (WAIT_OBJECT_0 + 1 == dwWaitResult) { // // LogicalDeviceSetChange Event // bResetLogDeviceSet = TRUE; } else if (WAIT_OBJECT_0 + 2 == dwWaitResult) { ximeta::CAutoLock autolock(this); // // Heartbeat Monitor Timer Event // CNdasDeviceSet::const_iterator devitr = m_hbMonDevices.begin(); m_bIterating = TRUE; for (; devitr != m_hbMonDevices.end();) { CNdasDevice* pDevice = *devitr; BOOL fDetach = pDevice->OnStatusCheck(); if (fDetach) { devitr = m_hbMonDevices.erase(devitr); pDevice->Release(); } else { ++devitr; } } m_bIterating = FALSE; // // Check the logical devices // std::for_each( m_vLogDevices.begin(), m_vLogDevices.end(), NdasLogicalDeviceStatusCheck); } else if (WAIT_OBJECT_0 + 3 <= dwWaitResult && dwWaitResult < WAIT_OBJECT_0 + 3 + dwLogDevices) { // // Disconnect Event // DWORD n = dwWaitResult - (WAIT_OBJECT_0 + 3); BOOL fHandled = OnLogicalDeviceDisconnected(n); if (!fHandled) { fSuccess = ::ResetEvent(hWaitingHandles[dwWaitResult - WAIT_OBJECT_0]); _ASSERTE(fSuccess); } } else if (WAIT_OBJECT_0 + 3 + dwLogDevices <= dwWaitResult && dwWaitResult < WAIT_OBJECT_0 + 3 + 2 * dwLogDevices) { // // Alarm Event // DWORD n = dwWaitResult - (WAIT_OBJECT_0 + 3 + dwLogDevices); BOOL fHandled = OnLogicalDeviceAlarmed(n); if (!fHandled) { fSuccess = ::ResetEvent(hWaitingHandles[dwWaitResult - WAIT_OBJECT_0]); _ASSERTE(fSuccess); } } else { // _ASSERTE(FALSE); // Some handles may be already invalid. // LogicalDeviceSetChange Event // bResetLogDeviceSet = TRUE; DBGPRT_ERR_EX(_FT("Wait failed: ")); } } while (!bResetLogDeviceSet && !bTerminateThread); delete [] hWaitingHandles; } while (!bTerminateThread); fSuccess = ::CancelWaitableTimer(m_hHeartbeatMonitorTimer); if (!fSuccess) { DBGPRT_ERR_EX(_FT("Canceling waitable timer failed: ")); } return 0; }