dom/plugins/base/nsPluginDirServiceProvider.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsPluginDirServiceProvider.h"
     8 #include "nsCRT.h"
     9 #include "nsIFile.h"
    10 #include "nsDependentString.h"
    11 #include "nsArrayEnumerator.h"
    12 #include "mozilla/Preferences.h"
    14 #include <windows.h>
    15 #include "nsIWindowsRegKey.h"
    17 using namespace mozilla;
    19 typedef struct structVer
    20 {
    21   WORD wMajor;
    22   WORD wMinor;
    23   WORD wRelease;
    24   WORD wBuild;
    25 } verBlock;
    27 static void
    28 ClearVersion(verBlock *ver)
    29 {
    30   ver->wMajor   = 0;
    31   ver->wMinor   = 0;
    32   ver->wRelease = 0;
    33   ver->wBuild   = 0;
    34 }
    36 static BOOL
    37 FileExists(LPCWSTR szFile)
    38 {
    39   return GetFileAttributesW(szFile) != 0xFFFFFFFF;
    40 }
    42 // Get file version information from a file
    43 static BOOL
    44 GetFileVersion(LPCWSTR szFile, verBlock *vbVersion)
    45 {
    46   UINT              uLen;
    47   UINT              dwLen;
    48   BOOL              bRv;
    49   DWORD             dwHandle;
    50   LPVOID            lpData;
    51   LPVOID            lpBuffer;
    52   VS_FIXEDFILEINFO  *lpBuffer2;
    54   ClearVersion(vbVersion);
    55   if (FileExists(szFile)) {
    56     bRv    = TRUE;
    57     LPCWSTR lpFilepath = szFile;
    58     dwLen  = GetFileVersionInfoSizeW(lpFilepath, &dwHandle);
    59     lpData = (LPVOID)malloc(dwLen);
    60     uLen   = 0;
    62     if (lpData && GetFileVersionInfoW(lpFilepath, dwHandle, dwLen, lpData) != 0) {
    63       if (VerQueryValueW(lpData, L"\\", &lpBuffer, &uLen) != 0) {
    64         lpBuffer2 = (VS_FIXEDFILEINFO *)lpBuffer;
    66         vbVersion->wMajor   = HIWORD(lpBuffer2->dwFileVersionMS);
    67         vbVersion->wMinor   = LOWORD(lpBuffer2->dwFileVersionMS);
    68         vbVersion->wRelease = HIWORD(lpBuffer2->dwFileVersionLS);
    69         vbVersion->wBuild   = LOWORD(lpBuffer2->dwFileVersionLS);
    70       }
    71     }
    73     free(lpData);
    74   } else {
    75     /* File does not exist */
    76     bRv = FALSE;
    77   }
    79   return bRv;
    80 }
    82 // Will deep copy ver2 into ver1
    83 static void
    84 CopyVersion(verBlock *ver1, verBlock *ver2)
    85 {
    86   ver1->wMajor   = ver2->wMajor;
    87   ver1->wMinor   = ver2->wMinor;
    88   ver1->wRelease = ver2->wRelease;
    89   ver1->wBuild   = ver2->wBuild;
    90 }
    92 // Convert a string version to a version struct
    93 static void
    94 TranslateVersionStr(const WCHAR* szVersion, verBlock *vbVersion)
    95 {
    96   WCHAR* szNum1 = nullptr;
    97   WCHAR* szNum2 = nullptr;
    98   WCHAR* szNum3 = nullptr;
    99   WCHAR* szNum4 = nullptr;
   100   WCHAR* szJavaBuild = nullptr;
   102   WCHAR *strVer = nullptr;
   103   if (szVersion) {
   104     strVer = wcsdup(szVersion);
   105   }
   107   if (!strVer) {
   108     // Out of memory
   109     ClearVersion(vbVersion);
   110     return;
   111   }
   113   // Java may be using an underscore instead of a dot for the build ID
   114   szJavaBuild = wcschr(strVer, '_');
   115   if (szJavaBuild) {
   116     szJavaBuild[0] = '.';
   117   }
   119   szNum1 = wcstok(strVer,  L".");
   120   szNum2 = wcstok(nullptr, L".");
   121   szNum3 = wcstok(nullptr, L".");
   122   szNum4 = wcstok(nullptr, L".");
   124   vbVersion->wMajor   = szNum1 ? (WORD) _wtoi(szNum1) : 0;
   125   vbVersion->wMinor   = szNum2 ? (WORD) _wtoi(szNum2) : 0;
   126   vbVersion->wRelease = szNum3 ? (WORD) _wtoi(szNum3) : 0;
   127   vbVersion->wBuild   = szNum4 ? (WORD) _wtoi(szNum4) : 0;
   129   free(strVer);
   130 }
   132 // Compare two version struct, return zero if the same
   133 static int
   134 CompareVersion(verBlock vbVersionOld, verBlock vbVersionNew)
   135 {
   136   if (vbVersionOld.wMajor > vbVersionNew.wMajor) {
   137     return 4;
   138   } else if (vbVersionOld.wMajor < vbVersionNew.wMajor) {
   139     return -4;
   140   }
   142   if (vbVersionOld.wMinor > vbVersionNew.wMinor) {
   143     return 3;
   144   } else if (vbVersionOld.wMinor < vbVersionNew.wMinor) {
   145     return -3;
   146   }
   148   if (vbVersionOld.wRelease > vbVersionNew.wRelease) {
   149     return 2;
   150   } else if (vbVersionOld.wRelease < vbVersionNew.wRelease) {
   151     return -2;
   152   }
   154   if (vbVersionOld.wBuild > vbVersionNew.wBuild) {
   155     return 1;
   156   } else if (vbVersionOld.wBuild < vbVersionNew.wBuild) {
   157     return -1;
   158   }
   160   /* the versions are all the same */
   161   return 0;
   162 }
   164 //*****************************************************************************
   165 // nsPluginDirServiceProvider::Constructor/Destructor
   166 //*****************************************************************************
   168 nsPluginDirServiceProvider::nsPluginDirServiceProvider()
   169 {
   170 }
   172 nsPluginDirServiceProvider::~nsPluginDirServiceProvider()
   173 {
   174 }
   176 //*****************************************************************************
   177 // nsPluginDirServiceProvider::nsISupports
   178 //*****************************************************************************
   180 NS_IMPL_ISUPPORTS(nsPluginDirServiceProvider,
   181                   nsIDirectoryServiceProvider)
   183 //*****************************************************************************
   184 // nsPluginDirServiceProvider::nsIDirectoryServiceProvider
   185 //*****************************************************************************
   187 NS_IMETHODIMP
   188 nsPluginDirServiceProvider::GetFile(const char *charProp, bool *persistant,
   189                                     nsIFile **_retval)
   190 {
   191   nsCOMPtr<nsIFile>  localFile;
   192   nsresult rv = NS_ERROR_FAILURE;
   194   NS_ENSURE_ARG(charProp);
   196   *_retval = nullptr;
   197   *persistant = false;
   199   nsCOMPtr<nsIWindowsRegKey> regKey =
   200     do_CreateInstance("@mozilla.org/windows-registry-key;1");
   201   NS_ENSURE_TRUE(regKey, NS_ERROR_FAILURE);
   203   if (nsCRT::strcmp(charProp, NS_WIN_QUICKTIME_SCAN_KEY) == 0) {
   204     nsAdoptingCString strVer = Preferences::GetCString(charProp);
   205     if (!strVer) {
   206       return NS_ERROR_FAILURE;
   207     }
   208     verBlock minVer;
   209     TranslateVersionStr(NS_ConvertASCIItoUTF16(strVer).get(), &minVer);
   211     // Look for the Quicktime system installation plugins directory
   212     verBlock qtVer;
   213     ClearVersion(&qtVer);
   215     // First we need to check the version of Quicktime via checking
   216     // the EXE's version table
   217     rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
   218                       NS_LITERAL_STRING("software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\QuickTimePlayer.exe"),
   219                       nsIWindowsRegKey::ACCESS_READ);
   220     if (NS_SUCCEEDED(rv)) {
   221       nsAutoString path;
   222       rv = regKey->ReadStringValue(NS_LITERAL_STRING(""), path);
   223       if (NS_SUCCEEDED(rv)) {
   224         GetFileVersion(path.get(), &qtVer);
   225       }
   226       regKey->Close();
   227     }
   228     if (CompareVersion(qtVer, minVer) < 0)
   229       return rv;
   231     rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
   232                       NS_LITERAL_STRING("software\\Apple Computer, Inc.\\QuickTime"),
   233                       nsIWindowsRegKey::ACCESS_READ);
   234     if (NS_SUCCEEDED(rv)) {
   235       nsAutoString path;
   236       rv = regKey->ReadStringValue(NS_LITERAL_STRING("InstallDir"), path);
   237       if (NS_SUCCEEDED(rv)) {
   238         path += NS_LITERAL_STRING("\\Plugins");
   239         rv = NS_NewLocalFile(path, true,
   240                              getter_AddRefs(localFile));
   241       }
   242     }
   243   } else if (nsCRT::strcmp(charProp, NS_WIN_WMP_SCAN_KEY) == 0) {
   244     nsAdoptingCString strVer = Preferences::GetCString(charProp);
   245     if (!strVer) {
   246       return NS_ERROR_FAILURE;
   247     }
   248     verBlock minVer;
   249     TranslateVersionStr(NS_ConvertASCIItoUTF16(strVer).get(), &minVer);
   251     // Look for Windows Media Player system installation plugins directory
   252     verBlock wmpVer;
   253     ClearVersion(&wmpVer);
   255     // First we need to check the version of WMP
   256     rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
   257                       NS_LITERAL_STRING("software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\wmplayer.exe"),
   258                       nsIWindowsRegKey::ACCESS_READ);
   259     if (NS_SUCCEEDED(rv)) {
   260       nsAutoString path;
   261       rv = regKey->ReadStringValue(NS_LITERAL_STRING(""), path);
   262       if (NS_SUCCEEDED(rv)) {
   263         GetFileVersion(path.get(), &wmpVer);
   264       }
   265       regKey->Close();
   266     }
   267     if (CompareVersion(wmpVer, minVer) < 0)
   268       return rv;
   270     rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
   271                       NS_LITERAL_STRING("software\\Microsoft\\MediaPlayer"),
   272                       nsIWindowsRegKey::ACCESS_READ);
   273     if (NS_SUCCEEDED(rv)) {
   274       nsAutoString path;
   275       rv = regKey->ReadStringValue(NS_LITERAL_STRING("Installation Directory"),
   276                                    path);
   277       if (NS_SUCCEEDED(rv)) {
   278         rv = NS_NewLocalFile(path, true,
   279                              getter_AddRefs(localFile));
   280       }
   281     }
   282   } else if (nsCRT::strcmp(charProp, NS_WIN_ACROBAT_SCAN_KEY) == 0) {
   283     nsAdoptingCString strVer = Preferences::GetCString(charProp);
   284     if (!strVer) {
   285       return NS_ERROR_FAILURE;
   286     }
   288     verBlock minVer;
   289     TranslateVersionStr(NS_ConvertASCIItoUTF16(strVer).get(), &minVer);
   291     // Look for Adobe Acrobat system installation plugins directory
   292     verBlock maxVer;
   293     ClearVersion(&maxVer);
   295     nsAutoString newestPath;
   297     rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
   298                       NS_LITERAL_STRING("software\\Adobe\\Acrobat Reader"),
   299                       nsIWindowsRegKey::ACCESS_READ);
   300     if (NS_FAILED(rv)) {
   301       rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
   302                         NS_LITERAL_STRING("software\\Adobe\\Adobe Acrobat"),
   303                         nsIWindowsRegKey::ACCESS_READ);
   304       if (NS_FAILED(rv)) {
   305         return NS_ERROR_FAILURE;
   306       }
   307     }
   309     // We must enumerate through the keys because what if there is
   310     // more than one version?
   311     uint32_t childCount = 0;
   312     regKey->GetChildCount(&childCount);
   314     for (uint32_t index = 0; index < childCount; ++index) {
   315       nsAutoString childName;
   316       rv = regKey->GetChildName(index, childName);
   317       if (NS_SUCCEEDED(rv)) {
   318         verBlock curVer;
   319         TranslateVersionStr(childName.get(), &curVer);
   321         childName += NS_LITERAL_STRING("\\InstallPath");
   323         nsCOMPtr<nsIWindowsRegKey> childKey;
   324         rv = regKey->OpenChild(childName, nsIWindowsRegKey::ACCESS_QUERY_VALUE,
   325                                getter_AddRefs(childKey));
   326         if (NS_SUCCEEDED(rv)) {
   327           // We have a sub key
   328           nsAutoString path;
   329           rv = childKey->ReadStringValue(NS_LITERAL_STRING(""), path);
   330           if (NS_SUCCEEDED(rv)) {
   331             if (CompareVersion(curVer, maxVer) >= 0 &&
   332                 CompareVersion(curVer, minVer) >= 0) {
   333               newestPath = path;
   334               CopyVersion(&maxVer, &curVer);
   335             }
   336           }
   337         }
   338       }
   339     }
   341     if (!newestPath.IsEmpty()) {
   342       newestPath += NS_LITERAL_STRING("\\browser");
   343       rv = NS_NewLocalFile(newestPath, true,
   344                            getter_AddRefs(localFile));
   345     }
   346   }
   348   if (NS_FAILED(rv)) {
   349     return rv;
   350   }
   352   localFile.forget(_retval);
   353   return NS_OK;
   354 }
   356 nsresult
   357 nsPluginDirServiceProvider::GetPLIDDirectories(nsISimpleEnumerator **aEnumerator)
   358 {
   359   NS_ENSURE_ARG_POINTER(aEnumerator);
   360   *aEnumerator = nullptr;
   362   nsCOMArray<nsIFile> dirs;
   364   GetPLIDDirectoriesWithRootKey(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, dirs);
   365   GetPLIDDirectoriesWithRootKey(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, dirs);
   367   return NS_NewArrayEnumerator(aEnumerator, dirs);
   368 }
   370 nsresult
   371 nsPluginDirServiceProvider::GetPLIDDirectoriesWithRootKey(uint32_t aKey, nsCOMArray<nsIFile> &aDirs)
   372 {
   373   nsCOMPtr<nsIWindowsRegKey> regKey =
   374     do_CreateInstance("@mozilla.org/windows-registry-key;1");
   375   NS_ENSURE_TRUE(regKey, NS_ERROR_FAILURE);
   377   nsresult rv = regKey->Open(aKey,
   378                              NS_LITERAL_STRING("Software\\MozillaPlugins"),
   379                              nsIWindowsRegKey::ACCESS_READ);
   380   if (NS_FAILED(rv)) {
   381     return rv;
   382   }
   384   uint32_t childCount = 0;
   385   regKey->GetChildCount(&childCount);
   387   for (uint32_t index = 0; index < childCount; ++index) {
   388     nsAutoString childName;
   389     rv = regKey->GetChildName(index, childName);
   390     if (NS_SUCCEEDED(rv)) {
   391       nsCOMPtr<nsIWindowsRegKey> childKey;
   392       rv = regKey->OpenChild(childName, nsIWindowsRegKey::ACCESS_QUERY_VALUE,
   393                              getter_AddRefs(childKey));
   394       if (NS_SUCCEEDED(rv) && childKey) {
   395         nsAutoString path;
   396         rv = childKey->ReadStringValue(NS_LITERAL_STRING("Path"), path);
   397         if (NS_SUCCEEDED(rv)) {
   398           nsCOMPtr<nsIFile> localFile;
   399           if (NS_SUCCEEDED(NS_NewLocalFile(path, true,
   400                                            getter_AddRefs(localFile))) &&
   401               localFile) {
   402             // Some vendors use a path directly to the DLL so chop off
   403             // the filename
   404             bool isDir = false;
   405             if (NS_SUCCEEDED(localFile->IsDirectory(&isDir)) && !isDir) {
   406               nsCOMPtr<nsIFile> temp;
   407               localFile->GetParent(getter_AddRefs(temp));
   408               if (temp)
   409                 localFile = temp;
   410             }
   412             // Now we check to make sure it's actually on disk and
   413             // To see if we already have this directory in the array
   414             bool isFileThere = false;
   415             bool isDupEntry = false;
   416             if (NS_SUCCEEDED(localFile->Exists(&isFileThere)) && isFileThere) {
   417               int32_t c = aDirs.Count();
   418               for (int32_t i = 0; i < c; i++) {
   419                 nsIFile *dup = static_cast<nsIFile*>(aDirs[i]);
   420                 if (dup &&
   421                     NS_SUCCEEDED(dup->Equals(localFile, &isDupEntry)) &&
   422                     isDupEntry) {
   423                   break;
   424                 }
   425               }
   427               if (!isDupEntry) {
   428                 aDirs.AppendObject(localFile);
   429               }
   430             }
   431           }
   432         }
   433       }
   434     }
   435   }
   436   return NS_OK;
   437 }

mercurial