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; }
BOOL CNdasDeviceRegistrar::Bootstrap() { BOOL fSuccess = FALSE; BOOL fMigrated = FALSE; // // Set bootstrapping flag to prevent multiple events // for DeviceSetChange Events // m_fBootstrapping = TRUE; TCHAR szSubcontainer[30] = {0}; for (DWORD i = 0; i < MAX_SLOT_NUMBER; ++i) { COMVERIFY(StringCchPrintf( szSubcontainer, 30, _T("%s\\%04d"), CFG_CONTAINER, i)); BOOL fAutoRegistered = FALSE; fSuccess = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("AutoRegistered"), &fAutoRegistered); if (fSuccess && fAutoRegistered) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Deleting %ls\n", szSubcontainer); // Auto registered devices are not persistent // it is an error to show up here. // We just ignore those entries fSuccess = _NdasSystemCfg.DeleteContainer(szSubcontainer, TRUE); if (!fSuccess) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Deleting a RegKey=%ls failed, error=0x%X\n", szSubcontainer, GetLastError()); } continue; } DWORD cbUsed; NDAS_DEVICE_ID_REG_DATA regData = {0}; const NDASID_EXT_DATA* ndasIdExtension = NULL; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("DeviceID2"), ®Data, sizeof(NDAS_DEVICE_ID_REG_DATA), &cbUsed); if (!fSuccess) { // // Non-extension data // fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("DeviceID"), ®Data.DeviceId, sizeof(regData.DeviceId), &cbUsed); // // ignore read fault - tampered or not exists // if (!fSuccess || cbUsed != sizeof(NDAS_DEVICE_ID)) { continue; } if (regData.DeviceId.VID == 0) { // Assume VID 0 is VID 1 to support registry entry created by older software(~3.11) regData.DeviceId.VID = 1; } } else { if (cbUsed != sizeof(NDAS_DEVICE_ID_REG_DATA)) { // // maybe more recent versions, unrecognized, ignore // continue; } ndasIdExtension = ®Data.NdasIdExtension; } DWORD regFlags; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("RegFlags"), ®Flags, sizeof(regFlags)); if (!fSuccess) { regFlags = NDAS_DEVICE_REG_FLAG_NONE; } CNdasDevicePtr pDevice = Register( i, regData.DeviceId, regFlags, ndasIdExtension); // This may happen due to auto-register feature! if (CNdasDeviceNullPtr == pDevice) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Registration failed for %s, error=0x%X\n", CNdasDeviceId(regData.DeviceId).ToStringA(), GetLastError()); // // During bootstrapping register may fail for unsupported VID. // In that case, we should retain this slot number to avoid // overwriting the existing data which may be created by // the higher version. // m_slotbit[i] = true; continue; } NDAS_OEM_CODE oemCode; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("OEMCode"), &oemCode, sizeof(NDAS_OEM_CODE), &cbUsed); if (fSuccess && cbUsed == sizeof(NDAS_OEM_CODE)) { pDevice->SetOemCode(oemCode); } ACCESS_MASK grantedAccess = GENERIC_READ; const DWORD cbBuffer = sizeof(ACCESS_MASK) + sizeof(NDAS_DEVICE_ID); BYTE pbBuffer[cbBuffer]; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("GrantedAccess"), pbBuffer, cbBuffer); if (fSuccess) { grantedAccess = *((ACCESS_MASK*)(pbBuffer)); } grantedAccess |= GENERIC_READ; // to prevent invalid access mask configuration // XTLASSERT(grantedAccess & GENERIC_READ); // invalid configuration? pDevice->SetGrantedAccess(grantedAccess); TCHAR szDeviceName[MAX_NDAS_DEVICE_NAME_LEN + 1]; fSuccess = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("DeviceName"), szDeviceName, sizeof(TCHAR)*(MAX_NDAS_DEVICE_NAME_LEN + 1)); if (fSuccess) { pDevice->SetName(szDeviceName); } BOOL fEnabled = FALSE; fSuccess = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("Enabled"), &fEnabled); if (fSuccess && fEnabled) { pDevice->Enable(fEnabled); } } // // Migration will be done only once // if there is no registered devices in the current configurations // and if the migration flag (Install\Migrate = 1) is set // if (m_deviceSlotMap.size() == 0) { fSuccess = _NdasSystemCfg.GetValueEx(_T("Install"), _T("Migrated"), &fMigrated); if (!fSuccess || !fMigrated) { fMigrated = TRUE; ImportLegacySettings(); _NdasSystemCfg.SetValueEx(_T("Install"), _T("Migrated"), fMigrated); } } // // Clear bootstrapping state // m_fBootstrapping = FALSE; return TRUE; }
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; }