Global Metrics

path: .metrics.nom.closures
old: 0.0
new: 12.0

path: .metrics.nom.total
old: 24.0
new: 36.0

path: .metrics.halstead.vocabulary
old: 312.0
new: 753.0

path: .metrics.halstead.length
old: 1428.0
new: 6466.0

path: .metrics.halstead.volume
old: 11831.554368535291
new: 61792.368149508686

path: .metrics.halstead.bugs
old: 1.4793798826961218
new: 10.020023904688337

path: .metrics.halstead.purity_ratio
old: 1.7273077361568678
new: 1.0748837177224864

path: .metrics.halstead.N1
old: 800.0
new: 3812.0

path: .metrics.halstead.n2
old: 289.0
new: 708.0

path: .metrics.halstead.level
old: 0.04001661589587372
new: 0.011856317508163778

path: .metrics.halstead.effort
old: 295666.0403099027
new: 5211767.322101569

path: .metrics.halstead.N2
old: 628.0
new: 2654.0

path: .metrics.halstead.estimated_program_length
old: 2466.5954472320072
new: 6950.198118793597

path: .metrics.halstead.time
old: 16425.891128327927
new: 289542.6290056427

path: .metrics.halstead.difficulty
old: 24.98961937716263
new: 84.34322033898304

path: .metrics.halstead.n1
old: 23.0
new: 45.0

path: .metrics.cyclomatic.sum
old: 36.0
new: 232.0

path: .metrics.cyclomatic.average
old: 1.2413793103448276
new: 8.285714285714286

path: .metrics.nexits.sum
old: 18.0
new: 89.0

path: .metrics.nexits.average
old: 0.75
new: 2.4722222222222223

path: .metrics.loc.blank
old: 92.0
new: 203.0

path: .metrics.loc.cloc
old: 86.0
new: 116.0

path: .metrics.loc.ploc
old: 312.0
new: 1229.0

path: .metrics.loc.sloc
old: 490.0
new: 1548.0

path: .metrics.loc.lloc
old: 50.0
new: 502.0

path: .metrics.cognitive.sum
old: 6.0
new: 260.0

path: .metrics.cognitive.average
old: 0.25
new: 7.222222222222222

path: .metrics.mi.mi_original
old: 13.602300893813222
new: -58.70843142131106

path: .metrics.mi.mi_sei
old: -22.191143170127805
new: -116.20282499414296

path: .metrics.mi.mi_visual_studio
old: 7.954561926206562
new: 0.0

path: .metrics.nargs.sum
old: 48.0
new: 39.0

path: .metrics.nargs.average
old: 2.0
new: 1.0833333333333333

Spaces Data

Minimal test - lines (108, 153)

path: .spaces[1].metrics.nargs.sum
old: 15.0
new: 3.0

path: .spaces[1].metrics.cognitive.average
old: 0.0
new: 14.0

path: .spaces[1].metrics.cognitive.sum
old: 0.0
new: 14.0

path: .spaces[1].metrics.mi.mi_original
old: 44.13672315598086
new: 69.07027766109776

path: .spaces[1].metrics.mi.mi_sei
old: 22.714564746670128
new: 49.610087688997254

path: .spaces[1].metrics.mi.mi_visual_studio
old: 25.810949214023896
new: 40.39197524040805

path: .spaces[1].metrics.cyclomatic.average
old: 1.3333333333333333
new: 12.0

path: .spaces[1].metrics.cyclomatic.sum
old: 8.0
new: 12.0

path: .spaces[1].metrics.loc.ploc
old: 101.0
new: 40.0

path: .spaces[1].metrics.loc.sloc
old: 164.0
new: 46.0

path: .spaces[1].metrics.loc.blank
old: 25.0
new: 1.0

path: .spaces[1].metrics.loc.cloc
old: 38.0
new: 5.0

path: .spaces[1].metrics.loc.lloc
old: 17.0
new: 24.0

path: .spaces[1].metrics.nom.total
old: 5.0
new: 1.0

path: .spaces[1].metrics.nom.functions
old: 5.0
new: 1.0

path: .spaces[1].metrics.nexits.average
old: 0.2
new: 2.0

path: .spaces[1].metrics.nexits.sum
old: 1.0
new: 2.0

path: .spaces[1].metrics.halstead.vocabulary
old: 127.0
new: 57.0

path: .spaces[1].metrics.halstead.estimated_program_length
old: 812.7907414266465
new: 276.0964047443681

path: .spaces[1].metrics.halstead.difficulty
old: 18.908256880733944
new: 47.36

path: .spaces[1].metrics.halstead.n1
old: 18.0
new: 32.0

path: .spaces[1].metrics.halstead.volume
old: 3480.3649740125384
new: 1265.737133073749

path: .spaces[1].metrics.halstead.n2
old: 109.0
new: 25.0

path: .spaces[1].metrics.halstead.level
old: 0.052886948083454635
new: 0.021114864864864864

path: .spaces[1].metrics.halstead.N2
old: 229.0
new: 74.0

path: .spaces[1].metrics.halstead.time
old: 3655.979720407666
new: 3330.295034576264

path: .spaces[1].metrics.halstead.length
old: 498.0
new: 217.0

path: .spaces[1].metrics.halstead.bugs
old: 0.5433290601490782
new: 0.5105624708171167

path: .spaces[1].metrics.halstead.purity_ratio
old: 1.6321099225434668
new: 1.272333662416443

path: .spaces[1].metrics.halstead.effort
old: 65807.63496733799
new: 59945.31062237275

path: .spaces[1].metrics.halstead.N1
old: 269.0
new: 143.0

Code

static void GetProcessorInformation(int* physical_cpus, int* cache_size_L2,
                                    int* cache_size_L3) {
  MOZ_ASSERT(physical_cpus && cache_size_L2 && cache_size_L3);

  *physical_cpus = 0;
  *cache_size_L2 = 0;  // This will be in kbytes
  *cache_size_L3 = 0;  // This will be in kbytes

  // Determine buffer size, allocate and get processor information.
  // Size can change between calls (unlikely), so a loop is done.
  SYSTEM_LOGICAL_PROCESSOR_INFORMATION info_buffer[32];
  SYSTEM_LOGICAL_PROCESSOR_INFORMATION* infos = &info_buffer[0];
  DWORD return_length = sizeof(info_buffer);
  while (!::GetLogicalProcessorInformation(infos, &return_length)) {
    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
        infos == &info_buffer[0]) {
      infos = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION
          [return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)];
    } else {
      return;
    }
  }

  for (size_t i = 0;
       i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
    if (infos[i].Relationship == RelationProcessorCore) {
      ++*physical_cpus;
    } else if (infos[i].Relationship == RelationCache) {
      // Only care about L2 and L3 cache
      switch (infos[i].Cache.Level) {
        case 2:
          *cache_size_L2 = static_cast(infos[i].Cache.Size / 1024);
          break;
        case 3:
          *cache_size_L3 = static_cast(infos[i].Cache.Size / 1024);
          break;
        default:
          break;
      }
    }
  }
  if (infos != &info_buffer[0]) {
    delete[] infos;
  }
  return;
}

