Bug 1279171 - Do not use WMF when application is in Windows pre-2000 compatibility mode. draft
authorKilik Kuo <kikuo@mozilla.com>
Thu, 24 Aug 2017 11:46:56 +0800
changeset 658411 ecc1ee63b21bf6d5ed4bdf35159fd28b2d1a9376
parent 651826 d1c70c20e7b52f7295411343e4dc5db8ee7c92b9
child 729643 9b54adb484a74ee820770cf420654e3979388169
push id77758
push userkikuo@mozilla.com
push dateMon, 04 Sep 2017 03:55:39 +0000
bugs1279171
milestone57.0a1
Bug 1279171 - Do not use WMF when application is in Windows pre-2000 compatibility mode. MozReview-Commit-ID: BPiz2WWrshF
dom/media/platforms/PDMFactory.cpp
dom/media/platforms/wmf/WMFUtils.cpp
mfbt/WindowsVersion.h
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -3,16 +3,17 @@
 /* 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 "PDMFactory.h"
 
 #ifdef XP_WIN
 #include "WMFDecoderModule.h"
+#include "mozilla/WindowsVersion.h"
 #endif
 #ifdef MOZ_FFVPX
 #include "FFVPXRuntimeLinker.h"
 #endif
 #ifdef MOZ_FFMPEG
 #include "FFmpegRuntimeLinker.h"
 #endif
 #ifdef MOZ_APPLEMEDIA
@@ -336,17 +337,17 @@ PDMFactory::CreatePDMs()
     StartupPDM(m);
     // The Blank PDM SupportsMimeType reports true for all codecs; the creation
     // of its decoder is infallible. As such it will be used for all media, we
     // can stop creating more PDM from this point.
     return;
   }
 
 #ifdef XP_WIN
-  if (MediaPrefs::PDMWMFEnabled()) {
+  if (MediaPrefs::PDMWMFEnabled() && !IsWin7AndPre2000Compatible()) {
     m = new WMFDecoderModule();
     RefPtr<PlatformDecoderModule> remote = new dom::RemoteDecoderModule(m);
     StartupPDM(remote);
     mWMFFailedToLoad = !StartupPDM(m);
   } else {
     mWMFFailedToLoad = MediaPrefs::DecoderDoctorWMFDisabledIsFailure();
   }
 #endif
--- a/dom/media/platforms/wmf/WMFUtils.cpp
+++ b/dom/media/platforms/wmf/WMFUtils.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/Logging.h"
 #include "mozilla/RefPtr.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsWindowsHelpers.h"
 #include <initguid.h>
 #include <stdint.h>
 #include "mozilla/mscom/EnsureMTA.h"
+#include "mozilla/WindowsVersion.h"
 
 #ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID
 // Some SDK versions don't define the AAC decoder CLSID.
 // {32D186A7-218F-4C75-8876-DD77273A8999}
 DEFINE_GUID(CLSID_CMSAACDecMFT, 0x32D186A7, 0x218F, 0x4C75, 0x88, 0x76, 0xDD, 0x77, 0x27, 0x3A, 0x89, 0x99);
 #endif
 
 namespace mozilla {
@@ -206,16 +207,26 @@ LoadDLLs()
   ENSURE_FUNCTION_PTR_HELPER(FunctionName##Ptr_t, FunctionName, DLL)
 
 #define DECL_FUNCTION_PTR(FunctionName, ...)                                   \
   typedef HRESULT(STDMETHODCALLTYPE* FunctionName##Ptr_t)(__VA_ARGS__)
 
 HRESULT
 MFStartup()
 {
+  if (IsWin7AndPre2000Compatible()) {
+    /*
+     * Specific exclude the usage of WMF on Win 7 with compatibility mode
+     * prior to Win 2000 as we may crash while trying to startup WMF.
+     * Using GetVersionEx API which takes compatibility mode into account.
+     * See Bug 1279171.
+     */
+    return E_FAIL;
+  }
+
   HRESULT hr = LoadDLLs();
   if (FAILED(hr)) {
     return hr;
   }
 
   const int MF_WIN7_VERSION = (0x0002 << 16 | MF_API_VERSION);
 
   // decltype is unusable for functions having default parameters
--- a/mfbt/WindowsVersion.h
+++ b/mfbt/WindowsVersion.h
@@ -153,11 +153,46 @@ IsWin10CreatorsUpdateOrLater()
 }
 
 MOZ_ALWAYS_INLINE bool
 IsNotWin7PreRTM()
 {
   return IsWin7SP1OrLater() || IsWindowsBuildOrLater(7600);
 }
 
+inline bool
+IsWin7AndPre2000Compatible() {
+  /*
+   * See Bug 1279171.
+   * We'd like to avoid using WMF on specific OS version when compatibility
+   * mode is in effect. The purpose of this function is to check if FF runs on
+   * Win7 OS with application compatibility mode being set to 95/98/ME.
+   * Those compatibility mode options (95/98/ME) can only display and
+   * be selected for 32-bit application.
+   * If the compatibility mode is in effect, the GetVersionEx function will
+   * report the OS as it identifies itself, which may not be the OS that is
+   * installed.
+   * Note : 1) We only target for Win7 build number greater than 7600.
+   *        2) GetVersionEx may be altered or unavailable for release after
+   *           Win8.1. Set pragma to avoid build warning as error.
+   */
+  bool isWin7 = IsNotWin7PreRTM() && !IsWin8OrLater();
+  if (!isWin7) {
+    return false;
+  }
+
+  OSVERSIONINFOEX info;
+  ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
+
+  info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+#pragma warning(push)
+#pragma warning(disable:4996)
+  bool success = GetVersionEx((LPOSVERSIONINFO) &info);
+#pragma warning(pop)
+  if (!success) {
+    return false;
+  }
+  return info.dwMajorVersion < 5;
+}
+
 } // namespace mozilla
 
 #endif /* mozilla_WindowsVersion_h */