diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/plugins/base/nsPluginDirServiceProvider.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/plugins/base/nsPluginDirServiceProvider.cpp')
-rw-r--r-- | dom/plugins/base/nsPluginDirServiceProvider.cpp | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/dom/plugins/base/nsPluginDirServiceProvider.cpp b/dom/plugins/base/nsPluginDirServiceProvider.cpp new file mode 100644 index 000000000..92348c182 --- /dev/null +++ b/dom/plugins/base/nsPluginDirServiceProvider.cpp @@ -0,0 +1,448 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsPluginDirServiceProvider.h" + +#include "nsCRT.h" +#include "nsIFile.h" +#include "nsDependentString.h" +#include "nsArrayEnumerator.h" +#include "mozilla/Preferences.h" + +#include <windows.h> +#include "nsIWindowsRegKey.h" + +using namespace mozilla; + +typedef struct structVer +{ + WORD wMajor; + WORD wMinor; + WORD wRelease; + WORD wBuild; +} verBlock; + +static void +ClearVersion(verBlock *ver) +{ + ver->wMajor = 0; + ver->wMinor = 0; + ver->wRelease = 0; + ver->wBuild = 0; +} + +static BOOL +FileExists(LPCWSTR szFile) +{ + return GetFileAttributesW(szFile) != 0xFFFFFFFF; +} + +// Get file version information from a file +static BOOL +GetFileVersion(LPCWSTR szFile, verBlock *vbVersion) +{ + UINT uLen; + UINT dwLen; + BOOL bRv; + DWORD dwHandle; + LPVOID lpData; + LPVOID lpBuffer; + VS_FIXEDFILEINFO *lpBuffer2; + + ClearVersion(vbVersion); + if (FileExists(szFile)) { + bRv = TRUE; + LPCWSTR lpFilepath = szFile; + dwLen = GetFileVersionInfoSizeW(lpFilepath, &dwHandle); + lpData = (LPVOID)malloc(dwLen); + uLen = 0; + + if (lpData && GetFileVersionInfoW(lpFilepath, dwHandle, dwLen, lpData) != 0) { + if (VerQueryValueW(lpData, L"\\", &lpBuffer, &uLen) != 0) { + lpBuffer2 = (VS_FIXEDFILEINFO *)lpBuffer; + + vbVersion->wMajor = HIWORD(lpBuffer2->dwFileVersionMS); + vbVersion->wMinor = LOWORD(lpBuffer2->dwFileVersionMS); + vbVersion->wRelease = HIWORD(lpBuffer2->dwFileVersionLS); + vbVersion->wBuild = LOWORD(lpBuffer2->dwFileVersionLS); + } + } + + free(lpData); + } else { + /* File does not exist */ + bRv = FALSE; + } + + return bRv; +} + +// Will deep copy ver2 into ver1 +static void +CopyVersion(verBlock *ver1, verBlock *ver2) +{ + ver1->wMajor = ver2->wMajor; + ver1->wMinor = ver2->wMinor; + ver1->wRelease = ver2->wRelease; + ver1->wBuild = ver2->wBuild; +} + +// Convert a string version to a version struct +static void +TranslateVersionStr(const WCHAR* szVersion, verBlock *vbVersion) +{ + WCHAR* szNum1 = nullptr; + WCHAR* szNum2 = nullptr; + WCHAR* szNum3 = nullptr; + WCHAR* szNum4 = nullptr; + WCHAR* szJavaBuild = nullptr; + + WCHAR *strVer = nullptr; + if (szVersion) { + strVer = wcsdup(szVersion); + } + + if (!strVer) { + // Out of memory + ClearVersion(vbVersion); + return; + } + + // Java may be using an underscore instead of a dot for the build ID + szJavaBuild = wcschr(strVer, '_'); + if (szJavaBuild) { + szJavaBuild[0] = '.'; + } + +#if defined(__MINGW32__) + // MSVC 2013 and earlier provided only a non-standard two-argument variant of + // wcstok that is generally not thread-safe. For our purposes here, it works + // fine, though. + auto wcstok = [](wchar_t* strToken, const wchar_t* strDelimit, + wchar_t** /*ctx*/) { + return ::std::wcstok(strToken, strDelimit); + }; +#endif + + wchar_t* ctx = nullptr; + szNum1 = wcstok(strVer, L".", &ctx); + szNum2 = wcstok(nullptr, L".", &ctx); + szNum3 = wcstok(nullptr, L".", &ctx); + szNum4 = wcstok(nullptr, L".", &ctx); + + vbVersion->wMajor = szNum1 ? (WORD) _wtoi(szNum1) : 0; + vbVersion->wMinor = szNum2 ? (WORD) _wtoi(szNum2) : 0; + vbVersion->wRelease = szNum3 ? (WORD) _wtoi(szNum3) : 0; + vbVersion->wBuild = szNum4 ? (WORD) _wtoi(szNum4) : 0; + + free(strVer); +} + +// Compare two version struct, return zero if the same +static int +CompareVersion(verBlock vbVersionOld, verBlock vbVersionNew) +{ + if (vbVersionOld.wMajor > vbVersionNew.wMajor) { + return 4; + } else if (vbVersionOld.wMajor < vbVersionNew.wMajor) { + return -4; + } + + if (vbVersionOld.wMinor > vbVersionNew.wMinor) { + return 3; + } else if (vbVersionOld.wMinor < vbVersionNew.wMinor) { + return -3; + } + + if (vbVersionOld.wRelease > vbVersionNew.wRelease) { + return 2; + } else if (vbVersionOld.wRelease < vbVersionNew.wRelease) { + return -2; + } + + if (vbVersionOld.wBuild > vbVersionNew.wBuild) { + return 1; + } else if (vbVersionOld.wBuild < vbVersionNew.wBuild) { + return -1; + } + + /* the versions are all the same */ + return 0; +} + +//***************************************************************************** +// nsPluginDirServiceProvider::Constructor/Destructor +//***************************************************************************** + +nsPluginDirServiceProvider::nsPluginDirServiceProvider() +{ +} + +nsPluginDirServiceProvider::~nsPluginDirServiceProvider() +{ +} + +//***************************************************************************** +// nsPluginDirServiceProvider::nsISupports +//***************************************************************************** + +NS_IMPL_ISUPPORTS(nsPluginDirServiceProvider, + nsIDirectoryServiceProvider) + +//***************************************************************************** +// nsPluginDirServiceProvider::nsIDirectoryServiceProvider +//***************************************************************************** + +NS_IMETHODIMP +nsPluginDirServiceProvider::GetFile(const char *charProp, bool *persistant, + nsIFile **_retval) +{ + nsCOMPtr<nsIFile> localFile; + nsresult rv = NS_ERROR_FAILURE; + + NS_ENSURE_ARG(charProp); + + *_retval = nullptr; + *persistant = false; + + nsCOMPtr<nsIWindowsRegKey> regKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1"); + NS_ENSURE_TRUE(regKey, NS_ERROR_FAILURE); + + if (nsCRT::strcmp(charProp, NS_WIN_QUICKTIME_SCAN_KEY) == 0) { + nsAdoptingCString strVer = Preferences::GetCString(charProp); + if (!strVer) { + return NS_ERROR_FAILURE; + } + verBlock minVer; + TranslateVersionStr(NS_ConvertASCIItoUTF16(strVer).get(), &minVer); + + // Look for the Quicktime system installation plugins directory + verBlock qtVer; + ClearVersion(&qtVer); + + // First we need to check the version of Quicktime via checking + // the EXE's version table + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + NS_LITERAL_STRING("software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\QuickTimePlayer.exe"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_SUCCEEDED(rv)) { + nsAutoString path; + rv = regKey->ReadStringValue(NS_LITERAL_STRING(""), path); + if (NS_SUCCEEDED(rv)) { + GetFileVersion(path.get(), &qtVer); + } + regKey->Close(); + } + if (CompareVersion(qtVer, minVer) < 0) + return rv; + + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + NS_LITERAL_STRING("software\\Apple Computer, Inc.\\QuickTime"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_SUCCEEDED(rv)) { + nsAutoString path; + rv = regKey->ReadStringValue(NS_LITERAL_STRING("InstallDir"), path); + if (NS_SUCCEEDED(rv)) { + path += NS_LITERAL_STRING("\\Plugins"); + rv = NS_NewLocalFile(path, true, + getter_AddRefs(localFile)); + } + } + } else if (nsCRT::strcmp(charProp, NS_WIN_WMP_SCAN_KEY) == 0) { + nsAdoptingCString strVer = Preferences::GetCString(charProp); + if (!strVer) { + return NS_ERROR_FAILURE; + } + verBlock minVer; + TranslateVersionStr(NS_ConvertASCIItoUTF16(strVer).get(), &minVer); + + // Look for Windows Media Player system installation plugins directory + verBlock wmpVer; + ClearVersion(&wmpVer); + + // First we need to check the version of WMP + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + NS_LITERAL_STRING("software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\wmplayer.exe"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_SUCCEEDED(rv)) { + nsAutoString path; + rv = regKey->ReadStringValue(NS_LITERAL_STRING(""), path); + if (NS_SUCCEEDED(rv)) { + GetFileVersion(path.get(), &wmpVer); + } + regKey->Close(); + } + if (CompareVersion(wmpVer, minVer) < 0) + return rv; + + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + NS_LITERAL_STRING("software\\Microsoft\\MediaPlayer"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_SUCCEEDED(rv)) { + nsAutoString path; + rv = regKey->ReadStringValue(NS_LITERAL_STRING("Installation Directory"), + path); + if (NS_SUCCEEDED(rv)) { + rv = NS_NewLocalFile(path, true, + getter_AddRefs(localFile)); + } + } + } else if (nsCRT::strcmp(charProp, NS_WIN_ACROBAT_SCAN_KEY) == 0) { + nsAdoptingCString strVer = Preferences::GetCString(charProp); + if (!strVer) { + return NS_ERROR_FAILURE; + } + + verBlock minVer; + TranslateVersionStr(NS_ConvertASCIItoUTF16(strVer).get(), &minVer); + + // Look for Adobe Acrobat system installation plugins directory + verBlock maxVer; + ClearVersion(&maxVer); + + nsAutoString newestPath; + + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + NS_LITERAL_STRING("software\\Adobe\\Acrobat Reader"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + NS_LITERAL_STRING("software\\Adobe\\Adobe Acrobat"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + } + + // We must enumerate through the keys because what if there is + // more than one version? + uint32_t childCount = 0; + regKey->GetChildCount(&childCount); + + for (uint32_t index = 0; index < childCount; ++index) { + nsAutoString childName; + rv = regKey->GetChildName(index, childName); + if (NS_SUCCEEDED(rv)) { + verBlock curVer; + TranslateVersionStr(childName.get(), &curVer); + + childName += NS_LITERAL_STRING("\\InstallPath"); + + nsCOMPtr<nsIWindowsRegKey> childKey; + rv = regKey->OpenChild(childName, nsIWindowsRegKey::ACCESS_QUERY_VALUE, + getter_AddRefs(childKey)); + if (NS_SUCCEEDED(rv)) { + // We have a sub key + nsAutoString path; + rv = childKey->ReadStringValue(NS_LITERAL_STRING(""), path); + if (NS_SUCCEEDED(rv)) { + if (CompareVersion(curVer, maxVer) >= 0 && + CompareVersion(curVer, minVer) >= 0) { + newestPath = path; + CopyVersion(&maxVer, &curVer); + } + } + } + } + } + + if (!newestPath.IsEmpty()) { + newestPath += NS_LITERAL_STRING("\\browser"); + rv = NS_NewLocalFile(newestPath, true, + getter_AddRefs(localFile)); + } + } + + if (NS_FAILED(rv)) { + return rv; + } + + localFile.forget(_retval); + return NS_OK; +} + +nsresult +nsPluginDirServiceProvider::GetPLIDDirectories(nsISimpleEnumerator **aEnumerator) +{ + NS_ENSURE_ARG_POINTER(aEnumerator); + *aEnumerator = nullptr; + + nsCOMArray<nsIFile> dirs; + + GetPLIDDirectoriesWithRootKey(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, dirs); + GetPLIDDirectoriesWithRootKey(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, dirs); + + return NS_NewArrayEnumerator(aEnumerator, dirs); +} + +nsresult +nsPluginDirServiceProvider::GetPLIDDirectoriesWithRootKey(uint32_t aKey, nsCOMArray<nsIFile> &aDirs) +{ + nsCOMPtr<nsIWindowsRegKey> regKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1"); + NS_ENSURE_TRUE(regKey, NS_ERROR_FAILURE); + + nsresult rv = regKey->Open(aKey, + NS_LITERAL_STRING("Software\\MozillaPlugins"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + return rv; + } + + uint32_t childCount = 0; + regKey->GetChildCount(&childCount); + + for (uint32_t index = 0; index < childCount; ++index) { + nsAutoString childName; + rv = regKey->GetChildName(index, childName); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIWindowsRegKey> childKey; + rv = regKey->OpenChild(childName, nsIWindowsRegKey::ACCESS_QUERY_VALUE, + getter_AddRefs(childKey)); + if (NS_SUCCEEDED(rv) && childKey) { + nsAutoString path; + rv = childKey->ReadStringValue(NS_LITERAL_STRING("Path"), path); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIFile> localFile; + if (NS_SUCCEEDED(NS_NewLocalFile(path, true, + getter_AddRefs(localFile))) && + localFile) { + // Some vendors use a path directly to the DLL so chop off + // the filename + bool isDir = false; + if (NS_SUCCEEDED(localFile->IsDirectory(&isDir)) && !isDir) { + nsCOMPtr<nsIFile> temp; + localFile->GetParent(getter_AddRefs(temp)); + if (temp) + localFile = temp; + } + + // Now we check to make sure it's actually on disk and + // To see if we already have this directory in the array + bool isFileThere = false; + bool isDupEntry = false; + if (NS_SUCCEEDED(localFile->Exists(&isFileThere)) && isFileThere) { + int32_t c = aDirs.Count(); + for (int32_t i = 0; i < c; i++) { + nsIFile *dup = static_cast<nsIFile*>(aDirs[i]); + if (dup && + NS_SUCCEEDED(dup->Equals(localFile, &isDupEntry)) && + isDupEntry) { + break; + } + } + + if (!isDupEntry) { + aDirs.AppendObject(localFile); + } + } + } + } + } + } + } + return NS_OK; +} |