Minimal test - lines (256, 267)

path: .spaces[2].spaces[1].metrics.halstead.volume
old: 8.0
new: 307.19248754831744

path: .spaces[2].spaces[1].metrics.halstead.effort
old: 12.0
new: 3401.0596835706574

path: .spaces[2].spaces[1].metrics.halstead.vocabulary
old: 4.0
new: 24.0

path: .spaces[2].spaces[1].metrics.halstead.purity_ratio
old: 1.188721875540867
new: 1.2913768635474638

path: .spaces[2].spaces[1].metrics.halstead.estimated_program_length
old: 4.754887502163468
new: 86.52224985768008

path: .spaces[2].spaces[1].metrics.halstead.N1
old: 3.0
new: 36.0

path: .spaces[2].spaces[1].metrics.halstead.n2
old: 1.0
new: 14.0

path: .spaces[2].spaces[1].metrics.halstead.N2
old: 1.0
new: 31.0

path: .spaces[2].spaces[1].metrics.halstead.level
old: 0.6666666666666666
new: 0.0903225806451613

path: .spaces[2].spaces[1].metrics.halstead.length
old: 4.0
new: 67.0

path: .spaces[2].spaces[1].metrics.halstead.time
old: 0.6666666666666666
new: 188.94776019836985

path: .spaces[2].spaces[1].metrics.halstead.bugs
old: 0.0017471609294725976
new: 0.07538557425168033

path: .spaces[2].spaces[1].metrics.halstead.difficulty
old: 1.5
new: 11.071428571428571

path: .spaces[2].spaces[1].metrics.halstead.n1
old: 3.0
new: 10.0

path: .spaces[2].spaces[1].metrics.cyclomatic.sum
old: 1.0
new: 3.0

path: .spaces[2].spaces[1].metrics.cyclomatic.average
old: 1.0
new: 3.0

path: .spaces[2].spaces[1].metrics.nexits.sum
old: 0.0
new: 3.0

path: .spaces[2].spaces[1].metrics.nexits.average
old: 0.0
new: 3.0

path: .spaces[2].spaces[1].metrics.loc.ploc
old: 1.0
new: 12.0

path: .spaces[2].spaces[1].metrics.loc.lloc
old: 0.0
new: 6.0

path: .spaces[2].spaces[1].metrics.loc.sloc
old: 1.0
new: 12.0

path: .spaces[2].spaces[1].metrics.cognitive.average
old: 0.0
new: 2.0

path: .spaces[2].spaces[1].metrics.cognitive.sum
old: 0.0
new: 2.0

path: .spaces[2].spaces[1].metrics.nargs.sum
old: 0.0
new: 4.0

path: .spaces[2].spaces[1].metrics.nargs.average
old: 0.0
new: 4.0

path: .spaces[2].spaces[1].metrics.mi.mi_original
old: 159.95690398326485
new: 100.27164463226268

path: .spaces[2].spaces[1].metrics.mi.mi_sei
old: 155.17000000000002
new: 69.26601203894644

path: .spaces[2].spaces[1].metrics.mi.mi_visual_studio
old: 93.54204911302038
new: 58.63838867383783

Code

static nsresult CollectDiskInfo(nsIFile* greDir, nsIFile* winDir,
                                nsIFile* profDir, DiskInfo& info) {
  nsresult rv = GetFolderDiskInfo(greDir, info.binary);
  if (NS_FAILED(rv)) {
    return rv;
  }
  rv = GetFolderDiskInfo(winDir, info.system);
  if (NS_FAILED(rv)) {
    return rv;
  }
  return GetFolderDiskInfo(profDir, info.profile);
}

Minimal test - lines (383, 405)

path: .spaces[2].spaces[3].metrics.cognitive.average
old: 0.0
new: 3.0

path: .spaces[2].spaces[3].metrics.cognitive.sum
old: 0.0
new: 3.0

path: .spaces[2].spaces[3].metrics.cyclomatic.average
old: 1.0
new: 4.0

path: .spaces[2].spaces[3].metrics.cyclomatic.sum
old: 1.0
new: 4.0

path: .spaces[2].spaces[3].metrics.mi.mi_visual_studio
old: 70.54838854584763
new: 50.97813672020155

path: .spaces[2].spaces[3].metrics.mi.mi_original
old: 120.63774441339945
new: 87.17261379154465

path: .spaces[2].spaces[3].metrics.mi.mi_sei
old: 98.44444347663332
new: 77.00817251560392

path: .spaces[2].spaces[3].metrics.loc.ploc
old: 5.0
new: 19.0

path: .spaces[2].spaces[3].metrics.loc.sloc
old: 5.0
new: 23.0

path: .spaces[2].spaces[3].metrics.loc.blank
old: 0.0
new: 1.0

path: .spaces[2].spaces[3].metrics.loc.cloc
old: 0.0
new: 3.0

path: .spaces[2].spaces[3].metrics.loc.lloc
old: 1.0
new: 10.0

path: .spaces[2].spaces[3].metrics.halstead.n2
old: 10.0
new: 23.0

path: .spaces[2].spaces[3].metrics.halstead.difficulty
old: 3.5
new: 11.304347826086955

path: .spaces[2].spaces[3].metrics.halstead.effort
old: 357.6529986094047
new: 5435.164631951092

path: .spaces[2].spaces[3].metrics.halstead.n1
old: 7.0
new: 13.0

path: .spaces[2].spaces[3].metrics.halstead.N1
old: 15.0
new: 53.0

path: .spaces[2].spaces[3].metrics.halstead.estimated_program_length
old: 52.87076540327685
new: 152.14764132514549

