VOID CNdasAutoRegister::Update(ximeta::CSubject* pChangedSubject) { const CNdasDeviceHeartbeatListener& listener = m_service.GetDeviceHeartbeatListener(); const CNdasDeviceHeartbeatListener* pListener = &listener; // // Ignore other than subscribed heartbeat listener // if (pListener == pChangedSubject) { NDAS_DEVICE_HEARTBEAT_DATA hbData; pListener->GetHeartbeatData(&hbData); NDAS_DEVICE_ID deviceId = {0}; ::CopyMemory(&deviceId, hbData.remoteAddr.Node, sizeof(deviceId)); ACCESS_MASK autoRegAccess = m_data.GetAutoRegAccess(deviceId); if (!autoRegAccess) { return; } // // If already registered, do nothing // CNdasDevicePtr pDevice = pGetNdasDevice(deviceId); if (0 != pDevice.get()) { return; } ::NdasLogEventInformation( EVT_NDASSVC_INFO_AUTOREG_NDAS_DEVICE_FOUND, NULL, 0, sizeof(deviceId), NULL, &deviceId); (VOID) AddToQueue(deviceId, autoRegAccess); } }
BOOL CNdasAutoRegister::ProcessRegister( const NDAS_DEVICE_ID& deviceId, ACCESS_MASK autoRegAccess) { CNdasDeviceRegistrar& registrar = m_service.GetDeviceRegistrar(); CNdasDevicePtr pExistingDevice = registrar.Find(deviceId); if (CNdasDeviceNullPtr != pExistingDevice) { return TRUE; } DWORD dwRegFlags = NDAS_DEVICE_REG_FLAG_AUTO_REGISTERED | NDAS_DEVICE_REG_FLAG_VOLATILE; CNdasDevicePtr pDevice = registrar.Register(deviceId, dwRegFlags); if (0 == pDevice.get()) { return FALSE; } pDevice->SetGrantedAccess(autoRegAccess); BOOL fSuccess = pDevice->Enable(TRUE); if (!fSuccess) { DBGPRT_ERR(_FT("Enable failed: ")); } TCHAR szName[MAX_NDAS_DEVICE_NAME_LEN + 1]; HRESULT hr = ::StringCchPrintf(szName, MAX_NDAS_DEVICE_NAME_LEN + 1, _T("NDAS Device A%04d"), pDevice->GetSlotNo()); XTLASSERT(SUCCEEDED(hr)); pDevice->SetName(szName); return TRUE; }
CNdasDevicePtr CNdasDeviceRegistrar::Register( __in_opt DWORD SlotNo, __in const NDAS_DEVICE_ID& DeviceId, __in DWORD RegFlags, __in_opt const NDASID_EXT_DATA* NdasIdExtension) { // // this will lock this class from here // and releases the lock when the function returns; // InstanceAutoLock autolock(this); 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_DEFAULT != NdasIdExtension->VID) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Unknown Vendor ID=0x%02X\n", NdasIdExtension->VID); ::SetLastError(NDASSVC_ERROR_UNKNOWN_VENDOR_ID); return CNdasDevicePtr(); } // If SlotNo is zero, automatically assign it. // check slot number if (0 == SlotNo) { SlotNo = LookupEmptySlot(); if (0 == SlotNo) { return CNdasDevicePtr(); } } else if (SlotNo > m_dwMaxSlotNo) { ::SetLastError(NDASSVC_ERROR_INVALID_SLOT_NUMBER); return CNdasDevicePtr(); } // check and see if the slot is occupied if (m_slotbit[SlotNo]) { ::SetLastError(NDASSVC_ERROR_SLOT_ALREADY_OCCUPIED); return CNdasDevicePtr(); } // find an duplicate address { CNdasDevicePtr pExistingDevice = Find(DeviceId); if (0 != pExistingDevice.get()) { ::SetLastError(NDASSVC_ERROR_DUPLICATE_DEVICE_ENTRY); return CNdasDevicePtr(); } } // register CNdasDevicePtr pDevice(new CNdasDevice(SlotNo, DeviceId, RegFlags, NdasIdExtension)); if (0 == pDevice.get()) { // memory allocation failed // No need to set error here! return CNdasDevicePtr(); } BOOL fSuccess = pDevice->Initialize(); if (!fSuccess) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Device initialization failed, error=0x%X\n", GetLastError()); return CNdasDevicePtr(); } m_slotbit[SlotNo] = true; bool insertResult; XTLVERIFY( m_deviceSlotMap.insert(std::make_pair(SlotNo, pDevice)).second ); //DeviceSlotMap::value_type(SlotNo, pDevice)).second; XTLVERIFY( m_deviceIdMap.insert(std::make_pair(DeviceId, pDevice)).second ); //DeviceIdMap::value_type(DeviceId, pDevice)).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 { 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 = DeviceId; regData.NdasIdExtension = *NdasIdExtension; fSuccess = _NdasSystemCfg.SetSecureValueEx( containerName, _T("DeviceID2"), ®Data, sizeof(regData)); } else { fSuccess = _NdasSystemCfg.SetSecureValueEx( containerName, _T("DeviceID"), &DeviceId, sizeof(DeviceId)); } if (!fSuccess) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Writing registration entry to the registry failed at %ls, error=0x%X\n", containerName.ToString(), GetLastError()); } fSuccess = _NdasSystemCfg.SetSecureValueEx( containerName, _T("RegFlags"), &RegFlags, sizeof(RegFlags)); if (!fSuccess) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Writing registration entry to the registry failed at %ls, error=0x%X\n", containerName.ToString(), GetLastError()); } } // // During bootstrapping, we do not publish this event // Bootstrap process will publish an event later // if (!m_fBootstrapping) { (void) m_service.GetEventPublisher().DeviceEntryChanged(); } return pDevice; }
BOOL CNdasDeviceRegistrar::ImportLegacyEntry(DWORD SlotNo, HKEY hEntryKey) { static CONST size_t CB_ADDR = sizeof(TCHAR) * 18; HRESULT hr = E_FAIL; TCHAR szAddrVal[CB_ADDR + 1]; DWORD cbAddrVal = sizeof(szAddrVal); DWORD dwValueType; LONG lResult = ::RegQueryValueEx( hEntryKey, _T("Address"), 0, &dwValueType, (LPBYTE)szAddrVal, &cbAddrVal); if (ERROR_SUCCESS != lResult) { // Ignore invalid values return FALSE; } if (cbAddrVal != CB_ADDR) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Invalid Entry(A): %ls, ignored\n", szAddrVal); return FALSE; } // // 00:0B:D0:00:D4:2F to NDAS_DEVICE_ID // NDAS_DEVICE_ID deviceId = {0}; BOOL fSuccess = pConvertStringToDeviceId(szAddrVal, &deviceId); if (!fSuccess) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Invalid Entry(D): %ls, ignored\n", szAddrVal); return FALSE; } XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Importing an entry: %s\n", CNdasDeviceId(deviceId).ToStringA()); TCHAR szNameVal[MAX_NDAS_DEVICE_NAME_LEN + 1] = {0}; DWORD cbNameVal = sizeof(szNameVal); lResult = ::RegQueryValueEx( hEntryKey, _T("Name"), 0, &dwValueType, (LPBYTE)szNameVal, &cbNameVal); if (ERROR_SUCCESS != lResult || _T('\0') == szNameVal[0]) { TCHAR szDefaultName[MAX_NDAS_DEVICE_NAME_LEN + 1] = {0}; fSuccess = _NdasSystemCfg.GetValueEx( _T("Devices"), _T("DefaultPrefix"), szDefaultName, sizeof(szDefaultName)); if (!fSuccess) { COMVERIFY( StringCchCopy( szDefaultName, MAX_NDAS_DEVICE_NAME_LEN + 1, _T("NDAS Device ")) ); } hr = ::StringCchPrintf( szNameVal, MAX_NDAS_DEVICE_NAME_LEN, _T("%s %d"), szDefaultName, SlotNo); } BYTE pbSerialKeyVal[9]; DWORD cbSerialKeyVal = sizeof(pbSerialKeyVal); lResult = ::RegQueryValueEx( hEntryKey, _T("SerialKey"), 0, &dwValueType, (LPBYTE)pbSerialKeyVal, &cbSerialKeyVal); if (ERROR_SUCCESS != lResult) { return FALSE; } if (cbSerialKeyVal != sizeof(pbSerialKeyVal)) { return FALSE; } ACCESS_MASK fAccessMode = GENERIC_READ; if (0xFF == pbSerialKeyVal[8]) { // Registered as RW fAccessMode |= GENERIC_WRITE; } else if (0x00 == pbSerialKeyVal[8]) { // Registered as RO } else { // Invalid value return FALSE; } CNdasDevicePtr pDevice = Register(SlotNo, deviceId, 0, NULL); if (0 == pDevice.get()) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Failed to register %s at %d during import, error=0x%X", CNdasDeviceId(deviceId).ToStringA(), SlotNo, GetLastError()); return FALSE; } // Always enable this! XTLVERIFY( pDevice->Enable(TRUE) ); pDevice->SetName(szNameVal); pDevice->SetGrantedAccess(fAccessMode); return TRUE; }