Bug 925599 - Replace WinUtils::GetWindowsVersion() and GetWindowsServicePackVersion(). r=jimm
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 22 Nov 2013 12:35:42 +0900
changeset 157352 a148cd4445aad2f0d650d55dedc8ce7579098c5c
parent 157351 34be216f6d0e8ef3a51140156a62a807ab315f48
child 157353 01e15a1abbb1442f5db4f33203d8cca0bae4c554
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersjimm
bugs925599
milestone28.0a1
Bug 925599 - Replace WinUtils::GetWindowsVersion() and GetWindowsServicePackVersion(). r=jimm
content/media/directshow/DirectShowDecoder.cpp
content/media/fmp4/MP4Decoder.cpp
content/media/fmp4/wmf/WMFVideoDecoder.cpp
content/media/fmp4/wmf/WMFVideoDecoder.h
content/media/wmf/WMFDecoder.cpp
content/media/wmf/WMFUtils.cpp
widget/windows/KeyboardLayout.cpp
widget/windows/WinMouseScrollHandler.cpp
widget/windows/WinTaskbar.cpp
widget/windows/WinUtils.cpp
widget/windows/WinUtils.h
widget/windows/nsDataObj.cpp
widget/windows/nsFilePicker.cpp
widget/windows/nsLookAndFeel.cpp
widget/windows/nsNativeThemeWin.cpp
widget/windows/nsTextStore.cpp
widget/windows/nsUXThemeData.cpp
widget/windows/nsWindow.cpp
--- a/content/media/directshow/DirectShowDecoder.cpp
+++ b/content/media/directshow/DirectShowDecoder.cpp
@@ -3,19 +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 "DirectShowDecoder.h"
 #include "DirectShowReader.h"
 #include "MediaDecoderStateMachine.h"
 #include "mozilla/Preferences.h"