path: .spaces[2].spaces[3].metrics.halstead.purity_ratio
old: 2.114830616131074
new: 1.6359961432811343

path: .spaces[2].spaces[3].metrics.halstead.length
old: 25.0
new: 93.0

path: .spaces[2].spaces[3].metrics.halstead.volume
old: 102.18657103125848
new: 480.80302513413505

path: .spaces[2].spaces[3].metrics.halstead.N2
old: 10.0
new: 40.0

path: .spaces[2].spaces[3].metrics.halstead.vocabulary
old: 17.0
new: 36.0

path: .spaces[2].spaces[3].metrics.halstead.time
old: 19.869611033855815
new: 301.95359066394957

path: .spaces[2].spaces[3].metrics.halstead.bugs
old: 0.016795257201959398
new: 0.10304348718180392

path: .spaces[2].spaces[3].metrics.halstead.level
old: 0.2857142857142857
new: 0.08846153846153845

path: .spaces[2].spaces[3].metrics.nexits.average
old: 1.0
new: 4.0

path: .spaces[2].spaces[3].metrics.nexits.sum
old: 1.0
new: 4.0

path: .spaces[2].spaces[3].metrics.nargs.average
old: 5.0
new: 1.0

path: .spaces[2].spaces[3].metrics.nargs.sum
old: 5.0
new: 1.0

Code

nsresult CollectCountryCode(nsAString& aCountryCode) {
  GEOID geoid = GetUserGeoID(GEOCLASS_NATION);
  if (geoid == GEOID_NOT_AVAILABLE) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  // Get required length
  int numChars = GetGeoInfoW(geoid, GEO_ISO2, nullptr, 0, 0);
  if (!numChars) {
    return NS_ERROR_FAILURE;
  }
  // Now get the string for real
  aCountryCode.SetLength(numChars);
  numChars =
      GetGeoInfoW(geoid, GEO_ISO2, char16ptr_t(aCountryCode.BeginWriting()),
                  aCountryCode.Length(), 0);
  if (!numChars) {
    return NS_ERROR_FAILURE;
  }

  // numChars includes null terminator
  aCountryCode.Truncate(numChars - 1);
  return NS_OK;
}

Minimal test - lines (158, 254)

path: .spaces[2].spaces[0].metrics.nexits.sum
old: 0.0
new: 5.0

path: .spaces[2].spaces[0].metrics.nexits.average
old: 0.0
new: 5.0

path: .spaces[2].spaces[0].metrics.loc.blank
old: 1.0
new: 4.0

path: .spaces[2].spaces[0].metrics.loc.ploc
old: 5.0
new: 84.0

path: .spaces[2].spaces[0].metrics.loc.sloc
old: 6.0
new: 97.0

path: .spaces[2].spaces[0].metrics.loc.cloc
old: 0.0
new: 9.0

path: .spaces[2].spaces[0].metrics.loc.lloc
old: 2.0
new: 37.0

path: .spaces[2].spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 14.0

path: .spaces[2].spaces[0].metrics.cyclomatic.average
old: 1.0
new: 14.0

path: .spaces[2].spaces[0].metrics.cognitive.average
old: 0.0
new: 17.0

path: .spaces[2].spaces[0].metrics.cognitive.sum
old: 0.0
new: 17.0

path: .spaces[2].spaces[0].metrics.halstead.N1
old: 17.0
new: 278.0

path: .spaces[2].spaces[0].metrics.halstead.volume
old: 147.1612434150308
new: 2973.2687181189913

path: .spaces[2].spaces[0].metrics.halstead.length
old: 33.0
new: 458.0

path: .spaces[2].spaces[0].metrics.halstead.estimated_program_length
old: 76.63504134881501
new: 510.469900749982

path: .spaces[2].spaces[0].metrics.halstead.N2
old: 16.0
new: 180.0

path: .spaces[2].spaces[0].metrics.halstead.n1
old: 9.0
new: 23.0

path: .spaces[2].spaces[0].metrics.halstead.level
old: 0.18055555555555555
new: 0.0323671497584541

path: .spaces[2].spaces[0].metrics.halstead.vocabulary
old: 22.0
new: 90.0

path: .spaces[2].spaces[0].metrics.halstead.purity_ratio
old: 2.3222739802671213
new: 1.1145631020741966

path: .spaces[2].spaces[0].metrics.halstead.time
old: 45.28038258924025
new: 5103.371680353493

path: .spaces[2].spaces[0].metrics.halstead.bugs
old: 0.029084870903957623
new: 0.6786281672060677

path: .spaces[2].spaces[0].metrics.halstead.difficulty
old: 5.538461538461538
new: 30.895522388059703

path: .spaces[2].spaces[0].metrics.halstead.effort
old: 815.0468866063245
new: 91860.69024636286

path: .spaces[2].spaces[0].metrics.halstead.n2
old: 13.0
new: 67.0

path: .spaces[2].spaces[0].metrics.mi.mi_sei
old: 91.44708689076764
new: 23.59321273585606

path: .spaces[2].spaces[0].metrics.mi.mi_original
old: 115.78754642453409
new: 52.08311268174872

path: .spaces[2].spaces[0].metrics.mi.mi_visual_studio
old: 67.7120154529439
new: 30.457960632601587

path: .spaces[2].spaces[0].metrics.nargs.average
old: 1.0
new: 2.0

path: .spaces[2].spaces[0].metrics.nargs.sum
old: 1.0
new: 2.0

Code

