// Pre-load DLLs that need to be used by the EME plugin but that can't be // loaded after the sandbox has started bool GMPChild::PreLoadLibraries(const nsAString& aPluginPath) { // This must be in sorted order and lowercase! static const char* whitelist[] = { "d3d9.dll", // Create an `IDirect3D9` to get adapter information "dxva2.dll", // Get monitor information "evr.dll", // MFGetStrideForBitmapInfoHeader "mfh264dec.dll", // H.264 decoder (on Windows Vista) "mfheaacdec.dll", // AAC decoder (on Windows Vista) "mfplat.dll", // MFCreateSample, MFCreateAlignedMemoryBuffer, MFCreateMediaType "msauddecmft.dll", // AAC decoder (on Windows 8) "msmpeg2adec.dll", // AAC decoder (on Windows 7) "msmpeg2vdec.dll", // H.264 decoder }; nsCOMPtr<nsIFile> infoFile; GetInfoFile(aPluginPath, infoFile); static const size_t MAX_GMP_INFO_FILE_LENGTH = 5 * 1024; nsAutoCString info; if (!ReadIntoString(infoFile, info, MAX_GMP_INFO_FILE_LENGTH)) { NS_WARNING("Failed to read info file in GMP process."); return false; } // Note: we pass "\r\n" to SplitAt so that we'll split lines delimited // by \n (Unix), \r\n (Windows) and \r (old MacOSX). nsTArray<nsCString> lines; SplitAt("\r\n", info, lines); for (nsCString line : lines) { // Make lowercase. std::transform(line.BeginWriting(), line.EndWriting(), line.BeginWriting(), tolower); const char* libraries = "libraries:"; int32_t offset = line.Find(libraries, false, 0); if (offset == kNotFound) { continue; } // Line starts with "libraries:". nsTArray<nsCString> libs; SplitAt(",", Substring(line, offset + strlen(libraries)), libs); for (nsCString lib : libs) { lib.Trim(" "); for (const char* whiteListedLib : whitelist) { if (lib.EqualsASCII(whiteListedLib)) { LoadLibraryA(lib.get()); break; } } } } return true; }
mozilla::ipc::IPCResult GMPChild::RecvPreloadLibs(const nsCString& aLibs) { #ifdef XP_WIN // Pre-load DLLs that need to be used by the EME plugin but that can't be // loaded after the sandbox has started // Items in this must be lowercase! static const char *const whitelist[] = { "dxva2.dll", // Get monitor information "evr.dll", // MFGetStrideForBitmapInfoHeader "mfplat.dll", // MFCreateSample, MFCreateAlignedMemoryBuffer, MFCreateMediaType "msmpeg2vdec.dll", // H.264 decoder }; nsTArray<nsCString> libs; SplitAt(", ", aLibs, libs); for (nsCString lib : libs) { ToLowerCase(lib); for (const char* whiteListedLib : whitelist) { if (lib.EqualsASCII(whiteListedLib)) { LoadLibraryA(lib.get()); break; } } } #endif return IPC_OK(); }
bool GMPChild::RecvPreloadLibs(const nsCString& aLibs) { #ifdef XP_WIN // Pre-load DLLs that need to be used by the EME plugin but that can't be // loaded after the sandbox has started // Items in this must be lowercase! static const char* whitelist[] = { "d3d9.dll", // Create an `IDirect3D9` to get adapter information "dxva2.dll", // Get monitor information "evr.dll", // MFGetStrideForBitmapInfoHeader "mfh264dec.dll", // H.264 decoder (on Windows Vista) "mfheaacdec.dll", // AAC decoder (on Windows Vista) "mfplat.dll", // MFCreateSample, MFCreateAlignedMemoryBuffer, MFCreateMediaType "msauddecmft.dll", // AAC decoder (on Windows 8) "msmpeg2adec.dll", // AAC decoder (on Windows 7) "msmpeg2vdec.dll", // H.264 decoder }; nsTArray<nsCString> libs; SplitAt(", ", aLibs, libs); for (nsCString lib : libs) { ToLowerCase(lib); for (const char* whiteListedLib : whitelist) { if (lib.EqualsASCII(whiteListedLib)) { LoadLibraryA(lib.get()); break; } } } #endif return true; }
bool plConfigSource::ReadString(const std::string & in) { std::string work = in; xtl::trim(work); // comment if (work[0] == '#') return true; // comment if (work[0] == ';') return true; // section if (work[0] == '[') { int close = work.find_first_of("]"); if(close == std::string::npos) return false; fCurrSection = work.substr(1,close-1); fEffectiveSection = fCurrSection; return true; } // key=value std::string key, value; SplitAt(key, value, '=', work); // dot notation makes section change for this key=value only. int t = key.find('.'); if (t>0 && t<key.size()-1) { fEffectiveSection.assign(key.substr(0,t)); key.assign(key.substr(t+1)); } bool ret=ReadPair(key, value); fEffectiveSection = fCurrSection; if(ret && strcmp("LoadIni",key.c_str()) == 0) { ret = ReadSubSource( value.c_str() ); } return ret; }
bool plIniNoSectionsConfigSource::ReadString(const std::string & in) { std::string work = in; xtl::trim(work); // ignore comments if (work[0]=='#' || work[0]==';') return true; // ignore sections if (work[0] == '[') return true; // parse key value std::string key, value; SplitAt(key, value, '=', work); return ReadPair(key, value); }
bool GMPInfoFileParser::Init(nsIFile* aInfoFile) { nsTArray<nsCString> lines; static const size_t MAX_GMP_INFO_FILE_LENGTH = 5 * 1024; nsAutoCString info; if (!ReadIntoString(aInfoFile, info, MAX_GMP_INFO_FILE_LENGTH)) { NS_WARNING("Failed to read info file in GMP process."); return false; } // Note: we pass "\r\n" to SplitAt so that we'll split lines delimited // by \n (Unix), \r\n (Windows) and \r (old MacOSX). SplitAt("\r\n", info, lines); for (nsCString line : lines) { // Field name is the string up to but not including the first ':' // character on the line. int32_t colon = line.FindChar(':'); if (colon <= 0) { // Not allowed to be the first character. // Info field name must be at least one character. continue; } nsAutoCString key(Substring(line, 0, colon)); ToLowerCase(key); key.Trim(" "); nsCString* value = new nsCString(Substring(line, colon + 1)); value->Trim(" "); mValues.Put(key, value); // Hashtable assumes ownership of value. } return true; }
// 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; }