Bug 1279171 - Add Windows Version checks in wmf::MFStartup() and PDMFactory::CreatePDMs(). r=mattwoodrow draft
authorChris Pearce <cpearce@mozilla.com>
Tue, 04 Oct 2016 16:05:53 +1300
changeset 420530 80e9f446a60c7f4edcb1219ec2702e68376e3aa0
parent 420017 955840bfd3c20eb24dd5a01be27bdc55c489a285
child 532835 7338801953a0fc5e913345a3c55fb9c1be053dd3
push id31225
push usercpearce@mozilla.com
push dateTue, 04 Oct 2016 09:12:33 +0000
reviewersmattwoodrow
bugs1279171
milestone52.0a1
Bug 1279171 - Add Windows Version checks in wmf::MFStartup() and PDMFactory::CreatePDMs(). r=mattwoodrow I was able to reproduce the crash in CMFPropertyStore::CreatePropertyStore once when running under Win95 Compatibility mode. Normally Firefox crashes trying to start up under Compatibility mode, so it's hard for me to verify that this patch fixes the crash. We'll just have to push it and see. In compatibility mode, GetVersionEx() returns the Windows version being emulated, so if we add version checks around where we start up WMF, we should catch the users running in compatibility mode. We can also refrain from starting the RemoteDecoderModule if we're not going to be able to use WMF in the GPU process; if we're on Windows less than Vista, or if we're emulating Windows less then Vista. MozReview-Commit-ID: Iu4B1NcgHio
dom/media/platforms/PDMFactory.cpp
dom/media/platforms/wmf/WMFUtils.cpp
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -41,16 +41,20 @@
 #include "AgnosticDecoderModule.h"
 #include "EMEDecoderModule.h"
 
 #include "DecoderDoctorDiagnostics.h"
 
 #include "MP4Decoder.h"
 #include "mozilla/dom/RemoteVideoDecoder.h"
 
+#ifdef XP_WIN
+#include "mozilla/WindowsVersion.h"
+#endif
+
 #include "mp4_demuxer/H264.h"
 
 namespace mozilla {
 
 extern already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule();
 extern already_AddRefed<PlatformDecoderModule> CreateBlankDecoderModule();
 
 class PDMFactoryImpl final {
@@ -313,17 +317,24 @@ PDMFactory::CreatePDMs()
 #ifdef MOZ_WIDGET_ANDROID
   if(MediaPrefs::PDMAndroidMediaCodecPreferred() &&
      MediaPrefs::PDMAndroidMediaCodecEnabled()) {
     m = new AndroidDecoderModule();
     StartupPDM(m);
   }
 #endif
 #ifdef XP_WIN
-  if (MediaPrefs::PDMWMFEnabled()) {
+  if (MediaPrefs::PDMWMFEnabled() && IsVistaOrLater()) {
+    // *Only* use WMF on Vista and later, as if Firefox is run in Windows 95
+    // compatibility mode on Windows 7 (it does happen!) we may crash trying
+    // to startup WMF. So we need to detect the OS version here, as in
+    // compatibility mode IsVistaOrLater() and friends behave as if we're on
+    // the emulated version of Windows. See bug 1279171.
+    // Additionally, we don't want to start the RemoteDecoderModule if we
+    // expect it's not going to work (i.e. on Windows older than Vista).
     m = new WMFDecoderModule();
     RefPtr<PlatformDecoderModule> remote = new dom::RemoteDecoderModule(m);
     mWMFFailedToLoad = !StartupPDM(remote);
     if (mWMFFailedToLoad) {
       mWMFFailedToLoad = !StartupPDM(m);
     }
   } else {
     mWMFFailedToLoad = MediaPrefs::DecoderDoctorWMFDisabledIsFailure();
--- a/dom/media/platforms/wmf/WMFUtils.cpp
+++ b/dom/media/platforms/wmf/WMFUtils.cpp
@@ -197,16 +197,25 @@ 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 (!IsVistaOrLater()) {
+    // *Only* use WMF on Vista and later, as if Firefox is run in Windows 95
+    // compatibility mode on Windows 7 (it does happen!) we may crash trying
+    // to startup WMF. So we need to detect the OS version here, as in
+    // compatibility mode IsVistaOrLater() and friends behave as if we're on
+    // the emulated version of Windows. See bug 1279171.
+    return E_FAIL;
+  }
+
   HRESULT hr = LoadDLLs();
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   const int MF_VISTA_VERSION = (0x0001 << 16 | MF_API_VERSION);
   const int MF_WIN7_VERSION = (0x0002 << 16 | MF_API_VERSION);
 
   // decltype is unusable for functions having default parameters
   DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);