static nsresult GetFolderDiskInfo(nsIFile* file, FolderDiskInfo& info) {
  info.model.Truncate();
  info.revision.Truncate();
  info.isSSD = false;

  nsAutoString filePath;
  nsresult rv = file->GetPath(filePath);
  NS_ENSURE_SUCCESS(rv, rv);
  wchar_t volumeMountPoint[MAX_PATH] = {L'\\', L'\\', L'.', L'\\'};
  const size_t PREFIX_LEN = 4;
  if (!::GetVolumePathNameW(
          filePath.get(), volumeMountPoint + PREFIX_LEN,
          mozilla::ArrayLength(volumeMountPoint) - PREFIX_LEN)) {
    return NS_ERROR_UNEXPECTED;
  }
  size_t volumeMountPointLen = wcslen(volumeMountPoint);
  // Since we would like to open a drive and not a directory, we need to
  // remove any trailing backslash. A drive handle is valid for
  // DeviceIoControl calls, a directory handle is not.
  if (volumeMountPoint[volumeMountPointLen - 1] == L'\\') {
    volumeMountPoint[volumeMountPointLen - 1] = L'\0';
  }
  ScopedHandle handle(::CreateFileW(volumeMountPoint, 0,
                                    FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                                    OPEN_EXISTING, 0, nullptr));
  if (!handle.IsValid()) {
    return NS_ERROR_UNEXPECTED;
  }
  STORAGE_PROPERTY_QUERY queryParameters = {StorageDeviceProperty,
                                            PropertyStandardQuery};
  STORAGE_DEVICE_DESCRIPTOR outputHeader = {sizeof(STORAGE_DEVICE_DESCRIPTOR)};
  DWORD bytesRead = 0;
  if (!::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &queryParameters,
                         sizeof(queryParameters), &outputHeader,
                         sizeof(outputHeader), &bytesRead, nullptr)) {
    return NS_ERROR_FAILURE;
  }
  PSTORAGE_DEVICE_DESCRIPTOR deviceOutput =
      (PSTORAGE_DEVICE_DESCRIPTOR)malloc(outputHeader.Size);
  if (!::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &queryParameters,
                         sizeof(queryParameters), deviceOutput,
                         outputHeader.Size, &bytesRead, nullptr)) {
    free(deviceOutput);
    return NS_ERROR_FAILURE;
  }

  queryParameters.PropertyId = StorageDeviceTrimProperty;
  bytesRead = 0;
  bool isSSD = false;
  DEVICE_TRIM_DESCRIPTOR trimDescriptor = {sizeof(DEVICE_TRIM_DESCRIPTOR)};
  if (::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &queryParameters,
                        sizeof(queryParameters), &trimDescriptor,
                        sizeof(trimDescriptor), &bytesRead, nullptr)) {
    if (trimDescriptor.TrimEnabled) {
      isSSD = true;
    }
  }

  if (isSSD) {
    // Get Seek Penalty
    queryParameters.PropertyId = StorageDeviceSeekPenaltyProperty;
    bytesRead = 0;
    DEVICE_SEEK_PENALTY_DESCRIPTOR seekPenaltyDescriptor = {
        sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR)};
    if (::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY,
                          &queryParameters, sizeof(queryParameters),
                          &seekPenaltyDescriptor, sizeof(seekPenaltyDescriptor),
                          &bytesRead, nullptr)) {
      // It is possible that the disk has TrimEnabled, but also
      // IncursSeekPenalty; In this case, this is an HDD
      if (seekPenaltyDescriptor.IncursSeekPenalty) {
        isSSD = false;
      }
    }
  }

  // Some HDDs are including product ID info in the vendor field. Since PNP
  // IDs include vendor info and product ID concatenated together, we'll do
  // that here and interpret the result as a unique ID for the HDD model.
  if (deviceOutput->VendorIdOffset) {
    info.model =
        reinterpret_cast(deviceOutput) + deviceOutput->VendorIdOffset;
  }
  if (deviceOutput->ProductIdOffset) {
    info.model +=
        reinterpret_cast(deviceOutput) + deviceOutput->ProductIdOffset;
  }
  info.model.CompressWhitespace();
  if (deviceOutput->ProductRevisionOffset) {
    info.revision = reinterpret_cast(deviceOutput) +
                    deviceOutput->ProductRevisionOffset;
    info.revision.CompressWhitespace();
  }
  info.isSSD = isSSD;
  free(deviceOutput);
  return NS_OK;
}

Minimal test - lines (411, 454)

path: .spaces[3].metrics.halstead.difficulty
old: 10.459090909090907
new: 20.60606060606061

path: .spaces[3].metrics.halstead.time
old: 1597.472587678559
new: 1121.2838223175231

path: .spaces[3].metrics.halstead.vocabulary
old: 123.0
new: 53.0

path: .spaces[3].metrics.halstead.level
old: 0.09561060408518036
new: 0.04852941176470588

path: .spaces[3].metrics.halstead.N1
old: 219.0
new: 103.0

path: .spaces[3].metrics.halstead.n2
old: 110.0
new: 33.0

path: .spaces[3].metrics.halstead.n1
old: 13.0
new: 20.0

path: .spaces[3].metrics.halstead.volume
old: 2749.235744114339
new: 979.474397730307

path: .spaces[3].metrics.halstead.N2
old: 177.0
new: 68.0

path: .spaces[3].metrics.halstead.purity_ratio
old: 2.005190113190775
new: 1.4789682329624338

path: .spaces[3].metrics.halstead.bugs
old: 0.3128595082439908
new: 0.2470988852770693

path: .spaces[3].metrics.halstead.length
old: 396.0
new: 171.0

path: .spaces[3].metrics.halstead.estimated_program_length
old: 794.0552848235468
new: 252.9035678365762

path: .spaces[3].metrics.halstead.effort
old: 28754.506578214063
new: 20183.108801715414

path: .spaces[3].metrics.loc.sloc
old: 126.0
new: 44.0

path: .spaces[3].metrics.loc.lloc
old: 4.0
new: 19.0

path: .spaces[3].metrics.loc.cloc
old: 12.0
new: 1.0

path: .spaces[3].metrics.loc.blank
old: 30.0
new: 8.0

path: .spaces[3].metrics.loc.ploc
old: 84.0
new: 35.0

path: .spaces[3].metrics.mi.mi_original
old: 50.32302625520013
new: 71.81364421602458

path: .spaces[3].metrics.mi.mi_visual_studio
old: 29.42867032467844
new: 41.99628316726584

path: .spaces[3].metrics.mi.mi_sei
old: 20.4133005167154
new: 40.392329485421904

path: .spaces[3].metrics.cyclomatic.average
old: 1.0
new: 9.0

path: .spaces[3].metrics.cyclomatic.sum
old: 5.0
new: 9.0

path: .spaces[3].metrics.nom.functions
old: 4.0
new: 1.0

path: .spaces[3].metrics.nom.total
old: 4.0
new: 1.0

path: .spaces[3].metrics.nargs.sum
old: 0.0
new: 2.0

path: .spaces[3].metrics.nargs.average
old: 0.0
new: 2.0

path: .spaces[3].metrics.cognitive.average
old: 0.0
new: 13.0

path: .spaces[3].metrics.cognitive.sum
old: 0.0
new: 13.0