-#include "WinUtils.h"
-
-using namespace mozilla::widget;
+#include "mozilla/WindowsVersion.h"
 
 namespace mozilla {
 
 MediaDecoderStateMachine* DirectShowDecoder::CreateStateMachine()
 {
   return new MediaDecoderStateMachine(this, new DirectShowReader(this));
 }
 
@@ -42,18 +40,18 @@ DirectShowDecoder::GetSupportedCodecs(co
 
   return false;
 }
 
 /* static */
 bool
 DirectShowDecoder::IsEnabled()
 {
-  return (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) &&
-          Preferences::GetBool("media.directshow.enabled");
+  return !IsVistaOrLater() &&
+         Preferences::GetBool("media.directshow.enabled");
 }
 
 DirectShowDecoder::DirectShowDecoder()
 {
   MOZ_COUNT_CTOR(DirectShowDecoder);
 }
 
 DirectShowDecoder::~DirectShowDecoder()
--- a/content/media/fmp4/MP4Decoder.cpp
+++ b/content/media/fmp4/MP4Decoder.cpp
@@ -5,18 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MP4Decoder.h"
 #include "MP4Reader.h"
 #include "MediaDecoderStateMachine.h"
 #include "mozilla/Preferences.h"
 
 #ifdef XP_WIN
-#include "WinUtils.h"
-using namespace mozilla::widget;
+#include "mozilla/WindowsVersion.h"
 #endif
 
 namespace mozilla {
 
 MediaDecoderStateMachine* MP4Decoder::CreateStateMachine()
 {
   return new MediaDecoderStateMachine(this, new MP4Reader(this));
 }
@@ -67,17 +66,17 @@ MP4Decoder::GetSupportedCodecs(const nsA
 
 static bool
 HavePlatformMPEGDecoders()
 {
   return
     Preferences::GetBool("media.fragmented-mp4.use-blank-decoder") ||
 #ifdef XP_WIN
     // We have H.264/AAC platform decoders on Windows Vista and up.
-    WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ||
+    IsVistaOrLater() ||
 #endif
     // TODO: Other platforms...
     false;
 }
 
 /* static */
 bool
 MP4Decoder::IsEnabled()
--- a/content/media/fmp4/wmf/WMFVideoDecoder.cpp
+++ b/content/media/fmp4/wmf/WMFVideoDecoder.cpp
@@ -6,17 +6,16 @@
 
 #include "WMFVideoDecoder.h"
 #include "MediaDecoderReader.h"
 #include "WMFUtils.h"
 #include "ImageContainer.h"
 #include "VideoUtils.h"
 #include "DXVA2Manager.h"
 #include "nsThreadUtils.h"
-#include "WinUtils.h"
 #include "Layers.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "prlog.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetDemuxerLog();
 #define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
@@ -30,17 +29,16 @@ using mozilla::layers::LayersBackend;
 namespace mozilla {
 
 WMFVideoDecoder::WMFVideoDecoder(bool aDXVAEnabled)
   : mVideoStride(0),
     mVideoWidth(0),
     mVideoHeight(0),
     mLastStreamOffset(0),
     mDXVAEnabled(aDXVAEnabled),
-    mIsRunningOnVista(widget::WinUtils::GetWindowsVersion() == widget::WinUtils::WIN7_VERSION),
     mUseHwAccel(false)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Must be on main thread.");
   MOZ_COUNT_CTOR(WMFVideoDecoder);
 }
 
 WMFVideoDecoder::~WMFVideoDecoder()
 {
--- a/content/media/fmp4/wmf/WMFVideoDecoder.h
+++ b/content/media/fmp4/wmf/WMFVideoDecoder.h
@@ -63,17 +63,16 @@ private:
   // This is used to approximate the decoder's position in the media resource.
   int64_t mLastStreamOffset;
 
   nsAutoPtr<MFTDecoder> mDecoder;
   RefPtr<layers::ImageContainer> mImageContainer;
   nsAutoPtr<DXVA2Manager> mDXVA2Manager;
 
   const bool mDXVAEnabled;
-  const bool mIsRunningOnVista;
   bool mUseHwAccel;
 };
 
 
 
 } // namespace mozilla
 
 #endif
\ No newline at end of file
--- a/content/media/wmf/WMFDecoder.cpp
+++ b/content/media/wmf/WMFDecoder.cpp
@@ -5,25 +5,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WMF.h"
 #include "WMFDecoder.h"
 #include "WMFReader.h"
 #include "WMFUtils.h"
 #include "MediaDecoderStateMachine.h"
 #include "mozilla/Preferences.h"
-#include "WinUtils.h"
+#include "mozilla/WindowsVersion.h"
 #include "nsCharSeparatedTokenizer.h"
 
 #ifdef MOZ_DIRECTSHOW
 #include "DirectShowDecoder.h"
 #endif
 
-using namespace mozilla::widget;
-
 namespace mozilla {
 
 MediaDecoderStateMachine* WMFDecoder::CreateStateMachine()
 {
   return new MediaDecoderStateMachine(this, new WMFReader(this));
 }
 
 /* static */
@@ -33,31 +31,25 @@ WMFDecoder::IsMP3Supported()
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
 #ifdef MOZ_DIRECTSHOW
   if (DirectShowDecoder::IsEnabled()) {
     // DirectShowDecoder is enabled, we use that in preference to the WMF
     // backend.
     return false;
   }
 #endif
- if (!MediaDecoder::IsWMFEnabled()) {
+  if (!MediaDecoder::IsWMFEnabled()) {
     return false;
   }
-  if (WinUtils::GetWindowsVersion() != WinUtils::WIN7_VERSION) {
+  if (!IsWin7OrLater()) {
     return true;
   }
-  // We're on Windows 7. MP3 support is disabled if no service pack
+  // MP3 support is disabled if we're on Windows 7 and no service pack
   // is installed, as it's crashy on Win7 SP0.
-  UINT spMajorVer = 0, spMinorVer = 0;
-  if (!WinUtils::GetWindowsServicePackVersion(spMajorVer, spMinorVer)) {
-    // Um... We can't determine the service pack version... Just block
-    // MP3 as a precaution...
-    return false;
-  }
-  return spMajorVer != 0;
+  return IsWin7SP1OrLater();
 }
 
 static bool
 IsSupportedH264Codec(const nsAString& aCodec)
 {
   // According to the WMF documentation:
   // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
   // "The Media Foundation H.264 video decoder is a Media Foundation Transform
@@ -158,14 +150,14 @@ WMFDecoder::UnloadDLLs()
   wmf::UnloadDLLs();
 }
 
 /* static */
 bool
 WMFDecoder::IsEnabled()
 {
   // We only use WMF on Windows Vista and up
-  return WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
+  return IsVistaOrLater() &&
          Preferences::GetBool("media.windows-media-foundation.enabled");
 }
 
 } // namespace mozilla
 
--- a/content/media/wmf/WMFUtils.cpp
+++ b/content/media/wmf/WMFUtils.cpp
@@ -2,25 +2,23 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "WMFUtils.h"
 #include <stdint.h>
 #include "mozilla/RefPtr.h"
+#include "mozilla/WindowsVersion.h"
 #include "prlog.h"
 #include "nsThreadUtils.h"
-#include "WinUtils.h"
 #include "nsWindowsHelpers.h"
 #include "mozilla/CheckedInt.h"
 #include "VideoUtils.h"
 
-using namespace mozilla::widget;
-
 #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 {
 
@@ -505,17 +503,17 @@ UnloadDLLs()
 HRESULT
 MFStartup()
 {
   const int MF_VISTA_VERSION = (0x0001 << 16 | MF_API_VERSION);
   const int MF_WIN7_VERSION = (0x0002 << 16 | MF_API_VERSION);
 
   DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
   ENSURE_FUNCTION_PTR(MFStartup, Mfplat.dll)
-  if (WinUtils::GetWindowsVersion() == WinUtils::VISTA_VERSION)
+  if (!IsWin7OrLater())
     return MFStartupPtr(MF_VISTA_VERSION, MFSTARTUP_FULL);
   else
     return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
 }
 
 HRESULT
 MFShutdown()
 {
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -2,16 +2,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 "mozilla/DebugOnly.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/Util.h"
+#include "mozilla/WindowsVersion.h"
 
 #include "KeyboardLayout.h"
 #include "nsIMM32Handler.h"
 
 #include "nsMemory.h"
 #include "nsToolkit.h"
 #include "nsQuickSort.h"
 #include "nsAlgorithm.h"
@@ -576,17 +577,17 @@ NativeKey::NativeKey(nsWindowBase* aWidg
   MOZ_ASSERT(aWidget);
   KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
   mKeyboardLayout = keyboardLayout->GetLayout();
   mScanCode = WinUtils::GetScanCode(mMsg.lParam);
   mIsExtended = WinUtils::IsExtendedScanCode(mMsg.lParam);
   // On WinXP and WinServer2003, we cannot compute the virtual keycode for
   // extended keys due to the API limitation.
   bool canComputeVirtualKeyCodeFromScanCode =
-    (!mIsExtended || WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION);
+    (!mIsExtended || IsVistaOrLater());
   switch (mMsg.message) {
     case WM_KEYDOWN:
     case WM_SYSKEYDOWN:
     case WM_KEYUP:
     case WM_SYSKEYUP: {
       // First, resolve the IME converted virtual keycode to its original
       // keycode.
       if (mMsg.wParam == VK_PROCESSKEY) {
@@ -804,18 +805,17 @@ NativeKey::IsIMEDoingKakuteiUndo() const
 UINT
 NativeKey::GetScanCodeWithExtendedFlag() const
 {
   // MapVirtualKeyEx() has been improved for supporting extended keys since
   // Vista.  When we call it for mapping a scancode of an extended key and
   // a virtual keycode, we need to add 0xE000 to the scancode.
   // On Win XP and Win Server 2003, this doesn't support. On them, we have
   // no way to get virtual keycodes from scancode of extended keys.
-  if (!mIsExtended ||
-      WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
+  if (!mIsExtended || !IsVistaOrLater()) {
     return mScanCode;
   }
   return (0xE000 | mScanCode);
 }
 
 uint32_t
 NativeKey::GetKeyLocation() const
 {
@@ -887,21 +887,19 @@ NativeKey::ComputeVirtualKeyCodeFromScan
 {
   return static_cast<uint8_t>(
            ::MapVirtualKeyEx(mScanCode, MAPVK_VSC_TO_VK, mKeyboardLayout));
 }
 
 uint8_t
 NativeKey::ComputeVirtualKeyCodeFromScanCodeEx() const
 {
-  bool VistaOrLater =
-    (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION);
   // NOTE: WinXP doesn't support mapping scan code to virtual keycode of
   //       extended keys.
-  NS_ENSURE_TRUE(!mIsExtended || VistaOrLater, 0);
+  NS_ENSURE_TRUE(!mIsExtended || IsVistaOrLater(), 0);
   return static_cast<uint8_t>(
            ::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(), MAPVK_VSC_TO_VK_EX,
                              mKeyboardLayout));
 }
 
 PRUnichar
 NativeKey::ComputeUnicharFromScanCode() const
 {
--- a/widget/windows/WinMouseScrollHandler.cpp
+++ b/widget/windows/WinMouseScrollHandler.cpp
@@ -18,16 +18,17 @@
 #include "WinUtils.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDOMWheelEvent.h"
 
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/WindowsVersion.h"
 
 #include <psapi.h>
 
 namespace mozilla {
 namespace widget {
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gMouseScrollLog = nullptr;
@@ -943,17 +944,17 @@ MouseScrollHandler::SystemSettings::Init
       ("MouseScroll::SystemSettings::Init(): mScrollChars is overridden by "
        "the pref: %d",
        mScrollChars));
   } else if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0,
                                      &mScrollChars, 0)) {
     PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
       ("MouseScroll::SystemSettings::Init(): ::SystemParametersInfo("
          "SPI_GETWHEELSCROLLCHARS) failed, %s",
-       WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
+       IsVistaOrLater() ?
          "this is unexpected on Vista or later" :
          "but on XP or earlier, this is not a problem"));
     mScrollChars = 1;
   }
 
   if (mScrollChars > WHEEL_DELTA) {
     PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
       ("MouseScroll::SystemSettings::Init(): the result of "
--- a/widget/windows/WinTaskbar.cpp
+++ b/widget/windows/WinTaskbar.cpp
@@ -23,16 +23,17 @@
 #include "WinUtils.h"
 #include "TaskbarTabPreview.h"
 #include "TaskbarWindowPreview.h"
 #include "JumpListBuilder.h"
 #include "nsWidgetsCID.h"
 #include "nsPIDOMWindow.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/WindowsVersion.h"
 #include <io.h>
 #include <propvarutil.h>
 #include <propkey.h>
 #include <shellapi.h>
 
 const PRUnichar kShellLibraryName[] =  L"shell32.dll";
 
 static NS_DEFINE_CID(kJumpListBuilderCID, NS_WIN_JUMPLISTBUILDER_CID);
@@ -325,17 +326,17 @@ WinTaskbar::GetDefaultGroupId(nsAString 
     return NS_ERROR_UNEXPECTED;
 
   return NS_OK;
 }
 
 // (static) Called from AppShell
 bool
 WinTaskbar::RegisterAppUserModelID() {
-  if (WinUtils::GetWindowsVersion() < WinUtils::WIN7_VERSION)
+  if (!IsWin7OrLater())
     return false;
 
   if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro) {
     return false;
   }
 
   SetCurrentProcessExplicitAppUserModelIDPtr funcAppUserModelID = nullptr;
   bool retVal = false;
@@ -360,19 +361,17 @@ WinTaskbar::RegisterAppUserModelID() {
   if (hDLL)
     ::FreeLibrary(hDLL);
 
   return retVal;
 }
 
 NS_IMETHODIMP
 WinTaskbar::GetAvailable(bool *aAvailable) {
-  *aAvailable = 
-    WinUtils::GetWindowsVersion() < WinUtils::WIN7_VERSION ?
-    false : true;
+  *aAvailable = IsWin7OrLater();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WinTaskbar::CreateTaskbarTabPreview(nsIDocShell *shell, nsITaskbarPreviewController *controller, nsITaskbarTabPreview **_retval) {
   if (!Initialize())
     return NS_ERROR_NOT_AVAILABLE;
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WinUtils.h"
 #include "nsWindow.h"
 #include "nsWindowDefs.h"
 #include "KeyboardLayout.h"
 #include "nsIDOMMouseEvent.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/WindowsVersion.h"
 
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif // MOZ_LOGGING
 #include "prlog.h"
 
 #include "nsString.h"
 #include "nsDirectoryServiceUtils.h"
@@ -84,69 +85,33 @@ WinUtils::DwmGetCompositionTimingInfoPro
 void
 WinUtils::Initialize()
 {
 #ifdef PR_LOGGING
   if (!gWindowsLog) {
     gWindowsLog = PR_NewLogModule("Widget");
   }
 #endif
-  if (!sDwmDll && WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+  if (!sDwmDll && IsVistaOrLater()) {
     sDwmDll = ::LoadLibraryW(kDwmLibraryName);
 
     if (sDwmDll) {
       dwmExtendFrameIntoClientAreaPtr = (DwmExtendFrameIntoClientAreaProc)::GetProcAddress(sDwmDll, "DwmExtendFrameIntoClientArea");
       dwmIsCompositionEnabledPtr = (DwmIsCompositionEnabledProc)::GetProcAddress(sDwmDll, "DwmIsCompositionEnabled");
       dwmSetIconicThumbnailPtr = (DwmSetIconicThumbnailProc)::GetProcAddress(sDwmDll, "DwmSetIconicThumbnail");
       dwmSetIconicLivePreviewBitmapPtr = (DwmSetIconicLivePreviewBitmapProc)::GetProcAddress(sDwmDll, "DwmSetIconicLivePreviewBitmap");
       dwmGetWindowAttributePtr = (DwmGetWindowAttributeProc)::GetProcAddress(sDwmDll, "DwmGetWindowAttribute");
       dwmSetWindowAttributePtr = (DwmSetWindowAttributeProc)::GetProcAddress(sDwmDll, "DwmSetWindowAttribute");
       dwmInvalidateIconicBitmapsPtr = (DwmInvalidateIconicBitmapsProc)::GetProcAddress(sDwmDll, "DwmInvalidateIconicBitmaps");
       dwmDwmDefWindowProcPtr = (DwmDefWindowProcProc)::GetProcAddress(sDwmDll, "DwmDefWindowProc");
       dwmGetCompositionTimingInfoPtr = (DwmGetCompositionTimingInfoProc)::GetProcAddress(sDwmDll, "DwmGetCompositionTimingInfo");
     }
   }
 }
 
-/* static */ 
-WinUtils::WinVersion
-WinUtils::GetWindowsVersion()
-{
-  static int32_t version = 0;
-
-  if (version) {
-    return static_cast<WinVersion>(version);
-  }
-
-  OSVERSIONINFOEX osInfo;
-  osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-  // This cast is safe and supposed to be here, don't worry
-  ::GetVersionEx((OSVERSIONINFO*)&osInfo);
-  version =
-    (osInfo.dwMajorVersion & 0xff) << 8 | (osInfo.dwMinorVersion & 0xff);
-  return static_cast<WinVersion>(version);
-}
-
-/* static */
-bool
-WinUtils::GetWindowsServicePackVersion(UINT& aOutMajor, UINT& aOutMinor)
-{
-  OSVERSIONINFOEX osInfo;
-  osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-  // This cast is safe and supposed to be here, don't worry
-  if (!::GetVersionEx((OSVERSIONINFO*)&osInfo)) {
-    return false;
-  }
-  
-  aOutMajor = osInfo.wServicePackMajor;
-  aOutMinor = osInfo.wServicePackMinor;
-
-  return true;
-}
-
 // static
 void
 WinUtils::LogW(const wchar_t *fmt, ...)
 {
   va_list args = nullptr;
   if(!lstrlenW(fmt)) {
     return;
   }
--- a/widget/windows/WinUtils.h
+++ b/widget/windows/WinUtils.h
@@ -64,30 +64,16 @@ class myDownloadObserver MOZ_FINAL : pub
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOWNLOADOBSERVER
 };
 
 class WinUtils {
 public:
-  enum WinVersion {
-    WINXP_VERSION     = 0x501,
-    WIN2K3_VERSION    = 0x502,
-    VISTA_VERSION     = 0x600,
-    WIN7_VERSION      = 0x601,
-    WIN8_VERSION      = 0x602,
-    WIN8_1_VERSION    = 0x603
-  };
-  static WinVersion GetWindowsVersion();
-
-  // Retrieves the Service Pack version number.
-  // Returns true on success, false on failure.
-  static bool GetWindowsServicePackVersion(UINT& aOutMajor, UINT& aOutMinor);
-
   /**
    * Logging helpers that dump output to prlog module 'Widget', console, and
    * OutputDebugString. Note these output in both debug and release builds.
    */
   static void Log(const char *fmt, ...);
   static void LogW(const wchar_t *fmt, ...);
 
   /**
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.cpp
@@ -27,16 +27,17 @@
 #include "nscore.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsITimer.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Preferences.h"
 
 #include "WinUtils.h"
 #include "mozilla/LazyIdleThread.h"
+#include "mozilla/WindowsVersion.h"
 #include <algorithm>
 
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 #define DEFAULT_THREAD_TIMEOUT_MS 30000
 
@@ -1110,17 +1111,17 @@ nsDataObj :: GetFileContentsInternetShor
   nsCOMPtr<nsIFile> icoFile;
   nsCOMPtr<nsIURI> aUri;
   NS_NewURI(getter_AddRefs(aUri), url);
 
   const char *shortcutFormatStr;
   int totalLen;
   nsCString path;
   if (!Preferences::GetBool(kShellIconPref, true) ||
-      WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
+      !IsVistaOrLater()) {
     shortcutFormatStr = "[InternetShortcut]\r\nURL=%s\r\n";
     const int formatLen = strlen(shortcutFormatStr) - 2;  // don't include %s
     totalLen = formatLen + asciiUrl.Length();  // don't include null character
   } else {
     nsCOMPtr<nsIFile> icoFile;
     nsCOMPtr<nsIURI> aUri;
     NS_NewURI(getter_AddRefs(aUri), url);
 
--- a/widget/windows/nsFilePicker.cpp
+++ b/widget/windows/nsFilePicker.cpp
@@ -5,32 +5,34 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsFilePicker.h"
 
 #include <shlobj.h>
 #include <shlwapi.h>
 #include <cderr.h>
 
+#include "mozilla/WindowsVersion.h"
 #include "nsReadableUtils.h"
 #include "nsNetUtil.h"
 #include "nsWindow.h"
 #include "nsILoadContext.h"
 #include "nsIServiceManager.h"
 #include "nsIPlatformCharset.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIURL.h"
 #include "nsIStringBundle.h"
 #include "nsEnumeratorUtils.h"
 #include "nsCRT.h"
 #include "nsString.h"
 #include "nsToolkit.h"
 #include "WinUtils.h"
 #include "nsPIDOMWindow.h"
 
+using mozilla::IsVistaOrLater;
 using namespace mozilla::widget;
 
 PRUnichar *nsFilePicker::mLastUsedUnicodeDirectory;
 char nsFilePicker::mLastUsedDirectory[MAX_PATH+1] = { 0 };
 
 static const PRUnichar kDialogPtrProp[] = L"DialogPtrProperty";
 static const DWORD kDialogTimerID = 9999;
 static const unsigned long kDialogTimerTimeout = 300;
@@ -684,17 +686,17 @@ nsFilePicker::ShowXPFilePicker(const nsS
   ofn.Flags = OFN_SHAREAWARE | OFN_LONGNAMES | OFN_OVERWRITEPROMPT |
               OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | 
               OFN_EXPLORER;
 
   // Windows Vista and up won't allow you to use the new looking dialogs with
   // a hook procedure.  The hook procedure fixes a problem on XP dialogs for
   // file picker visibility.  Vista and up automatically ensures the file 
   // picker is always visible.
-  if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
+  if (!IsVistaOrLater()) {
     ofn.lpfnHook = FilePickerHook;
     ofn.Flags |= OFN_ENABLEHOOK;
   }
 
   // Handle add to recent docs settings
   if (IsPrivacyModeEnabled() || !mAddToRecentDocs) {
     ofn.Flags |= OFN_DONTADDTORECENT;
   }
@@ -743,17 +745,17 @@ nsFilePicker::ShowXPFilePicker(const nsS
       // value of ofn.lpstrFile and deallocate the old buffer that it pointed
       // to (fileBuffer). The hook assumes that the passed in value is heap 
       // allocated and that the returned value should be freed by the caller.
       // If the hook changes the buffer, it will deallocate the old buffer.
       // This fix would be nice to have in Vista and up, but it would force
       // the file picker to use the old style dialogs because hooks are not
       // allowed in the new file picker UI.  We need to eventually move to
       // the new Common File Dialogs for Vista and up.
-      if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
+      if (!IsVistaOrLater()) {
         ofn.lpfnHook = MultiFilePickerHook;
         fileBuffer.forget();
         result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
         fileBuffer = ofn.lpstrFile;
       } else {
         result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
       }
       break;
@@ -1042,22 +1044,22 @@ nsFilePicker::ShowW(int16_t *aReturnVal)
 
   // Launch the XP file/folder picker on XP and as a fallback on Vista+. 
   // The CoCreateInstance call to CLSID_FileOpenDialog fails with "(0x80040111)
   // ClassFactory cannot supply requested class" when the checkbox for
   // Disable Visual Themes is on in the compatability tab within the shortcut
   // properties.
   bool result = false, wasInitError = true;
   if (mMode == modeGetFolder) {
-    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION)
+    if (IsVistaOrLater())
       result = ShowFolderPicker(initialDir, wasInitError);
     if (!result && wasInitError)
       result = ShowXPFolderPicker(initialDir);
   } else {
-    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION)
+    if (IsVistaOrLater())
       result = ShowFilePicker(initialDir, wasInitError);
     if (!result && wasInitError)
       result = ShowXPFilePicker(initialDir);
   }
 
   // exit, and return returnCancel in aReturnVal
   if (!result)
     return NS_OK;
@@ -1239,17 +1241,17 @@ nsFilePicker::AppendXPFilter(const nsASt
   }
 
   mFilterList.Append(PRUnichar('\0'));
 }
 
 NS_IMETHODIMP
 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
 {
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+  if (IsVistaOrLater()) {
     mComFilterList.Append(aTitle, aFilter);
   } else {
     AppendXPFilter(aTitle, aFilter);
   }
   return NS_OK;
 }
 
 void
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -6,22 +6,51 @@
 #include "nsLookAndFeel.h"
 #include <windows.h>
 #include <shellapi.h>
 #include "nsStyleConsts.h"
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 #include "gfxFont.h"
 #include "gfxWindowsPlatform.h"
-#include "WinUtils.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/WindowsVersion.h"
 #include "gfxFontConstants.h"
 
+using namespace mozilla;
 using namespace mozilla::widget;
-using mozilla::LookAndFeel;
+
+enum WinVersion {
+  WINXP_VERSION     = 0x501,
+  WIN2K3_VERSION    = 0x502,
+  VISTA_VERSION     = 0x600,
+  WIN7_VERSION      = 0x601,
+  WIN8_VERSION      = 0x602,
+  WIN8_1_VERSION    = 0x603
+};
+
+static WinVersion GetWindowsVersion()
+{
+  static int32_t version = 0;
+
+  if (version) {
+    return static_cast<WinVersion>(version);
+  }
+
+  OSVERSIONINFOEX osInfo;
+  osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+  // This cast is safe and supposed to be here, don't worry
+#pragma warning(push)
+#pragma warning(disable:4996)
+  ::GetVersionEx((OSVERSIONINFO*)&osInfo);
+#pragma warning(pop)
+  version =
+    (osInfo.dwMajorVersion & 0xff) << 8 | (osInfo.dwMinorVersion & 0xff);
+  return static_cast<WinVersion>(version);
+}
 
 static nsresult GetColorFromTheme(nsUXThemeClass cls,
                            int32_t aPart,
                            int32_t aState,
                            int32_t aPropId,
                            nscolor &aColor)
 {
   COLORREF color;
@@ -163,28 +192,26 @@ nsLookAndFeel::NativeGetColor(ColorID aI
       idx = COLOR_GRAYTEXT;
       break;
     case eColorID_highlight:
     case eColorID__moz_html_cellhighlight:
     case eColorID__moz_menuhover:
       idx = COLOR_HIGHLIGHT;
       break;
     case eColorID__moz_menubarhovertext:
-      if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ||
-          !IsAppThemed())
+      if (!IsVistaOrLater() || !IsAppThemed())
       {
         idx = nsUXThemeData::sFlatMenus ?
                 COLOR_HIGHLIGHTTEXT :
                 COLOR_MENUTEXT;
         break;
       }
       // Fall through
     case eColorID__moz_menuhovertext:
-      if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
-          IsAppThemed())
+      if (IsVistaOrLater() && IsAppThemed())
       {
         res = ::GetColorFromTheme(eUXMenu,
                                   MENU_POPUPITEM, MPI_HOT, TMT_TEXTCOLOR, aColor);
         if (NS_SUCCEEDED(res))
           return res;
         // fall through to highlight case
       }
     case eColorID_highlighttext:
@@ -250,29 +277,27 @@ nsLookAndFeel::NativeGetColor(ColorID aI
     case eColorID__moz_comboboxtext:
       idx = COLOR_WINDOWTEXT;
       break;
     case eColorID__moz_dialog:
     case eColorID__moz_cellhighlight:
       idx = COLOR_3DFACE;
       break;
     case eColorID__moz_win_mediatext:
-      if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
-          IsAppThemed()) {
+      if (IsVistaOrLater() && IsAppThemed()) {
         res = ::GetColorFromTheme(eUXMediaToolbar,
                                   TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
         if (NS_SUCCEEDED(res))
           return res;
       }
       // if we've gotten here just return -moz-dialogtext instead
       idx = COLOR_WINDOWTEXT;
       break;
     case eColorID__moz_win_communicationstext:
-      if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
-          IsAppThemed())
+      if (IsVistaOrLater() && IsAppThemed())
       {
         res = ::GetColorFromTheme(eUXCommunicationsToolbar,
                                   TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
         if (NS_SUCCEEDED(res))
           return res;
       }
       // if we've gotten here just return -moz-dialogtext instead
       idx = COLOR_WINDOWTEXT;
@@ -387,28 +412,28 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
         aResult = nsUXThemeData::IsDefaultWindowTheme();
         break;
     case eIntID_WindowsThemeIdentifier:
         aResult = nsUXThemeData::GetNativeThemeId();
         break;
 
     case eIntID_OperatingSystemVersionIdentifier:
     {
-        switch(WinUtils::GetWindowsVersion()) {
-            case WinUtils::WINXP_VERSION:
-            case WinUtils::WIN2K3_VERSION:
+        switch (GetWindowsVersion()) {
+            case WINXP_VERSION:
+            case WIN2K3_VERSION:
                 aResult = LookAndFeel::eOperatingSystemVersion_WindowsXP;
                 break;
-            case WinUtils::VISTA_VERSION:
+            case VISTA_VERSION:
                 aResult = LookAndFeel::eOperatingSystemVersion_WindowsVista;
                 break;
-            case WinUtils::WIN7_VERSION:
+            case WIN7_VERSION:
                 aResult = LookAndFeel::eOperatingSystemVersion_Windows7;
                 break;
-            case WinUtils::WIN8_VERSION:
+            case WIN8_VERSION:
                 aResult = LookAndFeel::eOperatingSystemVersion_Windows8;
                 break;
             default:
                 aResult = LookAndFeel::eOperatingSystemVersion_Unknown;
                 break;
         }
         break;
     }
@@ -418,18 +443,17 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
         aResult = 0;
         res = NS_ERROR_NOT_IMPLEMENTED;
         break;
     case eIntID_DWMCompositor:
         aResult = nsUXThemeData::CheckForCompositor();
         break;
     case eIntID_WindowsGlass:
         // Aero Glass is only available prior to Windows 8 when DWM is used.
-        aResult = (nsUXThemeData::CheckForCompositor() &&
-                   WinUtils::GetWindowsVersion() < WinUtils::WIN8_VERSION);
+        aResult = (nsUXThemeData::CheckForCompositor() && !IsWin8OrLater());
         break;
     case eIntID_AlertNotificationOrigin:
         aResult = 0;
         {
           // Get task bar window handle
           HWND shellWindow = FindWindowW(L"Shell_TrayWnd", nullptr);
 
           if (shellWindow != nullptr)
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 40; 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 <windows.h>
 #include "nsNativeThemeWin.h"
+#include "mozilla/WindowsVersion.h"
 #include "nsRenderingContext.h"
 #include "nsRect.h"
 #include "nsSize.h"
 #include "nsTransform2D.h"
 #include "nsThemeConstants.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
@@ -19,30 +19,29 @@
 #include "nsIDOMHTMLInputElement.h"
 #include "nsLookAndFeel.h"
 #include "nsMenuFrame.h"
 #include "nsGkAtoms.h"
 #include <malloc.h>
 #include "nsWindow.h"
 #include "nsIComboboxControlFrame.h"
 #include "prinrval.h"
-#include "WinUtils.h"
 
 #include "gfxPlatform.h"
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "gfxWindowsPlatform.h"
 #include "gfxWindowsSurface.h"
 #include "gfxWindowsNativeDrawing.h"
 
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 #include <algorithm>
 
-using namespace mozilla::widget;
+using mozilla::IsVistaOrLater;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gWindowsLog;
 #endif
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeWin, nsNativeTheme, nsITheme)
 
 nsNativeThemeWin::nsNativeThemeWin() :
@@ -345,32 +344,32 @@ static CaptionButtonPadding buttonData[3
 // Adds "hot" caption button padding to minimum widget size.
 static void
 AddPaddingRect(nsIntSize* aSize, CaptionButton button) {
   if (!aSize)
     return;
   RECT offset;
   if (!IsAppThemed())
     offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
-  else if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION)
+  else if (!IsVistaOrLater())
     offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
   else
     offset = buttonData[CAPTION_BASIC].hotPadding[button];
   aSize->width += offset.left + offset.right;
   aSize->height += offset.top + offset.bottom;
 }
 
 // If we've added padding to the minimum widget size, offset
 // the area we draw into to compensate.
 static void
 OffsetBackgroundRect(RECT& rect, CaptionButton button) {
   RECT offset;
   if (!IsAppThemed())
     offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
-  else if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION)
+  else if (!IsVistaOrLater())
     offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
   else
     offset = buttonData[CAPTION_BASIC].hotPadding[button];
   rect.left += offset.left;
   rect.top += offset.top;
   rect.right -= offset.right;
   rect.bottom -= offset.bottom;
 }
@@ -424,37 +423,37 @@ static const int32_t kProgressClassicOve
 /*
  * GetProgressOverlayStyle - returns the proper overlay part for themed
  * progress bars based on os and orientation.
  */
 static int32_t
 GetProgressOverlayStyle(bool aIsVertical)
 { 
   if (aIsVertical) {
-    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+    if (IsVistaOrLater()) {
       return PP_MOVEOVERLAYVERT;
     }
     return PP_CHUNKVERT;
   } else {
-    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+    if (IsVistaOrLater()) {
       return PP_MOVEOVERLAY;
     }
     return PP_CHUNK;
   }
 }
 
 /*
  * GetProgressOverlaySize - returns the minimum width or height for themed
  * progress bar overlays. This includes the width of indeterminate chunks
  * and vista pulse overlays.
  */
 static int32_t
 GetProgressOverlaySize(bool aIsVertical, bool aIsIndeterminate)
 {
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+  if (IsVistaOrLater()) {
     if (aIsVertical) {
       return aIsIndeterminate ? kProgressVerticalIndeterminateOverlaySize
                               : kProgressVerticalOverlaySize;
     }
     return kProgressHorizontalVistaOverlaySize;
   }
   return kProgressHorizontalXPOverlaySize;
 }
@@ -652,17 +651,17 @@ nsNativeThemeWin::DrawThemedProgressMete
     return;
 
   NS_ASSERTION(aWidgetRect, "bad rect pointer");
   NS_ASSERTION(aClipRect, "bad clip rect pointer");
 
   RECT adjWidgetRect, adjClipRect;
   adjWidgetRect = *aWidgetRect;
   adjClipRect = *aClipRect;
-  if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
+  if (!IsVistaOrLater()) {
     // Adjust clipping out by one pixel. XP progress meters are inset,
     // Vista+ are not.
     InflateRect(&adjWidgetRect, 1, 1);
     InflateRect(&adjClipRect, 1, 1);
   }
 
   nsIFrame* parentFrame = aFrame->GetParent();
   if (!parentFrame) {
@@ -672,17 +671,17 @@ nsNativeThemeWin::DrawThemedProgressMete
   }
 
   nsEventStates eventStates = GetContentState(parentFrame, aWidgetType);
   bool vertical = IsVerticalProgress(parentFrame) ||
                   aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL;
   bool indeterminate = IsIndeterminateProgress(parentFrame, eventStates);
   bool animate = indeterminate;
 
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+  if (IsVistaOrLater()) {
     // Vista and up progress meter is fill style, rendered here. We render
     // the pulse overlay in the follow up section below.
     DrawThemeBackground(aTheme, aHdc, aPart, aState,
                         &adjWidgetRect, &adjClipRect);
     if (!IsProgressMeterFilled(aFrame)) {
       animate = true;
     }
   } else if (!indeterminate) {
@@ -693,17 +692,17 @@ nsNativeThemeWin::DrawThemedProgressMete
   }    
 
   if (animate) {
     // Indeterminate rendering
     int32_t overlayPart = GetProgressOverlayStyle(vertical);
     RECT overlayRect =
       CalculateProgressOverlayRect(aFrame, &adjWidgetRect, vertical,
                                    indeterminate, false);
-    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+    if (IsVistaOrLater()) {
       DrawThemeBackground(aTheme, aHdc, overlayPart, aState, &overlayRect,
                           &adjClipRect);
     } else {
       DrawChunkProgressMeter(aTheme, aHdc, overlayPart, aState, aFrame,
                              &overlayRect, &adjClipRect, aAppUnits,
                              indeterminate, vertical, IsFrameRTL(aFrame));
     }
 
@@ -711,17 +710,17 @@ nsNativeThemeWin::DrawThemedProgressMete
       NS_WARNING("unable to animate progress widget!");
     }
   }
 }
 
 HANDLE
 nsNativeThemeWin::GetTheme(uint8_t aWidgetType)
 { 
-  if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
+  if (!IsVistaOrLater()) {
     // On XP or earlier, render dropdowns as textfields;
     // doing it the right way works fine with the MS themes,
     // but breaks on a lot of custom themes (presumably because MS
     // apps do the textfield border business as well).
     if (aWidgetType == NS_THEME_DROPDOWN)
       aWidgetType = NS_THEME_TEXTFIELD;
   }
 
@@ -731,17 +730,17 @@ nsNativeThemeWin::GetTheme(uint8_t aWidg
     case NS_THEME_CHECKBOX:
     case NS_THEME_GROUPBOX:
       return nsUXThemeData::GetTheme(eUXButton);
     case NS_THEME_TEXTFIELD:
     case NS_THEME_TEXTFIELD_MULTILINE:
       return nsUXThemeData::GetTheme(eUXEdit);
     case NS_THEME_TOOLTIP:
       // XP/2K3 should force a classic treatment of tooltips
-      return WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ?
+      return !IsVistaOrLater() ?
         nullptr : nsUXThemeData::GetTheme(eUXTooltip);
     case NS_THEME_TOOLBOX:
       return nsUXThemeData::GetTheme(eUXRebar);
     case NS_THEME_WIN_MEDIA_TOOLBOX:
       return nsUXThemeData::GetTheme(eUXMediaRebar);
     case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX:
       return nsUXThemeData::GetTheme(eUXCommunicationsRebar);
     case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX:
@@ -859,17 +858,17 @@ nsNativeThemeWin::IsMenuActive(nsIFrame 
  * us; 0 means that we should use part code 0, which isn't a real part code
  * but elicits some kind of default behaviour from UXTheme when drawing
  * (but isThemeBackgroundPartiallyTransparent may not work).
  */
 nsresult 
 nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, 
                                        int32_t& aPart, int32_t& aState)
 {
-  if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
+  if (!IsVistaOrLater()) {
     // See GetTheme
     if (aWidgetType == NS_THEME_DROPDOWN)
       aWidgetType = NS_THEME_TEXTFIELD;
   }
 
   switch (aWidgetType) {
     case NS_THEME_BUTTON: {
       aPart = BP_BUTTON;
@@ -936,17 +935,17 @@ nsNativeThemeWin::GetThemePartAndState(n
       // Since we don't support groupbox disabled and GBS_DISABLED looks the
       // same as GBS_NORMAL don't bother supporting GBS_DISABLED.
       return NS_OK;
     }
     case NS_THEME_TEXTFIELD:
     case NS_THEME_TEXTFIELD_MULTILINE: {
       nsEventStates eventState = GetContentState(aFrame, aWidgetType);
 
-      if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+      if (IsVistaOrLater()) {
         /* Note: the NOSCROLL type has a rounded corner in each
          * corner.  The more specific HSCROLL, VSCROLL, HVSCROLL types
          * have side and/or top/bottom edges rendered as straight
          * horizontal lines with sharp corners to accommodate a
          * scrollbar.  However, the scrollbar gets rendered on top of
          * this for us, so we don't care, and can just use NOSCROLL
          * here.
          */
@@ -1006,20 +1005,20 @@ nsNativeThemeWin::GetThemePartAndState(n
       return NS_OK;
     }
     case NS_THEME_PROGRESSBAR_CHUNK:
     case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL: {
       nsIFrame* parentFrame = aFrame->GetParent();
       nsEventStates eventStates = GetContentState(parentFrame, aWidgetType);
       if (aWidgetType == NS_THEME_PROGRESSBAR_CHUNK_VERTICAL ||
           IsVerticalProgress(parentFrame)) {
-        aPart = WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
+        aPart = IsVistaOrLater() ?
           PP_FILLVERT : PP_CHUNKVERT;
       } else {
-        aPart = WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
+        aPart = IsVistaOrLater() ?
           PP_FILL : PP_CHUNK;
       }
 
       aState = PBBVS_NORMAL;
       return NS_OK;
     }
     case NS_THEME_TOOLBAR_BUTTON: {
       aPart = BP_BUTTON;
@@ -1073,17 +1072,17 @@ nsNativeThemeWin::GetThemePartAndState(n
         aState += TS_DISABLED;
       else {
         nsIFrame *parent = aFrame->GetParent();
         nsEventStates parentState = GetContentState(parent, parent->StyleDisplay()->mAppearance);
         if (eventState.HasAllStates(NS_EVENT_STATE_HOVER | NS_EVENT_STATE_ACTIVE))
           aState += TS_ACTIVE;
         else if (eventState.HasState(NS_EVENT_STATE_HOVER))
           aState += TS_HOVER;
-        else if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
+        else if (IsVistaOrLater() &&
                  parentState.HasState(NS_EVENT_STATE_HOVER))
           aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE;
         else
           aState += TS_NORMAL;
       }
       return NS_OK;
     }
     case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
@@ -1177,17 +1176,17 @@ nsNativeThemeWin::GetThemePartAndState(n
     case NS_THEME_TOOLBOX:
     case NS_THEME_WIN_MEDIA_TOOLBOX:
     case NS_THEME_WIN_COMMUNICATIONS_TOOLBOX:
     case NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX:
     case NS_THEME_STATUSBAR:
     case NS_THEME_SCROLLBAR:
     case NS_THEME_SCROLLBAR_SMALL: {
       aState = 0;
-      if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+      if (IsVistaOrLater()) {
         // On vista, they have a part
         aPart = RP_BACKGROUND;
       } else {
         // Otherwise, they don't.  (But I bet
         // RP_BACKGROUND would work here, too);
         aPart = 0;
       }
       return NS_OK;
@@ -1309,17 +1308,17 @@ nsNativeThemeWin::GetThemePartAndState(n
       bool isMenulist = !isHTML && parentFrame->GetType() == nsGkAtoms::menuFrame;
       bool isOpen = false;
 
       // HTML select and XUL menulist dropdown buttons get state from the parent.
       if (isHTML || isMenulist)
         aFrame = parentFrame;
 
       nsEventStates eventState = GetContentState(aFrame, aWidgetType);
-      aPart = WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
+      aPart = IsVistaOrLater() ?
         CBP_DROPMARKER_VISTA : CBP_DROPMARKER;
 
       // For HTML controls with author styling, we should fall
       // back to the old dropmarker style to avoid clashes with
       // author-specified backgrounds and borders (bug #441034)
       if (isHTML && IsWidgetStyled(aFrame->PresContext(), aFrame, NS_THEME_DROPDOWN))
         aPart = CBP_DROPMARKER;
 
@@ -1330,17 +1329,17 @@ nsNativeThemeWin::GetThemePartAndState(n
 
       if (isHTML) {
         nsIComboboxControlFrame* ccf = do_QueryFrame(aFrame);
         isOpen = (ccf && ccf->IsDroppedDown());
       }
       else
         isOpen = IsOpenButton(aFrame);
 
-      if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+      if (IsVistaOrLater()) {
         if (isHTML || IsMenuListEditable(aFrame)) {
           if (isOpen) {
             /* Hover is propagated, but we need to know whether we're
              * hovering just the combobox frame, not the dropdown frame.
              * But, we can't get that information, since hover is on the
              * content node, and they share the same content node.  So,
              * instead, we cheat -- if the dropdown is open, we always
              * show the hover state.  This looks fine in practice.
@@ -1833,17 +1832,17 @@ RENDER_AGAIN:
         uint8_t id = SaveDC(hdc);
 
         ::SelectClipRgn(hdc, nullptr);
         ::GetViewportOrgEx(hdc, &vpOrg);
         ::SetBrushOrgEx(hdc, vpOrg.x + widgetRect.left, vpOrg.y + widgetRect.top, nullptr);
 
         // On vista, choose our own colors and draw an XP style half focus rect
         // for focused checkboxes and a full rect when active.
-        if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
+        if (IsVistaOrLater() &&
             aWidgetType == NS_THEME_CHECKBOX) {
           LOGBRUSH lb;
           lb.lbStyle = BS_SOLID;
           lb.lbColor = RGB(255,255,255);
           lb.lbHatch = 0;
 
           hPen = ::ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, nullptr);
           ::SelectObject(hdc, hPen);
@@ -2081,17 +2080,17 @@ nsNativeThemeWin::GetWidgetPadding(nsDev
   {
     SIZE popupSize;
     GetThemePartSize(theme, nullptr, MENU_POPUPBORDERS, /* state */ 0, nullptr, TS_TRUE, &popupSize);
     aResult->top = aResult->bottom = popupSize.cy;
     aResult->left = aResult->right = popupSize.cx;
     return true;
   }
 
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+  if (IsVistaOrLater()) {
     if (aWidgetType == NS_THEME_TEXTFIELD ||
         aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
         aWidgetType == NS_THEME_DROPDOWN)
     {
       /* If we have author-specified padding for these elements, don't do the fixups below */
       if (aFrame->PresContext()->HasAuthorSpecifiedRules(aFrame, NS_AUTHOR_SPECIFIED_PADDING))
         return false;
     }
@@ -2174,17 +2173,17 @@ nsNativeThemeWin::GetWidgetOverflow(nsDe
   /* This is disabled for now, because it causes invalidation problems --
    * see bug 420381.  The effect of not updating the overflow area is that
    * for dropdown buttons in content areas, there is a 1px border on 3 sides
    * where, if invalidated, the dropdown control probably won't be repainted.
    * This is fairly minor, as by default there is nothing in that area, and
    * a border only shows up if the widget is being hovered.
    */
 #if 0
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+  if (IsVistaOrLater()) {
     /* We explicitly draw dropdown buttons in HTML content 1px bigger
      * up, right, and bottom so that they overlap the dropdown's border
      * like they're supposed to.
      */
     if (aWidgetType == NS_THEME_DROPDOWN_BUTTON &&
         IsHTMLContent(aFrame) &&
         !IsWidgetStyled(aFrame->GetParent()->PresContext(),
                         aFrame->GetParent(),
@@ -2298,17 +2297,17 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
 
     case NS_THEME_RANGE_THUMB:
     case NS_THEME_SCALE_THUMB_HORIZONTAL:
     case NS_THEME_SCALE_THUMB_VERTICAL:
     {
       *aIsOverridable = false;
       // on Vista, GetThemePartAndState returns odd values for
       // scale thumbs, so use a hardcoded size instead.
-      if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+      if (IsVistaOrLater()) {
         if (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL ||
             (aWidgetType == NS_THEME_RANGE_THUMB && IsRangeHorizontal(aFrame))) {
           aResult->width = 12;
           aResult->height = 20;
         }
         else {
           aResult->width = 20;
           aResult->height = 12;
@@ -2348,39 +2347,39 @@ nsNativeThemeWin::GetMinimumWidgetSize(n
     case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
     case NS_THEME_WINDOW_BUTTON_RESTORE:
       // The only way to get accurate titlebar button info is to query a
       // window w/buttons when it's visible. nsWindow takes care of this and
       // stores that info in nsUXThemeData.
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_RESTORE].cy;
       // For XP, subtract 4 from system metrics dimensions.
-      if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION) {
+      if (!IsVistaOrLater()) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_RESTORE);
       *aIsOverridable = false;
       return NS_OK;
 
     case NS_THEME_WINDOW_BUTTON_MINIMIZE:
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy;
-      if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION) {
+      if (!IsVistaOrLater()) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_MINIMIZE);
       *aIsOverridable = false;
       return NS_OK;
 
     case NS_THEME_WINDOW_BUTTON_CLOSE:
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy;
-      if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION) {
+      if (!IsVistaOrLater()) {
         aResult->width -= 4;
         aResult->height -= 4;
       }
       AddPaddingRect(aResult, CAPTIONBUTTON_CLOSE);
       *aIsOverridable = false;
       return NS_OK;
 
     case NS_THEME_WINDOW_TITLEBAR:
@@ -2483,26 +2482,26 @@ nsNativeThemeWin::WidgetStateChanged(nsI
       aWidgetType == NS_THEME_WINDOW_BUTTON_MINIMIZE ||
       aWidgetType == NS_THEME_WINDOW_BUTTON_MINIMIZE ||
       aWidgetType == NS_THEME_WINDOW_BUTTON_RESTORE) {
     *aShouldRepaint = true;
     return NS_OK;
   }
 
   // On Vista, the scrollbar buttons need to change state when the track has/doesn't have hover
-  if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION &&
+  if (!IsVistaOrLater() &&
       (aWidgetType == NS_THEME_SCROLLBAR_TRACK_VERTICAL || 
       aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL)) {
     *aShouldRepaint = false;
     return NS_OK;
   }
 
   // We need to repaint the dropdown arrow in vista HTML combobox controls when
   // the control is closed to get rid of the hover effect.
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
+  if (IsVistaOrLater() &&
       (aWidgetType == NS_THEME_DROPDOWN || aWidgetType == NS_THEME_DROPDOWN_BUTTON) &&
       IsHTMLContent(aFrame))
   {
     *aShouldRepaint = true;
     return NS_OK;
   }
 
   // XXXdwh Not sure what can really be done here.  Can at least guess for
--- a/widget/windows/nsTextStore.cpp
+++ b/widget/windows/nsTextStore.cpp
@@ -15,16 +15,17 @@
 #include "nsWindow.h"
 #ifdef MOZ_METRO
 #include "winrt/MetroWidget.h"
 #endif
 #include "nsPrintfCString.h"
 #include "WinUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/TextEvents.h"
+#include "mozilla/WindowsVersion.h"
 
 #define INPUTSCOPE_INIT_GUID
 #include "nsTextStore.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 #ifdef PR_LOGGING
@@ -3597,17 +3598,17 @@ nsTextStore::CurrentKeyboardLayoutHasIME
   }
   nsRefPtr<ITfInputProcessorProfileMgr> profileMgr;
   hr = profiles->QueryInterface(IID_ITfInputProcessorProfileMgr,
                                 getter_AddRefs(profileMgr));
   if (FAILED(hr) || !profileMgr) {
     // On Windows Vista or later, ImmIsIME() API always returns true.
     // If we failed to obtain the profile manager, we cannot know if current
     // keyboard layout has IME.
-    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+    if (IsVistaOrLater()) {
       PR_LOG(sTextStoreLog, PR_LOG_ERROR,
         ("TSF: nsTextStore::CurrentKeyboardLayoutHasIME() FAILED to query "
          "ITfInputProcessorProfileMgr"));
       return false;
     }
     // If the profiles instance doesn't have ITfInputProcessorProfileMgr
     // interface, that means probably we're running on WinXP or WinServer2003
     // (except WinServer2003 R2).  Then, we should use ImmIsIME().
--- a/widget/windows/nsUXThemeData.cpp
+++ b/widget/windows/nsUXThemeData.cpp
@@ -1,16 +1,17 @@
 /* vim: se cin sw=2 ts=2 et : */
 /* -*- 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 "mozilla/Util.h"
+#include "mozilla/WindowsVersion.h"
 
 #include "nsUXThemeData.h"
 #include "nsDebug.h"
 #include "nsToolkit.h"
 #include "nsUXThemeConstants.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
@@ -139,17 +140,17 @@ nsUXThemeData::InitTitlebarInfo()
   sCommandButtons[1].cx = sCommandButtons[2].cx = sCommandButtons[0].cx;
   sCommandButtons[1].cy = sCommandButtons[2].cy = sCommandButtons[0].cy;
   sCommandButtons[3].cx = sCommandButtons[0].cx * 3;
   sCommandButtons[3].cy = sCommandButtons[0].cy;
 
   // Use system metrics for pre-vista, otherwise trigger a
   // refresh on the next layout.
   sTitlebarInfoPopulatedAero = sTitlebarInfoPopulatedThemed =
-    (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION);
+    !IsVistaOrLater();
 }
 
 // static
 void
 nsUXThemeData::UpdateTitlebarInfo(HWND aWnd)
 {
   if (!aWnd)
     return;
@@ -276,18 +277,17 @@ bool nsUXThemeData::CheckForCompositor(b
   return sCachedValue;
 }
 
 // static
 void
 nsUXThemeData::UpdateNativeThemeInfo()
 {
   // Trigger a refresh of themed button metrics if needed
-  sTitlebarInfoPopulatedThemed =
-    (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION);
+  sTitlebarInfoPopulatedThemed = !IsVistaOrLater();
 
   sIsDefaultWindowsTheme = false;
   sThemeId = LookAndFeel::eWindowsTheme_Generic;
 
   if (!IsAppThemed()) {
     sThemeId = LookAndFeel::eWindowsTheme_Classic;
     return;
   }
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -120,16 +120,17 @@
 #include "mozilla/Preferences.h"
 #include "nsISound.h"
 #include "WinTaskbar.h"
 #include "WinUtils.h"
 #include "WidgetUtils.h"
 #include "nsIWidgetListener.h"
 #include "mozilla/dom/Touch.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/WindowsVersion.h"
 
 #ifdef MOZ_ENABLE_D3D9_LAYER
 #include "LayerManagerD3D9.h"
 #endif
 
 #ifdef MOZ_ENABLE_D3D10_LAYER
 #include "LayerManagerD3D10.h"
 #endif
@@ -476,19 +477,17 @@ nsWindow::Create(nsIWidget *aParent,
   DWORD style = WindowStyle();
   DWORD extendedStyle = WindowExStyle();
 
   if (mWindowType == eWindowType_popup) {
     if (!aParent) {
       parent = nullptr;
     }
 
-    if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
-        WinUtils::GetWindowsVersion() <= WinUtils::WIN7_VERSION &&
-        HasBogusPopupsDropShadowOnMultiMonitor()) {
+    if (IsVistaOrLater() && !IsWin8OrLater()) {
       extendedStyle |= WS_EX_COMPOSITED;
     }
 
     if (aInitData->mIsDragPopup) {
       // This flag makes the window transparent to mouse events
       extendedStyle |= WS_EX_TRANSPARENT;
     }
   } else if (mWindowType == eWindowType_invisible) {
@@ -601,17 +600,17 @@ nsWindow::Create(nsIWidget *aParent,
   // do some initialization work.
   if (sTrimOnMinimize == 2 && mWindowType == eWindowType_invisible) {
     // Our internal trim prevention logic is effective on 2K/XP at maintaining
     // the working set when windows are minimized, but on Vista and up it has
     // little to no effect. Since this feature has been the source of numerous
     // bugs over the years, disable it (sTrimOnMinimize=1) on Vista and up.
     sTrimOnMinimize =
       Preferences::GetBool("config.trim_on_minimize",
-        (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION)) ? 1 : 0;
+        IsVistaOrLater() ? 1 : 0);
     sSwitchKeyboardLayout =
       Preferences::GetBool("intl.keyboard.per_window_layout", false);
   }
 
   // Query for command button metric data for rendering the titlebar. We
   // only do this once on the first window.
   if (mWindowType == eWindowType_toplevel &&
       (!nsUXThemeData::sTitlebarInfoPopulatedThemed ||
@@ -1221,33 +1220,31 @@ bool nsWindow::IsVisible() const
  * window clipping regions for window transparency.
  *
  **************************************************************/
 
 // XP and Vista visual styles sometimes require window clipping regions to be applied for proper
 // transparency. These routines are called on size and move operations.
 void nsWindow::ClearThemeRegion()
 {
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
-      !HasGlass() &&
+  if (IsVistaOrLater() && !HasGlass() &&
       (mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
        (mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
     SetWindowRgn(mWnd, nullptr, false);
   }
 }
 
 void nsWindow::SetThemeRegion()
 {
   // Popup types that have a visual styles region applied (bug 376408). This can be expanded
   // for other window types as needed. The regions are applied generically to the base window
   // so default constants are used for part and state. At some point we might need part and
   // state values from nsNativeThemeWin's GetThemePartAndState, but currently windows that
   // change shape based on state haven't come up.
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
-      !HasGlass() &&
+  if (IsVistaOrLater() && !HasGlass() &&
       (mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
        (mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
     HRGN hRgn = nullptr;
     RECT rect = {0,0,mBounds.width,mBounds.height};
     
     HDC dc = ::GetDC(mWnd);
     GetThemeBackgroundRegion(nsUXThemeData::GetTheme(eUXTooltip), dc, TTP_STANDARD, TS_NORMAL, &rect, &hRgn);
     if (hRgn) {
@@ -3490,17 +3487,17 @@ nsWindow::OverrideSystemMouseScrollSpeed
   // The default vertical scrolling speed is 3, this is defined on the document
   // of SystemParametersInfo in MSDN.
   if (systemSpeed != kSystemDefaultScrollingSpeed) {
     return NS_OK;
   }
 
   // Only Vista and later, Windows has the system setting of horizontal
   // scrolling by the mouse wheel.
-  if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
+  if (IsVistaOrLater()) {
     if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &systemSpeed, 0)) {
       return NS_ERROR_FAILURE;
     }
     // The default horizontal scrolling speed is 3, this is defined on the
     // document of SystemParametersInfo in MSDN.
     if (systemSpeed != kSystemDefaultScrollingSpeed) {
       return NS_OK;
     }