Ejemplo n.º 1
0
static bool
IsH264DecoderBlacklisted()
{
#ifdef BLACKLIST_CRASHY_H264_DECODERS
  WCHAR systemPath[MAX_PATH + 1];
  if (!ConstructSystem32Path(L"msmpeg2vdec.dll", systemPath, MAX_PATH + 1)) {
    // Cannot build path -> Assume it's not the blacklisted DLL.
    return false;
  }

  DWORD zero;
  DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
  if (infoSize == 0) {
    // Can't get file info -> Assume we don't have the blacklisted DLL.
    return false;
  }
  auto infoData = MakeUnique<unsigned char[]>(infoSize);
  VS_FIXEDFILEINFO *vInfo;
  UINT vInfoLen;
  if (GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get()) &&
    VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen))
  {
    if ((vInfo->dwFileVersionMS == ((12u << 16) | 0u))
        && ((vInfo->dwFileVersionLS == ((9200u << 16) | 16426u))
            || (vInfo->dwFileVersionLS == ((9200u << 16) | 17037u)))) {
      // 12.0.9200.16426 & .17037 are blacklisted on Win64, see bug 1242343.
      return true;
    }
  }
#endif // BLACKLIST_CRASHY_H264_DECODERS
  return false;
}
Ejemplo n.º 2
0
// If a blacklisted DLL is found, return its information, otherwise "".
static const nsACString&
FindDXVABlacklistedDLL(StaticAutoPtr<D3DDLLBlacklistingCache>& aDLLBlacklistingCache,
                       const char* aDLLBlacklistPrefName)
{
  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");

  if (!aDLLBlacklistingCache) {
    // First time here, create persistent data that will be reused in all
    // D3D11-blacklisting checks.
    aDLLBlacklistingCache = new D3DDLLBlacklistingCache();
    ClearOnShutdown(&aDLLBlacklistingCache);
  }

  nsAdoptingCString blacklist = Preferences::GetCString(aDLLBlacklistPrefName);
  if (blacklist.IsEmpty()) {
    // Empty blacklist -> No blacklisting.
    aDLLBlacklistingCache->mBlacklistPref.SetLength(0);
    aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
    return aDLLBlacklistingCache->mBlacklistedDLL;
  }

  // Detect changes in pref.
  if (aDLLBlacklistingCache->mBlacklistPref.Equals(blacklist)) {
    // Same blacklist -> Return same result (i.e., don't check DLLs again).
    return aDLLBlacklistingCache->mBlacklistedDLL;
  }
  // Adopt new pref now, so we don't work on it again.
  aDLLBlacklistingCache->mBlacklistPref = blacklist;

  // media.wmf.disable-d3d*-for-dlls format: (whitespace is trimmed)
  // "dll1.dll: 1.2.3.4[, more versions...][; more dlls...]"
  nsTArray<nsCString> dlls;
  SplitAt(";", blacklist, dlls);
  for (const auto& dll : dlls) {
    nsTArray<nsCString> nameAndVersions;
    SplitAt(":", dll, nameAndVersions);
    if (nameAndVersions.Length() != 2) {
      NS_WARNING(nsPrintfCString("Skipping incorrect '%s' dll:versions format",
                                 aDLLBlacklistPrefName).get());
      continue;
    }

    nameAndVersions[0].CompressWhitespace();
    NS_ConvertUTF8toUTF16 name(nameAndVersions[0]);
    WCHAR systemPath[MAX_PATH + 1];
    if (!ConstructSystem32Path(name.get(), systemPath, MAX_PATH + 1)) {
      // Cannot build path -> Assume it's not the blacklisted DLL.
      continue;
    }

    DWORD zero;
    DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
    if (infoSize == 0) {
      // Can't get file info -> Assume we don't have the blacklisted DLL.
      continue;
    }
    // vInfo is a pointer into infoData, that's why we keep it outside of the loop.
    auto infoData = MakeUnique<unsigned char[]>(infoSize);
    VS_FIXEDFILEINFO *vInfo;
    UINT vInfoLen;
    if (!GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get())
        || !VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen)
        || !vInfo) {
      // Can't find version -> Assume it's not blacklisted.
      continue;
    }

    nsTArray<nsCString> versions;
    SplitAt(",", nameAndVersions[1], versions);
    for (const auto& version : versions) {
      nsTArray<nsCString> numberStrings;
      SplitAt(".", version, numberStrings);
      if (numberStrings.Length() != 4) {
        NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format",
                                   aDLLBlacklistPrefName).get());
        continue;
      }
      DWORD numbers[4];
      nsresult errorCode = NS_OK;
      for (int i = 0; i < 4; ++i) {
        numberStrings[i].CompressWhitespace();
        numbers[i] = DWORD(numberStrings[i].ToInteger(&errorCode));
        if (NS_FAILED(errorCode)) {
          break;
        }
        if (numbers[i] > UINT16_MAX) {
          errorCode = NS_ERROR_FAILURE;
          break;
        }
      }

      if (NS_FAILED(errorCode)) {
        NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format",
                                   aDLLBlacklistPrefName).get());
        continue;
      }

      if (vInfo->dwFileVersionMS == ((numbers[0] << 16) | numbers[1])
          && vInfo->dwFileVersionLS == ((numbers[2] << 16) | numbers[3])) {
        // Blacklisted! Record bad DLL.
        aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
        aDLLBlacklistingCache->mBlacklistedDLL.AppendPrintf(
          "%s (%lu.%lu.%lu.%lu)",
          nameAndVersions[0].get(), numbers[0], numbers[1], numbers[2], numbers[3]);
        return aDLLBlacklistingCache->mBlacklistedDLL;
      }
    }
  }

  // No blacklisted DLL.
  aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
  return aDLLBlacklistingCache->mBlacklistedDLL;
}