path: .spaces[3].metrics.nexits.average
old: 1.0
new: 5.0

path: .spaces[3].metrics.nexits.sum
old: 4.0
new: 5.0

Code

static HRESULT EnumWSCProductList(nsAString& aOutput,
                                  NotNull aProdList) {
  MOZ_ASSERT(aOutput.IsEmpty());

  LONG count;
  HRESULT hr = aProdList->get_Count(&count);
  if (FAILED(hr)) {
    return hr;
  }

  for (LONG index = 0; index < count; ++index) {
    RefPtr product;
    hr = aProdList->get_Item(index, getter_AddRefs(product));
    if (FAILED(hr)) {
      return hr;
    }

    WSC_SECURITY_PRODUCT_STATE state;
    hr = product->get_ProductState(&state);
    if (FAILED(hr)) {
      return hr;
    }

    // We only care about products that are active
    if (state == WSC_SECURITY_PRODUCT_STATE_OFF ||
        state == WSC_SECURITY_PRODUCT_STATE_SNOOZED) {
      continue;
    }

    _bstr_t bName;
    hr = product->get_ProductName(bName.GetAddress());
    if (FAILED(hr)) {
      return hr;
    }

    if (!aOutput.IsEmpty()) {
      aOutput.AppendLiteral(u";");
    }

    aOutput.Append((wchar_t*)bName, bName.length());
  }

  return S_OK;
}

Minimal test - lines (269, 381)

path: .spaces[2].spaces[2].metrics.cyclomatic.sum
old: 1.0
new: 14.0

path: .spaces[2].spaces[2].metrics.cyclomatic.average
old: 1.0
new: 14.0

path: .spaces[2].spaces[2].metrics.mi.mi_visual_studio
old: 70.54838854584763
new: 29.686938184331822

path: .spaces[2].spaces[2].metrics.mi.mi_original
old: 120.63774441339945
new: 50.764664295207425

path: .spaces[2].spaces[2].metrics.mi.mi_sei
old: 98.44444347663332
new: 22.200006259191916

path: .spaces[2].spaces[2].metrics.halstead.n1
old: 7.0
new: 21.0

path: .spaces[2].spaces[2].metrics.halstead.difficulty
old: 3.5
new: 22.183098591549296

path: .spaces[2].spaces[2].metrics.halstead.effort
old: 357.6529986094047
new: 52820.178584341906

path: .spaces[2].spaces[2].metrics.halstead.volume
old: 102.18657103125848
new: 2381.1001139608097

path: .spaces[2].spaces[2].metrics.halstead.n2
old: 10.0
new: 71.0

path: .spaces[2].spaces[2].metrics.halstead.estimated_program_length
old: 52.87076540327685
new: 528.8707113631864

path: .spaces[2].spaces[2].metrics.halstead.N1
old: 15.0
new: 215.0

path: .spaces[2].spaces[2].metrics.halstead.N2
old: 10.0
new: 150.0

path: .spaces[2].spaces[2].metrics.halstead.bugs
old: 0.016795257201959398
new: 0.469258327898019

path: .spaces[2].spaces[2].metrics.halstead.level
old: 0.2857142857142857
new: 0.04507936507936508

path: .spaces[2].spaces[2].metrics.halstead.vocabulary
old: 17.0
new: 92.0

path: .spaces[2].spaces[2].metrics.halstead.time
old: 19.869611033855815
new: 2934.4543657967724

path: .spaces[2].spaces[2].metrics.halstead.purity_ratio
old: 2.114830616131074
new: 1.4489608530498257

path: .spaces[2].spaces[2].metrics.halstead.length
old: 25.0
new: 365.0

path: .spaces[2].spaces[2].metrics.nexits.sum
old: 1.0
new: 7.0

path: .spaces[2].spaces[2].metrics.nexits.average
old: 1.0
new: 7.0

path: .spaces[2].spaces[2].metrics.nargs.sum
old: 5.0
new: 1.0

path: .spaces[2].spaces[2].metrics.nargs.average
old: 5.0
new: 1.0

path: .spaces[2].spaces[2].metrics.loc.blank
old: 0.0
new: 26.0

path: .spaces[2].spaces[2].metrics.loc.sloc
old: 5.0
new: 113.0

path: .spaces[2].spaces[2].metrics.loc.ploc
old: 5.0
new: 76.0

path: .spaces[2].spaces[2].metrics.loc.lloc
old: 1.0
new: 24.0

path: .spaces[2].spaces[2].metrics.loc.cloc
old: 0.0
new: 11.0

path: .spaces[2].spaces[2].metrics.cognitive.average
old: 0.0
new: 16.0

path: .spaces[2].spaces[2].metrics.cognitive.sum
old: 0.0
new: 16.0

Code

