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
--- 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);