static nsresult CollectOSInfo(OSInfo& info) {
  HKEY installYearHKey;
  LONG status = RegOpenKeyExW(
      HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0,
      KEY_READ | KEY_WOW64_64KEY, &installYearHKey);

  if (status != ERROR_SUCCESS) {
    return NS_ERROR_UNEXPECTED;
  }

  nsAutoRegKey installYearKey(installYearHKey);

  DWORD type = 0;
  time_t raw_time = 0;
  DWORD time_size = sizeof(time_t);

  status = RegQueryValueExW(installYearHKey, L"InstallDate", nullptr, &type,
                            (LPBYTE)&raw_time, &time_size);

  if (status != ERROR_SUCCESS) {
    return NS_ERROR_UNEXPECTED;
  }

  if (type != REG_DWORD) {
    return NS_ERROR_UNEXPECTED;
  }

  tm time;
  if (localtime_s(&time, &raw_time) != 0) {
    return NS_ERROR_UNEXPECTED;
  }

  info.installYear = 1900UL + time.tm_year;

  nsAutoServiceHandle scm(
      OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT));

  if (!scm) {
    return NS_ERROR_UNEXPECTED;
  }

  bool superfetchServiceRunning = false;

  // Superfetch was introduced in Windows Vista as a service with the name
  // SysMain. The service display name was also renamed to SysMain after Windows
  // 10 build 1809.
  nsAutoServiceHandle hService(OpenService(scm, L"SysMain", GENERIC_READ));

  if (hService) {
    SERVICE_STATUS superfetchStatus;
    LPSERVICE_STATUS pSuperfetchStatus = &superfetchStatus;

    if (!QueryServiceStatus(hService, pSuperfetchStatus)) {
      return NS_ERROR_UNEXPECTED;
    }

    superfetchServiceRunning =
        superfetchStatus.dwCurrentState == SERVICE_RUNNING;
  }

  // If the SysMain (Superfetch) service is available, but not configured using
  // the defaults, then it's disabled for our purposes, since it's not going to
  // be operating as expected.
  bool superfetchUsingDefaultParams = true;
  bool prefetchUsingDefaultParams = true;

  static const WCHAR prefetchParamsKeyName[] =
      L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory "
      L"Management\\PrefetchParameters";
  static const DWORD SUPERFETCH_DEFAULT_PARAM = 3;
  static const DWORD PREFETCH_DEFAULT_PARAM = 3;

  HKEY prefetchParamsHKey;

  LONG prefetchParamsStatus =
      RegOpenKeyExW(HKEY_LOCAL_MACHINE, prefetchParamsKeyName, 0,
                    KEY_READ | KEY_WOW64_64KEY, &prefetchParamsHKey);

  if (prefetchParamsStatus == ERROR_SUCCESS) {
    DWORD valueSize = sizeof(DWORD);
    DWORD superfetchValue = 0;
    nsAutoRegKey prefetchParamsKey(prefetchParamsHKey);
    LONG superfetchParamStatus = RegQueryValueExW(
        prefetchParamsHKey, L"EnableSuperfetch", nullptr, &type,
        reinterpret_cast(&superfetchValue), &valueSize);

    // If the EnableSuperfetch registry key doesn't exist, then it's using the
    // default configuration.
    if (superfetchParamStatus == ERROR_SUCCESS &&
        superfetchValue != SUPERFETCH_DEFAULT_PARAM) {
      superfetchUsingDefaultParams = false;
    }

    DWORD prefetchValue = 0;

    LONG prefetchParamStatus = RegQueryValueExW(
        prefetchParamsHKey, L"EnablePrefetcher", nullptr, &type,
        reinterpret_cast(&prefetchValue), &valueSize);

    // If the EnablePrefetcher registry key doesn't exist, then we interpret
    // that as the Prefetcher being disabled (since Prefetch behaviour when
    // the key is not available appears to be undefined).
    if (prefetchParamStatus != ERROR_SUCCESS ||
        prefetchValue != PREFETCH_DEFAULT_PARAM) {
      prefetchUsingDefaultParams = false;
    }
  }

  info.hasSuperfetch = superfetchServiceRunning && superfetchUsingDefaultParams;
  info.hasPrefetch = prefetchUsingDefaultParams;

  return NS_OK;
}

Minimal test - lines (83, 102)

path: .spaces[0].metrics.mi.mi_sei
old: 57.52690427340841
new: 82.31601521355236

path: .spaces[0].metrics.mi.mi_original
old: 71.06814893953512
new: 89.67762446765975

path: .spaces[0].metrics.mi.mi_visual_studio
old: 41.560321017272
new: 52.44305524424547

path: .spaces[0].metrics.nargs.sum
old: 7.0
new: 2.0

path: .spaces[0].metrics.nargs.average
old: 2.3333333333333335
new: 2.0

path: .spaces[0].metrics.nexits.sum
old: 1.0
new: 0.0

path: .spaces[0].metrics.nexits.average
old: 0.3333333333333333
new: 0.0

path: .spaces[0].metrics.nom.total
old: 3.0
new: 1.0

path: .spaces[0].metrics.nom.functions
old: 3.0
new: 1.0

path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 6.0

path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 6.0

path: .spaces[0].metrics.halstead.effort
old: 11184.763035777643
new: 6257.4381578504945

path: .spaces[0].metrics.halstead.N2
old: 67.0
new: 37.0

path: .spaces[0].metrics.halstead.bugs
old: 0.16671062136977333
new: 0.1131904507539615

path: .spaces[0].metrics.halstead.estimated_program_length
old: 271.4804827296223
new: 134.01359166423458

path: .spaces[0].metrics.halstead.difficulty
old: 12.5625
new: 13.63157894736842

path: .spaces[0].metrics.halstead.level
old: 0.07960199004975124
new: 0.07335907335907335

path: .spaces[0].metrics.halstead.length
old: 154.0
new: 91.0

path: .spaces[0].metrics.halstead.n1
old: 15.0
new: 14.0

path: .spaces[0].metrics.halstead.n2
old: 40.0
new: 19.0

path: .spaces[0].metrics.halstead.volume
old: 890.3293958827976
new: 459.03986486161926

path: .spaces[0].metrics.halstead.vocabulary
old: 55.0
new: 33.0

path: .spaces[0].metrics.halstead.purity_ratio
old: 1.7628602774650797
new: 1.4726768314751053

path: .spaces[0].metrics.halstead.time
old: 621.3757242098692
new: 347.6354532139164

path: .spaces[0].metrics.halstead.N1
old: 87.0
new: 54.0

path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 4.0

path: .spaces[0].metrics.loc.lloc
old: 2.0
new: 6.0

path: .spaces[0].metrics.loc.sloc
old: 51.0
new: 20.0

path: .spaces[0].metrics.loc.blank
old: 9.0
new: 1.0

path: .spaces[0].metrics.loc.cloc
old: 9.0
new: 3.0

path: .spaces[0].metrics.loc.ploc
old: 33.0
new: 16.0

Code

static void SimpleParseKeyValuePairs(
    const std::string& aFilename,
    std::map& aKeyValuePairs) {
  std::ifstream input(aFilename.c_str());
  for (std::string line; std::getline(input, line);) {
    nsAutoCString key, value;

    nsCCharSeparatedTokenizer tokens(nsDependentCString(line.c_str()), ':');
    if (tokens.hasMoreTokens()) {
      key = tokens.nextToken();
      if (tokens.hasMoreTokens()) {
        value = tokens.nextToken();
      }
      // We want the value even if there was just one token, to cover the
      // case where we had the key, and the value was blank (seems to be
      // a valid scenario some files.)
      aKeyValuePairs[key] = value;
    }
  }
}

Minimal test - lines (157, 407)

path: .spaces[2].metrics.mi.mi_visual_studio
old: 30.82913446425164
new: 15.730621990958085

path: .spaces[2].metrics.mi.mi_sei
old: 15.54022234389272
new: -10.629968506169888

path: .spaces[2].metrics.mi.mi_original
old: 52.7178199338703
new: 26.899363604538323

path: .spaces[2].metrics.nom.total
old: 12.0
new: 4.0

path: .spaces[2].metrics.nom.functions
old: 12.0
new: 4.0

path: .spaces[2].metrics.cognitive.sum
old: 5.0
new: 38.0

path: .spaces[2].metrics.cognitive.average
old: 0.4166666666666667
new: 9.5

path: .spaces[2].metrics.nexits.sum
old: 12.0
new: 19.0

path: .spaces[2].metrics.nexits.average
old: 1.0
new: 4.75

path: .spaces[2].metrics.loc.sloc
old: 97.0
new: 251.0

path: .spaces[2].metrics.loc.blank
old: 18.0
new: 35.0

path: .spaces[2].metrics.loc.ploc
old: 76.0
new: 193.0

path: .spaces[2].metrics.loc.lloc
old: 27.0
new: 77.0

path: .spaces[2].metrics.loc.cloc
old: 3.0
new: 23.0

path: .spaces[2].metrics.halstead.level
old: 0.057971014492753624
new: 0.029541530788413584

path: .spaces[2].metrics.halstead.time
old: 2208.5825221471587
new: 13863.690370890305

path: .spaces[2].metrics.halstead.N1
old: 217.0
new: 583.0

path: .spaces[2].metrics.halstead.difficulty
old: 17.25
new: 33.85064935064935

path: .spaces[2].metrics.halstead.n1
old: 18.0
new: 26.0

path: .spaces[2].metrics.halstead.vocabulary
old: 90.0
new: 180.0

path: .spaces[2].metrics.halstead.n2
old: 72.0
new: 154.0

path: .spaces[2].metrics.halstead.bugs
old: 0.3882720863300512
new: 1.3212337196103938

path: .spaces[2].metrics.halstead.purity_ratio
old: 1.4627978876896002
new: 1.2614802438401251

path: .spaces[2].metrics.halstead.N2
old: 138.0
new: 401.0

path: .spaces[2].metrics.halstead.effort
old: 39754.48539864885
new: 249546.4266760255

path: .spaces[2].metrics.halstead.estimated_program_length
old: 519.293250129808
new: 1241.2965599386832

path: .spaces[2].metrics.halstead.volume
old: 2304.6078491970347
new: 7371.9834467884

path: .spaces[2].metrics.halstead.length
old: 355.0
new: 984.0

path: .spaces[2].metrics.cyclomatic.sum
old: 17.0
new: 36.0

path: .spaces[2].metrics.cyclomatic.average
old: 1.3076923076923077
new: 7.2

path: .spaces[2].metrics.nargs.average
old: 2.1666666666666665
new: 2.0

path: .spaces[2].metrics.nargs.sum
old: 26.0
new: 8.0

Code

namespace {
static nsresult GetFolderDiskInfo(nsIFile* file, FolderDiskInfo& info) {
  info.model.Truncate();
  info.revision.Truncate();
  info.isSSD = false;

  nsAutoString filePath;
  nsresult rv = file->GetPath(filePath);
  NS_ENSURE_SUCCESS(rv, rv);
  wchar_t volumeMountPoint[MAX_PATH] = {L'\\', L'\\', L'.', L'\\'};
  const size_t PREFIX_LEN = 4;
  if (!::GetVolumePathNameW(
          filePath.get(), volumeMountPoint + PREFIX_LEN,
          mozilla::ArrayLength(volumeMountPoint) - PREFIX_LEN)) {
    return NS_ERROR_UNEXPECTED;
  }
  size_t volumeMountPointLen = wcslen(volumeMountPoint);
  // Since we would like to open a drive and not a directory, we need to
  // remove any trailing backslash. A drive handle is valid for
  // DeviceIoControl calls, a directory handle is not.
  if (volumeMountPoint[volumeMountPointLen - 1] == L'\\') {
    volumeMountPoint[volumeMountPointLen - 1] = L'\0';
  }
  ScopedHandle handle(::CreateFileW(volumeMountPoint, 0,
                                    FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                                    OPEN_EXISTING, 0, nullptr));
  if (!handle.IsValid()) {
    return NS_ERROR_UNEXPECTED;
  }
  STORAGE_PROPERTY_QUERY queryParameters = {StorageDeviceProperty,
                                            PropertyStandardQuery};
  STORAGE_DEVICE_DESCRIPTOR outputHeader = {sizeof(STORAGE_DEVICE_DESCRIPTOR)};
  DWORD bytesRead = 0;
  if (!::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &queryParameters,
                         sizeof(queryParameters), &outputHeader,
                         sizeof(outputHeader), &bytesRead, nullptr)) {
    return NS_ERROR_FAILURE;
  }
  PSTORAGE_DEVICE_DESCRIPTOR deviceOutput =
      (PSTORAGE_DEVICE_DESCRIPTOR)malloc(outputHeader.Size);
  if (!::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &queryParameters,
                         sizeof(queryParameters), deviceOutput,
                         outputHeader.Size, &bytesRead, nullptr)) {
    free(deviceOutput);
    return NS_ERROR_FAILURE;
  }

  queryParameters.PropertyId = StorageDeviceTrimProperty;
  bytesRead = 0;
  bool isSSD = false;
  DEVICE_TRIM_DESCRIPTOR trimDescriptor = {sizeof(DEVICE_TRIM_DESCRIPTOR)};
  if (::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &queryParameters,
                        sizeof(queryParameters), &trimDescriptor,
                        sizeof(trimDescriptor), &bytesRead, nullptr)) {
    if (trimDescriptor.TrimEnabled) {
      isSSD = true;
    }
  }

  if (isSSD) {
    // Get Seek Penalty
    queryParameters.PropertyId = StorageDeviceSeekPenaltyProperty;
    bytesRead = 0;
    DEVICE_SEEK_PENALTY_DESCRIPTOR seekPenaltyDescriptor = {
        sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR)};
    if (::DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY,
                          &queryParameters, sizeof(queryParameters),
                          &seekPenaltyDescriptor, sizeof(seekPenaltyDescriptor),
                          &bytesRead, nullptr)) {
      // It is possible that the disk has TrimEnabled, but also
      // IncursSeekPenalty; In this case, this is an HDD
      if (seekPenaltyDescriptor.IncursSeekPenalty) {
        isSSD = false;
      }
    }
  }

  // Some HDDs are including product ID info in the vendor field. Since PNP
  // IDs include vendor info and product ID concatenated together, we'll do
  // that here and interpret the result as a unique ID for the HDD model.
  if (deviceOutput->VendorIdOffset) {
    info.model =
        reinterpret_cast(deviceOutput) + deviceOutput->VendorIdOffset;
  }
  if (deviceOutput->ProductIdOffset) {
    info.model +=
        reinterpret_cast(deviceOutput) + deviceOutput->ProductIdOffset;
  }
  info.model.CompressWhitespace();
  if (deviceOutput->ProductRevisionOffset) {
    info.revision = reinterpret_cast(deviceOutput) +
                    deviceOutput->ProductRevisionOffset;
    info.revision.CompressWhitespace();
  }
  info.isSSD = isSSD;
  free(deviceOutput);
  return NS_OK;
}

static nsresult CollectDiskInfo(nsIFile* greDir, nsIFile* winDir,
                                nsIFile* profDir, DiskInfo& info) {
  nsresult rv = GetFolderDiskInfo(greDir, info.binary);
  if (NS_FAILED(rv)) {
    return rv;
  }
  rv = GetFolderDiskInfo(winDir, info.system);
  if (NS_FAILED(rv)) {
    return rv;
  }
  return GetFolderDiskInfo(profDir, info.profile);
}

static nsresult CollectOSInfo(OSInfo& info) {
  HKEY installYearHKey;
  LONG status = RegOpenKeyExW(
      HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0,
      KEY_READ | KEY_WOW64_64KEY, &installYearHKey);

  if (status != ERROR_SUCCESS) {
    return NS_ERROR_UNEXPECTED;
  }

  nsAutoRegKey installYearKey(installYearHKey);

  DWORD type = 0;
  time_t raw_time = 0;
  DWORD time_size = sizeof(time_t);

  status = RegQueryValueExW(installYearHKey, L"InstallDate", nullptr, &type,
                            (LPBYTE)&raw_time, &time_size);

  if (status != ERROR_SUCCESS) {
    return NS_ERROR_UNEXPECTED;
  }

  if (type != REG_DWORD) {
    return NS_ERROR_UNEXPECTED;
  }

  tm time;
  if (localtime_s(&time, &raw_time) != 0) {
    return NS_ERROR_UNEXPECTED;
  }

  info.installYear = 1900UL + time.tm_year;

  nsAutoServiceHandle scm(
      OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT));

  if (!scm) {
    return NS_ERROR_UNEXPECTED;
  }

  bool superfetchServiceRunning = false;

  // Superfetch was introduced in Windows Vista as a service with the name
  // SysMain. The service display name was also renamed to SysMain after Windows
  // 10 build 1809.
  nsAutoServiceHandle hService(OpenService(scm, L"SysMain", GENERIC_READ));

  if (hService) {
    SERVICE_STATUS superfetchStatus;
    LPSERVICE_STATUS pSuperfetchStatus = &superfetchStatus;

    if (!QueryServiceStatus(hService, pSuperfetchStatus)) {
      return NS_ERROR_UNEXPECTED;
    }

    superfetchServiceRunning =
        superfetchStatus.dwCurrentState == SERVICE_RUNNING;
  }

  // If the SysMain (Superfetch) service is available, but not configured using
  // the defaults, then it's disabled for our purposes, since it's not going to
  // be operating as expected.
  bool superfetchUsingDefaultParams = true;
  bool prefetchUsingDefaultParams = true;

  static const WCHAR prefetchParamsKeyName[] =
      L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory "
      L"Management\\PrefetchParameters";
  static const DWORD SUPERFETCH_DEFAULT_PARAM = 3;
  static const DWORD PREFETCH_DEFAULT_PARAM = 3;

  HKEY prefetchParamsHKey;

  LONG prefetchParamsStatus =
      RegOpenKeyExW(HKEY_LOCAL_MACHINE, prefetchParamsKeyName, 0,
                    KEY_READ | KEY_WOW64_64KEY, &prefetchParamsHKey);

  if (prefetchParamsStatus == ERROR_SUCCESS) {
    DWORD valueSize = sizeof(DWORD);
    DWORD superfetchValue = 0;
    nsAutoRegKey prefetchParamsKey(prefetchParamsHKey);
    LONG superfetchParamStatus = RegQueryValueExW(
        prefetchParamsHKey, L"EnableSuperfetch", nullptr, &type,
        reinterpret_cast(&superfetchValue), &valueSize);

    // If the EnableSuperfetch registry key doesn't exist, then it's using the
    // default configuration.
    if (superfetchParamStatus == ERROR_SUCCESS &&
        superfetchValue != SUPERFETCH_DEFAULT_PARAM) {
      superfetchUsingDefaultParams = false;
    }

    DWORD prefetchValue = 0;

    LONG prefetchParamStatus = RegQueryValueExW(
        prefetchParamsHKey, L"EnablePrefetcher", nullptr, &type,
        reinterpret_cast(&prefetchValue), &valueSize);

    // If the EnablePrefetcher registry key doesn't exist, then we interpret
    // that as the Prefetcher being disabled (since Prefetch behaviour when
    // the key is not available appears to be undefined).
    if (prefetchParamStatus != ERROR_SUCCESS ||
        prefetchValue != PREFETCH_DEFAULT_PARAM) {
      prefetchUsingDefaultParams = false;
    }
  }

  info.hasSuperfetch = superfetchServiceRunning && superfetchUsingDefaultParams;
  info.hasPrefetch = prefetchUsingDefaultParams;

  return NS_OK;
}

nsresult CollectCountryCode(nsAString& aCountryCode) {
  GEOID geoid = GetUserGeoID(GEOCLASS_NATION);
  if (geoid == GEOID_NOT_AVAILABLE) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  // Get required length
  int numChars = GetGeoInfoW(geoid, GEO_ISO2, nullptr, 0, 0);
  if (!numChars) {
    return NS_ERROR_FAILURE;
  }
  // Now get the string for real
  aCountryCode.SetLength(numChars);
  numChars =
      GetGeoInfoW(geoid, GEO_ISO2, char16ptr_t(aCountryCode.BeginWriting()),
                  aCountryCode.Length(), 0);
  if (!numChars) {
    return NS_ERROR_FAILURE;
  }

  // numChars includes null terminator
  aCountryCode.Truncate(numChars - 1);
  return NS_OK;
}

}  // namespace