diff --git a/accessible/windows/ia2/ia2Accessible.cpp b/accessible/windows/ia2/ia2Accessible.cpp
index 97cd0d788..c72719b51 100644
--- a/accessible/windows/ia2/ia2Accessible.cpp
+++ b/accessible/windows/ia2/ia2Accessible.cpp
@@ -63,6 +63,8 @@ ia2Accessible::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ia2Accessible::get_nRelations(long* aNRelations)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNRelations)
     return E_INVALIDARG;
   *aNRelations = 0;
@@ -82,12 +84,16 @@ ia2Accessible::get_nRelations(long* aNRelations)
       (*aNRelations)++;
   }
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_relation(long aRelationIndex,
                             IAccessibleRelation** aRelation)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRelation || aRelationIndex < 0)
     return E_INVALIDARG;
   *aRelation = nullptr;
@@ -118,6 +124,8 @@ ia2Accessible::get_relation(long aRelationIndex,
   }
 
   return E_INVALIDARG;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -125,6 +133,8 @@ ia2Accessible::get_relations(long aMaxRelations,
                              IAccessibleRelation** aRelation,
                              long *aNRelations)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRelation || !aNRelations || aMaxRelations <= 0)
     return E_INVALIDARG;
   *aNRelations = 0;
@@ -150,11 +160,15 @@ ia2Accessible::get_relations(long aMaxRelations,
     }
   }
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::role(long* aRole)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRole)
     return E_INVALIDARG;
   *aRole = 0;
@@ -190,11 +204,15 @@ ia2Accessible::role(long* aRole)
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::scrollTo(enum IA2ScrollType aScrollType)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
@@ -204,12 +222,16 @@ ia2Accessible::scrollTo(enum IA2ScrollType aScrollType)
                         aScrollType);
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::scrollToPoint(enum IA2CoordinateType aCoordType,
                               long aX, long aY)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
@@ -222,6 +244,8 @@ ia2Accessible::scrollToPoint(enum IA2CoordinateType aCoordType,
   acc->ScrollToPoint(geckoCoordType, aX, aY);
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -229,6 +253,8 @@ ia2Accessible::get_groupPosition(long* aGroupLevel,
                                  long* aSimilarItemsInGroup,
                                  long* aPositionInGroup)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aGroupLevel || !aSimilarItemsInGroup || !aPositionInGroup)
     return E_INVALIDARG;
 
@@ -253,11 +279,15 @@ ia2Accessible::get_groupPosition(long* aGroupLevel,
   *aPositionInGroup = groupPos.posInSet;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_states(AccessibleStates* aStates)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStates)
     return E_INVALIDARG;
   *aStates = 0;
@@ -317,36 +347,50 @@ ia2Accessible::get_states(AccessibleStates* aStates)
     *aStates |= IA2_STATE_PINNED;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_extendedRole(BSTR* aExtendedRole)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aExtendedRole)
     return E_INVALIDARG;
 
   *aExtendedRole = nullptr;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_localizedExtendedRole(BSTR* aLocalizedExtendedRole)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aLocalizedExtendedRole)
     return E_INVALIDARG;
 
   *aLocalizedExtendedRole = nullptr;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_nExtendedStates(long* aNExtendedStates)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNExtendedStates)
     return E_INVALIDARG;
 
   *aNExtendedStates = 0;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -354,12 +398,16 @@ ia2Accessible::get_extendedStates(long aMaxExtendedStates,
                                   BSTR** aExtendedStates,
                                   long* aNExtendedStates)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aExtendedStates || !aNExtendedStates)
     return E_INVALIDARG;
 
   *aExtendedStates = nullptr;
   *aNExtendedStates = 0;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -367,28 +415,38 @@ ia2Accessible::get_localizedExtendedStates(long aMaxLocalizedExtendedStates,
                                            BSTR** aLocalizedExtendedStates,
                                            long* aNLocalizedExtendedStates)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aLocalizedExtendedStates || !aNLocalizedExtendedStates)
     return E_INVALIDARG;
 
   *aLocalizedExtendedStates = nullptr;
   *aNLocalizedExtendedStates = 0;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_uniqueID(long* aUniqueID)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aUniqueID)
     return E_INVALIDARG;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   *aUniqueID = AccessibleWrap::GetChildIDFor(acc);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_windowHandle(HWND* aWindowHandle)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aWindowHandle)
     return E_INVALIDARG;
   *aWindowHandle = 0;
@@ -399,11 +457,15 @@ ia2Accessible::get_windowHandle(HWND* aWindowHandle)
 
   *aWindowHandle = AccessibleWrap::GetHWNDFor(acc);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_indexInParent(long* aIndexInParent)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aIndexInParent)
     return E_INVALIDARG;
   *aIndexInParent = -1;
@@ -419,11 +481,15 @@ ia2Accessible::get_indexInParent(long* aIndexInParent)
     return S_FALSE;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_locale(IA2Locale* aLocale)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aLocale)
     return E_INVALIDARG;
 
@@ -466,11 +532,15 @@ ia2Accessible::get_locale(IA2Locale* aLocale)
   // country abbreviations or if there are more than one subcode.
   aLocale->variant = ::SysAllocString(lang.get());
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_attributes(BSTR* aAttributes)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAttributes)
     return E_INVALIDARG;
   *aAttributes = nullptr;
@@ -488,6 +558,8 @@ ia2Accessible::get_attributes(BSTR* aAttributes)
 
   MOZ_ASSERT(!acc->IsProxy());
   return E_UNEXPECTED;
+
+  A11Y_TRYBLOCK_END
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -496,16 +568,22 @@ ia2Accessible::get_attributes(BSTR* aAttributes)
 STDMETHODIMP
 ia2Accessible::get_attribute(BSTR name, VARIANT* aAttribute)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAttribute)
     return E_INVALIDARG;
 
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_accessibleWithCaret(IUnknown** aAccessible,
                                        long* aCaretOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAccessible || !aCaretOffset)
     return E_INVALIDARG;
 
@@ -533,6 +611,8 @@ ia2Accessible::get_accessibleWithCaret(IUnknown** aAccessible,
   (*aAccessible)->AddRef();
   *aCaretOffset = caretOffset;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -541,6 +621,8 @@ ia2Accessible::get_relationTargetsOfType(BSTR aType,
                                          IUnknown*** aTargets,
                                          long* aNTargets)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aTargets || !aNTargets || aMaxTargets < 0)
     return E_INVALIDARG;
   *aNTargets = 0;
@@ -581,12 +663,16 @@ ia2Accessible::get_relationTargetsOfType(BSTR aType,
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2Accessible::get_selectionRanges(IA2Range** aRanges,
                                    long *aNRanges)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRanges || !aNRanges)
     return E_INVALIDARG;
 
@@ -628,6 +714,8 @@ ia2Accessible::get_selectionRanges(IA2Range** aRanges,
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 
diff --git a/accessible/windows/ia2/ia2AccessibleAction.cpp b/accessible/windows/ia2/ia2AccessibleAction.cpp
index ffd19f049..0710b753f 100644
--- a/accessible/windows/ia2/ia2AccessibleAction.cpp
+++ b/accessible/windows/ia2/ia2AccessibleAction.cpp
@@ -39,6 +39,8 @@ ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ia2AccessibleAction::nActions(long* aActionCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aActionCount)
     return E_INVALIDARG;
 
@@ -50,22 +52,30 @@ ia2AccessibleAction::nActions(long* aActionCount)
 
   *aActionCount = acc->ActionCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleAction::doAction(long aActionIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   uint8_t index = static_cast<uint8_t>(aActionIndex);
   return acc->DoAction(index) ? S_OK : E_INVALIDARG;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aDescription)
     return E_INVALIDARG;
   *aDescription = nullptr;
@@ -83,6 +93,8 @@ ia2AccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
   *aDescription = ::SysAllocStringLen(description.get(),
                                       description.Length());
   return *aDescription ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -90,6 +102,8 @@ ia2AccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
                                   BSTR **aKeyBinding,
                                   long *aNumBinding)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aKeyBinding)
     return E_INVALIDARG;
   *aKeyBinding = nullptr;
@@ -129,11 +143,15 @@ ia2AccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
 
   *aNumBinding = 1;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleAction::get_name(long aActionIndex, BSTR *aName)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aName)
     return E_INVALIDARG;
 
@@ -151,14 +169,20 @@ ia2AccessibleAction::get_name(long aActionIndex, BSTR *aName)
 
   *aName = ::SysAllocStringLen(name.get(), name.Length());
   return *aName ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aLocalizedName)
     return E_INVALIDARG;
 
   *aLocalizedName = nullptr;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/accessible/windows/ia2/ia2AccessibleComponent.cpp b/accessible/windows/ia2/ia2AccessibleComponent.cpp
index 2c9cd0ab4..f32c09d1e 100644
--- a/accessible/windows/ia2/ia2AccessibleComponent.cpp
+++ b/accessible/windows/ia2/ia2AccessibleComponent.cpp
@@ -41,6 +41,8 @@ ia2AccessibleComponent::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ia2AccessibleComponent::get_locationInParent(long* aX, long* aY)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aX || !aY)
     return E_INVALIDARG;
 
@@ -73,11 +75,15 @@ ia2AccessibleComponent::get_locationInParent(long* aX, long* aY)
   *aX = rect.x - parentRect.x;
   *aY = rect.y - parentRect.y;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleComponent::get_foreground(IA2Color* aForeground)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aForeground)
     return E_INVALIDARG;
 
@@ -92,11 +98,15 @@ ia2AccessibleComponent::get_foreground(IA2Color* aForeground)
     *aForeground = frame->StyleColor()->mColor;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleComponent::get_background(IA2Color* aBackground)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aBackground)
     return E_INVALIDARG;
 
@@ -111,5 +121,7 @@ ia2AccessibleComponent::get_background(IA2Color* aBackground)
     *aBackground = frame->StyleBackground()->mBackgroundColor;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
diff --git a/accessible/windows/ia2/ia2AccessibleEditableText.cpp b/accessible/windows/ia2/ia2AccessibleEditableText.cpp
index 0b433bf6d..361d6a130 100644
--- a/accessible/windows/ia2/ia2AccessibleEditableText.cpp
+++ b/accessible/windows/ia2/ia2AccessibleEditableText.cpp
@@ -22,6 +22,8 @@ using namespace mozilla::a11y;
 STDMETHODIMP
 ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -33,11 +35,15 @@ ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
 
   textAcc->CopyText(aStartOffset, aEndOffset);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -49,11 +55,15 @@ ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
 
   textAcc->DeleteText(aStartOffset, aEndOffset);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleEditableText::insertText(long aOffset, BSTR *aText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   uint32_t length = ::SysStringLen(*aText);
   nsAutoString text(*aText, length);
   MOZ_ASSERT(!HyperTextProxyFor(this));
@@ -67,11 +77,15 @@ ia2AccessibleEditableText::insertText(long aOffset, BSTR *aText)
 
   textAcc->InsertText(text, aOffset);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -83,11 +97,15 @@ ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
 
   textAcc->CutText(aStartOffset, aEndOffset);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleEditableText::pasteText(long aOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -99,12 +117,16 @@ ia2AccessibleEditableText::pasteText(long aOffset)
 
   textAcc->PasteText(aOffset);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
                                        BSTR *aText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
@@ -119,6 +141,8 @@ ia2AccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
   textAcc->InsertText(text, aStartOffset);
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
diff --git a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
index d36c0ef25..c6d564103 100644
--- a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
+++ b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
@@ -45,6 +45,8 @@ ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAnchor)
     return E_INVALIDARG;
 
@@ -75,11 +77,15 @@ ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor)
   aAnchor->punkVal = static_cast<IUnknown*>(instancePtr);
   aAnchor->vt = VT_UNKNOWN;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAnchorTarget) {
     return E_INVALIDARG;
   }
@@ -118,11 +124,15 @@ ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget)
   aAnchorTarget->bstrVal = ::SysAllocStringLen(stringURI.get(),
                                                stringURI.Length());
   return aAnchorTarget->bstrVal ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHyperlink::get_startIndex(long* aIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aIndex)
     return E_INVALIDARG;
 
@@ -139,11 +149,15 @@ ia2AccessibleHyperlink::get_startIndex(long* aIndex)
 
   *aIndex = thisObj->StartOffset();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHyperlink::get_endIndex(long* aIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aIndex)
     return E_INVALIDARG;
 
@@ -160,11 +174,15 @@ ia2AccessibleHyperlink::get_endIndex(long* aIndex)
 
   *aIndex = thisObj->EndOffset();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHyperlink::get_valid(boolean* aValid)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aValid)
     return E_INVALIDARG;
 
@@ -181,5 +199,7 @@ ia2AccessibleHyperlink::get_valid(boolean* aValid)
 
   *aValid = thisObj->IsLinkValid();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
diff --git a/accessible/windows/ia2/ia2AccessibleHypertext.cpp b/accessible/windows/ia2/ia2AccessibleHypertext.cpp
index 555bde686..f4b3bdaf2 100644
--- a/accessible/windows/ia2/ia2AccessibleHypertext.cpp
+++ b/accessible/windows/ia2/ia2AccessibleHypertext.cpp
@@ -19,6 +19,8 @@ using namespace mozilla::a11y;
 STDMETHODIMP
 ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aHyperlinkCount)
     return E_INVALIDARG;
 
@@ -32,12 +34,16 @@ ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount)
 
   *aHyperlinkCount = hyperText->LinkCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHypertext::get_hyperlink(long aLinkIndex,
                                       IAccessibleHyperlink** aHyperlink)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aHyperlink)
     return E_INVALIDARG;
 
@@ -59,11 +65,15 @@ ia2AccessibleHypertext::get_hyperlink(long aLinkIndex,
     static_cast<IAccessibleHyperlink*>(hyperLink);
   (*aHyperlink)->AddRef();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aHyperlinkIndex)
     return E_INVALIDARG;
 
@@ -77,5 +87,7 @@ ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkInde
 
   *aHyperlinkIndex = hyperAcc->LinkIndexAtOffset(aCharIndex);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
diff --git a/accessible/windows/ia2/ia2AccessibleImage.cpp b/accessible/windows/ia2/ia2AccessibleImage.cpp
index 7dc7f765c..989fde925 100644
--- a/accessible/windows/ia2/ia2AccessibleImage.cpp
+++ b/accessible/windows/ia2/ia2AccessibleImage.cpp
@@ -43,6 +43,8 @@ ia2AccessibleImage::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ia2AccessibleImage::get_description(BSTR* aDescription)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aDescription)
     return E_INVALIDARG;
 
@@ -59,6 +61,8 @@ ia2AccessibleImage::get_description(BSTR* aDescription)
 
   *aDescription = ::SysAllocStringLen(description.get(), description.Length());
   return *aDescription ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -66,6 +70,8 @@ ia2AccessibleImage::get_imagePosition(enum IA2CoordinateType aCoordType,
                                       long* aX,
                                       long* aY)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aX || !aY)
     return E_INVALIDARG;
 
@@ -84,11 +90,15 @@ ia2AccessibleImage::get_imagePosition(enum IA2CoordinateType aCoordType,
   *aX = pos.x;
   *aY = pos.y;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleImage::get_imageSize(long* aHeight, long* aWidth)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aHeight || !aWidth)
     return E_INVALIDARG;
 
@@ -103,5 +113,7 @@ ia2AccessibleImage::get_imageSize(long* aHeight, long* aWidth)
   *aHeight = size.width;
   *aWidth = size.height;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
diff --git a/accessible/windows/ia2/ia2AccessibleRelation.cpp b/accessible/windows/ia2/ia2AccessibleRelation.cpp
index 67435ee52..cc6fd83c8 100644
--- a/accessible/windows/ia2/ia2AccessibleRelation.cpp
+++ b/accessible/windows/ia2/ia2AccessibleRelation.cpp
@@ -34,6 +34,8 @@ IMPL_IUNKNOWN_QUERY_TAIL
 STDMETHODIMP
 ia2AccessibleRelation::get_relationType(BSTR* aRelationType)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRelationType)
     return E_INVALIDARG;
 
@@ -49,31 +51,43 @@ ia2AccessibleRelation::get_relationType(BSTR* aRelationType)
   }
 
   return *aRelationType ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleRelation::get_localizedRelationType(BSTR *aLocalizedRelationType)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aLocalizedRelationType)
     return E_INVALIDARG;
 
   *aLocalizedRelationType = nullptr;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleRelation::get_nTargets(long *aNTargets)
 {
+  A11Y_TRYBLOCK_BEGIN
+
  if (!aNTargets)
    return E_INVALIDARG;
 
  *aNTargets = mTargets.Length();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleRelation::get_target(long aTargetIndex, IUnknown **aTarget)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (aTargetIndex < 0 || (uint32_t)aTargetIndex >= mTargets.Length() || !aTarget)
     return E_INVALIDARG;
 
@@ -83,12 +97,16 @@ ia2AccessibleRelation::get_target(long aTargetIndex, IUnknown **aTarget)
   (*aTarget)->AddRef();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleRelation::get_targets(long aMaxTargets, IUnknown **aTargets,
                                    long *aNTargets)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNTargets || !aTargets)
     return E_INVALIDARG;
 
@@ -102,4 +120,6 @@ ia2AccessibleRelation::get_targets(long aMaxTargets, IUnknown **aTargets,
 
   *aNTargets = maxTargets;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/accessible/windows/ia2/ia2AccessibleTable.cpp b/accessible/windows/ia2/ia2AccessibleTable.cpp
index a99f72def..6ac6bbab4 100644
--- a/accessible/windows/ia2/ia2AccessibleTable.cpp
+++ b/accessible/windows/ia2/ia2AccessibleTable.cpp
@@ -60,6 +60,8 @@ ia2AccessibleTable::get_accessibleAt(long aRowIdx, long aColIdx,
 STDMETHODIMP
 ia2AccessibleTable::get_caption(IUnknown** aAccessible)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAccessible)
     return E_INVALIDARG;
 
@@ -73,12 +75,16 @@ ia2AccessibleTable::get_caption(IUnknown** aAccessible)
 
   (*aAccessible = static_cast<IAccessible*>(caption))->AddRef();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_childIndex(long aRowIdx, long aColIdx,
                                    long* aChildIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aChildIdx)
     return E_INVALIDARG;
 
@@ -93,11 +99,15 @@ ia2AccessibleTable::get_childIndex(long aRowIdx, long aColIdx,
 
   *aChildIdx = mTable->CellIndexAt(aRowIdx, aColIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_columnDescription(long aColIdx, BSTR* aDescription)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aDescription)
     return E_INVALIDARG;
 
@@ -115,12 +125,16 @@ ia2AccessibleTable::get_columnDescription(long aColIdx, BSTR* aDescription)
 
   *aDescription = ::SysAllocStringLen(descr.get(), descr.Length());
   return *aDescription ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_columnExtentAt(long aRowIdx, long aColIdx,
                                       long* aSpan)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aSpan)
     return E_INVALIDARG;
 
@@ -135,23 +149,31 @@ ia2AccessibleTable::get_columnExtentAt(long aRowIdx, long aColIdx,
 
   *aSpan = mTable->ColExtentAt(aRowIdx, aColIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_columnHeader(IAccessibleTable** aAccessibleTable,
                                     long* aStartingRowIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAccessibleTable || !aStartingRowIndex)
     return E_INVALIDARG;
 
   *aAccessibleTable = nullptr;
   *aStartingRowIndex = -1;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_columnIndex(long aCellIdx, long* aColIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aColIdx)
     return E_INVALIDARG;
 
@@ -165,11 +187,15 @@ ia2AccessibleTable::get_columnIndex(long aCellIdx, long* aColIdx)
 
   *aColIdx = mTable->ColIndexAt(aCellIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_nColumns(long* aColCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aColCount)
     return E_INVALIDARG;
 
@@ -179,11 +205,15 @@ ia2AccessibleTable::get_nColumns(long* aColCount)
 
   *aColCount = mTable->ColCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_nRows(long* aRowCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRowCount)
     return E_INVALIDARG;
 
@@ -193,6 +223,8 @@ ia2AccessibleTable::get_nRows(long* aRowCount)
 
   *aRowCount = mTable->RowCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -204,6 +236,8 @@ ia2AccessibleTable::get_nSelectedChildren(long* aChildCount)
 STDMETHODIMP
 ia2AccessibleTable::get_nSelectedColumns(long* aColCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aColCount)
     return E_INVALIDARG;
 
@@ -213,11 +247,15 @@ ia2AccessibleTable::get_nSelectedColumns(long* aColCount)
 
   *aColCount = mTable->SelectedColCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_nSelectedRows(long* aRowCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRowCount)
     return E_INVALIDARG;
 
@@ -228,11 +266,15 @@ ia2AccessibleTable::get_nSelectedRows(long* aRowCount)
   *aRowCount = mTable->SelectedRowCount();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_rowDescription(long aRowIdx, BSTR* aDescription)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aDescription)
     return E_INVALIDARG;
 
@@ -250,11 +292,15 @@ ia2AccessibleTable::get_rowDescription(long aRowIdx, BSTR* aDescription)
 
   *aDescription = ::SysAllocStringLen(descr.get(), descr.Length());
   return *aDescription ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_rowExtentAt(long aRowIdx, long aColIdx, long* aSpan)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aSpan)
     return E_INVALIDARG;
 
@@ -269,23 +315,31 @@ ia2AccessibleTable::get_rowExtentAt(long aRowIdx, long aColIdx, long* aSpan)
 
   *aSpan = mTable->RowExtentAt(aRowIdx, aColIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_rowHeader(IAccessibleTable** aAccessibleTable,
                                   long* aStartingColumnIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAccessibleTable || !aStartingColumnIndex)
     return E_INVALIDARG;
 
   *aAccessibleTable = nullptr;
   *aStartingColumnIndex = -1;
   return E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_rowIndex(long aCellIdx, long* aRowIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRowIdx)
     return E_INVALIDARG;
 
@@ -299,12 +353,16 @@ ia2AccessibleTable::get_rowIndex(long aCellIdx, long* aRowIdx)
 
   *aRowIdx = mTable->RowIndexAt(aCellIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedChildren(long aMaxChildren, long** aChildren,
                                          long* aNChildren)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aChildren || !aNChildren)
     return E_INVALIDARG;
 
@@ -326,24 +384,36 @@ ia2AccessibleTable::get_selectedChildren(long aMaxChildren, long** aChildren,
     (*aChildren)[i] = cellIndices[i];
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedColumns(long aMaxColumns, long** aColumns,
                                         long* aNColumns)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   return get_selectedColumns(aColumns, aNColumns);
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedRows(long aMaxRows, long** aRows, long* aNRows)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   return get_selectedRows(aRows, aNRows);
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_summary(IUnknown** aAccessible)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAccessible)
     return E_INVALIDARG;
 
@@ -354,11 +424,15 @@ ia2AccessibleTable::get_summary(IUnknown** aAccessible)
 
   *aAccessible = nullptr;
   return S_FALSE;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_isColumnSelected(long aColIdx, boolean* aIsSelected)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aIsSelected)
     return E_INVALIDARG;
 
@@ -371,11 +445,15 @@ ia2AccessibleTable::get_isColumnSelected(long aColIdx, boolean* aIsSelected)
 
   *aIsSelected = mTable->IsColSelected(aColIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_isRowSelected(long aRowIdx, boolean* aIsSelected)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aIsSelected)
     return E_INVALIDARG;
 
@@ -388,12 +466,16 @@ ia2AccessibleTable::get_isRowSelected(long aRowIdx, boolean* aIsSelected)
 
   *aIsSelected = mTable->IsRowSelected(aRowIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_isSelected(long aRowIdx, long aColIdx,
                                    boolean* aIsSelected)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aIsSelected)
     return E_INVALIDARG;
 
@@ -408,11 +490,15 @@ ia2AccessibleTable::get_isSelected(long aRowIdx, long aColIdx,
 
   *aIsSelected = mTable->IsCellSelected(aRowIdx, aColIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::selectRow(long aRowIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
@@ -421,11 +507,15 @@ ia2AccessibleTable::selectRow(long aRowIdx)
 
   mTable->SelectRow(aRowIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::selectColumn(long aColIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
@@ -434,11 +524,15 @@ ia2AccessibleTable::selectColumn(long aColIdx)
 
   mTable->SelectCol(aColIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::unselectRow(long aRowIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
@@ -447,11 +541,15 @@ ia2AccessibleTable::unselectRow(long aRowIdx)
 
   mTable->UnselectRow(aRowIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::unselectColumn(long aColIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
@@ -460,6 +558,8 @@ ia2AccessibleTable::unselectColumn(long aColIdx)
 
   mTable->UnselectCol(aColIdx);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -469,6 +569,8 @@ ia2AccessibleTable::get_rowColumnExtentsAtIndex(long aCellIdx, long* aRowIdx,
                                                 long* aColExtents,
                                                 boolean* aIsSelected)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRowIdx || !aColIdx || !aRowExtents || !aColExtents || !aIsSelected)
     return E_INVALIDARG;
 
@@ -493,6 +595,8 @@ ia2AccessibleTable::get_rowColumnExtentsAtIndex(long aCellIdx, long* aRowIdx,
   *aIsSelected = mTable->IsCellSelected(rowIdx, colIdx);
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -507,6 +611,8 @@ ia2AccessibleTable::get_modelChange(IA2TableModelChange* aModelChange)
 STDMETHODIMP
 ia2AccessibleTable::get_cellAt(long aRowIdx, long aColIdx, IUnknown** aCell)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aCell)
     return E_INVALIDARG;
 
@@ -522,11 +628,15 @@ ia2AccessibleTable::get_cellAt(long aRowIdx, long aColIdx, IUnknown** aCell)
 
   (*aCell = static_cast<IAccessible*>(cell))->AddRef();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_nSelectedCells(long* aCellCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aCellCount)
     return E_INVALIDARG;
 
@@ -536,11 +646,15 @@ ia2AccessibleTable::get_nSelectedCells(long* aCellCount)
 
   *aCellCount = mTable->SelectedCellCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedCells(IUnknown*** aCells, long* aNSelectedCells)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aCells || !aNSelectedCells)
     return E_INVALIDARG;
 
@@ -568,11 +682,15 @@ ia2AccessibleTable::get_selectedCells(IUnknown*** aCells, long* aNSelectedCells)
 
   *aNSelectedCells = cells.Length();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedColumns(long** aColumns, long* aNColumns)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aColumns || !aNColumns)
     return E_INVALIDARG;
 
@@ -594,11 +712,15 @@ ia2AccessibleTable::get_selectedColumns(long** aColumns, long* aNColumns)
     (*aColumns)[i] = colIndices[i];
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedRows(long** aRows, long* aNRows)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRows || !aNRows)
     return E_INVALIDARG;
 
@@ -620,4 +742,6 @@ ia2AccessibleTable::get_selectedRows(long** aRows, long* aNRows)
     (*aRows)[i] = rowIndices[i];
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/accessible/windows/ia2/ia2AccessibleTableCell.cpp b/accessible/windows/ia2/ia2AccessibleTableCell.cpp
index 19cfc55da..e625a7049 100644
--- a/accessible/windows/ia2/ia2AccessibleTableCell.cpp
+++ b/accessible/windows/ia2/ia2AccessibleTableCell.cpp
@@ -46,6 +46,8 @@ ia2AccessibleTableCell::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ia2AccessibleTableCell::get_table(IUnknown** aTable)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aTable)
     return E_INVALIDARG;
 
@@ -61,11 +63,15 @@ ia2AccessibleTableCell::get_table(IUnknown** aTable)
   *aTable = static_cast<IAccessible*>(wrap);
   (*aTable)->AddRef();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_columnExtent(long* aSpan)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aSpan)
     return E_INVALIDARG;
 
@@ -76,12 +82,16 @@ ia2AccessibleTableCell::get_columnExtent(long* aSpan)
   *aSpan = mTableCell->ColExtent();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_columnHeaderCells(IUnknown*** aCellAccessibles,
                                               long* aNColumnHeaderCells)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aCellAccessibles || !aNColumnHeaderCells)
     return E_INVALIDARG;
 
@@ -108,11 +118,15 @@ ia2AccessibleTableCell::get_columnHeaderCells(IUnknown*** aCellAccessibles,
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_columnIndex(long* aColIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aColIdx)
     return E_INVALIDARG;
 
@@ -122,11 +136,15 @@ ia2AccessibleTableCell::get_columnIndex(long* aColIdx)
 
   *aColIdx = mTableCell->ColIdx();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_rowExtent(long* aSpan)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aSpan)
     return E_INVALIDARG;
 
@@ -136,12 +154,16 @@ ia2AccessibleTableCell::get_rowExtent(long* aSpan)
 
   *aSpan = mTableCell->RowExtent();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_rowHeaderCells(IUnknown*** aCellAccessibles,
                                            long* aNRowHeaderCells)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aCellAccessibles || !aNRowHeaderCells)
     return E_INVALIDARG;
 
@@ -167,11 +189,15 @@ ia2AccessibleTableCell::get_rowHeaderCells(IUnknown*** aCellAccessibles,
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_rowIndex(long* aRowIdx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRowIdx)
     return E_INVALIDARG;
 
@@ -181,6 +207,8 @@ ia2AccessibleTableCell::get_rowIndex(long* aRowIdx)
 
   *aRowIdx = mTableCell->RowIdx();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -189,6 +217,8 @@ ia2AccessibleTableCell::get_rowColumnExtents(long* aRowIdx, long* aColIdx,
                                              long* aColExtents,
                                              boolean* aIsSelected)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRowIdx || !aColIdx || !aRowExtents || !aColExtents || !aIsSelected)
     return E_INVALIDARG;
 
@@ -204,11 +234,15 @@ ia2AccessibleTableCell::get_rowColumnExtents(long* aRowIdx, long* aColIdx,
   *aIsSelected = mTableCell->Selected();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_isSelected(boolean* aIsSelected)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aIsSelected)
     return E_INVALIDARG;
 
@@ -218,4 +252,6 @@ ia2AccessibleTableCell::get_isSelected(boolean* aIsSelected)
 
   *aIsSelected = mTableCell->Selected();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/accessible/windows/ia2/ia2AccessibleText.cpp b/accessible/windows/ia2/ia2AccessibleText.cpp
index 86b3abdf6..7ac766f30 100644
--- a/accessible/windows/ia2/ia2AccessibleText.cpp
+++ b/accessible/windows/ia2/ia2AccessibleText.cpp
@@ -28,6 +28,8 @@ bool ia2AccessibleText::sLastTextChangeWasInsert = false;
 STDMETHODIMP
 ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -36,12 +38,16 @@ ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
 
   return textAcc->AddToSelection(aStartOffset, aEndOffset) ?
     S_OK : E_INVALIDARG;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
                                   long *aEndOffset, BSTR *aTextAttributes)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStartOffset || !aEndOffset || !aTextAttributes)
     return E_INVALIDARG;
 
@@ -68,11 +74,15 @@ ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
   *aEndOffset = endOffset;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_caretOffset(long *aOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aOffset)
     return E_INVALIDARG;
 
@@ -87,6 +97,8 @@ ia2AccessibleText::get_caretOffset(long *aOffset)
   *aOffset = textAcc->CaretOffset();
 
   return *aOffset != -1 ? S_OK : S_FALSE;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -95,6 +107,8 @@ ia2AccessibleText::get_characterExtents(long aOffset,
                                         long* aX, long* aY,
                                         long* aWidth, long* aHeight)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aX || !aY || !aWidth || !aHeight)
     return E_INVALIDARG;
   *aX = *aY = *aWidth = *aHeight = 0;
@@ -115,11 +129,15 @@ ia2AccessibleText::get_characterExtents(long aOffset,
   *aWidth = rect.width;
   *aHeight = rect.height;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_nSelections(long* aNSelections)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNSelections)
     return E_INVALIDARG;
   *aNSelections = 0;
@@ -133,6 +151,8 @@ ia2AccessibleText::get_nSelections(long* aNSelections)
   *aNSelections = textAcc->SelectionCount();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -140,6 +160,8 @@ ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
                                      enum IA2CoordinateType aCoordType,
                                      long* aOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aOffset)
     return E_INVALIDARG;
   *aOffset = 0;
@@ -157,12 +179,16 @@ ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
   *aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType);
 
   return *aOffset == -1 ? S_FALSE : S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset,
                                  long* aEndOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStartOffset || !aEndOffset)
     return E_INVALIDARG;
   *aStartOffset = *aEndOffset = 0;
@@ -181,11 +207,15 @@ ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset,
   *aStartOffset = startOffset;
   *aEndOffset = endOffset;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aText)
     return E_INVALIDARG;
 
@@ -209,6 +239,8 @@ ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText)
 
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -217,6 +249,8 @@ ia2AccessibleText::get_textBeforeOffset(long aOffset,
                                         long* aStartOffset, long* aEndOffset,
                                         BSTR* aText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStartOffset || !aEndOffset || !aText)
     return E_INVALIDARG;
 
@@ -253,6 +287,8 @@ ia2AccessibleText::get_textBeforeOffset(long aOffset,
 
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -261,6 +297,8 @@ ia2AccessibleText::get_textAfterOffset(long aOffset,
                                        long* aStartOffset, long* aEndOffset,
                                        BSTR* aText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStartOffset || !aEndOffset || !aText)
     return E_INVALIDARG;
 
@@ -297,6 +335,8 @@ ia2AccessibleText::get_textAfterOffset(long aOffset,
 
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -305,6 +345,8 @@ ia2AccessibleText::get_textAtOffset(long aOffset,
                                     long* aStartOffset, long* aEndOffset,
                                     BSTR* aText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStartOffset || !aEndOffset || !aText)
     return E_INVALIDARG;
 
@@ -339,11 +381,15 @@ ia2AccessibleText::get_textAtOffset(long aOffset,
 
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::removeSelection(long aSelectionIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -352,11 +398,15 @@ ia2AccessibleText::removeSelection(long aSelectionIndex)
 
   return textAcc->RemoveFromSelection(aSelectionIndex) ?
     S_OK : E_INVALIDARG;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::setCaretOffset(long aOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -368,12 +418,16 @@ ia2AccessibleText::setCaretOffset(long aOffset)
 
   textAcc->SetCaretOffset(aOffset);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
                                 long aEndOffset)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -382,11 +436,15 @@ ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
 
   return textAcc->SetSelectionBoundsAt(aSelectionIndex, aStartOffset, aEndOffset) ?
     S_OK : E_INVALIDARG;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_nCharacters(long* aNCharacters)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNCharacters)
     return E_INVALIDARG;
   *aNCharacters = 0;
@@ -399,12 +457,16 @@ ia2AccessibleText::get_nCharacters(long* aNCharacters)
 
   *aNCharacters  = textAcc->CharacterCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
                                      enum IA2ScrollType aScrollType)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   MOZ_ASSERT(!HyperTextProxyFor(this));
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
@@ -416,6 +478,8 @@ ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
 
   textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -423,6 +487,8 @@ ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
                                           enum IA2CoordinateType aCoordType,
                                           long aX, long aY)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
     nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
@@ -439,18 +505,28 @@ ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
   textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
                                   geckoCoordType, aX, aY);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_newText(IA2TextSegment *aNewText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   return GetModifiedText(true, aNewText);
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_oldText(IA2TextSegment *aOldText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   return GetModifiedText(false, aOldText);
+
+  A11Y_TRYBLOCK_END
 }
 
 // ia2AccessibleText
diff --git a/accessible/windows/ia2/ia2AccessibleValue.cpp b/accessible/windows/ia2/ia2AccessibleValue.cpp
index 44d2c31fb..e33442295 100644
--- a/accessible/windows/ia2/ia2AccessibleValue.cpp
+++ b/accessible/windows/ia2/ia2AccessibleValue.cpp
@@ -46,6 +46,8 @@ ia2AccessibleValue::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ia2AccessibleValue::get_currentValue(VARIANT* aCurrentValue)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aCurrentValue)
     return E_INVALIDARG;
 
@@ -66,11 +68,15 @@ ia2AccessibleValue::get_currentValue(VARIANT* aCurrentValue)
   aCurrentValue->vt = VT_R8;
   aCurrentValue->dblVal = currentValue;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleValue::setCurrentValue(VARIANT aValue)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (aValue.vt != VT_R8)
     return E_INVALIDARG;
 
@@ -81,11 +87,15 @@ ia2AccessibleValue::setCurrentValue(VARIANT aValue)
     return CO_E_OBJNOTCONNECTED;
 
   return valueAcc->SetCurValue(aValue.dblVal) ? S_OK : E_FAIL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleValue::get_maximumValue(VARIANT* aMaximumValue)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aMaximumValue)
     return E_INVALIDARG;
 
@@ -106,11 +116,15 @@ ia2AccessibleValue::get_maximumValue(VARIANT* aMaximumValue)
   aMaximumValue->vt = VT_R8;
   aMaximumValue->dblVal = maximumValue;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleValue::get_minimumValue(VARIANT* aMinimumValue)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aMinimumValue)
     return E_INVALIDARG;
 
@@ -131,5 +145,7 @@ ia2AccessibleValue::get_minimumValue(VARIANT* aMinimumValue)
   aMinimumValue->vt = VT_R8;
   aMinimumValue->dblVal = minimumValue;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp
index 426270814..6112c370a 100644
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -110,6 +110,8 @@ AccessibleWrap::Shutdown()
 STDMETHODIMP
 AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!ppv)
     return E_INVALIDARG;
 
@@ -163,6 +165,8 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 //-----------------------------------------------------
@@ -172,6 +176,8 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 AccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!ppdispParent)
     return E_INVALIDARG;
 
@@ -202,11 +208,15 @@ AccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
 
   *ppdispParent = NativeAccessible(xpParentAcc);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pcountChildren)
     return E_INVALIDARG;
 
@@ -220,6 +230,8 @@ AccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren)
 
   *pcountChildren = ChildCount();
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -227,6 +239,8 @@ AccessibleWrap::get_accChild(
       /* [in] */ VARIANT varChild,
       /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!ppdispChild)
     return E_INVALIDARG;
 
@@ -251,6 +265,8 @@ AccessibleWrap::get_accChild(
 
   child.forget(ppdispChild);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 /**
@@ -315,6 +331,8 @@ AccessibleWrap::get_accName(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszName)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pszName || varChild.vt != VT_I4)
     return E_INVALIDARG;
 
@@ -343,6 +361,8 @@ AccessibleWrap::get_accName(
   if (!*pszName)
     return E_OUTOFMEMORY;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 
@@ -351,6 +371,8 @@ AccessibleWrap::get_accValue(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszValue)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pszValue)
     return E_INVALIDARG;
 
@@ -379,12 +401,16 @@ AccessibleWrap::get_accValue(
   if (!*pszValue)
     return E_OUTOFMEMORY;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_accDescription(VARIANT varChild,
                                    BSTR __RPC_FAR *pszDescription)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pszDescription)
     return E_INVALIDARG;
 
@@ -406,6 +432,8 @@ AccessibleWrap::get_accDescription(VARIANT varChild,
   *pszDescription = ::SysAllocStringLen(description.get(),
                                         description.Length());
   return *pszDescription ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -413,6 +441,8 @@ AccessibleWrap::get_accRole(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarRole)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pvarRole)
     return E_INVALIDARG;
 
@@ -502,6 +532,8 @@ AccessibleWrap::get_accRole(
   }
 
   return E_FAIL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -509,6 +541,8 @@ AccessibleWrap::get_accState(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarState)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pvarState)
     return E_INVALIDARG;
 
@@ -540,6 +574,8 @@ AccessibleWrap::get_accState(
   nsAccUtils::To32States(state, &msaaState, nullptr);
   pvarState->lVal = msaaState;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 
@@ -548,11 +584,15 @@ AccessibleWrap::get_accHelp(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszHelp)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pszHelp)
     return E_INVALIDARG;
 
   *pszHelp = nullptr;
   return S_FALSE;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -561,12 +601,16 @@ AccessibleWrap::get_accHelpTopic(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ long __RPC_FAR *pidTopic)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pszHelpFile || !pidTopic)
     return E_INVALIDARG;
 
   *pszHelpFile = nullptr;
   *pidTopic = 0;
   return S_FALSE;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -574,6 +618,8 @@ AccessibleWrap::get_accKeyboardShortcut(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pszKeyboardShortcut)
     return E_INVALIDARG;
   *pszKeyboardShortcut = nullptr;
@@ -599,12 +645,16 @@ AccessibleWrap::get_accKeyboardShortcut(
   *pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(),
                                              shortcut.Length());
   return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_accFocus(
       /* [retval][out] */ VARIANT __RPC_FAR *pvarChild)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pvarChild)
     return E_INVALIDARG;
 
@@ -635,6 +685,8 @@ AccessibleWrap::get_accFocus(
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 /**
@@ -671,6 +723,8 @@ private:
 STDMETHODIMP
 AccessibleEnumerator::QueryInterface(REFIID iid, void ** ppvObject)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (iid == IID_IEnumVARIANT) {
     *ppvObject = static_cast<IEnumVARIANT*>(this);
     AddRef();
@@ -684,11 +738,15 @@ AccessibleEnumerator::QueryInterface(REFIID iid, void ** ppvObject)
 
   *ppvObject = nullptr;
   return E_NOINTERFACE;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long FAR* pceltFetched)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   uint32_t length = mArray.Length();
   HRESULT hr = S_OK;
 
@@ -708,21 +766,29 @@ AccessibleEnumerator::Next(unsigned long celt, VARIANT FAR* rgvar, unsigned long
     *pceltFetched = celt;
 
   return hr;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleEnumerator::Clone(IEnumVARIANT FAR* FAR* ppenum)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   *ppenum = new AccessibleEnumerator(*this);
   if (!*ppenum)
     return E_OUTOFMEMORY;
   NS_ADDREF(*ppenum);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleEnumerator::Skip(unsigned long celt)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   uint32_t length = mArray.Length();
   // Check if we can skip the requested number of elements
   if (celt > length - mCurIndex) {
@@ -731,6 +797,8 @@ AccessibleEnumerator::Skip(unsigned long celt)
   }
   mCurIndex += celt;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 /**
@@ -753,6 +821,8 @@ AccessibleEnumerator::Skip(unsigned long celt)
 STDMETHODIMP
 AccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pvarChildren)
     return E_INVALIDARG;
 
@@ -772,6 +842,8 @@ AccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren)
     NS_ADDREF(pvarChildren->punkVal = pEnum);
   }
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -779,6 +851,8 @@ AccessibleWrap::get_accDefaultAction(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pszDefaultAction)
     return E_INVALIDARG;
 
@@ -800,6 +874,8 @@ AccessibleWrap::get_accDefaultAction(
   *pszDefaultAction = ::SysAllocStringLen(defaultAction.get(),
                                           defaultAction.Length());
   return *pszDefaultAction ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -807,6 +883,8 @@ AccessibleWrap::accSelect(
       /* [in] */ long flagsSelect,
       /* [optional][in] */ VARIANT varChild)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   RefPtr<IAccessible> accessible;
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
@@ -848,6 +926,8 @@ AccessibleWrap::accSelect(
   }
 
   return E_FAIL;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -858,6 +938,8 @@ AccessibleWrap::accLocation(
       /* [out] */ long __RPC_FAR *pcyHeight,
       /* [optional][in] */ VARIANT varChild)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pxLeft || !pyTop || !pcxWidth || !pcyHeight)
     return E_INVALIDARG;
 
@@ -884,6 +966,8 @@ AccessibleWrap::accLocation(
   *pcxWidth = rect.width;
   *pcyHeight = rect.height;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -892,6 +976,8 @@ AccessibleWrap::accNavigate(
       /* [optional][in] */ VARIANT varStart,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pvarEndUpAt)
     return E_INVALIDARG;
 
@@ -974,6 +1060,8 @@ AccessibleWrap::accNavigate(
   pvarEndUpAt->pdispVal = NativeAccessible(navAccessible);
   pvarEndUpAt->vt = VT_DISPATCH;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -982,6 +1070,8 @@ AccessibleWrap::accHitTest(
       /* [in] */ long yTop,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarChild)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!pvarChild)
     return E_INVALIDARG;
 
@@ -1008,12 +1098,16 @@ AccessibleWrap::accHitTest(
     return S_FALSE;
   }
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::accDoDefaultAction(
       /* [optional][in] */ VARIANT varChild)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   RefPtr<IAccessible> accessible;
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
@@ -1025,6 +1119,8 @@ AccessibleWrap::accDoDefaultAction(
   }
 
   return DoAction(0) ? S_OK : E_INVALIDARG;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
diff --git a/accessible/windows/msaa/ApplicationAccessibleWrap.cpp b/accessible/windows/msaa/ApplicationAccessibleWrap.cpp
index ec9d511e4..b78a8dd55 100644
--- a/accessible/windows/msaa/ApplicationAccessibleWrap.cpp
+++ b/accessible/windows/msaa/ApplicationAccessibleWrap.cpp
@@ -69,6 +69,8 @@ ApplicationAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 STDMETHODIMP
 ApplicationAccessibleWrap::get_appName(BSTR* aName)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aName)
     return E_INVALIDARG;
 
@@ -84,11 +86,15 @@ ApplicationAccessibleWrap::get_appName(BSTR* aName)
 
   *aName = ::SysAllocStringLen(name.get(), name.Length());
   return *aName ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ApplicationAccessibleWrap::get_appVersion(BSTR* aVersion)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aVersion)
     return E_INVALIDARG;
 
@@ -104,11 +110,15 @@ ApplicationAccessibleWrap::get_appVersion(BSTR* aVersion)
 
   *aVersion = ::SysAllocStringLen(version.get(), version.Length());
   return *aVersion ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ApplicationAccessibleWrap::get_toolkitName(BSTR* aName)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aName)
     return E_INVALIDARG;
 
@@ -122,11 +132,15 @@ ApplicationAccessibleWrap::get_toolkitName(BSTR* aName)
 
   *aName = ::SysAllocStringLen(name.get(), name.Length());
   return *aName ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ApplicationAccessibleWrap::get_toolkitVersion(BSTR* aVersion)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aVersion)
     return E_INVALIDARG;
 
@@ -142,5 +156,7 @@ ApplicationAccessibleWrap::get_toolkitVersion(BSTR* aVersion)
 
   *aVersion = ::SysAllocStringLen(version.get(), version.Length());
   return *aVersion ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
diff --git a/accessible/windows/msaa/DocAccessibleWrap.cpp b/accessible/windows/msaa/DocAccessibleWrap.cpp
index 895fe9192..6fb89816d 100644
--- a/accessible/windows/msaa/DocAccessibleWrap.cpp
+++ b/accessible/windows/msaa/DocAccessibleWrap.cpp
@@ -65,6 +65,8 @@ DocAccessibleWrap::get_accParent(
 STDMETHODIMP
 DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aValue)
     return E_INVALIDARG;
   *aValue = nullptr;
@@ -88,6 +90,8 @@ DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue)
 
   *aValue = ::SysAllocStringLen(url.get(), url.Length());
   return *aValue ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/accessible/windows/msaa/EnumVariant.cpp b/accessible/windows/msaa/EnumVariant.cpp
index 2344208a3..86c81a105 100644
--- a/accessible/windows/msaa/EnumVariant.cpp
+++ b/accessible/windows/msaa/EnumVariant.cpp
@@ -21,6 +21,8 @@ STDMETHODIMP
 ChildrenEnumVariant::Next(ULONG aCount, VARIANT FAR* aItems,
                           ULONG FAR* aCountFetched)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aItems || !aCountFetched)
     return E_INVALIDARG;
 
@@ -53,11 +55,15 @@ ChildrenEnumVariant::Next(ULONG aCount, VARIANT FAR* aItems,
   (*aCountFetched) = countFetched;
 
   return countFetched < aCount ? S_FALSE : S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ChildrenEnumVariant::Skip(ULONG aCount)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (mAnchorAcc->IsDefunct() || mAnchorAcc->GetChildAt(mCurIndex) != mCurAcc)
     return CO_E_OBJNOTCONNECTED;
 
@@ -65,11 +71,15 @@ ChildrenEnumVariant::Skip(ULONG aCount)
   mCurAcc = mAnchorAcc->GetChildAt(mCurIndex);
 
   return mCurAcc ? S_OK : S_FALSE;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ChildrenEnumVariant::Reset()
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (mAnchorAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
@@ -77,11 +87,15 @@ ChildrenEnumVariant::Reset()
   mCurAcc = mAnchorAcc->GetChildAt(0);
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ChildrenEnumVariant::Clone(IEnumVARIANT** aEnumVariant)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aEnumVariant)
     return E_INVALIDARG;
 
@@ -89,4 +103,6 @@ ChildrenEnumVariant::Clone(IEnumVARIANT** aEnumVariant)
   (*aEnumVariant)->AddRef();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/accessible/windows/msaa/IUnknownImpl.cpp b/accessible/windows/msaa/IUnknownImpl.cpp
index c74f86e33..4a9fa5383 100644
--- a/accessible/windows/msaa/IUnknownImpl.cpp
+++ b/accessible/windows/msaa/IUnknownImpl.cpp
@@ -37,5 +37,22 @@ GetHRESULT(nsresult aResult)
   }
 }
 
+int
+FilterExceptions(unsigned int aCode, EXCEPTION_POINTERS* aExceptionInfo)
+{
+  if (aCode == EXCEPTION_ACCESS_VIOLATION) {
+#ifdef MOZ_CRASHREPORTER
+    // MSAA swallows crashes (because it is COM-based) but we still need to
+    // learn about those crashes so we can fix them. Make sure to pass them to
+    // the crash reporter.
+    CrashReporter::WriteMinidumpForException(aExceptionInfo);
+#endif
+  } else {
+    NS_NOTREACHED("We should only be catching crash exceptions");
+  }
+
+  return EXCEPTION_CONTINUE_SEARCH;
+}
+
 } // namespace a11y
 } // namespace mozilla
diff --git a/accessible/windows/msaa/IUnknownImpl.h b/accessible/windows/msaa/IUnknownImpl.h
index d939a4dfa..dbf6c1374 100644
--- a/accessible/windows/msaa/IUnknownImpl.h
+++ b/accessible/windows/msaa/IUnknownImpl.h
@@ -79,6 +79,7 @@ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**);              \
 STDMETHODIMP                                                                   \
 Class::QueryInterface(REFIID aIID, void** aInstancePtr)                        \
 {                                                                              \
+  A11Y_TRYBLOCK_BEGIN                                                          \
   if (!aInstancePtr)                                                           \
     return E_INVALIDARG;                                                       \
   *aInstancePtr = nullptr;                                                     \
@@ -87,14 +88,17 @@ Class::QueryInterface(REFIID aIID, void** aInstancePtr)                        \
 
 #define IMPL_IUNKNOWN_QUERY_TAIL                                               \
   return hr;                                                                   \
+  A11Y_TRYBLOCK_END                                                            \
 }
 
 #define IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(Member)                            \
   return Member->QueryInterface(aIID, aInstancePtr);                           \
+  A11Y_TRYBLOCK_END                                                            \
 }
 
 #define IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(BaseClass)                          \
   return BaseClass::QueryInterface(aIID, aInstancePtr);                        \
+  A11Y_TRYBLOCK_END                                                            \
 }
 
 #define IMPL_IUNKNOWN_QUERY_IFACE(Iface)                                       \
@@ -154,6 +158,21 @@ Class::QueryInterface(REFIID aIID, void** aInstancePtr)                        \
   IMPL_IUNKNOWN_QUERY_CLASS(Super2);                                           \
   IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0)
 
+
+/**
+ * Wrap every method body by these macroses to pass exception to the crash
+ * reporter.
+ */
+#define A11Y_TRYBLOCK_BEGIN                                                    \
+  MOZ_SEH_TRY {
+
+#define A11Y_TRYBLOCK_END                                                      \
+  } MOZ_SEH_EXCEPT(mozilla::a11y::FilterExceptions(::GetExceptionCode(),       \
+                                                   GetExceptionInformation())) \
+  { }                                                                          \
+  return E_FAIL;
+
+
 namespace mozilla {
 namespace a11y {
 
@@ -162,6 +181,11 @@ namespace a11y {
  */
 HRESULT GetHRESULT(nsresult aResult);
 
+/**
+ * Used to pass an exception to the crash reporter.
+ */
+int FilterExceptions(unsigned int aCode, EXCEPTION_POINTERS* aExceptionInfo);
+
 } // namespace a11y;
 } //namespace mozilla;
 
diff --git a/accessible/windows/sdn/sdnAccessible.cpp b/accessible/windows/sdn/sdnAccessible.cpp
index d90631c8f..909b0779c 100644
--- a/accessible/windows/sdn/sdnAccessible.cpp
+++ b/accessible/windows/sdn/sdnAccessible.cpp
@@ -28,6 +28,8 @@ using namespace mozilla::a11y;
 STDMETHODIMP
 sdnAccessible::QueryInterface(REFIID aREFIID, void** aInstancePtr)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aInstancePtr)
     return E_FAIL;
   *aInstancePtr = nullptr;
@@ -51,6 +53,8 @@ sdnAccessible::QueryInterface(REFIID aREFIID, void** aInstancePtr)
   }
 
   return E_NOINTERFACE;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -61,6 +65,8 @@ sdnAccessible::get_nodeInfo(BSTR __RPC_FAR* aNodeName,
                             unsigned int __RPC_FAR* aUniqueID,
                             unsigned short __RPC_FAR* aNodeType)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNodeName || !aNameSpaceID || !aNodeValue || !aNumChildren ||
       !aUniqueID || !aNodeType)
     return E_INVALIDARG;
@@ -108,6 +114,8 @@ sdnAccessible::get_nodeInfo(BSTR __RPC_FAR* aNodeName,
   *aNumChildren = mNode->GetChildCount();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -117,6 +125,8 @@ sdnAccessible::get_attributes(unsigned  short aMaxAttribs,
                               BSTR __RPC_FAR* aAttribValues,
                               unsigned short __RPC_FAR* aNumAttribs)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAttribNames || !aNameSpaceIDs || !aAttribValues || !aNumAttribs)
     return E_INVALIDARG;
 
@@ -149,6 +159,8 @@ sdnAccessible::get_attributes(unsigned  short aMaxAttribs,
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -157,6 +169,8 @@ sdnAccessible::get_attributesForNames(unsigned short aMaxAttribs,
                                       short __RPC_FAR* aNameSpaceID,
                                       BSTR __RPC_FAR* aAttribValues)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAttribNames || !aNameSpaceID || !aAttribValues)
     return E_INVALIDARG;
 
@@ -193,6 +207,8 @@ sdnAccessible::get_attributesForNames(unsigned short aMaxAttribs,
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -202,6 +218,8 @@ sdnAccessible::get_computedStyle(unsigned short aMaxStyleProperties,
                                  BSTR __RPC_FAR* aStyleValues,
                                  unsigned short __RPC_FAR* aNumStyleProperties)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStyleProperties || aStyleValues || !aNumStyleProperties)
     return E_INVALIDARG;
 
@@ -239,6 +257,8 @@ sdnAccessible::get_computedStyle(unsigned short aMaxStyleProperties,
   *aNumStyleProperties = static_cast<unsigned short>(realIndex);
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -247,6 +267,8 @@ sdnAccessible::get_computedStyleForProperties(unsigned short aNumStyleProperties
                                               BSTR __RPC_FAR* aStyleProperties,
                                               BSTR __RPC_FAR* aStyleValues)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aStyleProperties || !aStyleValues)
     return E_INVALIDARG;
 
@@ -269,11 +291,15 @@ sdnAccessible::get_computedStyleForProperties(unsigned short aNumStyleProperties
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::scrollTo(boolean aScrollTopLeft)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   DocAccessible* document = GetDocument();
   if (!document) // that's IsDefunct check
     return CO_E_OBJNOTCONNECTED;
@@ -287,11 +313,15 @@ sdnAccessible::scrollTo(boolean aScrollTopLeft)
 
   nsCoreUtils::ScrollTo(document->PresShell(), mNode->AsContent(), scrollType);
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNode)
     return E_INVALIDARG;
   *aNode = nullptr;
@@ -306,11 +336,15 @@ sdnAccessible::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNode)
     return E_INVALIDARG;
   *aNode = nullptr;
@@ -325,11 +359,15 @@ sdnAccessible::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNode)
     return E_INVALIDARG;
   *aNode = nullptr;
@@ -344,11 +382,15 @@ sdnAccessible::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNode)
     return E_INVALIDARG;
   *aNode = nullptr;
@@ -363,11 +405,15 @@ sdnAccessible::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNode)
     return E_INVALIDARG;
   *aNode = nullptr;
@@ -382,12 +428,16 @@ sdnAccessible::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_childAt(unsigned aChildIndex,
                            ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNode)
     return E_INVALIDARG;
   *aNode = nullptr;
@@ -403,11 +453,15 @@ sdnAccessible::get_childAt(unsigned aChildIndex,
 
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_innerHTML(BSTR __RPC_FAR* aInnerHTML)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aInnerHTML)
     return E_INVALIDARG;
   *aInnerHTML = nullptr;
@@ -428,11 +482,15 @@ sdnAccessible::get_innerHTML(BSTR __RPC_FAR* aInnerHTML)
     return E_OUTOFMEMORY;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_localInterface(void __RPC_FAR *__RPC_FAR* aLocalInterface)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aLocalInterface)
     return E_INVALIDARG;
   *aLocalInterface = nullptr;
@@ -444,11 +502,15 @@ sdnAccessible::get_localInterface(void __RPC_FAR *__RPC_FAR* aLocalInterface)
   AddRef();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnAccessible::get_language(BSTR __RPC_FAR* aLanguage)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aLanguage)
     return E_INVALIDARG;
   *aLanguage = nullptr;
@@ -472,4 +534,6 @@ sdnAccessible::get_language(BSTR __RPC_FAR* aLanguage)
    return E_OUTOFMEMORY;
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/accessible/windows/sdn/sdnDocAccessible.cpp b/accessible/windows/sdn/sdnDocAccessible.cpp
index a1c5be872..07b39e66f 100644
--- a/accessible/windows/sdn/sdnDocAccessible.cpp
+++ b/accessible/windows/sdn/sdnDocAccessible.cpp
@@ -24,6 +24,8 @@ IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible)
 STDMETHODIMP
 sdnDocAccessible::get_URL(BSTR __RPC_FAR* aURL)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aURL)
     return E_INVALIDARG;
   *aURL = nullptr;
@@ -38,11 +40,15 @@ sdnDocAccessible::get_URL(BSTR __RPC_FAR* aURL)
 
   *aURL = ::SysAllocStringLen(URL.get(), URL.Length());
   return *aURL ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnDocAccessible::get_title(BSTR __RPC_FAR* aTitle)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aTitle)
     return E_INVALIDARG;
   *aTitle = nullptr;
@@ -54,11 +60,15 @@ sdnDocAccessible::get_title(BSTR __RPC_FAR* aTitle)
   mAccessible->Title(title);
   *aTitle = ::SysAllocStringLen(title.get(), title.Length());
   return *aTitle ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnDocAccessible::get_mimeType(BSTR __RPC_FAR* aMimeType)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aMimeType)
     return E_INVALIDARG;
   *aMimeType = nullptr;
@@ -73,11 +83,15 @@ sdnDocAccessible::get_mimeType(BSTR __RPC_FAR* aMimeType)
 
   *aMimeType = ::SysAllocStringLen(mimeType.get(), mimeType.Length());
   return *aMimeType ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnDocAccessible::get_docType(BSTR __RPC_FAR* aDocType)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aDocType)
     return E_INVALIDARG;
   *aDocType = nullptr;
@@ -92,12 +106,16 @@ sdnDocAccessible::get_docType(BSTR __RPC_FAR* aDocType)
 
   *aDocType = ::SysAllocStringLen(docType.get(), docType.Length());
   return *aDocType ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnDocAccessible::get_nameSpaceURIForID(short aNameSpaceID,
                                         BSTR __RPC_FAR* aNameSpaceURI)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aNameSpaceURI)
     return E_INVALIDARG;
   *aNameSpaceURI = nullptr;
@@ -120,14 +138,20 @@ sdnDocAccessible::get_nameSpaceURIForID(short aNameSpaceID,
                                        nameSpaceURI.Length());
 
   return *aNameSpaceURI ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnDocAccessible::put_alternateViewMediaTypes(BSTR __RPC_FAR* aCommaSeparatedMediaTypes)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aCommaSeparatedMediaTypes)
     return E_INVALIDARG;
   *aCommaSeparatedMediaTypes = nullptr;
 
   return mAccessible->IsDefunct() ? CO_E_OBJNOTCONNECTED : E_NOTIMPL;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/accessible/windows/sdn/sdnTextAccessible.cpp b/accessible/windows/sdn/sdnTextAccessible.cpp
index b6f580ba3..b51caf44e 100644
--- a/accessible/windows/sdn/sdnTextAccessible.cpp
+++ b/accessible/windows/sdn/sdnTextAccessible.cpp
@@ -33,6 +33,8 @@ IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible)
 STDMETHODIMP
 sdnTextAccessible::get_domText(BSTR __RPC_FAR* aText)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aText)
     return E_INVALIDARG;
   *aText = nullptr;
@@ -49,6 +51,8 @@ sdnTextAccessible::get_domText(BSTR __RPC_FAR* aText)
 
   *aText = ::SysAllocStringLen(nodeValue.get(), nodeValue.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -59,6 +63,8 @@ sdnTextAccessible::get_clippedSubstringBounds(unsigned int aStartIndex,
                                               int __RPC_FAR* aWidth,
                                               int __RPC_FAR* aHeight)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   nscoord x = 0, y = 0, width = 0, height = 0;
   HRESULT rv = get_unclippedSubstringBounds(aStartIndex, aEndIndex,
                                             &x, &y, &width, &height);
@@ -80,6 +86,8 @@ sdnTextAccessible::get_clippedSubstringBounds(unsigned int aStartIndex,
   *aWidth = clippedRect.width;
   *aHeight = clippedRect.height;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
@@ -90,6 +98,8 @@ sdnTextAccessible::get_unclippedSubstringBounds(unsigned int aStartIndex,
                                                 int __RPC_FAR* aWidth,
                                                 int __RPC_FAR* aHeight)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aX || !aY || !aWidth || !aHeight)
     return E_INVALIDARG;
   *aX = *aY = *aWidth = *aHeight = 0;
@@ -125,12 +135,16 @@ sdnTextAccessible::get_unclippedSubstringBounds(unsigned int aStartIndex,
   *aHeight = presContext->AppUnitsToDevPixels(sum.height);
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
                                      unsigned int aEndIndex)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (mAccessible->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
@@ -145,11 +159,15 @@ sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
     nsCoreUtils::ScrollSubstringTo(mAccessible->GetFrame(), range,
                                    nsIAccessibleScrollType::SCROLL_TYPE_ANYWHERE);
   return GetHRESULT(rv);
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aFontFamily)
     return E_INVALIDARG;
   *aFontFamily = nullptr;
@@ -171,6 +189,8 @@ sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily)
 
   *aFontFamily = ::SysAllocStringLen(name.get(), name.Length());
   return *aFontFamily ? S_OK : E_OUTOFMEMORY;
+
+  A11Y_TRYBLOCK_END
 }
 
 nsIFrame*
diff --git a/accessible/windows/uia/uiaRawElmProvider.cpp b/accessible/windows/uia/uiaRawElmProvider.cpp
index 3121661e1..54e54766d 100644
--- a/accessible/windows/uia/uiaRawElmProvider.cpp
+++ b/accessible/windows/uia/uiaRawElmProvider.cpp
@@ -28,18 +28,24 @@ STDMETHODIMP
 uiaRawElmProvider::GetObjectForChild(long aIdChild,
                                      __RPC__deref_out_opt IAccessibleEx** aAccEx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAccEx)
     return E_INVALIDARG;
 
   *aAccEx = nullptr;
 
   return mAcc->IsDefunct() ? CO_E_OBJNOTCONNECTED : S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::GetIAccessiblePair(__RPC__deref_out_opt IAccessible** aAcc,
                                       __RPC__out long* aIdChild)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aAcc || !aIdChild)
     return E_INVALIDARG;
 
@@ -54,11 +60,15 @@ uiaRawElmProvider::GetIAccessiblePair(__RPC__deref_out_opt IAccessible** aAcc,
   mAcc->AddRef();
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::GetRuntimeId(__RPC__deref_out_opt SAFEARRAY** aRuntimeIds)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRuntimeIds)
     return E_INVALIDARG;
 
@@ -71,12 +81,16 @@ uiaRawElmProvider::GetRuntimeId(__RPC__deref_out_opt SAFEARRAY** aRuntimeIds)
     SafeArrayPutElement(*aRuntimeIds, &i, (void*)&(ids[i]));
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::ConvertReturnedElement(__RPC__in_opt IRawElementProviderSimple* aRawElmProvider,
                                           __RPC__deref_out_opt IAccessibleEx** aAccEx)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRawElmProvider || !aAccEx)
     return E_INVALIDARG;
 
@@ -88,6 +102,8 @@ uiaRawElmProvider::ConvertReturnedElement(__RPC__in_opt IRawElementProviderSimpl
     *aAccEx = static_cast<IAccessibleEx*>(instancePtr);
 
   return hr;
+
+  A11Y_TRYBLOCK_END
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -96,29 +112,39 @@ uiaRawElmProvider::ConvertReturnedElement(__RPC__in_opt IRawElementProviderSimpl
 STDMETHODIMP
 uiaRawElmProvider::get_ProviderOptions(__RPC__out enum ProviderOptions* aOptions)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aOptions)
     return E_INVALIDARG;
 
   // This method is not used with IAccessibleEx implementations.
   *aOptions = ProviderOptions_ServerSideProvider;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::GetPatternProvider(PATTERNID aPatternId,
                                       __RPC__deref_out_opt IUnknown** aPatternProvider)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aPatternProvider)
     return E_INVALIDARG;
 
   *aPatternProvider = nullptr;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId,
                                     __RPC__out VARIANT* aPropertyValue)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aPropertyValue)
     return E_INVALIDARG;
 
@@ -200,15 +226,21 @@ uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId,
   }
 
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::get_HostRawElementProvider(__RPC__deref_out_opt IRawElementProviderSimple** aRawElmProvider)
 {
+  A11Y_TRYBLOCK_BEGIN
+
   if (!aRawElmProvider)
     return E_INVALIDARG;
 
   // This method is not used with IAccessibleEx implementations.
   *aRawElmProvider = nullptr;
   return S_OK;
+
+  A11Y_TRYBLOCK_END
 }
diff --git a/browser/app/basilisk.exe.manifest b/browser/app/basilisk.exe.manifest
index 079e15b58..bf5aac416 100644
--- a/browser/app/basilisk.exe.manifest
+++ b/browser/app/basilisk.exe.manifest
@@ -37,6 +37,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/browser/base/content/browser-media.js b/browser/base/content/browser-media.js
index a013dbd8a..81e7faf17 100644
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -201,16 +201,29 @@ let gDecoderDoctorHandler = {
   getLabelForNotificationBox(type) {
     if (type == "adobe-cdm-not-found" &&
         AppConstants.platform == "win") {
+      if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
+        // We supply our own Learn More button so we don't need to populate the message here.
+        return gNavigatorBundle.getFormattedString("emeNotifications.drmContentDisabled.message", [""]);
+      }
       return gNavigatorBundle.getString("decoder.noCodecs.message");
     }
     if (type == "adobe-cdm-not-activated" &&
         AppConstants.platform == "win") {
+      if (AppConstants.isPlatformAndVersionAtMost("win", "5.9")) {
+        return gNavigatorBundle.getString("decoder.noCodecsXP.message");
+      }
+      if (!AppConstants.isPlatformAndVersionAtLeast("win", "6.1")) {
+        return gNavigatorBundle.getString("decoder.noCodecsVista.message");
+      }
       return gNavigatorBundle.getString("decoder.noCodecs.message");
     }
     if (type == "platform-decoder-not-found") {
-      if (AppConstants.platform == "win") {
+      if (AppConstants.isPlatformAndVersionAtLeast("win", "6.1")) {
         return gNavigatorBundle.getString("decoder.noHWAcceleration.message");
       }
+      if (AppConstants.isPlatformAndVersionAtLeast("win", "6")) {
+        return gNavigatorBundle.getString("decoder.noHWAccelerationVista.message");
+      }
       if (AppConstants.platform == "linux") {
         return gNavigatorBundle.getString("decoder.noCodecsLinux.message");
       }
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 910dc4f68..9ccd86b12 100755
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -97,6 +97,11 @@ XPCOMUtils.defineLazyGetter(this, "gCustomizeMode", function() {
   return new scope.CustomizeMode(window);
 });
 
+XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
+  // Only show resizers on Windows 2000 and XP
+  return AppConstants.isPlatformAndVersionAtMost("win", "5.9");
+});
+
 XPCOMUtils.defineLazyGetter(this, "gPrefService", function() {
   return Services.prefs;
 });
@@ -3367,6 +3372,8 @@ var PrintPreviewListener = {
     this._chromeState.notificationsOpen = !notificationBox.notificationsHidden;
     notificationBox.notificationsHidden = true;
 
+    gBrowser.updateWindowResizers();
+
     this._chromeState.findOpen = gFindBarInitialized && !gFindBar.hidden;
     if (gFindBarInitialized)
       gFindBar.close();
@@ -5215,6 +5222,7 @@ function setToolbarVisibility(toolbar, isVisible, persist=true) {
 
   PlacesToolbarHelper.init();
   BookmarkingUI.onToolbarVisibilityChange();
+  gBrowser.updateWindowResizers();
   if (isVisible)
     ToolbarIconColor.inferFromText();
 }
diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
index be17fb0e2..2c74aecdf 100644
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -546,7 +546,9 @@
 #ifdef MENUBAR_CAN_AUTOHIDE
              toolbarname="&menubarCmd.label;"
              accesskey="&menubarCmd.accesskey;"
+#if defined(MOZ_WIDGET_GTK)
              autohide="true"
+#endif
 #endif
              context="toolbar-context-menu">
       <toolbaritem id="menubar-items" align="center">
diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml
index 0cb0f3bd6..3f4c3518e 100644
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -214,6 +214,18 @@
         ]]></body>
       </method>
 
+      <method name="updateWindowResizers">
+        <body><![CDATA[
+          if (!window.gShowPageResizers)
+            return;
+
+          var show = window.windowState == window.STATE_NORMAL;
+          for (let i = 0; i < this.browsers.length; i++) {
+            this.browsers[i].showWindowResizer = show;
+          }
+        ]]></body>
+      </method>
+
       <method name="_setCloseKeyState">
         <parameter name="aEnabled"/>
         <body><![CDATA[
@@ -1958,6 +1970,10 @@
               b.QueryInterface(Ci.nsIFrameLoaderOwner).presetOpenerWindow(aParams.opener);
             }
 
+            if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) {
+              b.setAttribute("showresizer", "true");
+            }
+
             if (!aParams.isPreloadBrowser && this.hasAttribute("autocompletepopup")) {
               b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
             }
@@ -4819,6 +4835,7 @@
           this.appendChild(this._autoScrollPopup);
           this.mCurrentBrowser.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
           this.mCurrentBrowser.droppedLinkHandler = handleDroppedLink;
+          this.updateWindowResizers();
 
           // Hook up the event listeners to the first browser
           var tabListener = this.mTabProgressListener(this.mCurrentTab, this.mCurrentBrowser, true, false);
@@ -5837,6 +5854,8 @@
                 this._handleTabSelect();
                 this.mTabstripWidth = width;
               }
+
+              this.tabbrowser.updateWindowResizers();
               break;
             case "mouseout":
               // If the "related target" (the node to which the pointer went) is not
diff --git a/browser/base/jar.mn b/browser/base/jar.mn
index 3fa5ea408..60f1facc0 100644
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -8,6 +8,9 @@ browser.jar:
 %  overlay chrome://mozapps/content/update/updates.xul chrome://browser/content/softwareUpdateOverlay.xul
 %  overlay chrome://global/content/console.xul chrome://browser/content/jsConsoleOverlay.xul
 #endif
+#ifdef XP_WIN
+%  overlay chrome://browser/content/browser.xul chrome://browser/content/win6BrowserOverlay.xul os=WINNT osversion>=6
+#endif
 %  overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
 
@@ -183,6 +186,9 @@ browser.jar:
 *       content/browser/webrtcIndicator.xul           (content/webrtcIndicator.xul)
         content/browser/webrtcIndicator.js            (content/webrtcIndicator.js)
 #endif
+#ifdef XP_WIN
+        content/browser/win6BrowserOverlay.xul        (content/win6BrowserOverlay.xul)
+#endif
 # the following files are browser-specific overrides
 *       content/browser/license.html                  (/toolkit/content/license.html)
 % override chrome://global/content/license.html chrome://browser/content/license.html
diff --git a/browser/components/customizableui/CustomizableUI.jsm b/browser/components/customizableui/CustomizableUI.jsm
index 01389108d..86ff2708b 100644
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -262,14 +262,24 @@ var CustomizableUIInternal = {
       defaultCollapsed: false,
     }, true);
 
-    if (AppConstants.MENUBAR_CAN_AUTOHIDE) {
+    if (AppConstants.platform != "macosx") {
       this.registerArea(CustomizableUI.AREA_MENUBAR, {
         legacy: true,
         type: CustomizableUI.TYPE_TOOLBAR,
         defaultPlacements: [
           "menubar-items",
         ],
-        defaultCollapsed: true,
+        get defaultCollapsed() {
+          if (AppConstants.MENUBAR_CAN_AUTOHIDE) {
+            if (AppConstants.platform == "linux") {
+              return true;
+            }
+            // This is duplicated logic from /browser/base/jar.mn
+            // for win6BrowserOverlay.xul.
+            return AppConstants.isPlatformAndVersionAtLeast("win", 6);
+          }
+          return false;
+        }
       }, true);
     }
 
diff --git a/browser/components/shell/nsWindowsShellService.cpp b/browser/components/shell/nsWindowsShellService.cpp
index 879b0c7f0..cb13c0910 100644
--- a/browser/components/shell/nsWindowsShellService.cpp
+++ b/browser/components/shell/nsWindowsShellService.cpp
@@ -648,6 +648,11 @@ nsWindowsShellService::LaunchControlPanelDefaultsSelectionUI()
 nsresult
 nsWindowsShellService::LaunchControlPanelDefaultPrograms()
 {
+  // This Default Programs feature is Win7+ only.
+  if (!IsWin7OrLater()) {
+    return NS_ERROR_FAILURE;
+  }
+
   // Build the path control.exe path safely
   WCHAR controlEXEPath[MAX_PATH + 1] = { '\0' };
   if (!GetSystemDirectoryW(controlEXEPath, MAX_PATH)) {
diff --git a/browser/components/webextensions/extension-win-panel.css b/browser/components/webextensions/extension-win-panel.css
index 9da6da14c..ddafe3ea5 100644
--- a/browser/components/webextensions/extension-win-panel.css
+++ b/browser/components/webextensions/extension-win-panel.css
@@ -1,4 +1,6 @@
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   body {
     border-radius: 4px;
   }
diff --git a/browser/config/mozconfigs/win32/common-opt b/browser/config/mozconfigs/win32/common-opt
index 816c8926a..d43a9878b 100644
--- a/browser/config/mozconfigs/win32/common-opt
+++ b/browser/config/mozconfigs/win32/common-opt
@@ -4,6 +4,7 @@
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-jemalloc
+ac_add_options --enable-require-all-d3dc-versions
 
 if [ -f /c/builds/gapi.data ]; then
   _gapi_keyfile=c:/builds/gapi.data
diff --git a/browser/config/mozconfigs/win32/debug b/browser/config/mozconfigs/win32/debug
index 815276d0f..6beee93c2 100644
--- a/browser/config/mozconfigs/win32/debug
+++ b/browser/config/mozconfigs/win32/debug
@@ -6,6 +6,7 @@ ac_add_options --enable-debug
 ac_add_options --enable-dmd
 ac_add_options --enable-profiling  # needed for --enable-dmd to work on Windows
 ac_add_options --enable-verify-mar
+ac_add_options --enable-require-all-d3dc-versions
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
diff --git a/browser/installer/Makefile.in b/browser/installer/Makefile.in
index ccfce3cd9..55df797ef 100644
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -61,6 +61,9 @@ DEFINES += -DMOZ_ANGLE_RENDERER=$(MOZ_ANGLE_RENDERER)
 ifdef MOZ_D3DCOMPILER_VISTA_DLL
 DEFINES += -DMOZ_D3DCOMPILER_VISTA_DLL=$(MOZ_D3DCOMPILER_VISTA_DLL)
 endif
+ifdef MOZ_D3DCOMPILER_XP_DLL
+DEFINES += -DMOZ_D3DCOMPILER_XP_DLL=$(MOZ_D3DCOMPILER_XP_DLL)
+endif
 endif
 
 DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
diff --git a/browser/installer/allowed-dupes.mn b/browser/installer/allowed-dupes.mn
index 7baa6ebed..366842598 100644
--- a/browser/installer/allowed-dupes.mn
+++ b/browser/installer/allowed-dupes.mn
@@ -171,7 +171,7 @@ chrome/toolkit/skin/classic/global/dialog.css
 chrome/toolkit/skin/classic/global/dropmarker.css
 chrome/toolkit/skin/classic/global/global.css
 chrome/toolkit/skin/classic/global/groupbox.css
-chrome/toolkit/skin/classic/global/icons/close-win7.png
+chrome/toolkit/skin/classic/global/icons/close-XPVista7.png
 chrome/toolkit/skin/classic/global/icons/tabprompts-bgtexture.png
 chrome/toolkit/skin/classic/global/listbox.css
 chrome/toolkit/skin/classic/global/media/clicktoplay-bgtexture.png
@@ -196,6 +196,7 @@ chrome/toolkit/skin/classic/global/toolbarbutton.css
 chrome/toolkit/skin/classic/global/tree.css
 chrome/toolkit/skin/classic/global/wizard.css
 chrome/toolkit/skin/classic/mozapps/downloads/buttons.png
+chrome/toolkit/skin/classic/mozapps/downloads/downloadButtons-XP.png
 chrome/toolkit/skin/classic/mozapps/downloads/downloadButtons.png
 chrome/toolkit/skin/classic/mozapps/extensions/category-dictionaries.png
 chrome/toolkit/skin/classic/mozapps/extensions/category-experiments.png
@@ -208,6 +209,7 @@ chrome/toolkit/skin/classic/mozapps/extensions/localeGeneric.png
 chrome/toolkit/skin/classic/mozapps/extensions/category-extensions.png
 chrome/toolkit/skin/classic/mozapps/extensions/extensionGeneric.png
 chrome/toolkit/skin/classic/mozapps/update/buttons.png
+chrome/toolkit/skin/classic/mozapps/update/downloadButtons-XP.png
 chrome/toolkit/skin/classic/mozapps/update/downloadButtons.png
 chrome/toolkit/skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png
 
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index c2269c069..bddca2f29 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -607,6 +607,10 @@
 #ifdef MOZ_D3DCOMPILER_VISTA_DLL
 @BINPATH@/@MOZ_D3DCOMPILER_VISTA_DLL@
 #endif
+
+#ifdef MOZ_D3DCOMPILER_XP_DLL
+@BINPATH@/@MOZ_D3DCOMPILER_XP_DLL@
+#endif
 #endif # MOZ_ANGLE_RENDERER
 
 ; [Browser Chrome Files]
diff --git a/browser/installer/windows/nsis/defines.nsi.in b/browser/installer/windows/nsis/defines.nsi.in
index 5ad9b7966..d0f0c443a 100644
--- a/browser/installer/windows/nsis/defines.nsi.in
+++ b/browser/installer/windows/nsis/defines.nsi.in
@@ -63,7 +63,7 @@
 !define MinSupportedVer "Microsoft Windows 7 x64"
 #else
 !define ARCH "x86"
-!define MinSupportedVer "Microsoft Windows 7"
+!define MinSupportedVer "Microsoft Windows XP SP2"
 #endif
 
 !define MinSupportedCPU "SSE2"
diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
index 6f3aab397..1947a3c90 100644
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -731,8 +731,11 @@ pendingCrashReports.alwaysSend = Always Send
 decoder.noCodecs.button = Learn how
 decoder.noCodecs.accesskey = L
 decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
+decoder.noCodecsVista.message = To play video, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
+decoder.noCodecsXP.message = To play video, you may need to enable Adobe’s Primetime Content Decryption Module.
 decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
 decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsoft’s Media Feature Pack.
+decoder.noHWAccelerationVista.message = To improve video quality, you may need to install Microsoft’s Platform Update Supplement for Windows Vista.
 decoder.noPulseAudio.message = To play audio, you may need to install the required PulseAudio software.
 decoder.unsupportedLibavcodec.message = libavcodec may be vulnerable or is not supported, and should be updated to play video.
 
diff --git a/browser/themes/windows/browser-aero.css b/browser/themes/windows/browser-aero.css
index dbac6bb7a..28599af7a 100644
--- a/browser/themes/windows/browser-aero.css
+++ b/browser/themes/windows/browser-aero.css
@@ -445,7 +445,7 @@
     }
 
     /* The borders on the glass frame are ours, and inside #browser, and on
-     * win7 we want to make sure they are "glassy", so we can't use
+     * vista and win7 we want to make sure they are "glassy", so we can't use
      * #browser as the exclude-glass container. We use #appcontent instead. */
     #browser {
       -moz-appearance: none;
@@ -458,7 +458,7 @@
 
   @media (-moz-os-version: windows-win8) {
     /* Artificially draw window borders that are covered by lwtheme, see bug 591930.
-     * Borders for win7 are below, win10 doesn't need them. */
+     * Borders for vista/win7 are below, win10 doesn't need them. */
     #main-window[sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
       border-top: 1px solid @toolbarShadowColor@;
     }
@@ -473,9 +473,11 @@
      * On aero, the menubar fog disappears for inactive windows, and renders gray
      * illegible.
      */
-    @media not all and (-moz-os-version: windows-win7) {
-      #toolbar-menubar:not(:-moz-lwtheme):-moz-window-inactive {
-        color: ThreeDShadow;
+    @media not all and (-moz-os-version: windows-vista) {
+      @media not all and (-moz-os-version: windows-win7) {
+        #toolbar-menubar:not(:-moz-lwtheme):-moz-window-inactive {
+          color: ThreeDShadow;
+        }
       }
     }
   }
@@ -485,8 +487,9 @@
     color: white;
   }
 
-  /* Show borders on win7 and win8, but not on win10 and later: */
-  @media (-moz-os-version: windows-win7),
+  /* Show borders on vista through win8, but not on win10 and later: */
+  @media (-moz-os-version: windows-vista),
+         (-moz-os-version: windows-win7),
          (-moz-os-version: windows-win8) {
     /* Vertical toolbar border */
     #main-window:not([customizing])[sizemode=normal] #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(:-moz-lwtheme),
diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css
index a0cdabfb2..15e776da1 100644
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -131,7 +131,8 @@ toolbar:-moz-lwtheme {
 }
 
 @media (-moz-windows-default-theme) {
-  @media (-moz-os-version: windows-win7) {
+  @media (-moz-os-version: windows-vista),
+         (-moz-os-version: windows-win7) {
     #navigator-toolbox::after {
       border-bottom-color: #aabccf;
     }
@@ -159,7 +160,9 @@ toolbar:-moz-lwtheme {
   background-image: linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   #nav-bar {
     background-image: linear-gradient(@toolbarHighlight@, transparent) !important;
   }
@@ -315,6 +318,64 @@ toolbar:-moz-lwtheme {
   }
 }
 
+/* Render a window top border for lwthemes on WinXP modern themes: */
+@media (-moz-windows-theme: luna-blue) {
+  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
+    background-image: linear-gradient(to bottom,
+        rgb(8, 49, 216) 0, rgb(8, 49, 216) 1px,
+        rgb(15, 77, 227) 1px, rgb(15, 77, 227) 2px,
+        rgb(22, 106, 238) 2px, rgb(22, 106, 238) 3px,
+        rgb(8, 85, 221) 3px, rgb(8, 85, 221) 4px,
+        transparent 4px);
+  }
+
+  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
+    background-image: linear-gradient(to bottom,
+        rgb(91, 104, 205) 0, rgb(91, 104, 205) 1px,
+        rgb(116, 128, 220) 1px, rgb(116, 128, 220) 2px,
+        rgb(117, 140, 221) 2px, rgb(117, 140, 221) 4px,
+        transparent 4px);
+  }
+}
+
+@media (-moz-windows-theme: luna-silver) {
+  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
+    background-image: linear-gradient(to bottom,
+        rgb(102,102,126) 0, rgb(102,102,126) 1px,
+        rgb(168,167,191) 1px, rgb(168,167,191) 2px,
+        white 2px, white 3px,
+        rgb(188,188,207) 3px, rgb(188,188,207) 4px,
+        transparent 4px);
+  }
+
+  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
+    background-image: linear-gradient(to bottom,
+        rgb(186,186,197) 0, rgb(186,186,197) 1px,
+        rgb(236,238,245) 1px, rgb(236,238,245) 2px,
+        white 2px, white 3px,
+        rgb(215,215,227) 3px, rgb(215,215,227) 4px,
+        transparent 4px);
+  }
+}
+
+@media (-moz-windows-theme: luna-olive) {
+  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme {
+    background-image: linear-gradient(to bottom,
+        rgb(139,161,105) 0, rgb(139,161,105) 1px,
+        rgb(171, 189, 133) 1px, rgb(171, 189, 133) 2px,
+        rgb(164,178,127) 2px, rgb(164,178,127) 3px,
+        transparent 3px);
+  }
+
+  #main-window[tabsintitlebar][sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
+    background-image: linear-gradient(to bottom,
+        rgb(207, 214, 188) 0, rgb(207, 214, 188) 1px,
+        rgb(224, 226, 200) 1px, rgb(224, 226, 200) 2px,
+        rgb(214, 216, 190) 2px, rgb(214, 216, 190) 3px,
+        transparent 3px);
+  }
+}
+
 #TabsToolbar:not([collapsed="true"]) + #nav-bar {
   /* Move up into the TabsToolbar for the inner highlight at the top of the nav-bar */
   margin-top: calc(-1 * var(--navbar-tab-toolbar-highlight-overlap));
@@ -345,6 +406,12 @@ toolbar:-moz-lwtheme {
   background-color: -moz-dialog;
 }
 
+@media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) {
+  #main-window[tabsintitlebar][sizemode="normal"] #toolbar-menubar {
+    margin-top: 4px;
+  }
+}
+
 /* ::::: titlebar ::::: */
 
 #main-window[sizemode="normal"] > #titlebar {
@@ -365,7 +432,7 @@ toolbar:-moz-lwtheme {
  * click and hover mouse events to work properly for the button in the restored
  * window state. Otherwise, elements in the navigator-toolbox, like the menubar,
  * can swallow those events. It will also place the buttons above the fog on
- * Windows 7 with Aero Glass.
+ * themes with Aero Glass.
  */
 #titlebar-buttonbox {
   z-index: 1;
@@ -375,6 +442,12 @@ toolbar:-moz-lwtheme {
   margin-left: 22px; /* space needed for Aero Snap */
 }
 
+@media (-moz-os-version: windows-xp) {
+  .titlebar-placeholder[type="caption-buttons"] {
+    margin-left: 10px; /* less space needed on XP because there's no Aero Snap */
+  }
+}
+
 /* titlebar command buttons */
 
 #titlebar-min {
@@ -597,6 +670,13 @@ menuitem.bookmark-item {
 
 %include ../shared/toolbarbuttons.inc.css
 
+@media (-moz-windows-theme: luna-silver) and (max-resolution: 1dppx) {
+  :-moz-any(@primaryToolbarButtons@),
+  #bookmarks-menu-button.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
+    list-style-image: url("chrome://browser/skin/Toolbar-lunaSilver.png");
+  }
+}
+
 #main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-icon,
 #main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-menu-dropmarker,
 #main-window:not([customizing]) .toolbarbutton-1[disabled=true] > .toolbarbutton-menubutton-dropmarker,
@@ -700,7 +780,10 @@ toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   max-width: 32px;
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
+  /* < Win8 */
   :root {
     --toolbarbutton-hover-background: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
     --toolbarbutton-hover-bordercolor: hsla(210,54%,20%,.15) hsla(210,54%,20%,.2) hsla(210,54%,20%,.25);
@@ -1018,7 +1101,9 @@ toolbar[brighttext] #close-button {
   list-style-image: url(chrome://browser/skin/caption-buttons.svg#close-white);
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   #window-controls {
     margin-inline-start: 4px;
   }
@@ -1074,7 +1159,8 @@ toolbar[brighttext] #close-button {
   }
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   #window-controls {
     -moz-box-align: start;
   }
@@ -1118,7 +1204,8 @@ toolbar[brighttext] #close-button {
 }
 
 @media (-moz-windows-default-theme) {
-  @media (-moz-os-version: windows-win7),
+  @media (-moz-os-version: windows-vista),
+         (-moz-os-version: windows-win7),
          (-moz-os-version: windows-win8) {
     #main-window:not(:-moz-lwtheme) {
       --urlbar-border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
@@ -1155,7 +1242,8 @@ toolbar[brighttext] #close-button {
     border-radius: 1px;
   }
 
-  @media (-moz-os-version: windows-win7),
+  @media (-moz-os-version: windows-vista),
+         (-moz-os-version: windows-win7),
          (-moz-os-version: windows-win8) {
     #urlbar:not(:-moz-lwtheme),
     .searchbar-textbox:not(:-moz-lwtheme) {
@@ -1178,9 +1266,11 @@ toolbar[brighttext] #close-button {
     }
   }
 
-  #urlbar:not(:-moz-lwtheme)[focused],
-  .searchbar-textbox:not(:-moz-lwtheme)[focused] {
-    border-color: Highlight;
+  @media not all and (-moz-os-version: windows-xp) {
+    #urlbar:not(:-moz-lwtheme)[focused],
+    .searchbar-textbox:not(:-moz-lwtheme)[focused] {
+      border-color: Highlight;
+    }
   }
 }
 
@@ -1933,7 +2023,9 @@ html|span.ac-emphasize-text-url {
   }
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   #sidebar-header > .close-icon {
     padding-top: 4px;
     padding-bottom: 4px;
@@ -1954,28 +2046,39 @@ html|span.ac-emphasize-text-url {
   margin-bottom: calc(-1 * var(--tab-toolbar-navbar-overlap)); /* overlap the nav-bar's top border */
 }
 
+@media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) {
+  #main-window[sizemode=normal] #TabsToolbar {
+    padding-left: 2px;
+    padding-right: 2px;
+  }
+}
+
 %include ../shared/tabs.inc.css
 
 /* Remove border between tab strip and navigation toolbar on Windows 10+ */
-@media not all and (-moz-os-version: windows-win7) {
-  @media not all and (-moz-os-version: windows-win8) {
-    @media (-moz-windows-default-theme) {
-      .tab-background-end[selected=true]::after,
-      .tab-background-start[selected=true]::after {
-        content: none;
-      }
-
-      #TabsToolbar {
-        --tab-stroke-background-size: 0 0;
-      }
-
-      :root {
-        --tab-toolbar-navbar-overlap: 0px;
-      }
-
-      #nav-bar {
-        border-top-style: none !important;
-        box-shadow: none;
+@media not all and (-moz-os-version: windows-xp) {
+  @media not all and (-moz-os-version: windows-vista) {
+    @media not all and (-moz-os-version: windows-win7) {
+      @media not all and (-moz-os-version: windows-win8) {
+        @media (-moz-windows-default-theme) {
+          .tab-background-end[selected=true]::after,
+          .tab-background-start[selected=true]::after {
+            content: none;
+          }
+
+          #TabsToolbar {
+            --tab-stroke-background-size: 0 0;
+          }
+
+          :root {
+            --tab-toolbar-navbar-overlap: 0px;
+          }
+
+          #nav-bar {
+            border-top-style: none !important;
+            box-shadow: none;
+          }
+        }
       }
     }
   }
@@ -2460,6 +2563,22 @@ notification.pluginVulnerable > .notification-inner > .messageCloseButton {
   position: relative;
 }
 
+@media (-moz-os-version: windows-xp) {
+  @media not all and (-moz-windows-classic) {
+    #private-browsing-indicator-titlebar > .private-browsing-indicator {
+      background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
+      height: 28px;
+    }
+
+    #main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
+      top: -5px;
+    }
+    #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
+      top: -1px;
+    }
+  }
+}
+
 @media (-moz-windows-classic) {
   /**
    * We have to use top instead of background-position in this case, otherwise
@@ -2471,7 +2590,8 @@ notification.pluginVulnerable > .notification-inner > .messageCloseButton {
   }
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   @media (-moz-windows-glass) {
     #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
       top: 1px;
@@ -2488,7 +2608,7 @@ notification.pluginVulnerable > .notification-inner > .messageCloseButton {
   @media (-moz-windows-default-theme) {
     @media not all and (-moz-windows-compositor) {
       #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-        background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-win7-tall.png");
+        background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
         height: 28px;
       }
     }
@@ -2521,14 +2641,19 @@ notification.pluginVulnerable > .notification-inner > .messageCloseButton {
   margin-top: -4px;
 }
 
+
+@media not all and (-moz-os-version: windows-xp) {
 %include browser-aero.css
+}
 
 .browser-extension-panel > .panel-arrowcontainer > .panel-arrowcontent {
   padding: 0;
   overflow: hidden;
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   .cui-widget-panelview[id^=PanelUI-webext-] {
     border-radius: 4px;
   }
diff --git a/browser/themes/windows/customizableui/panelUI.css b/browser/themes/windows/customizableui/panelUI.css
index 189a163f3..92080d599 100644
--- a/browser/themes/windows/customizableui/panelUI.css
+++ b/browser/themes/windows/customizableui/panelUI.css
@@ -131,17 +131,21 @@ menu.subviewbutton > .menu-right:-moz-locale-dir(rtl) {
 }
 
 /* Win8 and beyond. */
-@media not all and (-moz-os-version: windows-win7) {
-  panelview .toolbarbutton-1,
-  .subviewbutton,
-  .widget-overflow-list .toolbarbutton-1,
-  .panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
-  #BMB_bookmarksPopup menupopup[placespopup=true] > hbox,
-  #edit-controls@inAnyPanel@,
-  #zoom-controls@inAnyPanel@,
-  #edit-controls@inAnyPanel@ > toolbarbutton,
-  #zoom-controls@inAnyPanel@ > toolbarbutton {
-    border-radius: 0;
+@media not all and (-moz-os-version: windows-xp) {
+  @media not all and (-moz-os-version: windows-vista) {
+    @media not all and (-moz-os-version: windows-win7) {
+      panelview .toolbarbutton-1,
+      .subviewbutton,
+      .widget-overflow-list .toolbarbutton-1,
+      .panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+      #BMB_bookmarksPopup menupopup[placespopup=true] > hbox,
+      #edit-controls@inAnyPanel@,
+      #zoom-controls@inAnyPanel@,
+      #edit-controls@inAnyPanel@ > toolbarbutton,
+      #zoom-controls@inAnyPanel@ > toolbarbutton {
+        border-radius: 0;
+      }
+    }
   }
 }
 
diff --git a/browser/themes/windows/devedition.css b/browser/themes/windows/devedition.css
index bdf4bb80e..2dc72eeeb 100644
--- a/browser/themes/windows/devedition.css
+++ b/browser/themes/windows/devedition.css
@@ -16,7 +16,7 @@
 
 /* The window background is white due to no accentcolor in the lightweight
    theme. It can't be changed to transparent when there is no compositor
-   (Win 7 in classic / basic theme), or else dragging and focus become
+   (Win XP or 7 in classic / basic theme), or else dragging and focus become
    broken. So instead just show the normal titlebar in that case, and override
    the window color as transparent when the compositor is available. */
 @media not all and (-moz-windows-compositor) {
@@ -116,7 +116,9 @@
   }
 }
 
-@media (-moz-os-version: windows-win7),
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7),
        (-moz-os-version: windows-win8) {
   :root {
     --space-above-tabbar: 15px;
@@ -259,7 +261,8 @@
   color: var(--chrome-color);
 }
 
-@media (-moz-os-version: windows-win7),
+@media (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7),
        (-moz-os-version: windows-win8) {
   /* And then we add them back on toolbars so that they don't look borderless: */
   #main-window:not([customizing])[sizemode=normal] #navigator-toolbox::after,
diff --git a/browser/themes/windows/downloads/allDownloadsViewOverlay.css b/browser/themes/windows/downloads/allDownloadsViewOverlay.css
index 0ee83f669..e288f1e90 100644
--- a/browser/themes/windows/downloads/allDownloadsViewOverlay.css
+++ b/browser/themes/windows/downloads/allDownloadsViewOverlay.css
@@ -18,30 +18,32 @@
 
 /*** Highlighted list items ***/
 
-@media (-moz-windows-default-theme) {
-  /*
-  -moz-appearance: menuitem is almost right, but the hover effect is not
-  transparent and is lighter than desired.
-
-  Copied from the autocomplete richlistbox styling in
-  toolkit/themes/windows/global/autocomplete.css
-
-  This styling should be kept in sync with the style from the above file.
-  */
-  @itemFocused@ {
-    color: inherit;
-    background-color: transparent;
-    /* four gradients for the bevel highlights on each edge, one for blue background */
-    background-image:
-      linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
-      linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
-      linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
-      linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
-      linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
-    background-clip: content-box;
-    border-radius: 6px;
-    outline: 1px solid rgb(124,163,206);
-    -moz-outline-radius: 3px;
-    outline-offset: -2px;
+@media not all and (-moz-os-version: windows-xp) {
+  @media (-moz-windows-default-theme) {
+    /*
+    -moz-appearance: menuitem is almost right, but the hover effect is not
+    transparent and is lighter than desired.
+
+    Copied from the autocomplete richlistbox styling in
+    toolkit/themes/windows/global/autocomplete.css
+
+    This styling should be kept in sync with the style from the above file.
+    */
+    @itemFocused@ {
+      color: inherit;
+      background-color: transparent;
+      /* four gradients for the bevel highlights on each edge, one for blue background */
+      background-image:
+        linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, transparent 3px),
+        linear-gradient(to right, rgba(255,255,255,0.5) 3px, transparent 3px),
+        linear-gradient(to left, rgba(255,255,255,0.5) 3px, transparent 3px),
+        linear-gradient(to top, rgba(255,255,255,0.4) 3px, transparent 3px),
+        linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
+      background-clip: content-box;
+      border-radius: 6px;
+      outline: 1px solid rgb(124,163,206);
+      -moz-outline-radius: 3px;
+      outline-offset: -2px;
+    }
   }
 }
diff --git a/browser/themes/windows/downloads/indicator.css b/browser/themes/windows/downloads/indicator.css
index 7f921f8de..627265088 100644
--- a/browser/themes/windows/downloads/indicator.css
+++ b/browser/themes/windows/downloads/indicator.css
@@ -166,9 +166,13 @@ toolbar[brighttext] #downloads-button:not([counter])[attention="success"] > #dow
   font-size: 9px;
   line-height: 9px;
   text-align: center;
+}
 
-  /* Bug 812345 added this... */
-  margin-bottom: -1px;
+@media not all and (-moz-os-version: windows-xp) {
+  #downloads-indicator-counter {
+    /* Bug 812345 added this... */
+    margin-bottom: -1px;
+  }
 }
 
 toolbar[brighttext] #downloads-indicator-counter {
diff --git a/browser/themes/windows/jar.mn b/browser/themes/windows/jar.mn
index 10abfd001..89c589aba 100644
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -11,17 +11,21 @@ browser.jar:
 * skin/classic/browser/syncedtabs/sidebar.css     (syncedtabs/sidebar.css)
   skin/classic/browser/actionicon-tab.png
   skin/classic/browser/actionicon-tab@2x.png
-  skin/classic/browser/actionicon-tab-win7.png
+  skin/classic/browser/actionicon-tab-XPVista7.png
 * skin/classic/browser/browser.css
 * skin/classic/browser/devedition.css
 * skin/classic/browser/browser-lightweightTheme.css
   skin/classic/browser/caption-buttons.svg
   skin/classic/browser/click-to-play-warning-stripes.png
   skin/classic/browser/Info.png
+  skin/classic/browser/Info-XP.png
   skin/classic/browser/keyhole-forward-mask.svg
   skin/classic/browser/livemark-folder.png
+  skin/classic/browser/livemark-folder-XP.png
   skin/classic/browser/menu-back.png
+  skin/classic/browser/menu-back-XP.png
   skin/classic/browser/menu-forward.png
+  skin/classic/browser/menu-forward-XP.png
   skin/classic/browser/menuPanel-customize.png
   skin/classic/browser/menuPanel-customize@2x.png
   skin/classic/browser/menuPanel-exit.png
@@ -32,33 +36,36 @@ browser.jar:
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
+  skin/classic/browser/pageInfo-XP.png
   skin/classic/browser/privatebrowsing-mask-tabstrip.png
-  skin/classic/browser/privatebrowsing-mask-tabstrip-win7.png
+  skin/classic/browser/privatebrowsing-mask-tabstrip-XPVista7.png
   skin/classic/browser/privatebrowsing-mask-titlebar.png
-  skin/classic/browser/privatebrowsing-mask-titlebar-win7.png
-  skin/classic/browser/privatebrowsing-mask-titlebar-win7-tall.png
+  skin/classic/browser/privatebrowsing-mask-titlebar-XPVista7.png
+  skin/classic/browser/privatebrowsing-mask-titlebar-XPVista7-tall.png
   skin/classic/browser/reload-stop-go.png
   skin/classic/browser/reload-stop-go@2x.png
-  skin/classic/browser/reload-stop-go-win7.png
-  skin/classic/browser/reload-stop-go-win7@2x.png
+  skin/classic/browser/reload-stop-go-XPVista7.png
+  skin/classic/browser/reload-stop-go-XPVista7@2x.png
   skin/classic/browser/searchbar.css
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/slowStartup-16.png
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar@2x.png
-  skin/classic/browser/Toolbar-win7.png
-  skin/classic/browser/Toolbar-win7@2x.png
+  skin/classic/browser/Toolbar-aero.png
+  skin/classic/browser/Toolbar-aero@2x.png
   skin/classic/browser/Toolbar-inverted.png
   skin/classic/browser/Toolbar-inverted@2x.png
+  skin/classic/browser/Toolbar-lunaSilver.png
   skin/classic/browser/Toolbar-win8.png
   skin/classic/browser/Toolbar-win8@2x.png
-  skin/classic/browser/toolbarbutton-dropdown-arrow-win7.png
+  skin/classic/browser/Toolbar-XP.png
+  skin/classic/browser/toolbarbutton-dropdown-arrow-XPVista7.png
   skin/classic/browser/toolbarbutton-dropdown-arrow-inverted.png
   skin/classic/browser/urlbar-popup-blocked.png
   skin/classic/browser/urlbar-history-dropmarker.png
   skin/classic/browser/urlbar-history-dropmarker@2x.png
-  skin/classic/browser/urlbar-history-dropmarker-win7.png
-  skin/classic/browser/urlbar-history-dropmarker-win7@2x.png
+  skin/classic/browser/urlbar-history-dropmarker-XPVista7.png
+  skin/classic/browser/urlbar-history-dropmarker-XPVista7@2x.png
   skin/classic/browser/webRTC-indicator.css
 * skin/classic/browser/controlcenter/panel.css                 (controlcenter/panel.css)
   skin/classic/browser/customizableui/background-noise-toolbar.png  (customizableui/background-noise-toolbar.png)
@@ -71,40 +78,57 @@ browser.jar:
 * skin/classic/browser/customizableui/panelUI.css       (customizableui/panelUI.css)
 * skin/classic/browser/downloads/allDownloadsViewOverlay.css   (downloads/allDownloadsViewOverlay.css)
   skin/classic/browser/downloads/download-glow-menuPanel.png   (downloads/download-glow-menuPanel.png)
-  skin/classic/browser/downloads/download-glow-menuPanel-win7.png   (downloads/download-glow-menuPanel-win7.png)
+  skin/classic/browser/downloads/download-glow-menuPanel-XPVista7.png   (downloads/download-glow-menuPanel-XPVista7.png)
   skin/classic/browser/downloads/download-notification-finish.png (downloads/download-notification-finish.png)
   skin/classic/browser/downloads/download-notification-start.png (downloads/download-notification-start.png)
 * skin/classic/browser/downloads/downloads.css                 (downloads/downloads.css)
   skin/classic/browser/feeds/feedIcon.png                      (feeds/feedIcon.png)
   skin/classic/browser/feeds/feedIcon16.png                    (feeds/feedIcon16.png)
+  skin/classic/browser/feeds/feedIcon-XP.png                   (feeds/feedIcon-XP.png)
+  skin/classic/browser/feeds/feedIcon16-XP.png                 (feeds/feedIcon16-XP.png)
   skin/classic/browser/feeds/subscribe.css                     (feeds/subscribe.css)
   skin/classic/browser/feeds/subscribe-ui.css                  (feeds/subscribe-ui.css)
 * skin/classic/browser/newtab/newTab.css                       (newtab/newTab.css)
   skin/classic/browser/places/autocomplete-star.png            (places/autocomplete-star.png)
   skin/classic/browser/places/autocomplete-star@2x.png         (places/autocomplete-star@2x.png)
-  skin/classic/browser/places/autocomplete-star-win7.png       (places/autocomplete-star-win7.png)
+  skin/classic/browser/places/autocomplete-star-XPVista7.png   (places/autocomplete-star-XPVista7.png)
   skin/classic/browser/places/places.css                       (places/places.css)
 * skin/classic/browser/places/organizer.css                    (places/organizer.css)
   skin/classic/browser/places/query.png                        (places/query.png)
+  skin/classic/browser/places/query-XP.png                     (places/query-XP.png)
   skin/classic/browser/places/bookmarksMenu.png                (places/bookmarksMenu.png)
+  skin/classic/browser/places/bookmarksMenu-XP.png             (places/bookmarksMenu-XP.png)
   skin/classic/browser/places/bookmarksToolbar.png             (places/bookmarksToolbar.png)
+  skin/classic/browser/places/bookmarksToolbar-XP.png          (places/bookmarksToolbar-XP.png)
   skin/classic/browser/places/bookmarksToolbar-menuPanel.png   (places/bookmarksToolbar-menuPanel.png)
+  skin/classic/browser/places/bookmarksToolbar-menuPanel-XP.png (places/bookmarksToolbar-menuPanel-XP.png)
   skin/classic/browser/places/bookmarks-notification-finish.png (places/bookmarks-notification-finish.png)
   skin/classic/browser/places/calendar.png                     (places/calendar.png)
+  skin/classic/browser/places/calendar-XP.png                  (places/calendar-XP.png)
   skin/classic/browser/places/toolbarDropMarker.png            (places/toolbarDropMarker.png)
+  skin/classic/browser/places/toolbarDropMarker-XP.png         (places/toolbarDropMarker-XP.png)
   skin/classic/browser/places/editBookmarkOverlay.css          (places/editBookmarkOverlay.css)
   skin/classic/browser/places/libraryToolbar.png               (places/libraryToolbar.png)
+  skin/classic/browser/places/libraryToolbar-XP.png            (places/libraryToolbar-XP.png)
   skin/classic/browser/places/starred48.png                    (places/starred48.png)
+  skin/classic/browser/places/starred48-XP.png                 (places/starred48-XP.png)
   skin/classic/browser/places/unstarred48.png                  (places/unstarred48.png)
   skin/classic/browser/places/tag.png                          (places/tag.png)
+  skin/classic/browser/places/tag-XP.png                       (places/tag-XP.png)
   skin/classic/browser/places/history.png                      (places/history.png)
+  skin/classic/browser/places/history-XP.png                   (places/history-XP.png)
   skin/classic/browser/places/allBookmarks.png                 (places/allBookmarks.png)
+  skin/classic/browser/places/allBookmarks-XP.png              (places/allBookmarks-XP.png)
   skin/classic/browser/places/unsortedBookmarks.png            (places/unsortedBookmarks.png)
+  skin/classic/browser/places/unsortedBookmarks-XP.png         (places/unsortedBookmarks-XP.png)
   skin/classic/browser/places/downloads.png                    (places/downloads.png)
   skin/classic/browser/places/livemark-item.png                (places/livemark-item.png)
   skin/classic/browser/preferences/alwaysAsk.png               (preferences/alwaysAsk.png)
+  skin/classic/browser/preferences/alwaysAsk-XP.png            (preferences/alwaysAsk-XP.png)
   skin/classic/browser/preferences/application.png             (preferences/application.png)
+  skin/classic/browser/preferences/application-XP.png          (preferences/application-XP.png)
   skin/classic/browser/preferences/saveFile.png                (preferences/saveFile.png)
+  skin/classic/browser/preferences/saveFile-XP.png             (preferences/saveFile-XP.png)
   skin/classic/browser/preferences/preferences.css             (preferences/preferences.css)
 * skin/classic/browser/preferences/in-content/preferences.css  (preferences/in-content/preferences.css)
 * skin/classic/browser/preferences/in-content/dialog.css       (preferences/in-content/dialog.css)
@@ -112,13 +136,13 @@ browser.jar:
   skin/classic/browser/social/services-16.png                  (social/services-16.png)
   skin/classic/browser/social/services-64.png                  (social/services-64.png)
   skin/classic/browser/tabbrowser/newtab.svg                   (tabbrowser/newtab.svg)
-  skin/classic/browser/tabbrowser/newtab-win7.svg              (tabbrowser/newtab-win7.svg)
+  skin/classic/browser/tabbrowser/newtab-XPVista7.svg          (tabbrowser/newtab-XPVista7.svg)
   skin/classic/browser/tabbrowser/newtab-inverted.svg          (tabbrowser/newtab-inverted.svg)
-  skin/classic/browser/tabbrowser/newtab-inverted-win7.svg     (tabbrowser/newtab-inverted-win7.svg)
+  skin/classic/browser/tabbrowser/newtab-inverted-XPVista7.svg (tabbrowser/newtab-inverted-XPVista7.svg)
   skin/classic/browser/tabbrowser/tab-active-middle.png        (tabbrowser/tab-active-middle.png)
   skin/classic/browser/tabbrowser/tab-active-middle@2x.png     (tabbrowser/tab-active-middle@2x.png)
   skin/classic/browser/tabbrowser/tab-arrow-left.svg           (tabbrowser/tab-arrow-left.svg)
-  skin/classic/browser/tabbrowser/tab-arrow-left-win7.svg      (tabbrowser/tab-arrow-left-win7.svg)
+  skin/classic/browser/tabbrowser/tab-arrow-left-XPVista7.svg  (tabbrowser/tab-arrow-left-XPVista7.svg)
   skin/classic/browser/tabbrowser/tab-arrow-left-inverted.svg  (tabbrowser/tab-arrow-left-inverted.svg)
   skin/classic/browser/tabbrowser/tab-background-start.png     (tabbrowser/tab-background-start.png)
   skin/classic/browser/tabbrowser/tab-background-start@2x.png  (tabbrowser/tab-background-start@2x.png)
@@ -150,8 +174,8 @@ browser.jar:
   skin/classic/browser/sync-desktopIcon.svg  (../shared/sync-desktopIcon.svg)
   skin/classic/browser/sync-horizontalbar.png
   skin/classic/browser/sync-horizontalbar@2x.png
-  skin/classic/browser/sync-horizontalbar-win7.png
-  skin/classic/browser/sync-horizontalbar-win7@2x.png
+  skin/classic/browser/sync-horizontalbar-XPVista7.png
+  skin/classic/browser/sync-horizontalbar-XPVista7@2x.png
   skin/classic/browser/sync-mobileIcon.svg  (../shared/sync-mobileIcon.svg)
   skin/classic/browser/sync-notification-24.png
   skin/classic/browser/syncSetup.css
@@ -159,16 +183,16 @@ browser.jar:
   skin/classic/browser/syncQuota.css
   skin/classic/browser/syncProgress-horizontalbar.png
   skin/classic/browser/syncProgress-horizontalbar@2x.png
-  skin/classic/browser/syncProgress-horizontalbar-win7.png
-  skin/classic/browser/syncProgress-horizontalbar-win7@2x.png
+  skin/classic/browser/syncProgress-horizontalbar-XPVista7.png
+  skin/classic/browser/syncProgress-horizontalbar-XPVista7@2x.png
   skin/classic/browser/syncProgress-menuPanel.png
   skin/classic/browser/syncProgress-menuPanel@2x.png
   skin/classic/browser/syncProgress-toolbar.png
   skin/classic/browser/syncProgress-toolbar@2x.png
   skin/classic/browser/syncProgress-toolbar-inverted.png
   skin/classic/browser/syncProgress-toolbar-inverted@2x.png
-  skin/classic/browser/syncProgress-toolbar-win7.png
-  skin/classic/browser/syncProgress-toolbar-win7@2x.png
+  skin/classic/browser/syncProgress-toolbar-XPVista7.png
+  skin/classic/browser/syncProgress-toolbar-XPVista7@2x.png
 #ifdef E10S_TESTING_ONLY
   skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png)
 #endif
@@ -181,31 +205,58 @@ browser.jar:
 % override chrome://browser/skin/feeds/videoFeedIcon16.png            chrome://browser/skin/feeds/feedIcon16.png
 
 % override chrome://browser/skin/aboutSessionRestore-window-icon.png  chrome://browser/skin/preferences/application.png                 os!=WINNT
+% override chrome://browser/skin/aboutSessionRestore-window-icon.png  chrome://browser/skin/preferences/application.png                 os=WINNT osversion<6
 
-% override chrome://browser/skin/actionicon-tab.png                   chrome://browser/skin/actionicon-tab-win7.png                 os=WINNT osversion<=6.1
-% override chrome://browser/skin/privatebrowsing-mask-tabstrip.png    chrome://browser/skin/privatebrowsing-mask-tabstrip-win7.png  os=WINNT osversion<=6.1
-% override chrome://browser/skin/privatebrowsing-mask-titlebar.png    chrome://browser/skin/privatebrowsing-mask-titlebar-win7.png  os=WINNT osversion<=6.1
-% override chrome://browser/skin/reload-stop-go.png                   chrome://browser/skin/reload-stop-go-win7.png                 os=WINNT osversion<=6.1
-% override chrome://browser/skin/reload-stop-go@2x.png                chrome://browser/skin/reload-stop-go-win7@2x.png              os=WINNT osversion<=6.1
-% override chrome://browser/skin/sync-horizontalbar.png               chrome://browser/skin/sync-horizontalbar-win7.png             os=WINNT osversion<=6.1
-% override chrome://browser/skin/sync-horizontalbar@2x.png            chrome://browser/skin/sync-horizontalbar-win7@2x.png          os=WINNT osversion<=6.1
-% override chrome://browser/skin/syncProgress-horizontalbar.png       chrome://browser/skin/syncProgress-horizontalbar-win7.png     os=WINNT osversion<=6.1
-% override chrome://browser/skin/syncProgress-horizontalbar@2x.png    chrome://browser/skin/syncProgress-horizontalbar-win7@2x.png  os=WINNT osversion<=6.1
-% override chrome://browser/skin/syncProgress-toolbar.png             chrome://browser/skin/syncProgress-toolbar-win7.png           os=WINNT osversion<=6.1
-% override chrome://browser/skin/syncProgress-toolbar@2x.png          chrome://browser/skin/syncProgress-toolbar-win7@2x.png        os=WINNT osversion<=6.1
-% override chrome://browser/skin/toolbarbutton-dropdown-arrow.png     chrome://browser/skin/toolbarbutton-dropdown-arrow-win7.png   os=WINNT osversion<=6.1
-% override chrome://browser/skin/urlbar-history-dropmarker.png        chrome://browser/skin/urlbar-history-dropmarker-win7.png      os=WINNT osversion<=6.1
-% override chrome://browser/skin/urlbar-history-dropmarker@2x.png     chrome://browser/skin/urlbar-history-dropmarker-win7@2x.png   os=WINNT osversion<=6.1
-% override chrome://browser/skin/downloads/download-glow-menuPanel.png  chrome://browser/skin/downloads/download-glow-menuPanel-win7.png os=WINNT osversion<=6.1
-% override chrome://browser/skin/places/autocomplete-star.png         chrome://browser/skin/places/autocomplete-star-win7.png       os=WINNT osversion<=6.1
-% override chrome://browser/skin/tabbrowser/newtab.svg                chrome://browser/skin/tabbrowser/newtab-win7.svg              os=WINNT osversion<=6.1
-% override chrome://browser/skin/tabbrowser/newtab-inverted.svg       chrome://browser/skin/tabbrowser/newtab-inverted-win7.svg     os=WINNT osversion<=6.1
-% override chrome://browser/skin/tabbrowser/tab-arrow-left.svg        chrome://browser/skin/tabbrowser/tab-arrow-left-win7.svg      os=WINNT osversion<=6.1
+% override chrome://browser/skin/Info.png                             chrome://browser/skin/Info-XP.png                                 os=WINNT osversion<6
+% override chrome://browser/skin/livemark-folder.png                  chrome://browser/skin/livemark-folder-XP.png                      os=WINNT osversion<6
+% override chrome://browser/skin/menu-back.png                        chrome://browser/skin/menu-back-XP.png                            os=WINNT osversion<6
+% override chrome://browser/skin/menu-forward.png                     chrome://browser/skin/menu-forward-XP.png                         os=WINNT osversion<6
+% override chrome://browser/skin/pageInfo.png                         chrome://browser/skin/pageInfo-XP.png                             os=WINNT osversion<6
+% override chrome://browser/skin/feeds/feedIcon.png                   chrome://browser/skin/feeds/feedIcon-XP.png                       os=WINNT osversion<6
+% override chrome://browser/skin/feeds/feedIcon16.png                 chrome://browser/skin/feeds/feedIcon16-XP.png                     os=WINNT osversion<6
+% override chrome://browser/skin/places/query.png                     chrome://browser/skin/places/query-XP.png                         os=WINNT osversion<6
+% override chrome://browser/skin/places/bookmarksMenu.png             chrome://browser/skin/places/bookmarksMenu-XP.png                 os=WINNT osversion<6
+% override chrome://browser/skin/places/bookmarksToolbar.png          chrome://browser/skin/places/bookmarksToolbar-XP.png              os=WINNT osversion<6
+% override chrome://browser/skin/places/bookmarksToolbar-menuPanel.png  chrome://browser/skin/places/bookmarksToolbar-menuPanel-XP.png  os=WINNT osversion<6
+% override chrome://browser/skin/places/calendar.png                  chrome://browser/skin/places/calendar-XP.png                      os=WINNT osversion<6
+% override chrome://browser/skin/places/toolbarDropMarker.png         chrome://browser/skin/places/toolbarDropMarker-XP.png             os=WINNT osversion<6
+% override chrome://browser/skin/places/libraryToolbar.png            chrome://browser/skin/places/libraryToolbar-XP.png                os=WINNT osversion<6
+% override chrome://browser/skin/places/starred48.png                 chrome://browser/skin/places/starred48-XP.png                     os=WINNT osversion<6
+% override chrome://browser/skin/places/tag.png                       chrome://browser/skin/places/tag-XP.png                           os=WINNT osversion<6
+% override chrome://browser/skin/places/history.png                   chrome://browser/skin/places/history-XP.png                       os=WINNT osversion<6
+% override chrome://browser/skin/places/allBookmarks.png              chrome://browser/skin/places/allBookmarks-XP.png                  os=WINNT osversion<6
+% override chrome://browser/skin/places/unsortedBookmarks.png         chrome://browser/skin/places/unsortedBookmarks-XP.png             os=WINNT osversion<6
+% override chrome://browser/skin/preferences/alwaysAsk.png            chrome://browser/skin/preferences/alwaysAsk-XP.png                os=WINNT osversion<6
+% override chrome://browser/skin/preferences/application.png          chrome://browser/skin/preferences/application-XP.png              os=WINNT osversion<6
+% override chrome://browser/skin/preferences/saveFile.png             chrome://browser/skin/preferences/saveFile-XP.png                 os=WINNT osversion<6
 
-% override chrome://browser/skin/Toolbar@2x.png                       chrome://browser/skin/Toolbar-win7@2x.png                         os=WINNT osversion=6.1
+% override chrome://browser/skin/actionicon-tab.png                   chrome://browser/skin/actionicon-tab-XPVista7.png                 os=WINNT osversion<=6.1
+% override chrome://browser/skin/privatebrowsing-mask-tabstrip.png    chrome://browser/skin/privatebrowsing-mask-tabstrip-XPVista7.png  os=WINNT osversion<=6.1
+% override chrome://browser/skin/privatebrowsing-mask-titlebar.png    chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7.png  os=WINNT osversion<=6.1
+% override chrome://browser/skin/reload-stop-go.png                   chrome://browser/skin/reload-stop-go-XPVista7.png                 os=WINNT osversion<=6.1
+% override chrome://browser/skin/reload-stop-go@2x.png                chrome://browser/skin/reload-stop-go-XPVista7@2x.png              os=WINNT osversion<=6.1
+% override chrome://browser/skin/sync-horizontalbar.png               chrome://browser/skin/sync-horizontalbar-XPVista7.png             os=WINNT osversion<=6.1
+% override chrome://browser/skin/sync-horizontalbar@2x.png            chrome://browser/skin/sync-horizontalbar-XPVista7@2x.png          os=WINNT osversion<=6.1
+% override chrome://browser/skin/syncProgress-horizontalbar.png       chrome://browser/skin/syncProgress-horizontalbar-XPVista7.png     os=WINNT osversion<=6.1
+% override chrome://browser/skin/syncProgress-horizontalbar@2x.png    chrome://browser/skin/syncProgress-horizontalbar-XPVista7@2x.png  os=WINNT osversion<=6.1
+% override chrome://browser/skin/syncProgress-toolbar.png             chrome://browser/skin/syncProgress-toolbar-XPVista7.png           os=WINNT osversion<=6.1
+% override chrome://browser/skin/syncProgress-toolbar@2x.png          chrome://browser/skin/syncProgress-toolbar-XPVista7@2x.png        os=WINNT osversion<=6.1
+% override chrome://browser/skin/toolbarbutton-dropdown-arrow.png     chrome://browser/skin/toolbarbutton-dropdown-arrow-XPVista7.png   os=WINNT osversion<=6.1
+% override chrome://browser/skin/urlbar-history-dropmarker.png        chrome://browser/skin/urlbar-history-dropmarker-XPVista7.png      os=WINNT osversion<=6.1
+% override chrome://browser/skin/urlbar-history-dropmarker@2x.png     chrome://browser/skin/urlbar-history-dropmarker-XPVista7@2x.png   os=WINNT osversion<=6.1
+% override chrome://browser/skin/downloads/download-glow-menuPanel.png  chrome://browser/skin/downloads/download-glow-menuPanel-XPVista7.png os=WINNT osversion<=6.1
+% override chrome://browser/skin/places/autocomplete-star.png         chrome://browser/skin/places/autocomplete-star-XPVista7.png       os=WINNT osversion<=6.1
+% override chrome://browser/skin/tabbrowser/newtab.svg                chrome://browser/skin/tabbrowser/newtab-XPVista7.svg              os=WINNT osversion<=6.1
+% override chrome://browser/skin/tabbrowser/newtab-inverted.svg       chrome://browser/skin/tabbrowser/newtab-inverted-XPVista7.svg     os=WINNT osversion<=6.1
+% override chrome://browser/skin/tabbrowser/tab-arrow-left.svg        chrome://browser/skin/tabbrowser/tab-arrow-left-XPVista7.svg      os=WINNT osversion<=6.1
+
+% override chrome://browser/skin/Toolbar@2x.png                       chrome://browser/skin/Toolbar-aero@2x.png                         os=WINNT osversion=6
+% override chrome://browser/skin/Toolbar@2x.png                       chrome://browser/skin/Toolbar-aero@2x.png                         os=WINNT osversion=6.1
 % override chrome://browser/skin/Toolbar@2x.png                       chrome://browser/skin/Toolbar-win8@2x.png                         os=WINNT osversion=6.2
 % override chrome://browser/skin/Toolbar@2x.png                       chrome://browser/skin/Toolbar-win8@2x.png                         os=WINNT osversion=6.3
-% override chrome://browser/skin/Toolbar.png                          chrome://browser/skin/Toolbar-win7.png                            os=WINNT osversion=6.1
+% override chrome://browser/skin/Toolbar.png                          chrome://browser/skin/Toolbar-XP.png                              os=WINNT osversion<6
+% override chrome://browser/skin/Toolbar.png                          chrome://browser/skin/Toolbar-aero.png                            os=WINNT osversion=6
+% override chrome://browser/skin/Toolbar.png                          chrome://browser/skin/Toolbar-aero.png                            os=WINNT osversion=6.1
 % override chrome://browser/skin/Toolbar.png                          chrome://browser/skin/Toolbar-win8.png                            os=WINNT osversion=6.2
 % override chrome://browser/skin/Toolbar.png                          chrome://browser/skin/Toolbar-win8.png                            os=WINNT osversion=6.3
 
diff --git a/browser/themes/windows/places/organizer.css b/browser/themes/windows/places/organizer.css
index 9ae4c8370..4de603b9f 100644
--- a/browser/themes/windows/places/organizer.css
+++ b/browser/themes/windows/places/organizer.css
@@ -20,6 +20,13 @@
   list-style-image: url("chrome://browser/skin/Toolbar.png");
 }
 
+@media (-moz-windows-theme: luna-silver) {
+  #back-button,
+  #forward-button {
+    list-style-image: url("chrome://browser/skin/Toolbar-lunaSilver.png");
+  }
+}
+
 #back-button {
   -moz-image-region: rect(0, 54px, 18px, 36px);
 }
@@ -112,6 +119,11 @@
   -moz-image-region: rect(16px, 48px, 32px, 32px);
 }
 
+/* Root View */
+#placesView {
+  border-top: 1px solid ThreeDDarkShadow;
+}
+
 /* Info box */
 #detailsDeck {
   border-top: 1px solid ThreeDShadow;
@@ -139,28 +151,35 @@
   padding-inline-end: 9px;
 }
 
-@media not all and (-moz-windows-classic) {
-  #placesToolbox {
-    -moz-appearance: none;
-    background-color: transparent;
+
+@media not all and (-moz-os-version: windows-xp) {
+  #placesView {
+    border-top: none;
   }
 
-  #placesToolbar {
-    -moz-appearance: none;
-    background-color: -moz-Dialog;
-    color: -moz-dialogText;
+  @media not all and (-moz-windows-classic) {
+    #placesToolbox {
+      -moz-appearance: none;
+      background-color: transparent;
+    }
+
+    #placesToolbar {
+      -moz-appearance: none;
+      background-color: -moz-Dialog;
+      color: -moz-dialogText;
+    }
   }
-}
 
-@media (-moz-windows-default-theme) {
-  #placesView > splitter {
-    border: 0;
-    border-inline-end: 1px solid #A9B7C9;
-    min-width: 0;
-    width: 3px;
-    background-color: transparent;
-    margin-inline-start: -3px;
-    position: relative;
+  @media (-moz-windows-default-theme) {
+    #placesView > splitter {
+      border: 0;
+      border-inline-end: 1px solid #A9B7C9;
+      min-width: 0;
+      width: 3px;
+      background-color: transparent;
+      margin-inline-start: -3px;
+      position: relative;
+    }
   }
 }
 
@@ -174,7 +193,8 @@
   }
 }
 
-@media (-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
+@media (-moz-windows-default-theme) and (-moz-os-version: windows-vista),
+       (-moz-windows-default-theme) and (-moz-os-version: windows-win7) {
   #placesView,
   #infoPane,
   #placesList,
diff --git a/browser/themes/windows/places/places.css b/browser/themes/windows/places/places.css
index 769cfcc25..4ec8f6555 100644
--- a/browser/themes/windows/places/places.css
+++ b/browser/themes/windows/places/places.css
@@ -24,17 +24,21 @@
   cursor: default;
 }
 
+/* Style Places sidebars as Vista media collection */
 @media (-moz-windows-default-theme) {
-  .sidebar-placesTree {
-    background-color: transparent;
-    border-top: none;
-  }
+  @media not all and (-moz-os-version: windows-xp) {
+    .sidebar-placesTree {
+      background-color: transparent;
+      border-top: none;
+    }
 
-  .sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
-    text-decoration: none;
+    .sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
+      text-decoration: none;
+    }
   }
 
-  @media (-moz-os-version: windows-win7) {
+  @media (-moz-os-version: windows-vista),
+         (-moz-os-version: windows-win7) {
     #bookmarksPanel,
     #history-panel,
     #tabs-panel {
diff --git a/browser/themes/windows/windowsShared.inc b/browser/themes/windows/windowsShared.inc
index 199a62292..0cb2ab163 100644
--- a/browser/themes/windows/windowsShared.inc
+++ b/browser/themes/windows/windowsShared.inc
@@ -8,4 +8,6 @@
 %define fgTabTexture linear-gradient(transparent 2px, @toolbarHighlight@ 2px, @toolbarHighlight@)
 %define fgTabBackgroundColor -moz-dialog
 %define fgTabTextureLWT @fgTabTexture@
+
+% Aero-only defines
 %define customToolbarColor hsl(210,75%,92%)
diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure
index b33f18623..f7877f96f 100644
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -218,6 +218,7 @@ def old_configure_options(*options):
     '--enable-readline',
     '--enable-reflow-perf',
     '--enable-release',
+    '--enable-require-all-d3dc-versions',
     '--enable-safe-browsing',
     '--enable-sandbox',
     '--enable-signmar',
diff --git a/dom/ipc/ContentProcess.cpp b/dom/ipc/ContentProcess.cpp
index 2413d8808..66125f332 100644
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -8,6 +8,10 @@
 
 #include "ContentProcess.h"
 
+#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/WindowsVersion.h"
+#endif
+
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
 #include <stdlib.h>
 #endif
@@ -29,8 +33,9 @@ static bool
 IsSandboxTempDirRequired()
 {
   // On Windows, a sandbox-writable temp directory is only used
-  // when sandbox pref level >= 1.
-  return Preferences::GetInt("security.sandbox.content.level") >= 1;
+  // for Vista or later with sandbox pref level >= 1.
+  return (IsVistaOrLater() &&
+    (Preferences::GetInt("security.sandbox.content.level") >= 1));
 }
 
 static void
diff --git a/dom/media/DecoderDoctorDiagnostics.cpp b/dom/media/DecoderDoctorDiagnostics.cpp
index 778e8c4c5..91c2d8dfb 100644
--- a/dom/media/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/DecoderDoctorDiagnostics.cpp
@@ -576,9 +576,16 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
       // going through expected decoders from most to least desirable.
 #if defined(XP_WIN)
       if (!formatsRequiringWMF.IsEmpty()) {
-        DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because WMF was not found",
-                this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
-        ReportAnalysis(mDocument, sMediaWMFNeeded, false, formatsRequiringWMF);
+        if (IsVistaOrLater()) {
+          DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because WMF was not found",
+                  this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
+          ReportAnalysis(mDocument, sMediaWMFNeeded, false, formatsRequiringWMF);
+        } else {
+          DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media before Windows Vista",
+                  this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
+          ReportAnalysis(mDocument, sMediaUnsupportedBeforeWindowsVista,
+                         false, formatsRequiringWMF);
+        }
         return;
       }
 #endif
diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp
index 97a6855d9..96e2c23e0 100644
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1853,18 +1853,20 @@ MediaManager::GetNonE10sParent()
 MediaManager::StartupInit()
 {
 #ifdef WIN32
-  // Bug 1107702 - Some Windows versions fail in GetAdaptersInfo (and others)
-  // if the first(?) call occurs after the process size is over 2GB (kb/2588507).
-  // Attempt to 'prime' the pump by making a call at startup.
-  unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
-  PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
-  if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
-    free(pAdapterInfo);
-    pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
-    GetAdaptersInfo(pAdapterInfo, &out_buf_len);
-  }
-  if (pAdapterInfo) {
-    free(pAdapterInfo);
+  if (IsVistaOrLater() && !IsWin8OrLater()) {
+    // Bug 1107702 - Older Windows fail in GetAdaptersInfo (and others) if the
+    // first(?) call occurs after the process size is over 2GB (kb/2588507).
+    // Attempt to 'prime' the pump by making a call at startup.
+    unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
+    PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
+    if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
+      free(pAdapterInfo);
+      pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
+      GetAdaptersInfo(pAdapterInfo, &out_buf_len);
+    }
+    if (pAdapterInfo) {
+      free(pAdapterInfo);
+    }
   }
 #endif
 }
@@ -2128,11 +2130,19 @@ if (privileged) {
       case MediaSourceEnum::Application:
       case MediaSourceEnum::Window:
         // Deny screensharing request if support is disabled, or
-        // the requesting document is not from a host on the whitelist
+        // the requesting document is not from a host on the whitelist, or
+        // we're on WinXP until proved that it works
         if (!Preferences::GetBool(((videoType == MediaSourceEnum::Browser)?
                                    "media.getusermedia.browser.enabled" :
                                    "media.getusermedia.screensharing.enabled"),
                                   false) ||
+#if defined(XP_WIN)
+            (
+              // Allow tab sharing for all platforms including XP
+              (videoType != MediaSourceEnum::Browser) &&
+              !Preferences::GetBool("media.getusermedia.screensharing.allow_on_old_platforms",
+                                    false) && !IsVistaOrLater()) ||
+#endif
             (!privileged && !HostIsHttps(*docURI))) {
           RefPtr<MediaStreamError> error =
               new MediaStreamError(aWindow,
diff --git a/dom/media/eme/MediaKeySystemAccess.cpp b/dom/media/eme/MediaKeySystemAccess.cpp
index 4cff464e7..7007d3a03 100644
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -140,12 +140,26 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
         aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");
         return MediaKeySystemStatus::Cdm_disabled;
       }
+#ifdef XP_WIN
+      // Win Vista and later only.
+      if (!IsVistaOrLater()) {
+        aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version (Vista) not met for Adobe EME");
+        return MediaKeySystemStatus::Cdm_not_supported;
+      }
+#endif
       return EnsureCDMInstalled(aKeySystem, aOutMessage);
     }
   }
 
   if (IsWidevineKeySystem(aKeySystem)) {
     if (Preferences::GetBool("media.gmp-widevinecdm.visible", false)) {
+#ifdef XP_WIN
+      // Win Vista and later only.
+      if (!IsVistaOrLater()) {
+        aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version (Vista) not met for Widevine EME");
+        return MediaKeySystemStatus::Cdm_not_supported;
+      }
+#endif
       if (!Preferences::GetBool("media.gmp-widevinecdm.enabled", false)) {
         aOutMessage = NS_LITERAL_CSTRING("Widevine EME disabled");
         return MediaKeySystemStatus::Cdm_disabled;
diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp
index fdd6f2c7e..4cf07ddbd 100644
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -52,6 +52,14 @@ IsWhitelistedH264Codec(const nsAString& aCodec)
     return false;
   }
 
+#ifdef XP_WIN
+  // Disable 4k video on windows vista since it performs poorly.
+  if (!IsWin7OrLater() &&
+      level >= H264_LEVEL_5) {
+    return false;
+  }
+#endif
+
   // Just assume what we can play on all platforms the codecs/formats that
   // WMF can play, since we don't have documentation about what other
   // platforms can play... According to the WMF documentation:
diff --git a/dom/media/gtest/TestGMPCrossOrigin.cpp b/dom/media/gtest/TestGMPCrossOrigin.cpp
index 33ac98388..036282153 100644
--- a/dom/media/gtest/TestGMPCrossOrigin.cpp
+++ b/dom/media/gtest/TestGMPCrossOrigin.cpp
@@ -1521,6 +1521,11 @@ TEST(GeckoMediaPlugins, GMPPluginVoucher) {
 
 #if defined(XP_WIN)
 TEST(GeckoMediaPlugins, GMPOutputProtection) {
+  // Output Protection is not available pre-Vista.
+  if (!IsVistaOrLater()) {
+    return;
+  }
+
   RefPtr<GMPStorageTest> runner = new GMPStorageTest();
   runner->DoTest(&GMPStorageTest::TestOutputProtection);
 }
diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp
index c1e58fdc2..a72d910f5 100644
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -47,6 +47,10 @@
 #include "MP4Decoder.h"
 #include "mozilla/dom/RemoteVideoDecoder.h"
 
+#ifdef XP_WIN
+#include "mozilla/WindowsVersion.h"
+#endif
+
 #include "mp4_demuxer/H264.h"
 
 namespace mozilla {
@@ -363,7 +367,16 @@ PDMFactory::CreatePDMs()
   }
 #endif
 #ifdef XP_WIN
-  if (MediaPrefs::PDMWMFEnabled()) {
+  if (MediaPrefs::PDMWMFEnabled() && IsVistaOrLater() && !IsWin7AndPre2000Compatible()) {
+    // *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).
+    // IsWin7AndPre2000Compatible() uses GetVersionEx as the user specified OS version can
+    // be reflected when compatibility mode is in effect.
     m = new WMFDecoderModule();
     RefPtr<PlatformDecoderModule> remote = new dom::RemoteDecoderModule(m);
     StartupPDM(remote);
diff --git a/dom/media/platforms/wmf/WMF.h b/dom/media/platforms/wmf/WMF.h
index 6988ef083..5ede0d361 100644
--- a/dom/media/platforms/wmf/WMF.h
+++ b/dom/media/platforms/wmf/WMF.h
@@ -7,6 +7,18 @@
 #ifndef WMF_H_
 #define WMF_H_
 
+#if WINVER < _WIN32_WINNT_WIN7
+#error \
+You must include WMF.h before including mozilla headers, \
+otherwise mozconfig.h will be included \
+and that sets WINVER to WinXP, \
+which makes Windows Media Foundation unavailable.
+#endif
+
+#pragma push_macro("WINVER")
+#undef WINVER
+#define WINVER _WIN32_WINNT_WIN7
+
 #include <windows.h>
 #include <mfapi.h>
 #include <mfidl.h>
@@ -23,7 +35,7 @@
 #include <codecapi.h>
 
 // The Windows headers helpfully declare min and max macros, which don't
-// compile in the presence of std::min and std::max and unified builds.
+// compile in the prescence of std::min and std::max and unified builds.
 // So undef them here.
 #ifdef min
 #undef min
@@ -85,4 +97,8 @@ HRESULT MFCreateDXGISurfaceBuffer(REFIID riid,
 } // end namespace wmf
 } // end namespace mozilla
 
+
+
+#pragma pop_macro("WINVER")
+
 #endif
diff --git a/dom/media/platforms/wmf/WMFUtils.cpp b/dom/media/platforms/wmf/WMFUtils.cpp
index 055012d0f..8aec8a8af 100644
--- a/dom/media/platforms/wmf/WMFUtils.cpp
+++ b/dom/media/platforms/wmf/WMFUtils.cpp
@@ -205,17 +205,31 @@ LoadDLLs()
 HRESULT
 MFStartup()
 {
+  if (!IsVistaOrLater() || IsWin7AndPre2000Compatible()) {
+    // *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.
+    // Using GetVersionEx API which takes compatibility mode into account.
+    return E_FAIL;
+  }
+
   HRESULT hr = LoadDLLs();
   if (FAILED(hr)) {
     return 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);
   ENSURE_FUNCTION_PTR_(MFStartup, Mfplat.dll)
-  return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
+  if (!IsWin7OrLater())
+    return MFStartupPtr(MF_VISTA_VERSION, MFSTARTUP_FULL);
+  else
+    return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
 }
 
 HRESULT
diff --git a/dom/media/webrtc/MediaEngineWebRTC.cpp b/dom/media/webrtc/MediaEngineWebRTC.cpp
index 1a2dc9a04..522f23f61 100644
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -268,7 +268,11 @@ MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
 bool
 MediaEngineWebRTC::SupportsDuplex()
 {
+#ifndef XP_WIN
   return mFullDuplex;
+#else
+  return IsVistaOrLater() && mFullDuplex;
+#endif
 }
 
 void
diff --git a/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest b/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest
index f5b7345f9..8d6149c58 100644
--- a/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest
+++ b/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest
@@ -32,6 +32,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
index 0394b352b..da63a55ca 100755
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -9,6 +9,10 @@ ifdef MOZ_D3DCOMPILER_VISTA_DLL_PATH
 	cp -fp "$(MOZ_D3DCOMPILER_VISTA_DLL_PATH)" "$(DIST)/bin"
 endif
 
+ifdef MOZ_D3DCOMPILER_XP_CAB
+	expand '$(MOZ_D3DCOMPILER_XP_CAB)' -F:$(MOZ_D3DCOMPILER_XP_DLL) '$(DIST)/bin'
+endif
+
 endif
 
 include $(topsrcdir)/config/rules.mk
diff --git a/gfx/angle/moz.build b/gfx/angle/moz.build
index 2a40e0ac6..1da8356a5 100755
--- a/gfx/angle/moz.build
+++ b/gfx/angle/moz.build
@@ -139,6 +139,9 @@ if CONFIG['GNU_CXX']:
             '-Wno-shadow-local',
         ]
 
+if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
+    LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
+
 DEFINES['_CRT_SECURE_NO_DEPRECATE'] = True
 DEFINES['_HAS_EXCEPTIONS'] = 0
 
diff --git a/gfx/angle/src/libANGLE/moz.build b/gfx/angle/src/libANGLE/moz.build
index e127ccce1..0a2a4437f 100755
--- a/gfx/angle/src/libANGLE/moz.build
+++ b/gfx/angle/src/libANGLE/moz.build
@@ -353,6 +353,9 @@ if CONFIG['GNU_CXX']:
             '-Wno-shadow-local',
         ]
 
+if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
+    LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
+
 DEFINES['_CRT_SECURE_NO_DEPRECATE'] = True
 DEFINES['_HAS_EXCEPTIONS'] = 0
 
@@ -385,6 +388,11 @@ DEFINES['ANGLE_DEFAULT_D3D11'] = "0"
 
 if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
   OS_LIBS += [ 'd3d9', 'dxguid' ]
+else:
+  EXTRA_DSO_LDOPTS += [
+    '\'%s/lib/%s/d3d9.lib\'' % (CONFIG['MOZ_DIRECTX_SDK_PATH'], CONFIG['MOZ_D3D_CPU_SUFFIX']),
+    '\'%s/lib/%s/dxguid.lib\'' % (CONFIG['MOZ_DIRECTX_SDK_PATH'], CONFIG['MOZ_D3D_CPU_SUFFIX']),
+  ]
 
 Library('libANGLE')
 
diff --git a/gfx/angle/src/libEGL/moz.build b/gfx/angle/src/libEGL/moz.build
index c1e33c86e..8e99d44ff 100755
--- a/gfx/angle/src/libEGL/moz.build
+++ b/gfx/angle/src/libEGL/moz.build
@@ -32,6 +32,9 @@ if CONFIG['GNU_CXX']:
             '-Wno-shadow-local',
         ]
 
+if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
+    LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
+
 DEFINES['_CRT_SECURE_NO_DEPRECATE'] = True
 DEFINES['_HAS_EXCEPTIONS'] = 0
 
@@ -64,6 +67,11 @@ DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 
 if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
   OS_LIBS += [ 'd3d9', 'dxguid' ]
+else:
+  EXTRA_DSO_LDOPTS += [
+    '\'%s/lib/%s/d3d9.lib\'' % (CONFIG['MOZ_DIRECTX_SDK_PATH'], CONFIG['MOZ_D3D_CPU_SUFFIX']),
+    '\'%s/lib/%s/dxguid.lib\'' % (CONFIG['MOZ_DIRECTX_SDK_PATH'], CONFIG['MOZ_D3D_CPU_SUFFIX']),
+  ]
 
 
 GeckoSharedLibrary('libEGL', linkage=None)
diff --git a/gfx/angle/src/libGLESv2/moz.build b/gfx/angle/src/libGLESv2/moz.build
index 08c60c213..1d40b3b67 100755
--- a/gfx/angle/src/libGLESv2/moz.build
+++ b/gfx/angle/src/libGLESv2/moz.build
@@ -39,6 +39,9 @@ if CONFIG['GNU_CXX']:
             '-Wno-shadow-local',
         ]
 
+if CONFIG['MOZ_DIRECTX_SDK_PATH'] and not CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
+    LOCAL_INCLUDES += ['%' + '%s/include/' % CONFIG['MOZ_DIRECTX_SDK_PATH']]
+
 DEFINES['_CRT_SECURE_NO_DEPRECATE'] = True
 DEFINES['_HAS_EXCEPTIONS'] = 0
 
@@ -70,6 +73,11 @@ DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 
 if CONFIG['MOZ_HAS_WINSDK_WITH_D3D']:
   OS_LIBS += [ 'd3d9', 'dxguid' ]
+else:
+  EXTRA_DSO_LDOPTS += [
+    '\'%s/lib/%s/d3d9.lib\'' % (CONFIG['MOZ_DIRECTX_SDK_PATH'], CONFIG['MOZ_D3D_CPU_SUFFIX']),
+    '\'%s/lib/%s/dxguid.lib\'' % (CONFIG['MOZ_DIRECTX_SDK_PATH'], CONFIG['MOZ_D3D_CPU_SUFFIX']),
+  ]
 
 GeckoSharedLibrary('libGLESv2', linkage=None)
 
diff --git a/gfx/gl/moz.build b/gfx/gl/moz.build
index 6f43a495d..596612bb8 100644
--- a/gfx/gl/moz.build
+++ b/gfx/gl/moz.build
@@ -150,6 +150,8 @@ FINAL_LIBRARY = 'xul'
 
 if CONFIG['MOZ_D3DCOMPILER_VISTA_DLL']:
     DEFINES['MOZ_D3DCOMPILER_VISTA_DLL'] = CONFIG['MOZ_D3DCOMPILER_VISTA_DLL']
+if CONFIG['MOZ_D3DCOMPILER_XP_DLL']:
+    DEFINES['MOZ_D3DCOMPILER_XP_DLL'] = CONFIG['MOZ_D3DCOMPILER_XP_DLL']
 
 CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
 CXXFLAGS += CONFIG['TK_CFLAGS']
diff --git a/gfx/thebes/gfxGDIFont.cpp b/gfx/thebes/gfxGDIFont.cpp
index d6e98105c..e6ceeaf6d 100644
--- a/gfx/thebes/gfxGDIFont.cpp
+++ b/gfx/thebes/gfxGDIFont.cpp
@@ -461,7 +461,8 @@ gfxGDIFont::FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize,
         weight = mNeedsBold ? 700 : fe->Weight();
     }
 
-    fe->FillLogFont(&aLogFont, weight, aSize);
+    fe->FillLogFont(&aLogFont, weight, aSize, 
+                    (mAntialiasOption == kAntialiasSubpixel) ? true : false);
 
     // If GDI synthetic italic is wanted, force the lfItalic field to true
     if (aUseGDIFakeItalic) {
diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp
index cc047ef38..d80c49356 100644
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -37,6 +37,11 @@ using namespace mozilla;
 
 #define ROUND(x) floor((x) + 0.5)
 
+
+#ifndef CLEARTYPE_QUALITY
+#define CLEARTYPE_QUALITY 5
+#endif
+
 #define LOG_FONTLIST(args) MOZ_LOG(gfxPlatform::GetLog(eGfxLog_fontlist), \
                                LogLevel::Debug, args)
 #define LOG_FONTLIST_ENABLED() MOZ_LOG_TEST( \
@@ -217,7 +222,16 @@ GDIFontEntry::IsSymbolFont()
 gfxFont *
 GDIFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, bool aNeedsBold)
 {
-    return new gfxGDIFont(this, aFontStyle, aNeedsBold);
+    bool isXP = !IsVistaOrLater();
+
+    bool useClearType = isXP && !aFontStyle->systemFont &&
+        (gfxWindowsPlatform::GetPlatform()->UseClearTypeAlways() ||
+         (mIsDataUserFont &&
+          gfxWindowsPlatform::GetPlatform()->UseClearTypeForDownloadableFonts()));
+
+    return new gfxGDIFont(this, aFontStyle, aNeedsBold, 
+                          (useClearType ? gfxFont::kAntialiasSubpixel
+                                        : gfxFont::kAntialiasDefault));
 }
 
 nsresult
@@ -249,7 +263,8 @@ GDIFontEntry::CopyFontTable(uint32_t aTableTag, nsTArray<uint8_t>& aBuffer)
 
 void
 GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
-                          uint16_t aWeight, gfxFloat aSize)
+                          uint16_t aWeight, gfxFloat aSize,
+                          bool aUseCleartype)
 {
     memcpy(aLogFont, &mLogFont, sizeof(LOGFONTW));
 
@@ -275,6 +290,8 @@ GDIFontEntry::FillLogFont(LOGFONTW *aLogFont,
     if (mIsDataUserFont) {
         aLogFont->lfItalic = 0;
     }
+
+    aLogFont->lfQuality = (aUseCleartype ? CLEARTYPE_QUALITY : DEFAULT_QUALITY);
 }
 
 #define MISSING_GLYPH 0x1F // glyph index returned for missing characters
@@ -862,8 +879,15 @@ gfxGDIFontList::MakePlatformFont(const nsAString& aFontName,
         gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/,
         aStyle, w, aStretch, winUserFontData, false);
 
-    if (fe) {
-      fe->mIsDataUserFont = true;
+    if (!fe)
+        return fe;
+
+    fe->mIsDataUserFont = true;
+
+    // Uniscribe doesn't place CFF fonts loaded privately
+    // via AddFontMemResourceEx on XP/Vista
+    if (isCFF && !IsWin7OrLater()) {
+        fe->mForceGDI = true;
     }
 
     return fe;
diff --git a/gfx/thebes/gfxGDIFontList.h b/gfx/thebes/gfxGDIFontList.h
index 60fb292e8..ffb513d64 100644
--- a/gfx/thebes/gfxGDIFontList.h
+++ b/gfx/thebes/gfxGDIFontList.h
@@ -112,7 +112,8 @@ public:
 
     virtual bool IsSymbolFont();
 
-    void FillLogFont(LOGFONTW *aLogFont, uint16_t aWeight, gfxFloat aSize);
+    void FillLogFont(LOGFONTW *aLogFont, uint16_t aWeight, gfxFloat aSize,
+                     bool aUseCleartype);
 
     static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics, 
                                                 DWORD fontType)
diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp
index 84199170b..be1780797 100755
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -146,6 +146,9 @@ public:
 
 NS_IMPL_ISUPPORTS(GfxD2DVramReporter, nsIMemoryReporter)
 
+#define GFX_USE_CLEARTYPE_ALWAYS "gfx.font_rendering.cleartype.always_use_for_content"
+#define GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE "gfx.font_rendering.cleartype.use_for_downloadable_fonts"
+
 #define GFX_CLEARTYPE_PARAMS           "gfx.font_rendering.cleartype_params."
 #define GFX_CLEARTYPE_PARAMS_GAMMA     "gfx.font_rendering.cleartype_params.gamma"
 #define GFX_CLEARTYPE_PARAMS_CONTRAST  "gfx.font_rendering.cleartype_params.enhanced_contrast"
@@ -191,6 +194,10 @@ public:
         HMODULE gdi32Handle;
         PFND3DKMTQS queryD3DKMTStatistics = nullptr;
 
+        // GPU memory reporting is not available before Windows 7
+        if (!IsWin7OrLater())
+            return NS_OK;
+
         if ((gdi32Handle = LoadLibrary(TEXT("gdi32.dll"))))
             queryD3DKMTStatistics = (PFND3DKMTQS)GetProcAddress(gdi32Handle, "D3DKMTQueryStatistics");
 
@@ -313,6 +320,9 @@ NS_IMPL_ISUPPORTS(D3DSharedTexturesReporter, nsIMemoryReporter)
 gfxWindowsPlatform::gfxWindowsPlatform()
   : mRenderMode(RENDER_GDI)
 {
+  mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
+  mUseClearTypeAlways = UNINITIALIZED_VALUE;
+
   /*
    * Initialize COM
    */
@@ -392,6 +402,10 @@ gfxWindowsPlatform::CanUseHardwareVideoDecoding()
 bool
 gfxWindowsPlatform::InitDWriteSupport()
 {
+  if (!IsVistaOrLater()) {
+    return false;
+  }
+
   // DWrite is only supported on Windows 7 with the platform update and higher.
   // We check this by seeing if D2D1 support is available.
   if (!Factory::SupportsD2D1()) {
@@ -983,6 +997,26 @@ gfxWindowsPlatform::GetPlatformCMSOutputProfile(void* &mem, size_t &mem_size)
 #endif // _WIN32
 }
 
+bool
+gfxWindowsPlatform::UseClearTypeForDownloadableFonts()
+{
+    if (mUseClearTypeForDownloadableFonts == UNINITIALIZED_VALUE) {
+        mUseClearTypeForDownloadableFonts = Preferences::GetBool(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, true);
+    }
+
+    return mUseClearTypeForDownloadableFonts;
+}
+
+bool
+gfxWindowsPlatform::UseClearTypeAlways()
+{
+    if (mUseClearTypeAlways == UNINITIALIZED_VALUE) {
+        mUseClearTypeAlways = Preferences::GetBool(GFX_USE_CLEARTYPE_ALWAYS, false);
+    }
+
+    return mUseClearTypeAlways;
+}
+
 void
 gfxWindowsPlatform::GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion)
 {
@@ -1126,7 +1160,14 @@ gfxWindowsPlatform::FontsPrefsChanged(const char *aPref)
 
     gfxPlatform::FontsPrefsChanged(aPref);
 
-    if (aPref && !strncmp(GFX_CLEARTYPE_PARAMS, aPref, strlen(GFX_CLEARTYPE_PARAMS))) {
+    if (!aPref) {
+        mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
+        mUseClearTypeAlways = UNINITIALIZED_VALUE;
+    } else if (!strcmp(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, aPref)) {
+        mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
+    } else if (!strcmp(GFX_USE_CLEARTYPE_ALWAYS, aPref)) {
+        mUseClearTypeAlways = UNINITIALIZED_VALUE;
+    } else if (!strncmp(GFX_CLEARTYPE_PARAMS, aPref, strlen(GFX_CLEARTYPE_PARAMS))) {
         SetupClearTypeParams();
     } else {
         clearTextFontCaches = false;
@@ -1374,13 +1415,17 @@ gfxWindowsPlatform::InitializeD3D9Config()
     return;
   }
 
-  d3d9.SetDefaultFromPref(
-    gfxPrefs::GetLayersAllowD3D9FallbackPrefName(),
-    true,
-    gfxPrefs::GetLayersAllowD3D9FallbackPrefDefault());
+  if (!IsVistaOrLater()) {
+    d3d9.EnableByDefault();
+  } else {
+    d3d9.SetDefaultFromPref(
+      gfxPrefs::GetLayersAllowD3D9FallbackPrefName(),
+      true,
+      gfxPrefs::GetLayersAllowD3D9FallbackPrefDefault());
 
-  if (!d3d9.IsEnabled() && gfxPrefs::LayersPreferD3D9()) {
-    d3d9.UserEnable("Direct3D9 enabled via layers.prefer-d3d9");
+    if (!d3d9.IsEnabled() && gfxPrefs::LayersPreferD3D9()) {
+      d3d9.UserEnable("Direct3D9 enabled via layers.prefer-d3d9");
+    }
   }
 
   nsCString message;
@@ -1551,6 +1596,11 @@ gfxWindowsPlatform::InitializeD2DConfig()
                           NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_D3D11_COMP"));
     return;
   }
+  if (!IsVistaOrLater()) {
+    d2d1.DisableByDefault(FeatureStatus::Unavailable, "Direct2D is not available on Windows XP",
+                          NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_XP"));
+    return;
+  }
 
   d2d1.SetDefaultFromPref(
     gfxPrefs::GetDirect2DDisabledPrefName(),
@@ -1642,12 +1692,14 @@ gfxWindowsPlatform::InitGPUProcessSupport()
       "Not using GPU Process since D3D11 is unavailable",
       NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_D3D11"));
   } else if (!IsWin7SP1OrLater()) {
-    // On Windows 7 Pre-SP1, DXGI 1.2 is not available and remote presentation
-    // for D3D11 will not work. Rather than take a regression and use D3D9, we
-    // revert back to in-process rendering.
+    // For Windows XP, we simply don't care enough to support this
+    // configuration. On Windows Vista and 7 Pre-SP1, DXGI 1.2 is not
+    // available and remote presentation for D3D11 will not work. Rather
+    // than take a regression and use D3D9, we revert back to in-process
+    // rendering.
     gpuProc.Disable(
       FeatureStatus::Unavailable,
-      "Windows 7 Pre-SP1 cannot use the GPU process",
+      "Windows XP, Vista, and 7 Pre-SP1 cannot use the GPU process",
       NS_LITERAL_CSTRING("FEATURE_FAILURE_OLD_WINDOWS"));
   } else if (!IsWin8OrLater()) {
     // Windows 7 SP1 can have DXGI 1.2 only via the Platform Update, so we
@@ -1670,6 +1722,10 @@ gfxWindowsPlatform::InitGPUProcessSupport()
 bool
 gfxWindowsPlatform::DwmCompositionEnabled()
 {
+  if (!IsVistaOrLater()) {
+    return false;
+  }
+
   MOZ_ASSERT(WinUtils::dwmIsCompositionEnabledPtr);
   BOOL dwmEnabled = false;
 
diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h
index f77d9a87a..8db7cf575 100644
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -184,6 +184,11 @@ public:
 
     mozilla::gfx::BackendType GetContentBackendFor(mozilla::layers::LayersBackend aLayers) override;
 
+    // ClearType is not always enabled even when available (e.g. Windows XP)
+    // if either of these prefs are enabled and apply, use ClearType rendering
+    bool UseClearTypeForDownloadableFonts();
+    bool UseClearTypeAlways();
+
     static void GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion);
 
     // returns ClearType tuning information for each display
@@ -242,6 +247,9 @@ protected:
 protected:
     RenderMode mRenderMode;
 
+    int8_t mUseClearTypeForDownloadableFonts;
+    int8_t mUseClearTypeAlways;
+
 private:
     void Init();
     void InitAcceleration() override;
diff --git a/hal/windows/WindowsBattery.cpp b/hal/windows/WindowsBattery.cpp
index 520330242..c1b9a31e6 100644
--- a/hal/windows/WindowsBattery.cpp
+++ b/hal/windows/WindowsBattery.cpp
@@ -5,20 +5,45 @@
 
 #include "Hal.h"
 #include "HalImpl.h"
+#include "nsITimer.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/battery/Constants.h"
+#include "nsComponentManagerUtils.h"
 
 #include <windows.h>
+#include "mozilla/WindowsVersion.h"
 
 using namespace mozilla::dom::battery;
 
 namespace mozilla {
 namespace hal_impl {
 
+static nsCOMPtr<nsITimer> sUpdateTimer;
+
+/* Power Event API is Vista or later */
+static decltype(RegisterPowerSettingNotification)* sRegisterPowerSettingNotification = nullptr;
+static decltype(UnregisterPowerSettingNotification)* sUnregisterPowerSettingNotification = nullptr;
 static HPOWERNOTIFY sPowerHandle = nullptr;
 static HPOWERNOTIFY sCapacityHandle = nullptr;
 static HWND sHWnd = nullptr;
 
+static void
+UpdateHandler(nsITimer* aTimer, void* aClosure) {
+  NS_ASSERTION(!IsVistaOrLater(),
+               "We shouldn't call this function for Vista or later version!");
+
+  static hal::BatteryInformation sLastInfo;
+  hal::BatteryInformation currentInfo;
+
+  hal_impl::GetCurrentBatteryInformation(&currentInfo);
+  if (sLastInfo.level() != currentInfo.level() ||
+      sLastInfo.charging() != currentInfo.charging() ||
+      sLastInfo.remainingTime() != currentInfo.remainingTime()) {
+    hal::NotifyBatteryChange(currentInfo);
+    sLastInfo = currentInfo;
+  }
+}
+
 static
 LRESULT CALLBACK
 BatteryWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
@@ -38,56 +63,94 @@ BatteryWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
 void
 EnableBatteryNotifications()
 {
-  // Create custom window to watch battery event
-  // If we can get Gecko's window handle, this is unnecessary.
-
-  if (sHWnd == nullptr) {
-    WNDCLASSW wc;
-    HMODULE hSelf = GetModuleHandle(nullptr);
-
-    if (!GetClassInfoW(hSelf, L"MozillaBatteryClass", &wc)) {
-      ZeroMemory(&wc, sizeof(WNDCLASSW));
-      wc.hInstance = hSelf;
-      wc.lpfnWndProc = BatteryWindowProc;
-      wc.lpszClassName = L"MozillaBatteryClass";
-      RegisterClassW(&wc);
+  if (IsVistaOrLater()) {
+    // RegisterPowerSettingNotification is from Vista or later.
+    // Use this API if available.
+    HMODULE hUser32 = GetModuleHandleW(L"USER32.DLL");
+    if (!sRegisterPowerSettingNotification)
+      sRegisterPowerSettingNotification = (decltype(RegisterPowerSettingNotification)*)
+        GetProcAddress(hUser32, "RegisterPowerSettingNotification");
+    if (!sUnregisterPowerSettingNotification)
+      sUnregisterPowerSettingNotification = (decltype(UnregisterPowerSettingNotification)*)
+        GetProcAddress(hUser32, "UnregisterPowerSettingNotification");
+
+    if (!sRegisterPowerSettingNotification ||
+        !sUnregisterPowerSettingNotification) {
+      NS_ASSERTION(false, "Canot find PowerSettingNotification functions.");
+      return;
     }
 
-    sHWnd = CreateWindowW(L"MozillaBatteryClass", L"Battery Watcher",
-                          0, 0, 0, 0, 0,
-                          nullptr, nullptr, hSelf, nullptr);
-  }
+    // Create custom window to watch battery event
+    // If we can get Gecko's window handle, this is unnecessary.
 
-  if (sHWnd == nullptr) {
-    return;
-  }
+    if (sHWnd == nullptr) {
+      WNDCLASSW wc;
+      HMODULE hSelf = GetModuleHandle(nullptr);
+
+      if (!GetClassInfoW(hSelf, L"MozillaBatteryClass", &wc)) {
+        ZeroMemory(&wc, sizeof(WNDCLASSW));
+        wc.hInstance = hSelf;
+        wc.lpfnWndProc = BatteryWindowProc;
+        wc.lpszClassName = L"MozillaBatteryClass";
+        RegisterClassW(&wc);
+      }
 
-  sPowerHandle =
-    RegisterPowerSettingNotification(sHWnd,
-                                     &GUID_ACDC_POWER_SOURCE,
-                                     DEVICE_NOTIFY_WINDOW_HANDLE);
-  sCapacityHandle =
-    RegisterPowerSettingNotification(sHWnd,
-                                     &GUID_BATTERY_PERCENTAGE_REMAINING,
-                                     DEVICE_NOTIFY_WINDOW_HANDLE);
+      sHWnd = CreateWindowW(L"MozillaBatteryClass", L"Battery Watcher",
+                            0, 0, 0, 0, 0,
+                            nullptr, nullptr, hSelf, nullptr);
+    }
+
+    if (sHWnd == nullptr) {
+      return;
+    }
+
+    sPowerHandle =
+      sRegisterPowerSettingNotification(sHWnd,
+                                        &GUID_ACDC_POWER_SOURCE,
+                                        DEVICE_NOTIFY_WINDOW_HANDLE);
+    sCapacityHandle =
+      sRegisterPowerSettingNotification(sHWnd,
+                                        &GUID_BATTERY_PERCENTAGE_REMAINING,
+                                        DEVICE_NOTIFY_WINDOW_HANDLE);
+  } else
+  {
+    // for Windows XP.  If we remove Windows XP support,
+    // we should remove timer-based power notification
+    sUpdateTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
+    if (sUpdateTimer) {
+      sUpdateTimer->InitWithFuncCallback(UpdateHandler,
+                                         nullptr,
+                                         Preferences::GetInt("dom.battery.timer",
+                                                             30000 /* 30s */),
+                                         nsITimer::TYPE_REPEATING_SLACK);
+    } 
+  }
 }
 
 void
 DisableBatteryNotifications()
 {
-  if (sPowerHandle) {
-    UnregisterPowerSettingNotification(sPowerHandle);
-    sPowerHandle = nullptr;
-  }
+  if (IsVistaOrLater()) {
+    if (sPowerHandle) {
+      sUnregisterPowerSettingNotification(sPowerHandle);
+      sPowerHandle = nullptr;
+    }
 
-  if (sCapacityHandle) {
-    UnregisterPowerSettingNotification(sCapacityHandle);
-    sCapacityHandle = nullptr;
-  }
+    if (sCapacityHandle) {
+      sUnregisterPowerSettingNotification(sCapacityHandle);
+      sCapacityHandle = nullptr;
+    }
 
-  if (sHWnd) {
-    DestroyWindow(sHWnd);
-    sHWnd = nullptr;
+    if (sHWnd) {
+      DestroyWindow(sHWnd);
+      sHWnd = nullptr;
+    }
+  } else
+  {
+    if (sUpdateTimer) {
+      sUpdateTimer->Cancel();
+      sUpdateTimer = nullptr;
+    }
   }
 }
 
diff --git a/image/decoders/icon/win/nsIconChannel.cpp b/image/decoders/icon/win/nsIconChannel.cpp
index 04680627a..9ddcbbc48 100644
--- a/image/decoders/icon/win/nsIconChannel.cpp
+++ b/image/decoders/icon/win/nsIconChannel.cpp
@@ -29,6 +29,11 @@
 #include "nsContentSecurityManager.h"
 #include "nsContentUtils.h"
 
+#ifdef _WIN32_WINNT
+#undef _WIN32_WINNT
+#endif
+#define _WIN32_WINNT 0x0600
+
 // we need windows.h to read out registry information...
 #include <windows.h>
 #include <shellapi.h>
@@ -411,27 +416,41 @@ nsIconChannel::GetStockHIcon(nsIMozIconURI* aIconURI,
 {
   nsresult rv = NS_OK;
 
-  uint32_t desiredImageSize;
-  aIconURI->GetImageSize(&desiredImageSize);
-  nsAutoCString stockIcon;
-  aIconURI->GetStockIcon(stockIcon);
-
-  SHSTOCKICONID stockIconID = GetStockIconIDForName(stockIcon);
-  if (stockIconID == SIID_INVALID) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
+  // We can only do this on Vista or above
+  HMODULE hShellDLL = ::LoadLibraryW(L"shell32.dll");
+  decltype(SHGetStockIconInfo)* pSHGetStockIconInfo =
+    (decltype(SHGetStockIconInfo)*) ::GetProcAddress(hShellDLL,
+                                                    "SHGetStockIconInfo");
+
+  if (pSHGetStockIconInfo) {
+    uint32_t desiredImageSize;
+    aIconURI->GetImageSize(&desiredImageSize);
+    nsAutoCString stockIcon;
+    aIconURI->GetStockIcon(stockIcon);
+
+    SHSTOCKICONID stockIconID = GetStockIconIDForName(stockIcon);
+    if (stockIconID == SIID_INVALID) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
 
-  UINT infoFlags = SHGSI_ICON;
-  infoFlags |= GetSizeInfoFlag(desiredImageSize);
+    UINT infoFlags = SHGSI_ICON;
+    infoFlags |= GetSizeInfoFlag(desiredImageSize);
 
-  SHSTOCKICONINFO sii = {0};
-  sii.cbSize = sizeof(sii);
-  HRESULT hr = SHGetStockIconInfo(stockIconID, infoFlags, &sii);
+    SHSTOCKICONINFO sii = {0};
+    sii.cbSize = sizeof(sii);
+    HRESULT hr = pSHGetStockIconInfo(stockIconID, infoFlags, &sii);
 
-  if (SUCCEEDED(hr)) {
-    *hIcon = sii.hIcon;
+    if (SUCCEEDED(hr)) {
+      *hIcon = sii.hIcon;
+    } else {
+      rv = NS_ERROR_FAILURE;
+    }
   } else {
-    rv = NS_ERROR_FAILURE;
+    rv = NS_ERROR_NOT_AVAILABLE;
+  }
+
+  if (hShellDLL) {
+    ::FreeLibrary(hShellDLL);
   }
 
   return rv;
diff --git a/ipc/app/plugin-container.exe.manifest b/ipc/app/plugin-container.exe.manifest
index 303109523..d61ddec1a 100644
--- a/ipc/app/plugin-container.exe.manifest
+++ b/ipc/app/plugin-container.exe.manifest
@@ -37,6 +37,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/ipc/chromium/src/base/process_util_win.cc b/ipc/chromium/src/base/process_util_win.cc
index f22f7216f..12fbc23a5 100644
--- a/ipc/chromium/src/base/process_util_win.cc
+++ b/ipc/chromium/src/base/process_util_win.cc
@@ -297,6 +297,43 @@ bool LaunchApp(const std::wstring& cmdline,
   startup_info.wShowWindow = start_hidden ? SW_HIDE : SW_SHOW;
 
   LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList = NULL;
+  // Don't even bother trying pre-Vista...
+  if (mozilla::IsVistaOrLater()) {
+    // setup our handle array first - if we end up with no handles that can
+    // be inherited we can avoid trying to do the ThreadAttributeList dance...
+    HANDLE handlesToInherit[2];
+    int handleCount = 0;
+    HANDLE stdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
+    HANDLE stdErr = ::GetStdHandle(STD_ERROR_HANDLE);
+
+    if (IsInheritableHandle(stdOut))
+      handlesToInherit[handleCount++] = stdOut;
+    if (stdErr != stdOut && IsInheritableHandle(stdErr))
+      handlesToInherit[handleCount++] = stdErr;
+
+    if (handleCount) {
+      lpAttributeList = CreateThreadAttributeList(handlesToInherit, handleCount);
+      if (lpAttributeList) {
+        // it's safe to inherit handles, so arrange for that...
+        startup_info.cb = sizeof(startup_info_ex);
+        startup_info.dwFlags |= STARTF_USESTDHANDLES;
+        startup_info.hStdOutput = stdOut;
+        startup_info.hStdError = stdErr;
+        startup_info.hStdInput = INVALID_HANDLE_VALUE;
+        startup_info_ex.lpAttributeList = lpAttributeList;
+        dwCreationFlags |= EXTENDED_STARTUPINFO_PRESENT;
+        bInheritHandles = TRUE;
+      }
+    }
+  } else if (PR_GetEnv("MOZ_WIN_INHERIT_STD_HANDLES_PRE_VISTA")) {
+    // Even if we can't limit what gets inherited, we sometimes want to inherit
+    // stdout/err for testing purposes.
+    startup_info.dwFlags |= STARTF_USESTDHANDLES;
+    startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+    startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+    startup_info.hStdInput = INVALID_HANDLE_VALUE;
+    bInheritHandles = TRUE;
+  }
 
   PROCESS_INFORMATION process_info;
   BOOL createdOK = CreateProcess(NULL,
diff --git a/ipc/glue/WindowsMessageLoop.cpp b/ipc/glue/WindowsMessageLoop.cpp
index 8f3471efc..8057ee25d 100644
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -1034,7 +1034,7 @@ MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages)
   MOZ_ASSERT(gUIThreadId, "InitUIThread was not called!");
 
 #if defined(ACCESSIBILITY)
-  if (mFlags & REQUIRE_A11Y_REENTRY) {
+  if (IsVistaOrLater() && (mFlags & REQUIRE_A11Y_REENTRY)) {
     MOZ_ASSERT(!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION));
     return WaitForSyncNotifyWithA11yReentry();
   }
diff --git a/ipc/mscom/MainThreadRuntime.cpp b/ipc/mscom/MainThreadRuntime.cpp
index a061eaf54..d86317966 100644
--- a/ipc/mscom/MainThreadRuntime.cpp
+++ b/ipc/mscom/MainThreadRuntime.cpp
@@ -44,6 +44,13 @@ MainThreadRuntime::MainThreadRuntime()
     return;
   }
 
+  // Windows XP doesn't support setting of the COM exception policy, so we'll
+  // just stop here in that case.
+  if (!IsVistaOrLater()) {
+    mInitResult = S_OK;
+    return;
+  }
+
   // We are required to initialize security in order to configure global options.
   mInitResult = InitializeSecurity();
   MOZ_ASSERT(SUCCEEDED(mInitResult));
@@ -60,8 +67,11 @@ MainThreadRuntime::MainThreadRuntime()
     return;
   }
 
-  // Use the strictest policy available.
-  ULONG_PTR exceptionSetting = COMGLB_EXCEPTION_DONOT_HANDLE_ANY;
+  // Windows 7 has a policy that is even more strict. We should use that one
+  // whenever possible.
+  ULONG_PTR exceptionSetting = IsWin7OrLater() ?
+                               COMGLB_EXCEPTION_DONOT_HANDLE_ANY :
+                               COMGLB_EXCEPTION_DONOT_HANDLE;
   mInitResult = globalOpts->Set(COMGLB_EXCEPTION_HANDLING, exceptionSetting);
   MOZ_ASSERT(SUCCEEDED(mInitResult));
 }
diff --git a/js/src/jsutil.cpp b/js/src/jsutil.cpp
index 705d21975..bb9f33df9 100644
--- a/js/src/jsutil.cpp
+++ b/js/src/jsutil.cpp
@@ -39,7 +39,7 @@ mozilla::Atomic<AutoEnterOOMUnsafeRegion*> AutoEnterOOMUnsafeRegion::owner_;
 namespace oom {
 
 JS_PUBLIC_DATA(uint32_t) targetThread = 0;
-MOZ_THREAD_LOCAL(uint32_t) threadType;
+JS_PUBLIC_DATA(MOZ_THREAD_LOCAL(uint32_t)) threadType;
 JS_PUBLIC_DATA(uint64_t) maxAllocations = UINT64_MAX;
 JS_PUBLIC_DATA(uint64_t) counter = 0;
 JS_PUBLIC_DATA(bool) failAlways = true;
diff --git a/js/src/old-configure.in b/js/src/old-configure.in
index 5da81ce3e..94ecc5fd7 100644
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -143,7 +143,8 @@ MOZ_TOOL_VARIABLES
 dnl Special win32 checks
 dnl ========================================================
 
-WINVER=601
+# Target the Windows 8.1 SDK by default
+WINVER=502
 
 case "$target" in
 *-mingw*)
@@ -721,7 +722,12 @@ case "$target" in
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
-        WIN32_SUBSYSTEM_VERSION=6.01
+        dnl Set subsystem version 5 for Windows XP.
+        if test "$CPU_ARCH" = "x86"; then
+            WIN32_SUBSYSTEM_VERSION=5.01
+        else
+            WIN32_SUBSYSTEM_VERSION=5.02
+        fi
         WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
         WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
diff --git a/js/src/threading/windows/ConditionVariable.cpp b/js/src/threading/windows/ConditionVariable.cpp
index 3c75a0f27..868c35141 100644
--- a/js/src/threading/windows/ConditionVariable.cpp
+++ b/js/src/threading/windows/ConditionVariable.cpp
@@ -28,34 +28,342 @@
   _InterlockedIncrement((volatile long*)(addend))
 #endif
 
+// Windows XP and Server 2003 don't support condition variables natively. The
+// NativeImports class is responsible for detecting native support and
+// retrieving the appropriate function pointers. It gets instantiated once,
+// using a static initializer.
+class ConditionVariableNativeImports
+{
+public:
+  ConditionVariableNativeImports() {
+    HMODULE kernel32_dll = GetModuleHandle("kernel32.dll");
+    MOZ_RELEASE_ASSERT(kernel32_dll != NULL);
+
+#define LOAD_SYMBOL(symbol) loadSymbol(kernel32_dll, #symbol, symbol)
+    supported_ = LOAD_SYMBOL(InitializeConditionVariable) &&
+                 LOAD_SYMBOL(WakeConditionVariable) &&
+                 LOAD_SYMBOL(WakeAllConditionVariable) &&
+                 LOAD_SYMBOL(SleepConditionVariableCS);
+#undef LOAD_SYMBOL
+  }
+
+  inline bool supported() const {
+    return supported_;
+  }
+
+  void(WINAPI* InitializeConditionVariable)(CONDITION_VARIABLE* ConditionVariable);
+  void(WINAPI* WakeAllConditionVariable)(PCONDITION_VARIABLE ConditionVariable);
+  void(WINAPI* WakeConditionVariable)(CONDITION_VARIABLE* ConditionVariable);
+  BOOL(WINAPI* SleepConditionVariableCS)(CONDITION_VARIABLE* ConditionVariable,
+                                         CRITICAL_SECTION* CriticalSection,
+                                         DWORD dwMilliseconds);
+
+private:
+  template <typename T>
+  inline bool loadSymbol(HMODULE module, const char* name, T& fn) {
+    FARPROC ptr = GetProcAddress(module, name);
+    if (!ptr)
+      return false;
+
+    fn = reinterpret_cast<T>(ptr);
+    return true;
+  }
+
+  bool supported_;
+};
+
+static ConditionVariableNativeImports sNativeImports;
+
 // Wrapper for native condition variable APIs.
-struct js::ConditionVariable::PlatformData
+struct ConditionVariableNative
 {
+  inline void initialize() {
+    sNativeImports.InitializeConditionVariable(&cv_);
+  }
+
+  inline void destroy() {
+    // Native condition variables don't require cleanup.
+  }
+
+  inline void notify_one() { sNativeImports.WakeConditionVariable(&cv_); }
+
+  inline void notify_all() { sNativeImports.WakeAllConditionVariable(&cv_); }
+
+  inline bool wait(CRITICAL_SECTION* cs, DWORD msec) {
+    return sNativeImports.SleepConditionVariableCS(&cv_, cs, msec);
+  }
+
+private:
   CONDITION_VARIABLE cv_;
 };
 
+// Fallback condition variable support for Windows XP and Server 2003. Given the
+// difficulty of testing on these antiquated platforms and their rapidly
+// diminishing market share, this implementation trades performance for
+// predictable behavior.
+struct ConditionVariableFallback
+{
+  static const uint32_t WAKEUP_MODE_NONE = 0;
+  static const uint32_t WAKEUP_MODE_ONE = 0x40000000;
+  static const uint32_t WAKEUP_MODE_ALL = 0x80000000;
+
+  static const uint32_t WAKEUP_MODE_MASK = WAKEUP_MODE_ONE | WAKEUP_MODE_ALL;
+  static const uint32_t SLEEPERS_COUNT_MASK = ~WAKEUP_MODE_MASK;
+
+  void initialize()
+  {
+    // Initialize the state variable to 0 sleepers, no wakeup.
+    sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
+
+    // Create a semaphore that prevents threads from entering sleep,
+    // or waking other threads while a wakeup is ongoing.
+    sleepWakeupSemaphore_ = CreateSemaphoreW(NULL, 1, 1, NULL);
+    MOZ_RELEASE_ASSERT(sleepWakeupSemaphore_);
+
+    // Use an auto-reset event for waking up a single sleeper.
+    wakeOneEvent_ = CreateEventW(NULL, FALSE, FALSE, NULL);
+    MOZ_RELEASE_ASSERT(wakeOneEvent_);
+
+    // Use a manual-reset event for waking up all sleepers.
+    wakeAllEvent_ = CreateEventW(NULL, TRUE, FALSE, NULL);
+    MOZ_RELEASE_ASSERT(wakeAllEvent_);
+  }
+
+  void destroy()
+  {
+    BOOL r;
+
+    MOZ_RELEASE_ASSERT(sleepersCountAndWakeupMode_ == (0 | WAKEUP_MODE_NONE));
+
+    r = CloseHandle(sleepWakeupSemaphore_);
+    MOZ_RELEASE_ASSERT(r);
+
+    r = CloseHandle(wakeOneEvent_);
+    MOZ_RELEASE_ASSERT(r);
+
+    r = CloseHandle(wakeAllEvent_);
+    MOZ_RELEASE_ASSERT(r);
+  }
+
+private:
+  void wakeup(uint32_t wakeupMode, HANDLE wakeEvent)
+  {
+    // Ensure that only one thread at a time can wake up others.
+    BOOL result = WaitForSingleObject(sleepWakeupSemaphore_, INFINITE);
+    MOZ_RELEASE_ASSERT(result == WAIT_OBJECT_0);
+
+    // Atomically set the wakeup mode and retrieve the number of sleepers.
+    uint32_t wcwm = InterlockedExchangeAdd(&sleepersCountAndWakeupMode_,
+                                           wakeupMode);
+    uint32_t sleepersCount = wcwm & SLEEPERS_COUNT_MASK;
+    MOZ_RELEASE_ASSERT((wcwm & WAKEUP_MODE_MASK) == WAKEUP_MODE_NONE);
+
+    if (sleepersCount > 0) {
+      // If there are any sleepers, set the wake event. The (last) woken
+      // up thread is responsible for releasing the semaphore.
+      BOOL success = SetEvent(wakeEvent);
+      MOZ_RELEASE_ASSERT(success);
+
+    } else {
+      // If there are no sleepers, set the wakeup mode back to 'none'
+      // and release the semaphore ourselves.
+      sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
+
+      BOOL success = ReleaseSemaphore(sleepWakeupSemaphore_, 1, NULL);
+      MOZ_RELEASE_ASSERT(success);
+    }
+  }
+
+public:
+  void notify_one() { wakeup(WAKEUP_MODE_ONE, wakeOneEvent_); }
+
+  void notify_all() { wakeup(WAKEUP_MODE_ALL, wakeAllEvent_); }
+
+  bool wait(CRITICAL_SECTION* userLock, DWORD msec)
+  {
+    // Make sure that we can't enter sleep when there are other threads
+    // that still need to wake up on either of the wake events being set.
+    DWORD result = WaitForSingleObject(sleepWakeupSemaphore_, INFINITE);
+    MOZ_RELEASE_ASSERT(result == WAIT_OBJECT_0);
+
+    // Register ourselves as a sleeper. Use an atomic operation, because
+    // if another thread times out at the same time, it will decrement the
+    // sleepers count without acquiring the semaphore.
+    uint32_t wcwm = InterlockedIncrement(&sleepersCountAndWakeupMode_);
+    MOZ_RELEASE_ASSERT((wcwm & WAKEUP_MODE_MASK) == WAKEUP_MODE_NONE);
+
+    // Now that that this thread has been enlisted as a sleeper, it is safe
+    // again for other threads to do a wakeup.
+    BOOL success = ReleaseSemaphore(sleepWakeupSemaphore_, 1, NULL);
+    MOZ_RELEASE_ASSERT(success);
+
+    // Release the caller's mutex.
+    LeaveCriticalSection(userLock);
+
+    // Wait for either event to become signaled, which happens when
+    // notify_one() or notify_all() is called, or for a timeout.
+    HANDLE handles[2] = { wakeOneEvent_, wakeAllEvent_ };
+    DWORD waitResult = WaitForMultipleObjects(2, handles, FALSE, msec);
+    MOZ_RELEASE_ASSERT(waitResult == WAIT_OBJECT_0 ||
+                       waitResult == WAIT_OBJECT_0 + 1 ||
+                       (waitResult == WAIT_TIMEOUT && msec != INFINITE));
+
+    // Atomically decrease the sleepers count and retrieve the wakeup mode
+    // and new sleepers count.
+    // If the wait returned because wakeOneEvent_ was set, we are certain
+    // that the wakeup mode will be WAKEUP_MODE_ONE. In that case,
+    // atomically reset the wakeup mode to 'none', because if another
+    // thread's sleep times out at same time and it finds that it was the
+    // last sleeper, it decides whether or not to reset the wakeOneEvent_
+    // based on the current wakeup mode.
+    uint32_t sub;
+    if (waitResult == WAIT_OBJECT_0)
+      sub = 1 | WAKEUP_MODE_ONE;
+    else
+      sub = 1;
+    // Note that InterlockedExchangeAdd returns the old value, but it's
+    // easier to work with the new value.
+    wcwm = InterlockedExchangeAdd(&sleepersCountAndWakeupMode_, -sub) - sub;
+
+    uint32_t wakeupMode = wcwm & WAKEUP_MODE_MASK;
+    uint32_t sleepersCount = wcwm & SLEEPERS_COUNT_MASK;
+
+    bool releaseSleepWakeupSemaphore = false;
+
+    if (waitResult == WAIT_OBJECT_0) {
+      // The wake-one event is an auto-reset event so if we're woken by
+      // it, it should already have been reset. We also already removed
+      // the WAKEUP_MODE_ONE bit so the wakeup mode should now be 'none'
+      // again.
+      MOZ_RELEASE_ASSERT(wakeupMode == WAKEUP_MODE_NONE);
+
+      // The signaling thread has acquired the enter-wakeup semaphore and
+      // expects the woken (this) thread to release it again.
+      releaseSleepWakeupSemaphore = true;
+
+    } else if (waitResult == WAIT_TIMEOUT && wakeupMode == WAKEUP_MODE_ONE &&
+               sleepersCount == 0) {
+      // In theory a race condition is possible where the last sleeper
+      // times out right at the moment that another thread signals it.
+      // If that just happened we now have a dangling signal event and
+      // mode, but no threads to be woken up by it, and we need to clean
+      // that up.
+      BOOL success = ResetEvent(wakeOneEvent_);
+      MOZ_RELEASE_ASSERT(success);
+
+      // This is safe - we are certain there are no other sleepers that
+      // could wake up right now, and the semaphore ensures that no
+      // non-sleeping threads are messing with
+      // sleepersCountAndWakeupMode_.
+      sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
+
+      // The signaling thread has acquired the sleep-wakeup semaphore and
+      // expects the woken thread to release it. But since there are no
+      // sleeping threads left this thread will do it instead.
+      releaseSleepWakeupSemaphore = true;
+
+    } else if (wakeupMode == WAKEUP_MODE_ALL && sleepersCount == 0) {
+      // If this was the last thread waking up in response to a
+      // notify_all, clear the wakeup mode and reset the wake-all event.
+      // A race condition similar to the case described above could
+      // occur, so waitResult could be WAIT_TIMEOUT, but that doesn't
+      // matter for the actions that need to be taken.
+      MOZ_RELEASE_ASSERT(waitResult = WAIT_OBJECT_0 + 1 ||
+                         waitResult == WAIT_TIMEOUT);
+
+      BOOL success = ResetEvent(wakeAllEvent_);
+      MOZ_RELEASE_ASSERT(success);
+
+      sleepersCountAndWakeupMode_ = 0 | WAKEUP_MODE_NONE;
+
+      // The broadcasting thread has acquired the enter-wakeup semaphore
+      // and expects the last thread that wakes up to release it.
+      releaseSleepWakeupSemaphore = true;
+
+    } else if ((waitResult == WAIT_TIMEOUT && msec != INFINITE) ||
+               (waitResult == WAIT_OBJECT_0 + 1 &&
+                wakeupMode == WAKEUP_MODE_ALL)) {
+      // Either:
+      //   * The wait timed out but found no active notify_one or notify_all
+      //     the moment it decreased the wait count.
+      //   * A notify_all woke up this thread but there are more threads
+      //     that need to be woken up by the wake-all event.
+      // These are ordinary conditions in which we don't have to do
+      // anything.
+
+    } else {
+      MOZ_CRASH("invalid wakeup condition");
+    }
+
+    // Release the enter-wakeup semaphore if the wakeup condition requires
+    // us to do it.
+    if (releaseSleepWakeupSemaphore) {
+      BOOL success = ReleaseSemaphore(sleepWakeupSemaphore_, 1, NULL);
+      MOZ_RELEASE_ASSERT(success);
+    }
+
+    // Reacquire the user mutex.
+    EnterCriticalSection(userLock);
+
+    // Return true if woken up, false when timed out.
+    if (waitResult == WAIT_TIMEOUT) {
+      SetLastError(ERROR_TIMEOUT);
+      return false;
+    }
+    return true;
+  }
+
+private:
+  uint32_t sleepersCountAndWakeupMode_;
+  HANDLE sleepWakeupSemaphore_;
+  HANDLE wakeOneEvent_;
+  HANDLE wakeAllEvent_;
+};
+
+struct js::ConditionVariable::PlatformData
+{
+  union
+  {
+    ConditionVariableNative native;
+    ConditionVariableFallback fallback;
+  };
+};
+
 js::ConditionVariable::ConditionVariable()
 {
-  InitializeConditionVariable(&platformData()->cv_);
+  if (sNativeImports.supported())
+    platformData()->native.initialize();
+  else
+    platformData()->fallback.initialize();
 }
 
 void
 js::ConditionVariable::notify_one()
 {
-  WakeConditionVariable(&platformData()->cv_);
+  if (sNativeImports.supported())
+    platformData()->native.notify_one();
+  else
+    platformData()->fallback.notify_one();
 }
 
 void
 js::ConditionVariable::notify_all()
 {
-  WakeAllConditionVariable(&platformData()->cv_);
+  if (sNativeImports.supported())
+    platformData()->native.notify_all();
+  else
+    platformData()->fallback.notify_all();
 }
 
 void
 js::ConditionVariable::wait(UniqueLock<Mutex>& lock)
 {
   CRITICAL_SECTION* cs = &lock.lock.platformData()->criticalSection;
-  bool r = SleepConditionVariableCS(&platformData()->cv_, cs, INFINITE);
+  bool r;
+  if (sNativeImports.supported())
+    r = platformData()->native.wait(cs, INFINITE);
+  else
+    r = platformData()->fallback.wait(cs, INFINITE);
   MOZ_RELEASE_ASSERT(r);
 }
 
@@ -82,7 +390,11 @@ js::ConditionVariable::wait_for(UniqueLock<Mutex>& lock,
                  ? INFINITE
                  : static_cast<DWORD>(msecd);
 
-  BOOL r = SleepConditionVariableCS(&platformData()->cv_, cs, msec);
+  BOOL r;
+  if (sNativeImports.supported())
+    r = platformData()->native.wait(cs, msec);
+  else
+    r = platformData()->fallback.wait(cs, msec);
   if (r)
     return CVStatus::NoTimeout;
   MOZ_RELEASE_ASSERT(GetLastError() == ERROR_TIMEOUT);
@@ -91,7 +403,10 @@ js::ConditionVariable::wait_for(UniqueLock<Mutex>& lock,
 
 js::ConditionVariable::~ConditionVariable()
 {
-  // Native condition variables don't require cleanup.
+  if (sNativeImports.supported())
+    platformData()->native.destroy();
+  else
+    platformData()->fallback.destroy();
 }
 
 inline js::ConditionVariable::PlatformData*
diff --git a/js/src/vm/Stopwatch.h b/js/src/vm/Stopwatch.h
index 38a3eb801..a1b8bbbcb 100644
--- a/js/src/vm/Stopwatch.h
+++ b/js/src/vm/Stopwatch.h
@@ -301,9 +301,9 @@ struct PerformanceMonitoring {
 
 #if WINVER >= 0x0600
 struct cpuid_t {
-    uint16_t group_;
-    uint8_t number_;
-    cpuid_t(uint16_t group, uint8_t number)
+    WORD group_;
+    BYTE number_;
+    cpuid_t(WORD group, BYTE number)
         : group_(group),
           number_(number)
     { }
diff --git a/js/xpconnect/shell/xpcshell.exe.manifest b/js/xpconnect/shell/xpcshell.exe.manifest
index c35b77af4..db2aa0861 100644
--- a/js/xpconnect/shell/xpcshell.exe.manifest
+++ b/js/xpconnect/shell/xpcshell.exe.manifest
@@ -25,6 +25,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
index 5a54d5455..052ce58e8 100644
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -70,6 +70,8 @@ struct OperatingSystemVersionInfo {
 
 // Os version identities used in the -moz-os-version media query.
 const OperatingSystemVersionInfo osVersionStrings[] = {
+  { LookAndFeel::eOperatingSystemVersion_WindowsXP,     L"windows-xp" },
+  { LookAndFeel::eOperatingSystemVersion_WindowsVista,  L"windows-vista" },
   { LookAndFeel::eOperatingSystemVersion_Windows7,      L"windows-win7" },
   { LookAndFeel::eOperatingSystemVersion_Windows8,      L"windows-win8" },
   { LookAndFeel::eOperatingSystemVersion_Windows10,     L"windows-win10" }
diff --git a/layout/style/test/chrome/bug418986-2.js b/layout/style/test/chrome/bug418986-2.js
index b083f48ee..4336f4abd 100644
--- a/layout/style/test/chrome/bug418986-2.js
+++ b/layout/style/test/chrome/bug418986-2.js
@@ -53,6 +53,8 @@ var suppressed_toggles = [
 
 // Possible values for '-moz-os-version'
 var windows_versions = [
+  "windows-xp",
+  "windows-vista",
   "windows-win7",
   "windows-win8",
   "windows-win10",
diff --git a/layout/style/test/test_media_queries.html b/layout/style/test/test_media_queries.html
index d503fad0b..479306a55 100644
--- a/layout/style/test/test_media_queries.html
+++ b/layout/style/test/test_media_queries.html
@@ -713,6 +713,8 @@ function run() {
   expression_should_not_be_parseable("-moz-windows-theme: ");
 
   // os version media queries (currently windows only)
+  expression_should_be_parseable("-moz-os-version: windows-xp");
+  expression_should_be_parseable("-moz-os-version: windows-vista");
   expression_should_be_parseable("-moz-os-version: windows-win7");
   expression_should_be_parseable("-moz-os-version: windows-win8");
   expression_should_be_parseable("-moz-os-version: windows-win10");
diff --git a/mfbt/ThreadLocal.h b/mfbt/ThreadLocal.h
index 391e748ad..880e67735 100644
--- a/mfbt/ThreadLocal.h
+++ b/mfbt/ThreadLocal.h
@@ -9,7 +9,20 @@
 #ifndef mozilla_ThreadLocal_h
 #define mozilla_ThreadLocal_h
 
-#if !defined(XP_WIN)
+#if defined(XP_WIN)
+// This file will get included in any file that wants to add a profiler mark.
+// In order to not bring <windows.h> together we could include windef.h and
+// winbase.h which are sufficient to get the prototypes for the Tls* functions.
+// # include <windef.h>
+// # include <winbase.h>
+// Unfortunately, even including these headers causes us to add a bunch of ugly
+// stuff to our namespace e.g #define CreateEvent CreateEventW
+extern "C" {
+__declspec(dllimport) void* __stdcall TlsGetValue(unsigned long);
+__declspec(dllimport) int __stdcall TlsSetValue(unsigned long, void*);
+__declspec(dllimport) unsigned long __stdcall TlsAlloc();
+}
+#else
 #  include <pthread.h>
 #  include <signal.h>
 #endif
@@ -31,7 +44,7 @@ typedef sig_atomic_t sig_safe_t;
 
 namespace detail {
 
-#if defined(HAVE_THREAD_TLS_KEYWORD) || defined(XP_WIN) || defined(XP_MACOSX)
+#if defined(HAVE_THREAD_TLS_KEYWORD)
 #define MOZ_HAS_THREAD_LOCAL
 #endif
 
@@ -78,7 +91,11 @@ template<typename T>
 class ThreadLocal
 {
 #ifndef MOZ_HAS_THREAD_LOCAL
+#if defined(XP_WIN)
+  typedef unsigned long key_t;
+#else
   typedef pthread_key_t key_t;
+#endif
 
   // Integral types narrower than void* must be extended to avoid
   // warnings from valgrind on some platforms.  This helper type
@@ -144,7 +161,12 @@ ThreadLocal<T>::init()
   return true;
 #else
   if (!initialized()) {
+#ifdef XP_WIN
+    mKey = TlsAlloc();
+    mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
+#else
     mInited = !pthread_key_create(&mKey, nullptr);
+#endif
   }
   return mInited;
 #endif
@@ -159,7 +181,11 @@ ThreadLocal<T>::get() const
 #else
   MOZ_ASSERT(initialized());
   void* h;
+#ifdef XP_WIN
+  h = TlsGetValue(mKey);
+#else
   h = pthread_getspecific(mKey);
+#endif
   return static_cast<T>(reinterpret_cast<typename Helper<T>::Type>(h));
 #endif
 }
@@ -173,7 +199,11 @@ ThreadLocal<T>::set(const T aValue)
 #else
   MOZ_ASSERT(initialized());
   void* h = reinterpret_cast<void*>(static_cast<typename Helper<T>::Type>(aValue));
+#ifdef XP_WIN
+  bool succeeded = TlsSetValue(mKey, h);
+#else
   bool succeeded = !pthread_setspecific(mKey, h);
+#endif
   if (!succeeded) {
     MOZ_CRASH();
   }
@@ -181,11 +211,7 @@ ThreadLocal<T>::set(const T aValue)
 }
 
 #ifdef MOZ_HAS_THREAD_LOCAL
-#if defined(XP_WIN) || defined(XP_MACOSX)
-#define MOZ_THREAD_LOCAL(TYPE) thread_local mozilla::detail::ThreadLocal<TYPE>
-#else
 #define MOZ_THREAD_LOCAL(TYPE) __thread mozilla::detail::ThreadLocal<TYPE>
-#endif
 #else
 #define MOZ_THREAD_LOCAL(TYPE) mozilla::detail::ThreadLocal<TYPE>
 #endif
diff --git a/mfbt/WindowsVersion.h b/mfbt/WindowsVersion.h
index 4d0cb374b..f8b071861 100644
--- a/mfbt/WindowsVersion.h
+++ b/mfbt/WindowsVersion.h
@@ -84,11 +84,44 @@ IsWindowsBuildOrLater(uint32_t aBuild)
   return false;
 }
 
-// Although many of the older versions are not supported, we should keep
-// these entries for completeness (since they don't take any resources of
-// note), and to cater to corner cases for applications running e.g. in
-// Windows' compatibility mode.
+#if defined(_M_X64) || defined(_M_AMD64)
+// We support only Win7 or later on Win64.
+MOZ_ALWAYS_INLINE bool
+IsXPSP3OrLater()
+{
+  return true;
+}
+
+MOZ_ALWAYS_INLINE bool
+IsWin2003OrLater()
+{
+  return true;
+}
+
+MOZ_ALWAYS_INLINE bool
+IsWin2003SP2OrLater()
+{
+  return true;
+}
+
+MOZ_ALWAYS_INLINE bool
+IsVistaOrLater()
+{
+  return true;
+}
+
+MOZ_ALWAYS_INLINE bool
+IsVistaSP1OrLater()
+{
+  return true;
+}
 
+MOZ_ALWAYS_INLINE bool
+IsWin7OrLater()
+{
+  return true;
+}
+#else
 MOZ_ALWAYS_INLINE bool
 IsXPSP3OrLater()
 {
@@ -124,6 +157,7 @@ IsWin7OrLater()
 {
   return IsWindowsVersionOrLater(0x06010000ul);
 }
+#endif
 
 MOZ_ALWAYS_INLINE bool
 IsWin7SP1OrLater()
@@ -156,6 +190,41 @@ IsNotWin7PreRTM()
          IsWindowsBuildOrLater(7600);
 }
 
+MOZ_ALWAYS_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 */
diff --git a/mozglue/build/WindowsDllBlocklist.cpp b/mozglue/build/WindowsDllBlocklist.cpp
index 9b63d6673..a3c662723 100644
--- a/mozglue/build/WindowsDllBlocklist.cpp
+++ b/mozglue/build/WindowsDllBlocklist.cpp
@@ -67,6 +67,7 @@ struct DllBlockInfo {
   enum {
     FLAGS_DEFAULT = 0,
     BLOCK_WIN8PLUS_ONLY = 1,
+    BLOCK_XP_ONLY = 2,
     USE_TIMESTAMP = 4,
   } flags;
 };
@@ -155,6 +156,9 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
   // Topcrash with Conduit SearchProtect, bug 944542
   { "spvc32.dll", ALL_VERSIONS },
 
+  // XP topcrash with F-Secure, bug 970362
+  { "fs_ccf_ni_umh32.dll", MAKE_VERSION(1, 42, 101, 0), DllBlockInfo::BLOCK_XP_ONLY },
+
   // Topcrash with V-bates, bug 1002748 and bug 1023239
   { "libinject.dll", UNVERSIONED },
   { "libinject2.dll", 0x537DDC93, DllBlockInfo::USE_TIMESTAMP },
@@ -672,6 +676,11 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
       goto continue_loading;
     }
 
+    if ((info->flags == DllBlockInfo::BLOCK_XP_ONLY) &&
+        IsWin2003OrLater()) {
+      goto continue_loading;
+    }
+
     unsigned long long fVersion = ALL_VERSIONS;
 
     if (info->maxVersion != ALL_VERSIONS) {
@@ -740,7 +749,7 @@ continue_loading:
       return STATUS_DLL_NOT_FOUND;
     }
 
-    if (!CheckASLR(full_fname.get())) {
+    if (IsVistaOrLater() && !CheckASLR(full_fname.get())) {
       printf_stderr("LdrLoadDll: Blocking load of '%s'.  XPCOM components must support ASLR.\n", dllName);
       return STATUS_DLL_NOT_FOUND;
     }
diff --git a/mozglue/misc/TimeStamp_windows.cpp b/mozglue/misc/TimeStamp_windows.cpp
index 683c2209a..cd519affd 100644
--- a/mozglue/misc/TimeStamp_windows.cpp
+++ b/mozglue/misc/TimeStamp_windows.cpp
@@ -5,7 +5,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Implement TimeStamp::Now() with QueryPerformanceCounter() controlled with
-// values of GetTickCount64().
+// values of GetTickCount().
 
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/TimeStamp.h"
@@ -69,7 +69,7 @@ static const DWORD kDefaultTimeIncrement = 156001;
  * further just referred as [mt], meaning milli-ticks.
  *
  * This is needed to preserve maximum precision of the performance frequency
- * representation.  GetTickCount64 values in milliseconds are multiplied with
+ * representation.  GetTickCount values in milliseconds are multiplied with
  * frequency per second.  Therefor we need to multiply QPC value by 1000 to
  * have the same units to allow simple arithmentic with both QPC and GTC.
  */
@@ -156,8 +156,41 @@ static CRITICAL_SECTION sTimeStampLock;
 // Kept in [mt]
 static ULONGLONG sFaultIntoleranceCheckpoint = 0;
 
+// Used only when GetTickCount64 is not available on the platform.
+// Last result of GetTickCount call.
+//
+// Kept in [ms]
+static DWORD sLastGTCResult = 0;
+
+// Higher part of the 64-bit value of MozGetTickCount64,
+// incremented atomically.
+static DWORD sLastGTCRollover = 0;
+
 namespace mozilla {
 
+typedef ULONGLONG (WINAPI* GetTickCount64_t)();
+static GetTickCount64_t sGetTickCount64 = nullptr;
+
+// Function protecting GetTickCount result from rolling over,
+// result is in [ms]
+static ULONGLONG WINAPI
+MozGetTickCount64()
+{
+  DWORD GTC = ::GetTickCount();
+
+  // Cheaper then CMPXCHG8B
+  AutoCriticalSection lock(&sTimeStampLock);
+
+  // Pull the rollover counter forward only if new value of GTC goes way
+  // down under the last saved result
+  if ((sLastGTCResult > GTC) && ((sLastGTCResult - GTC) > (1UL << 30))) {
+    ++sLastGTCRollover;
+  }
+
+  sLastGTCResult = GTC;
+  return ULONGLONG(sLastGTCRollover) << 32 | sLastGTCResult;
+}
+
 // Result is in [mt]
 static inline ULONGLONG
 PerformanceCounter()
@@ -322,7 +355,7 @@ TimeStampValue::CheckQPC(const TimeStampValue& aOther) const
   if (duration < sHardFailureLimit) {
     // Interval between the two time stamps is very short, consider
     // QPC as unstable and record a failure.
-    uint64_t now = ms2mt(GetTickCount64());
+    uint64_t now = ms2mt(sGetTickCount64());
 
     AutoCriticalSection lock(&sTimeStampLock);
 
@@ -452,6 +485,17 @@ TimeStamp::Startup()
 
   gInitialized = true;
 
+  // Decide which implementation to use for the high-performance timer.
+
+  HMODULE kernelDLL = GetModuleHandleW(L"kernel32.dll");
+  sGetTickCount64 = reinterpret_cast<GetTickCount64_t>(
+    GetProcAddress(kernelDLL, "GetTickCount64"));
+  if (!sGetTickCount64) {
+    // If the platform does not support the GetTickCount64 (Windows XP doesn't),
+    // then use our fallback implementation based on GetTickCount.
+    sGetTickCount64 = MozGetTickCount64;
+  }
+
   InitializeCriticalSectionAndSpinCount(&sTimeStampLock, kLockSpinCount);
 
   sHasStableTSC = HasStableTSC();
@@ -460,10 +504,10 @@ TimeStamp::Startup()
   LARGE_INTEGER freq;
   sUseQPC = ::QueryPerformanceFrequency(&freq);
   if (!sUseQPC) {
-    // No Performance Counter.  Fall back to use GetTickCount64.
+    // No Performance Counter.  Fall back to use GetTickCount.
     InitResolution();
 
-    LOG(("TimeStamp: using GetTickCount64"));
+    LOG(("TimeStamp: using GetTickCount"));
     return;
   }
 
@@ -490,7 +534,7 @@ TimeStamp::Now(bool aHighResolution)
 
   // Both values are in [mt] units.
   ULONGLONG QPC = useQPC ? PerformanceCounter() : uint64_t(0);
-  ULONGLONG GTC = ms2mt(GetTickCount64());
+  ULONGLONG GTC = ms2mt(sGetTickCount64());
   return TimeStamp(TimeStampValue(GTC, QPC, useQPC));
 }
 
diff --git a/netwerk/base/nsSocketTransport2.cpp b/netwerk/base/nsSocketTransport2.cpp
index 184757d33..1bfd1fc91 100644
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -40,6 +40,7 @@
 #include "xpcpublic.h"
 
 #if defined(XP_WIN)
+#include "mozilla/WindowsVersion.h"
 #include "ShutdownLayer.h"
 #endif
 
@@ -1723,6 +1724,21 @@ nsSocketTransport::OnSocketConnected()
         NS_ASSERTION(mFDref == 1, "wrong socket ref count");
         SetSocketName(mFD);
         mFDconnected = true;
+
+#ifdef XP_WIN
+        if (!IsWin2003OrLater()) { // windows xp
+            PRSocketOptionData opt;
+            opt.option = PR_SockOpt_RecvBufferSize;
+            if (PR_GetSocketOption(mFD, &opt) == PR_SUCCESS) {
+                SOCKET_LOG(("%p checking rwin on xp originally=%u\n",
+                            this, opt.value.recv_buffer_size));
+                if (opt.value.recv_buffer_size < 65535) {
+                    opt.value.recv_buffer_size = 65535;
+                    PR_SetSocketOption(mFD, &opt);
+                }
+            }
+        }
+#endif
     }
 
     // Ensure keepalive is configured correctly if previously enabled.
diff --git a/netwerk/base/nsSocketTransportService2.cpp b/netwerk/base/nsSocketTransportService2.cpp
index 068bf0eca..d2f20651e 100644
--- a/netwerk/base/nsSocketTransportService2.cpp
+++ b/netwerk/base/nsSocketTransportService2.cpp
@@ -28,6 +28,10 @@
 #include "nsIWidget.h"
 #include "mozilla/dom/FlyWebService.h"
 
+#if defined(XP_WIN)
+#include "mozilla/WindowsVersion.h"
+#endif
+
 namespace mozilla {
 namespace net {
 
@@ -1200,7 +1204,12 @@ nsSocketTransportService::UpdateSendBufferPref(nsIPrefBranch *pref)
     }
 
 #if defined(XP_WIN)
-    mSendBufferSize = 131072 * 4;
+    // If the pref is not set but this is windows set it depending on windows version
+    if (!IsWin2003OrLater()) { // windows xp
+        mSendBufferSize = 131072;
+    } else { // vista or later
+        mSendBufferSize = 131072 * 4;
+    }
 #endif
 }
 
diff --git a/netwerk/test/TestUDPSocket.cpp b/netwerk/test/TestUDPSocket.cpp
index 0ec43a650..9236d2ea3 100644
--- a/netwerk/test/TestUDPSocket.cpp
+++ b/netwerk/test/TestUDPSocket.cpp
@@ -13,6 +13,9 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsITimer.h"
 #include "mozilla/net/DNS.h"
+#ifdef XP_WIN
+#include "mozilla/WindowsVersion.h"
+#endif
 #include "prerror.h"
 
 #define REQUEST  0x68656c6f
@@ -331,6 +334,16 @@ main(int32_t argc, char *argv[])
   }
   RefPtr<MulticastTimerCallback> timerCb = new MulticastTimerCallback();
 
+  // The following multicast tests using multiple sockets require a firewall
+  // exception on Windows XP (the earliest version of Windows we now support)
+  // before they pass. For now, we'll skip them here. Later versions of Windows
+  // (Win2003 and onward) don't seem to have this issue.
+#ifdef XP_WIN
+  if (!mozilla::IsWin2003OrLater()) {   // i.e. if it is WinXP
+    goto close;
+  }
+#endif
+
   // Join multicast group
   printf("Joining multicast group\n");
   phase = TEST_MULTICAST;
diff --git a/netwerk/wifi/moz.build b/netwerk/wifi/moz.build
index e3edb0842..b6ddd2139 100644
--- a/netwerk/wifi/moz.build
+++ b/netwerk/wifi/moz.build
@@ -45,6 +45,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT':
         'nsWifiScannerWin.cpp',
         'win_wifiScanner.cpp',
         'win_wlanLibrary.cpp',
+        'win_xp_wifiScanner.cpp'
     ]
 elif CONFIG['OS_ARCH'] == 'SunOS':
     CXXFLAGS += CONFIG['GLIB_CFLAGS']
diff --git a/netwerk/wifi/nsWifiMonitor.h b/netwerk/wifi/nsWifiMonitor.h
index 665798efc..3783d38bd 100644
--- a/netwerk/wifi/nsWifiMonitor.h
+++ b/netwerk/wifi/nsWifiMonitor.h
@@ -76,7 +76,7 @@ class nsWifiMonitor final : nsIRunnable, nsIWifiMonitor, nsIObserver
   mozilla::ReentrantMonitor mReentrantMonitor;
 
 #ifdef XP_WIN
-  nsAutoPtr<WinWifiScanner> mWinWifiScanner;
+  nsAutoPtr<WindowsWifiScannerInterface> mWinWifiScanner;
 #endif
 };
 #else
diff --git a/netwerk/wifi/nsWifiScannerWin.cpp b/netwerk/wifi/nsWifiScannerWin.cpp
index 6089c45c6..ef18706e4 100644
--- a/netwerk/wifi/nsWifiScannerWin.cpp
+++ b/netwerk/wifi/nsWifiScannerWin.cpp
@@ -12,6 +12,8 @@
 #include "nsServiceManagerUtils.h"
 #include "nsWifiAccessPoint.h"
 #include "win_wifiScanner.h"
+#include "win_xp_wifiScanner.h"
+#include "mozilla/WindowsVersion.h"
 
 using namespace mozilla;
 
@@ -29,7 +31,14 @@ nsresult
 nsWifiMonitor::DoScan()
 {
     if (!mWinWifiScanner) {
-      mWinWifiScanner = new WinWifiScanner();
+      if (IsWin2003OrLater()) {
+        mWinWifiScanner = new WinWifiScanner();
+        LOG(("Using Windows 2003+ wifi scanner."));
+      } else {
+        mWinWifiScanner = new WinXPWifiScanner();
+        LOG(("Using Windows XP wifi scanner."));
+      }
+
       if (!mWinWifiScanner) {
         // TODO: Probably return OOM error
         return NS_ERROR_FAILURE;
diff --git a/netwerk/wifi/win_wifiScanner.h b/netwerk/wifi/win_wifiScanner.h
index 79b1bf132..b43c23899 100644
--- a/netwerk/wifi/win_wifiScanner.h
+++ b/netwerk/wifi/win_wifiScanner.h
@@ -11,10 +11,19 @@
 
 class nsWifiAccessPoint;
 
-class WinWifiScanner final {
+// This class allows the wifi monitor to use WinWifiScanner and WinXPWifiScanner interchangeably.
+class WindowsWifiScannerInterface {
+public:
+  virtual ~WindowsWifiScannerInterface() {}
+
+  virtual nsresult GetAccessPointsFromWLAN(nsCOMArray<nsWifiAccessPoint> &accessPoints) = 0;
+};
+
+
+class WinWifiScanner : public WindowsWifiScannerInterface {
  public:
   WinWifiScanner();
-  ~WinWifiScanner();
+  virtual ~WinWifiScanner();
 
   /**
    * GetAccessPointsFromWLAN
diff --git a/old-configure.in b/old-configure.in
index 92a5f729e..3024c2d01 100644
--- a/old-configure.in
+++ b/old-configure.in
@@ -212,7 +212,7 @@ dnl ========================================================
 dnl Special win32 checks
 dnl ========================================================
 
-WINVER=601
+WINVER=502
 
 case "$target" in
 *-mingw*)
@@ -1013,7 +1013,12 @@ case "$target" in
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
-        WIN32_SUBSYSTEM_VERSION=6.01
+        dnl Set subsystem version 5 for Windows XP.
+        if test "$CPU_ARCH" = "x86"; then
+            WIN32_SUBSYSTEM_VERSION=5.01
+        else
+            WIN32_SUBSYSTEM_VERSION=5.02
+        fi
         WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
         WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
@@ -3312,6 +3317,9 @@ MOZ_D3D_CPU_SUFFIX=
 MOZ_HAS_WINSDK_WITH_D3D=
 MOZ_D3DCOMPILER_VISTA_DLL=
 MOZ_D3DCOMPILER_VISTA_DLL_PATH=
+MOZ_DIRECTX_SDK_PATH=
+MOZ_D3DCOMPILER_XP_DLL=
+MOZ_D3DCOMPILER_XP_CAB=
 
 if test "$COMPILE_ENVIRONMENT" ; then
 case "$target_os" in
@@ -3330,6 +3338,11 @@ x86_64)
   ;;
 esac
 
+MOZ_ARG_ENABLE_BOOL(require-all-d3dc-versions,
+[  --enable-require-all-d3dc-versions Require all versions of the D3D compiler needed for supported Windows systems.],
+    MOZ_REQUIRE_ALL_D3DCS=1,
+    MOZ_REQUIRE_ALL_D3DCS=)
+
 # This is potentially set in external mozconfig files; if it's set,
 # then the build exposes the "webgl" context name, which is reserved
 # for conformant implementations.
@@ -3387,19 +3400,89 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
     MOZ_CHECK_HEADER(d3d10.h, MOZ_HAS_WINSDK_WITH_D3D=1)
   fi
 
+  ######################################
+  # Find _43 for use by XP.
+
+  if test "$HAVE_64BIT_BUILD"; then
+    AC_MSG_RESULT([We are building a 64-bit binary, skip checking d3dcompiler_43.])
+  else
+    # Get the SDK path from the registry.
+    # First try to get the June 2010 SDK
+    MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK (June 2010)' | head -n 1`
+    if test -z "$MOZ_DIRECTX_SDK_REG_KEY" ; then
+      # Otherwise just take whatever comes first
+      MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK' | head -n 1`
+    fi
+    MOZ_DIRECTX_SDK_PATH=`reg query "$MOZ_DIRECTX_SDK_REG_KEY" //v InstallPath | grep REG_SZ | sed 's/.*\([[a-zA-Z]]\)\\:\\\\/\\1\\:\\\\/' | sed 's,\\\\,/,g'`
+
+    if test -n "$MOZ_DIRECTX_SDK_PATH" &&
+       test -f "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_D3D_CPU_SUFFIX/dxguid.lib ; then
+      AC_MSG_RESULT([Found DirectX SDK via registry, using $MOZ_DIRECTX_SDK_PATH])
+    else
+      AC_MSG_RESULT([DirectX SDK not found.])
+      MOZ_DIRECTX_SDK_PATH=
+    fi
+
+    # Check that our DirectX SDK is acceptable.
+    if test -n "$MOZ_DIRECTX_SDK_PATH"; then
+      if test -n "`echo $MOZ_DIRECTX_SDK_REG_KEY | grep 'February 2010'`" ; then
+        AC_MSG_RESULT([Found the February 2010 DirectX SDK, which is unacceptable to ANGLE.])
+        MOZ_DIRECTX_SDK_PATH=
+      fi
+    fi
+
+    if test -n "$MOZ_DIRECTX_SDK_PATH"; then
+      # Find a D3D compiler DLL in the DirectX SDK, if we didn't find one already.
+      # Get the SDK numeric version (e.g. 43) by looking at the dependencies of d3dx9.lib
+      MOZ_D3DX9_VERSION=`dumpbin //headers "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_D3D_CPU_SUFFIX/d3dx9.lib | egrep d3dx9_[[0-9]][[0-9]]\.dll | head -n1 | sed 's/.*\([[0-9]][[0-9]]\).*/\\1/g'`
+
+      if test -n "$MOZ_D3DX9_VERSION" ; then
+        MOZ_D3DCOMPILER_XP_CAB=`find "$MOZ_DIRECTX_SDK_PATH"/Redist -name *D3DCompiler_${MOZ_D3DX9_VERSION}_${MOZ_D3D_CPU_SUFFIX}.cab | head -n1`
+
+        if test -n "$MOZ_D3DCOMPILER_XP_CAB"; then
+          MOZ_D3DCOMPILER_XP_DLL=D3DCompiler_$MOZ_D3DX9_VERSION.dll
+        else
+          AC_MSG_RESULT([Couldn't find a CAB containing the D3D compiler DLL.])
+          AC_MSG_ERROR([DirectX SDK at "$MOZ_DIRECTX_SDK_PATH" appears broken.])
+          MOZ_DIRECTX_SDK_PATH=
+        fi
+      else
+        AC_MSG_RESULT([Couldn't determine the D3DX9 version for the DirectX SDK.])
+        MOZ_DIRECTX_SDK_PATH=
+      fi
+    else
+      AC_MSG_RESULT([Couldn't find an acceptable DirectX SDK for ANGLE, needed for d3dcompiler_43.])
+    fi
+  fi
+
   ######################################
   # Check that we found what we needed.
   MOZ_FOUND_A_D3D_COMPILER=
+  MOZ_FOUND_BOTH_D3D_COMPILERS=1
 
   if test -n "$MOZ_D3DCOMPILER_VISTA_DLL"; then
     MOZ_FOUND_A_D3D_COMPILER=1
     AC_MSG_RESULT([Found d3dcompiler DLL for Vista+: $MOZ_D3DCOMPILER_VISTA_DLL])
+  else
+    MOZ_FOUND_BOTH_D3D_COMPILERS=
+  fi
+
+  if test -n "$MOZ_D3DCOMPILER_XP_DLL"; then
+    MOZ_FOUND_A_D3D_COMPILER=1
+    AC_MSG_RESULT([Found d3dcompiler DLL for XP: $MOZ_D3DCOMPILER_XP_DLL])
+  else
+    MOZ_FOUND_BOTH_D3D_COMPILERS=
   fi
 
   if test -z "$CROSS_COMPILE"; then
     if test -z "MOZ_FOUND_A_D3D_COMPILER"; then
       AC_MSG_ERROR([Couldn't find an acceptable D3D compiler DLL.])
     fi
+
+    if test -n "$MOZ_REQUIRE_ALL_D3DCS" -a -z "$MOZ_FOUND_BOTH_D3D_COMPILERS"; then
+      AC_MSG_ERROR([Both D3D compilers _43 and _46+ are required by --enable-require-d3d-compilers.])
+      AC_MSG_ERROR([  Install Windows SDK 8.0+, as well as DirectX SDK (June 2010 version or newer), or reconfigure without this flag.])
+    fi
   fi
 fi # MOZ_ANGLE_RENDERER
 
@@ -5268,6 +5351,9 @@ AC_SUBST(MOZ_D3D_CPU_SUFFIX)
 AC_SUBST(MOZ_HAS_WINSDK_WITH_D3D)
 AC_SUBST(MOZ_D3DCOMPILER_VISTA_DLL)
 AC_SUBST(MOZ_D3DCOMPILER_VISTA_DLL_PATH)
+AC_SUBST(MOZ_DIRECTX_SDK_PATH)
+AC_SUBST(MOZ_D3DCOMPILER_XP_DLL)
+AC_SUBST(MOZ_D3DCOMPILER_XP_CAB)
 
 AC_SUBST(MOZ_ANDROID_APPLICATION_CLASS)
 AC_SUBST(MOZ_ANDROID_BROWSER_INTENT_CLASS)
diff --git a/toolkit/components/alerts/nsAlertsService.cpp b/toolkit/components/alerts/nsAlertsService.cpp
index dd67ad983..35418dd17 100644
--- a/toolkit/components/alerts/nsAlertsService.cpp
+++ b/toolkit/components/alerts/nsAlertsService.cpp
@@ -22,10 +22,6 @@
 #include "nsIFaviconService.h"
 #endif // MOZ_PLACES
 
-#ifdef XP_WIN
-#include <shellapi.h>
-#endif
-
 using namespace mozilla;
 
 using mozilla::dom::ContentChild;
@@ -158,12 +154,23 @@ bool nsAlertsService::ShouldShowAlert()
   bool result = true;
 
 #ifdef XP_WIN
-  QUERY_USER_NOTIFICATION_STATE qstate;
-  if (SUCCEEDED(SHQueryUserNotificationState(&qstate))) {
-    if (qstate != QUNS_ACCEPTS_NOTIFICATIONS) {
-       result = false;
+  HMODULE shellDLL = ::LoadLibraryW(L"shell32.dll");
+  if (!shellDLL)
+    return result;
+
+  SHQueryUserNotificationStatePtr pSHQueryUserNotificationState =
+    (SHQueryUserNotificationStatePtr) ::GetProcAddress(shellDLL, "SHQueryUserNotificationState");
+
+  if (pSHQueryUserNotificationState) {
+    MOZ_QUERY_USER_NOTIFICATION_STATE qstate;
+    if (SUCCEEDED(pSHQueryUserNotificationState(&qstate))) {
+      if (qstate != QUNS_ACCEPTS_NOTIFICATIONS) {
+         result = false;
+      }
     }
   }
+
+  ::FreeLibrary(shellDLL);
 #endif
 
   return result;
diff --git a/toolkit/components/alerts/nsAlertsService.h b/toolkit/components/alerts/nsAlertsService.h
index d2b2e1e6c..3f23eaabf 100644
--- a/toolkit/components/alerts/nsAlertsService.h
+++ b/toolkit/components/alerts/nsAlertsService.h
@@ -10,6 +10,23 @@
 #include "nsCOMPtr.h"
 #include "nsXULAlerts.h"
 
+#ifdef XP_WIN
+typedef enum tagMOZ_QUERY_USER_NOTIFICATION_STATE {
+    QUNS_NOT_PRESENT = 1,
+    QUNS_BUSY = 2,
+    QUNS_RUNNING_D3D_FULL_SCREEN = 3,
+    QUNS_PRESENTATION_MODE = 4,
+    QUNS_ACCEPTS_NOTIFICATIONS = 5,
+    QUNS_QUIET_TIME = 6,
+    QUNS_IMMERSIVE = 7
+} MOZ_QUERY_USER_NOTIFICATION_STATE;
+
+extern "C" {
+// This function is Windows Vista or later
+typedef HRESULT (__stdcall *SHQueryUserNotificationStatePtr)(MOZ_QUERY_USER_NOTIFICATION_STATE *pquns);
+}
+#endif // defined(XP_WIN)
+
 class nsAlertsService : public nsIAlertsService,
                         public nsIAlertsDoNotDisturb
 {
diff --git a/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest b/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest
index e6bfba8ca..cb317c47d 100644
--- a/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest
+++ b/toolkit/components/maintenanceservice/maintenanceservice.exe.manifest
@@ -20,6 +20,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/toolkit/crashreporter/client/crashreporter.exe.manifest b/toolkit/crashreporter/client/crashreporter.exe.manifest
index e6b2ceefb..f8587bfad 100644
--- a/toolkit/crashreporter/client/crashreporter.exe.manifest
+++ b/toolkit/crashreporter/client/crashreporter.exe.manifest
@@ -32,6 +32,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/toolkit/library/libxul.mk b/toolkit/library/libxul.mk
index 9e7e8beee..d918d9c84 100644
--- a/toolkit/library/libxul.mk
+++ b/toolkit/library/libxul.mk
@@ -16,6 +16,16 @@ EXTRA_DEPS += symverscript
 endif
 endif
 
+ifdef MOZ_WEBRTC
+ifeq (WINNT,$(OS_TARGET))
+ifndef MOZ_HAS_WINSDK_WITH_D3D
+OS_LDFLAGS += \
+  -LIBPATH:'$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_D3D_CPU_SUFFIX)' \
+  $(NULL)
+endif
+endif
+endif
+
 # Generate GDB pretty printer-autoload files only on Linux. OSX's GDB is
 # too old to support Python pretty-printers; if this changes, we could make
 # this 'ifdef GNU_CC'.
diff --git a/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest b/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest
index 6bb850199..9a6cdb565 100644
--- a/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest
+++ b/toolkit/mozapps/update/updater/updater.exe.comctl32.manifest
@@ -32,6 +32,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/toolkit/mozapps/update/updater/updater.exe.manifest b/toolkit/mozapps/update/updater/updater.exe.manifest
index 619b4abfe..cd229c954 100644
--- a/toolkit/mozapps/update/updater/updater.exe.manifest
+++ b/toolkit/mozapps/update/updater/updater.exe.manifest
@@ -20,6 +20,7 @@
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
     </application>
   </compatibility>
 </assembly>
diff --git a/toolkit/themes/windows/global/global.css b/toolkit/themes/windows/global/global.css
index aaddef882..20a190684 100644
--- a/toolkit/themes/windows/global/global.css
+++ b/toolkit/themes/windows/global/global.css
@@ -350,7 +350,9 @@ popupnotificationcontent {
   width: 20px;
 }
 
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   .close-icon {
     -moz-image-region: rect(0, 16px, 16px, 0);
   }
@@ -384,7 +386,9 @@ popupnotificationcontent {
     -moz-image-region: rect(0, 120px, 40px, 80px);
   }
 
-  @media (-moz-os-version: windows-win7) {
+  @media (-moz-os-version: windows-xp),
+         (-moz-os-version: windows-vista),
+         (-moz-os-version: windows-win7) {
     .close-icon {
       -moz-image-region: rect(0, 32px, 32px, 0);
     }
diff --git a/toolkit/themes/windows/global/jar.mn b/toolkit/themes/windows/global/jar.mn
index 7f2f29942..7f0771020 100644
--- a/toolkit/themes/windows/global/jar.mn
+++ b/toolkit/themes/windows/global/jar.mn
@@ -44,36 +44,102 @@ toolkit.jar:
   skin/classic/global/icons/autocomplete-search.svg        (icons/autocomplete-search.svg)
   skin/classic/global/icons/blacklist_favicon.png          (icons/blacklist_favicon.png)
   skin/classic/global/icons/blacklist_large.png            (icons/blacklist_large.png)
-  skin/classic/global/icons/close-win7.png                 (icons/close-win7.png)
-  skin/classic/global/icons/close-win7@2x.png              (icons/close-win7@2x.png)
-  skin/classic/global/icons/close-inverted-win7.png        (icons/close-inverted-win7.png)
-  skin/classic/global/icons/close-inverted-win7@2x.png     (icons/close-inverted-win7@2x.png)
+  skin/classic/global/icons/close-XPVista7.png             (icons/close-XPVista7.png)
+  skin/classic/global/icons/close-XPVista7@2x.png          (icons/close-XPVista7@2x.png)
+  skin/classic/global/icons/close-inverted-XPVista7.png    (icons/close-inverted-XPVista7.png)
+  skin/classic/global/icons/close-inverted-XPVista7@2x.png (icons/close-inverted-XPVista7@2x.png)
   skin/classic/global/icons/resizer.png                    (icons/resizer.png)
   skin/classic/global/icons/sslWarning.png                 (icons/sslWarning.png)
 * skin/classic/global/in-content/common.css                (in-content/common.css)
 * skin/classic/global/in-content/info-pages.css            (in-content/info-pages.css)
   skin/classic/global/toolbar/spring.png                   (toolbar/spring.png)
 
-  skin/classic/global/icons/autoscroll.png                 (icons/autoscroll.png)
-  skin/classic/global/tree/twisty.svg                      (tree/twisty.svg)
-  skin/classic/global/tree/twisty-preWin10.svg             (tree/twisty-preWin10.svg)
+  skin/classic/global/dirListing/folder-XP.png                   (dirListing/folder-XP.png)
+  skin/classic/global/dirListing/local-XP.png                    (dirListing/local-XP.png)
+  skin/classic/global/dirListing/remote-XP.png                   (dirListing/remote-XP.png)
+  skin/classic/global/dirListing/up-XP.png                       (dirListing/up-XP.png)
+  skin/classic/global/icons/autoscroll.png                       (icons/autoscroll.png)
+  skin/classic/global/icons/autoscroll-XP.png                    (icons/autoscroll-XP.png)
+  skin/classic/global/icons/blacklist_favicon-XP.png             (icons/blacklist_favicon-XP.png)
+  skin/classic/global/icons/blacklist_large-XP.png               (icons/blacklist_large-XP.png)
+  skin/classic/global/icons/Error-XP.png                         (icons/Error-XP.png)
+  skin/classic/global/icons/error-16-XP.png                      (icons/error-16-XP.png)
+  skin/classic/global/icons/error-64-XP.png                      (icons/error-64-XP.png)
+  skin/classic/global/icons/folder-item-XP.png                   (icons/folder-item-XP.png)
+  skin/classic/global/icons/information-16-XP.png                (icons/information-16-XP.png)
+  skin/classic/global/icons/information-24-XP.png                (icons/information-24-XP.png)
+  skin/classic/global/icons/information-32-XP.png                (icons/information-32-XP.png)
+  skin/classic/global/icons/Print-preview-XP.png                 (icons/Print-preview-XP.png)
+  skin/classic/global/icons/Portrait-XP.png                      (icons/Portrait-XP.png)
+  skin/classic/global/icons/Landscape-XP.png                     (icons/Landscape-XP.png)
+  skin/classic/global/icons/Question-XP.png                      (icons/Question-XP.png)
+  skin/classic/global/icons/question-16-XP.png                   (icons/question-16-XP.png)
+  skin/classic/global/icons/question-64-XP.png                   (icons/question-64-XP.png)
+  skin/classic/global/icons/Search-close-XP.png                  (icons/Search-close-XP.png)
+  skin/classic/global/icons/Search-glass-XP.png                  (icons/Search-glass-XP.png)
+  skin/classic/global/icons/sslWarning-XP.png                    (icons/sslWarning-XP.png)
+  skin/classic/global/icons/Warning-XP.png                       (icons/Warning-XP.png)
+  skin/classic/global/icons/warning-large-XP.png                 (icons/warning-large-XP.png)
+  skin/classic/global/icons/warning-16-XP.png                    (icons/warning-16-XP.png)
+  skin/classic/global/icons/warning-64-XP.png                    (icons/warning-64-XP.png)
+  skin/classic/global/icons/windowControls-XP.png                (icons/windowControls-XP.png)
+  skin/classic/global/toolbar/spring-XP.png                      (toolbar/spring-XP.png)
+  skin/classic/global/tree/sort-asc-XP.png                       (tree/sort-asc-XP.png)
+  skin/classic/global/tree/sort-dsc-XP.png                       (tree/sort-dsc-XP.png)
+  skin/classic/global/tree/twisty.svg                            (tree/twisty.svg)
+  skin/classic/global/tree/twisty-XP.svg                         (tree/twisty-XP.svg)
+  skin/classic/global/tree/twisty-Vista78.svg                    (tree/twisty-Vista78.svg)
 
 #ifdef MOZ_PHOENIX
 [browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 #elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
 [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 #endif
+% override chrome://global/skin/dirListing/folder.png             chrome://global/skin/dirListing/folder-XP.png            osversion<6
+% override chrome://global/skin/dirListing/local.png              chrome://global/skin/dirListing/local-XP.png             osversion<6
+% override chrome://global/skin/dirListing/remote.png             chrome://global/skin/dirListing/remote-XP.png            osversion<6
+% override chrome://global/skin/dirListing/up.png                 chrome://global/skin/dirListing/up-XP.png                osversion<6
+% override chrome://global/skin/icons/autoscroll.png              chrome://global/skin/icons/autoscroll-XP.png             osversion<6
+% override chrome://global/skin/icons/blacklist_favicon.png       chrome://global/skin/icons/blacklist_favicon-XP.png      osversion<6
+% override chrome://global/skin/icons/blacklist_large.png         chrome://global/skin/icons/blacklist_large-XP.png        osversion<6
+% override chrome://global/skin/icons/Error.png                   chrome://global/skin/icons/Error-XP.png                  osversion<6
+% override chrome://global/skin/icons/error-16.png                chrome://global/skin/icons/error-16-XP.png               osversion<6
+% override chrome://global/skin/icons/error-64.png                chrome://global/skin/icons/error-64-XP.png               osversion<6
+% override chrome://global/skin/icons/folder-item.png             chrome://global/skin/icons/folder-item-XP.png            osversion<6
+% override chrome://global/skin/icons/information-16.png          chrome://global/skin/icons/information-16-XP.png         osversion<6
+% override chrome://global/skin/icons/information-24.png          chrome://global/skin/icons/information-24-XP.png         osversion<6
+% override chrome://global/skin/icons/information-32.png          chrome://global/skin/icons/information-32-XP.png         osversion<6
+% override chrome://global/skin/icons/Print-preview.png           chrome://global/skin/icons/Print-preview-XP.png          osversion<6
+% override chrome://global/skin/icons/Portrait.png                chrome://global/skin/icons/Portrait-XP.png               osversion<6
+% override chrome://global/skin/icons/Landscape.png               chrome://global/skin/icons/Landscape-XP.png              osversion<6
+% override chrome://global/skin/icons/Question.png                chrome://global/skin/icons/Question-XP.png               osversion<6
+% override chrome://global/skin/icons/question-16.png             chrome://global/skin/icons/question-16-XP.png            osversion<6
+% override chrome://global/skin/icons/question-64.png             chrome://global/skin/icons/question-64-XP.png            osversion<6
+% override chrome://global/skin/icons/Search-close.png            chrome://global/skin/icons/Search-close-XP.png           osversion<6
+% override chrome://global/skin/icons/Search-glass.png            chrome://global/skin/icons/Search-glass-XP.png           osversion<6
+% override chrome://global/skin/icons/sslWarning.png              chrome://global/skin/icons/sslWarning-XP.png             osversion<6
+% override chrome://global/skin/icons/Warning.png                 chrome://global/skin/icons/Warning-XP.png                osversion<6
+% override chrome://global/skin/icons/warning-large.png           chrome://global/skin/icons/warning-large-XP.png          osversion<6
+% override chrome://global/skin/icons/warning-16.png              chrome://global/skin/icons/warning-16-XP.png             osversion<6
+% override chrome://global/skin/icons/warning-64.png              chrome://global/skin/icons/warning-64-XP.png             osversion<6
+% override chrome://global/skin/icons/windowControls.png          chrome://global/skin/icons/windowControls-XP.png         osversion<6
+% override chrome://global/skin/toolbar/spring.png                chrome://global/skin/toolbar/spring-XP.png               osversion<6
+% override chrome://global/skin/tree/sort-asc.png                 chrome://global/skin/tree/sort-asc-XP.png                osversion<6
+% override chrome://global/skin/tree/sort-dsc.png                 chrome://global/skin/tree/sort-dsc-XP.png                osversion<6
 
-% override chrome://global/skin/icons/close.png                   chrome://global/skin/icons/close-win7.png            osversion<=6.1
-% override chrome://global/skin/icons/close@2x.png                chrome://global/skin/icons/close-win7@2x.png         osversion<=6.1
-% override chrome://global/skin/icons/close-inverted.png          chrome://global/skin/icons/close-inverted-win7.png   osversion<=6.1
-% override chrome://global/skin/icons/close-inverted@2x.png       chrome://global/skin/icons/close-inverted-win7@2x.png osversion<=6.1
+% override chrome://global/skin/icons/close.png                   chrome://global/skin/icons/close-XPVista7.png            osversion<=6.1
+% override chrome://global/skin/icons/close@2x.png                chrome://global/skin/icons/close-XPVista7@2x.png         osversion<=6.1
+% override chrome://global/skin/icons/close-inverted.png          chrome://global/skin/icons/close-inverted-XPVista7.png   osversion<=6.1
+% override chrome://global/skin/icons/close-inverted@2x.png       chrome://global/skin/icons/close-inverted-XPVista7@2x.png osversion<=6.1
 
-% override chrome://global/skin/tree/twisty.svg#clsd              chrome://global/skin/tree/twisty-preWin10.svg#clsd           osversion<=6.3
-% override chrome://global/skin/tree/twisty.svg#clsd-rtl          chrome://global/skin/tree/twisty-preWin10.svg#clsd-rtl       osversion<=6.3
-% override chrome://global/skin/tree/twisty.svg#clsd-hover        chrome://global/skin/tree/twisty-preWin10.svg#clsd-hover     osversion<=6.3
-% override chrome://global/skin/tree/twisty.svg#clsd-hover-rtl    chrome://global/skin/tree/twisty-preWin10.svg#clsd-hover-rtl osversion<=6.3
-% override chrome://global/skin/tree/twisty.svg#open              chrome://global/skin/tree/twisty-preWin10.svg#open           osversion<=6.3
-% override chrome://global/skin/tree/twisty.svg#open-rtl          chrome://global/skin/tree/twisty-preWin10.svg#open-rtl       osversion<=6.3
-% override chrome://global/skin/tree/twisty.svg#open-hover        chrome://global/skin/tree/twisty-preWin10.svg#open-hover     osversion<=6.3
-% override chrome://global/skin/tree/twisty.svg#open-hover-rtl    chrome://global/skin/tree/twisty-preWin10.svg#open-hover-rtl osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#clsd              chrome://global/skin/tree/twisty-Vista78.svg#clsd           osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#clsd-rtl          chrome://global/skin/tree/twisty-Vista78.svg#clsd-rtl       osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#clsd-hover        chrome://global/skin/tree/twisty-Vista78.svg#clsd-hover     osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#clsd-hover-rtl    chrome://global/skin/tree/twisty-Vista78.svg#clsd-hover-rtl osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#open              chrome://global/skin/tree/twisty-Vista78.svg#open           osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#open-rtl          chrome://global/skin/tree/twisty-Vista78.svg#open-rtl       osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#open-hover        chrome://global/skin/tree/twisty-Vista78.svg#open-hover     osversion<=6.3
+% override chrome://global/skin/tree/twisty.svg#open-hover-rtl    chrome://global/skin/tree/twisty-Vista78.svg#open-hover-rtl osversion<=6.3
+# to be sure osversion<6 has always higher precedence than osversion<=6.3 we override twisty-Vista78.svg instead of twisty.svg
+% override chrome://global/skin/tree/twisty-Vista78.svg#clsd      chrome://global/skin/tree/twisty-XP.svg#clsd                osversion<6
+% override chrome://global/skin/tree/twisty-Vista78.svg#open      chrome://global/skin/tree/twisty-XP.svg#open                osversion<6
diff --git a/toolkit/themes/windows/global/listbox.css b/toolkit/themes/windows/global/listbox.css
index ddea3f8fa..fd60b1693 100644
--- a/toolkit/themes/windows/global/listbox.css
+++ b/toolkit/themes/windows/global/listbox.css
@@ -144,67 +144,70 @@ listheader[sortable="true"]:hover:active {
 }
 
 @media (-moz-windows-default-theme) {
-  listitem {
-    --listitem-selectedColor: rgb(217,217,217);
-    --listitem-selectedBorder: var(--listitem-selectedColor);
-    --listitem-selectedBottomBorder: rgb(204,204,204);
-    --listitem-selectedBackground: var(--listitem-selectedColor);
-    --listitem-selectedImage: none;
-    --listitem-selectedCurrentBorder: rgb(123,195,255);
-    --listitem-selectedFocusColor: rgb(205,232,255);
-    --listitem-selectedFocusBorder: var(--listitem-selectedFocusColor);
-    --listitem-selectedFocusBottomBorder: rgb(165,214,255);
-    --listitem-selectedFocusBackground: var(--listitem-selectedFocusColor);
-    --listitem-selectedFocusImage: none;
-    --listitem-selectedFocusCurrentBorder: var(--listitem-selectedFocusColor);
-    --listitem-selectedFocusCurrentBottomBorder: var(--listitem-selectedFocusBottomBorder);
-    --listitem-selectedFocusCurrentBackground: var(--listitem-selectedFocusColor);
-
-    color: -moz-FieldText;
-    margin-inline-start: 1px;
-    margin-inline-end: 1px;
-    padding-top: 1px;
-    padding-bottom: 1px;
-    border-width: 1px;
-    background-repeat: no-repeat;
-    background-size: 100% 100%;
-  }
+  @media not all and (-moz-os-version: windows-xp) {
+    listitem {
+      --listitem-selectedColor: rgb(217,217,217);
+      --listitem-selectedBorder: var(--listitem-selectedColor);
+      --listitem-selectedBottomBorder: rgb(204,204,204);
+      --listitem-selectedBackground: var(--listitem-selectedColor);
+      --listitem-selectedImage: none;
+      --listitem-selectedCurrentBorder: rgb(123,195,255);
+      --listitem-selectedFocusColor: rgb(205,232,255);
+      --listitem-selectedFocusBorder: var(--listitem-selectedFocusColor);
+      --listitem-selectedFocusBottomBorder: rgb(165,214,255);
+      --listitem-selectedFocusBackground: var(--listitem-selectedFocusColor);
+      --listitem-selectedFocusImage: none;
+      --listitem-selectedFocusCurrentBorder: var(--listitem-selectedFocusColor);
+      --listitem-selectedFocusCurrentBottomBorder: var(--listitem-selectedFocusBottomBorder);
+      --listitem-selectedFocusCurrentBackground: var(--listitem-selectedFocusColor);
+
+      color: -moz-FieldText;
+      margin-inline-start: 1px;
+      margin-inline-end: 1px;
+      padding-top: 1px;
+      padding-bottom: 1px;
+      border-width: 1px;
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+    }
 
-  listitem[selected="true"] {
-    border-top-color: var(--listitem-selectedBorder);
-    border-right-color: var(--listitem-selectedBorder);
-    border-left-color: var(--listitem-selectedBorder);
-    border-bottom-color: var(--listitem-selectedBottomBorder);
-    background-image: var(--listitem-selectedImage);
-    background-color: var(--listitem-selectedBackground);
-    color: -moz-DialogText;
-  }
+    listitem[selected="true"] {
+      border-top-color: var(--listitem-selectedBorder);
+      border-right-color: var(--listitem-selectedBorder);
+      border-left-color: var(--listitem-selectedBorder);
+      border-bottom-color: var(--listitem-selectedBottomBorder);
+      background-image: var(--listitem-selectedImage);
+      background-color: var(--listitem-selectedBackground);
+      color: -moz-DialogText;
+    }
 
-  listbox:focus > listitem[selected="true"] {
-    border-top-color: var(--listitem-selectedFocusBorder);
-    border-right-color: var(--listitem-selectedFocusBorder);
-    border-left-color: var(--listitem-selectedFocusBorder);
-    border-bottom-color: var(--listitem-selectedFocusBottomBorder);
-    background-image: var(--listitem-selectedFocusImage);
-    background-color: var(--listitem-selectedFocusBackground);
-    color: -moz-DialogText;
-  }
+    listbox:focus > listitem[selected="true"] {
+      border-top-color: var(--listitem-selectedFocusBorder);
+      border-right-color: var(--listitem-selectedFocusBorder);
+      border-left-color: var(--listitem-selectedFocusBorder);
+      border-bottom-color: var(--listitem-selectedFocusBottomBorder);
+      background-image: var(--listitem-selectedFocusImage);
+      background-color: var(--listitem-selectedFocusBackground);
+      color: -moz-DialogText;
+    }
 
-  listbox:focus > listitem[current="true"] {
-    border-color: var(--listitem-selectedCurrentBorder);
-    outline: none;
-  }
+    listbox:focus > listitem[current="true"] {
+      border-color: var(--listitem-selectedCurrentBorder);
+      outline: none;
+    }
 
-  listbox:focus > listitem[selected="true"][current="true"] {
-    border-top-color: var(--listitem-selectedFocusCurrentBorder);
-    border-right-color: var(--listitem-selectedFocusCurrentBorder);
-    border-left-color: var(--listitem-selectedFocusCurrentBorder);
-    border-bottom-color: var(--listitem-selectedFocusCurrentBottomBorder);
-    background-color: var(--listitem-selectedFocusCurrentBackground);
-    outline: none;
+    listbox:focus > listitem[selected="true"][current="true"] {
+      border-top-color: var(--listitem-selectedFocusCurrentBorder);
+      border-right-color: var(--listitem-selectedFocusCurrentBorder);
+      border-left-color: var(--listitem-selectedFocusCurrentBorder);
+      border-bottom-color: var(--listitem-selectedFocusCurrentBottomBorder);
+      background-color: var(--listitem-selectedFocusCurrentBackground);
+      outline: none;
+    }
   }
 
-  @media (-moz-os-version: windows-win7) {
+  @media (-moz-os-version: windows-vista),
+         (-moz-os-version: windows-win7) {
     listitem {
       --listitem-selectedBottomBorder: var(--listitem-selectedColor);
       --listitem-selectedBackground: rgba(190,190,190,.15);
diff --git a/toolkit/themes/windows/global/menu.css b/toolkit/themes/windows/global/menu.css
index c22aedd7a..2a228251d 100644
--- a/toolkit/themes/windows/global/menu.css
+++ b/toolkit/themes/windows/global/menu.css
@@ -148,13 +148,15 @@ menubar > menu:-moz-lwtheme[_moz-menuactive="true"]:not([disabled="true"]) {
 }
 
 @media (-moz-windows-default-theme) {
-  menubar > menu:-moz-lwtheme {
-    -moz-appearance: menuitem;
-  }
-
-  menubar > menu:-moz-lwtheme[_moz-menuactive="true"]:not([disabled="true"]) {
-    color: inherit !important;
-    text-shadow: inherit;
+  @media not all and (-moz-os-version: windows-xp) {
+    menubar > menu:-moz-lwtheme {
+      -moz-appearance: menuitem;
+    }
+
+    menubar > menu:-moz-lwtheme[_moz-menuactive="true"]:not([disabled="true"]) {
+      color: inherit !important;
+      text-shadow: inherit;
+    }
   }
 }
 
diff --git a/toolkit/themes/windows/global/menulist.css b/toolkit/themes/windows/global/menulist.css
index de24dbdde..9480bffda 100644
--- a/toolkit/themes/windows/global/menulist.css
+++ b/toolkit/themes/windows/global/menulist.css
@@ -82,6 +82,12 @@ menulist:-moz-focusring:not([open="true"]) > .menulist-label-box {
   border: 1px dotted ThreeDDarkShadow;
 }
 
+@media (-moz-os-version: windows-xp) {
+  menulist:-moz-focusring:not([open="true"]) > .menulist-label-box {
+    border: 1px dotted #F5DB95;
+  }
+}
+
 /* ..... disabled state ..... */
 
 menulist[disabled="true"] {
@@ -107,29 +113,31 @@ html|*.menulist-editable-input {
 }
 
 @media (-moz-windows-default-theme) {
-  .menulist-label-box {
-    background-color: transparent !important;
-    color: inherit !important;
-  }
-
-  .menulist-label {
-    margin-top: -1px !important;
-    margin-bottom: -1px !important;
-    margin-inline-start: 0 !important;
-  }
-
-  .menulist-description {
-    margin-inline-start: 1ex !important;
-  }
-
-  menulist:not([editable="true"]) > .menulist-dropmarker {
-    margin-top: -2px;
-    margin-inline-start: 3px;
-    margin-inline-end: -3px;
-  }
-
-  .menulist-icon {
-    margin-top: -1px;
-    margin-bottom: -1px;
+  @media not all and (-moz-os-version: windows-xp) {
+    .menulist-label-box {
+      background-color: transparent !important;
+      color: inherit !important;
+    }
+
+    .menulist-label {
+      margin-top: -1px !important;
+      margin-bottom: -1px !important;
+      margin-inline-start: 0 !important;
+    }
+
+    .menulist-description {
+      margin-inline-start: 1ex !important;
+    }
+
+    menulist:not([editable="true"]) > .menulist-dropmarker {
+      margin-top: -2px;
+      margin-inline-start: 3px;
+      margin-inline-end: -3px;
+    }
+
+    .menulist-icon {
+      margin-top: -1px;
+      margin-bottom: -1px;
+    }
   }
 }
diff --git a/toolkit/themes/windows/global/popup.css b/toolkit/themes/windows/global/popup.css
index e5c3c4500..010e85a93 100644
--- a/toolkit/themes/windows/global/popup.css
+++ b/toolkit/themes/windows/global/popup.css
@@ -58,7 +58,9 @@ panel[type="arrow"][side="right"] {
 }
 
 %ifdef XP_WIN
-@media (-moz-os-version: windows-win7) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
 %endif
 .panel-arrowcontent {
   border-radius: 4px;
diff --git a/toolkit/themes/windows/global/textbox.css b/toolkit/themes/windows/global/textbox.css
index 7b136a0ea..78ca7f320 100644
--- a/toolkit/themes/windows/global/textbox.css
+++ b/toolkit/themes/windows/global/textbox.css
@@ -37,8 +37,10 @@ html|*.textbox-textarea {
 }
 
 @media (-moz-windows-default-theme) {
-  textbox html|*.textbox-input::placeholder {
-    font-style: italic;
+  @media not all and (-moz-os-version: windows-xp) {
+    textbox html|*.textbox-input::placeholder {
+      font-style: italic;
+    }
   }
 }
 
diff --git a/toolkit/themes/windows/global/toolbarbutton.css b/toolkit/themes/windows/global/toolbarbutton.css
index ac3c7ba4a..e96e529cf 100644
--- a/toolkit/themes/windows/global/toolbarbutton.css
+++ b/toolkit/themes/windows/global/toolbarbutton.css
@@ -84,11 +84,17 @@ toolbarbutton[checked="true"]:not([disabled="true"]) {
     text-shadow: none;
   }
 
-  toolbarbutton:-moz-lwtheme:not([disabled="true"]) {
+  toolbarbutton:-moz-lwtheme:not(:hover):not([checked="true"]):not([open="true"]):not([disabled="true"]) {
     color: inherit;
     text-shadow: inherit;
   }
 
+  @media not all and (-moz-os-version: windows-xp) {
+    toolbarbutton:-moz-lwtheme:not([disabled="true"]) {
+      color: inherit;
+      text-shadow: inherit;
+    }
+  }
 }
 
 @media not all and (-moz-windows-default-theme) {
diff --git a/toolkit/themes/windows/global/tree.css b/toolkit/themes/windows/global/tree.css
index 2b4957c6c..130096824 100644
--- a/toolkit/themes/windows/global/tree.css
+++ b/toolkit/themes/windows/global/tree.css
@@ -310,7 +310,7 @@ treecol:not([hideheader="true"]) > .treecol-sortdirection[sortDirection="descend
 /* ::::: twisty :::::  */
 
 treechildren::-moz-tree-twisty {
-  padding-inline-end: 1px;
+  padding-inline-end: 4px;
   padding-top: 1px;
   width: 9px; /* The image's width is 9 pixels */
   list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd");
@@ -320,32 +320,8 @@ treechildren::-moz-tree-twisty(open) {
   list-style-image: url("chrome://global/skin/tree/twisty.svg#open");
 }
 
-treechildren::-moz-tree-twisty(hover) {
-  list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd-hover");
-}
-
-treechildren::-moz-tree-twisty(hover, open) {
-  list-style-image: url("chrome://global/skin/tree/twisty.svg#open-hover");
-}
-
-treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty {
-  list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd-rtl");
-}
-
-treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open) {
-  list-style-image: url("chrome://global/skin/tree/twisty.svg#open-rtl");
-}
-
-treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(hover) {
-  list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd-hover-rtl");
-}
-
-treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(hover, open) {
-  list-style-image: url("chrome://global/skin/tree/twisty.svg#open-hover-rtl");
-}
-
 treechildren::-moz-tree-indentation {
-  width: 12px;
+  width: 18px;
 }
 
 /* ::::: gridline style ::::: */
@@ -394,196 +370,233 @@ treechildren::-moz-tree-cell-text(active, selected, editing) {
 }
 
 %ifdef XP_WIN
-@media (-moz-windows-default-theme) {
-  treechildren {
-    --treechildren-outline: none;
-    --treechildren-2ndBorderColor: rgba(255,255,255,.4);
-    --treechildren-selectedColor: rgb(217,217,217);
-    --treechildren-focusColor: rgb(123,195,255);
-    --treechildren-selectedFocusColor: rgb(205,232,255);
-    --treechildren-currentColor: rgb(125,162,206);
-    --treechildren-hoverColor: rgb(229,243,255);
-    --treechildren-selectedBorder: var(--treechildren-selectedColor);
-    --treechildren-selectedBottomBorder: rgb(204,204,204);
-    --treechildren-selectedImage: linear-gradient(rgb(217,217,217), rgb(217,217,217));
-    --treechildren-selectedBackground: transparent;
-    --treechildren-currentFocusBorder: var(--treechildren-focusColor);
-    --treechildren-currentFocusBottomBorder: var(--treechildren-focusColor);
-    --treechildren-selectedFocusBorder: var(--treechildren-selectedFocusColor);
-    --treechildren-selectedFocusBottomBorder: rgb(165,214,255);
-    --treechildren-selectedFocusImage: none;
-    --treechildren-selectedFocusBackground: var(--treechildren-selectedFocusColor);
-    --treechildren-selectedFocusCurrentBorder: var(--treechildren-focusColor);
-    --treechildren-selectedFocusCurrentBottomBorder: var(--treechildren-focusColor);
-    --treechildren-selectedFocusCurrentImage: linear-gradient(rgb(205,232,255), rgb(205,232,255));
-    --treechildren-hoverBorder: var(--treechildren-hoverColor);
-    --treechildren-hoverBottomBorder: var(--treechildren-hoverColor);
-    --treechildren-hoverImage: linear-gradient(rgb(229,243,255), rgb(229,243,255));
-    --treechildren-hoverCurrentBorder: var(--treechildren-currentColor);
-    --treechildren-hoverCurrentBottomBorder: var(--treechildren-currentColor);
-    --treechildren-hoverCurrentImage: linear-gradient(rgba(131,183,249,.16), rgba(131,183,249,.16));
-    --treechildren-hoverSelectedBorder: var(--treechildren-focusColor);
-    --treechildren-hoverSelectedBottomBorder: var(--treechildren-focusColor);
-    --treechildren-hoverSelectedImage: linear-gradient(rgb(205,232,255), rgb(205,232,255));
-  }
+@media not all and (-moz-os-version: windows-xp) {
+  /* ::::: twisty :::::  */
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row {
-    height: 1.8em;
-    color: -moz-FieldText;
-    margin-inline-start: 1px;
-    margin-inline-end: 1px;
-    border-width: 1px;
-    border-color: transparent;
-    background-repeat: no-repeat;
-    background-size: 100% 100%;
+  treechildren::-moz-tree-indentation {
+    width: 12px;
   }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row(selected) {
-    -moz-border-top-colors: var(--treechildren-selectedBorder);
-    -moz-border-right-colors: var(--treechildren-selectedBorder);
-    -moz-border-left-colors: var(--treechildren-selectedBorder);
-    -moz-border-bottom-colors: var(--treechildren-selectedBottomBorder);
-    background-image: var(--treechildren-selectedImage);
-    background-color: var(--treechildren-selectedBackground);
-    outline: var(--treechildren-outline);
+  treechildren::-moz-tree-twisty {
+    padding-inline-end: 1px;
   }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row(current, focus) {
-    border-style: solid;
-    -moz-border-top-colors: var(--treechildren-currentFocusBorder);
-    -moz-border-right-colors: var(--treechildren-currentFocusBorder);
-    -moz-border-left-colors: var(--treechildren-currentFocusBorder);
-    -moz-border-bottom-colors: var(--treechildren-currentFocusBottomBorder);
-    outline: var(--treechildren-outline);
+  treechildren::-moz-tree-twisty(hover) {
+    list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd-hover");
   }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row(selected, focus),
-  treechildren::-moz-tree-row(dropOn) {
-    -moz-border-top-colors: var(--treechildren-selectedFocusBorder);
-    -moz-border-right-colors: var(--treechildren-selectedFocusBorder);
-    -moz-border-left-colors: var(--treechildren-selectedFocusBorder);
-    -moz-border-bottom-colors: var(--treechildren-selectedFocusBottomBorder);
-    background-image: var(--treechildren-selectedFocusImage);
-    background-color: var(--treechildren-selectedFocusBackground);
+  treechildren::-moz-tree-twisty(hover, open) {
+    list-style-image: url("chrome://global/skin/tree/twisty.svg#open-hover");
   }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row(selected, current, focus) {
-    border-style: solid;
-    -moz-border-top-colors: var(--treechildren-selectedFocusCurrentBorder);
-    -moz-border-right-colors: var(--treechildren-selectedFocusCurrentBorder);
-    -moz-border-left-colors: var(--treechildren-selectedFocusCurrentBorder);
-    -moz-border-bottom-colors: var(--treechildren-selectedFocusCurrentBottomBorder);
-    background-image: var(--treechildren-selectedFocusCurrentImage);
+  treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty {
+    list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd-rtl");
   }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row(hover) {
-    -moz-border-top-colors: var(--treechildren-hoverBorder);
-    -moz-border-right-colors: var(--treechildren-hoverBorder);
-    -moz-border-left-colors: var(--treechildren-hoverBorder);
-    -moz-border-bottom-colors: var(--treechildren-hoverBottomBorder);
-    background-image: var(--treechildren-hoverImage);
-    outline: var(--treechildren-outline);
+  treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(open) {
+    list-style-image: url("chrome://global/skin/tree/twisty.svg#open-rtl");
   }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row(hover, current) {
-    -moz-border-top-colors: var(--treechildren-hoverCurrentBorder);
-    -moz-border-right-colors: var(--treechildren-hoverCurrentBorder);
-    -moz-border-left-colors: var(--treechildren-hoverCurrentBorder);
-    -moz-border-bottom-colors: var(--treechildren-hoverCurrentBottomBorder);
-    background-image: var(--treechildren-hoverCurrentImage);
+  treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(hover) {
+    list-style-image: url("chrome://global/skin/tree/twisty.svg#clsd-hover-rtl");
   }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-row(hover, selected) {
-    -moz-border-top-colors: var(--treechildren-hoverSelectedBorder);
-    -moz-border-right-colors: var(--treechildren-hoverSelectedBorder);
-    -moz-border-left-colors: var(--treechildren-hoverSelectedBorder);
-    -moz-border-bottom-colors: var(--treechildren-hoverSelectedBottomBorder);
-    background-image: var(--treechildren-hoverSelectedImage);
+  treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(hover, open) {
+    list-style-image: url("chrome://global/skin/tree/twisty.svg#open-hover-rtl");
   }
 
-  tree[disabled="true"] > treechildren::-moz-tree-row {
-    background: none;
-    -moz-border-top-colors: transparent;
-    -moz-border-right-colors: transparent;
-    -moz-border-left-colors: transparent;
-    -moz-border-bottom-colors: transparent;
-  }
+  @media (-moz-windows-default-theme) {
+    treechildren {
+      --treechildren-outline: none;
+      --treechildren-2ndBorderColor: rgba(255,255,255,.4);
+      --treechildren-selectedColor: rgb(217,217,217);
+      --treechildren-focusColor: rgb(123,195,255);
+      --treechildren-selectedFocusColor: rgb(205,232,255);
+      --treechildren-currentColor: rgb(125,162,206);
+      --treechildren-hoverColor: rgb(229,243,255);
+      --treechildren-selectedBorder: var(--treechildren-selectedColor);
+      --treechildren-selectedBottomBorder: rgb(204,204,204);
+      --treechildren-selectedImage: linear-gradient(rgb(217,217,217), rgb(217,217,217));
+      --treechildren-selectedBackground: transparent;
+      --treechildren-currentFocusBorder: var(--treechildren-focusColor);
+      --treechildren-currentFocusBottomBorder: var(--treechildren-focusColor);
+      --treechildren-selectedFocusBorder: var(--treechildren-selectedFocusColor);
+      --treechildren-selectedFocusBottomBorder: rgb(165,214,255);
+      --treechildren-selectedFocusImage: none;
+      --treechildren-selectedFocusBackground: var(--treechildren-selectedFocusColor);
+      --treechildren-selectedFocusCurrentBorder: var(--treechildren-focusColor);
+      --treechildren-selectedFocusCurrentBottomBorder: var(--treechildren-focusColor);
+      --treechildren-selectedFocusCurrentImage: linear-gradient(rgb(205,232,255), rgb(205,232,255));
+      --treechildren-hoverBorder: var(--treechildren-hoverColor);
+      --treechildren-hoverBottomBorder: var(--treechildren-hoverColor);
+      --treechildren-hoverImage: linear-gradient(rgb(229,243,255), rgb(229,243,255));
+      --treechildren-hoverCurrentBorder: var(--treechildren-currentColor);
+      --treechildren-hoverCurrentBottomBorder: var(--treechildren-currentColor);
+      --treechildren-hoverCurrentImage: linear-gradient(rgba(131,183,249,.16), rgba(131,183,249,.16));
+      --treechildren-hoverSelectedBorder: var(--treechildren-focusColor);
+      --treechildren-hoverSelectedBottomBorder: var(--treechildren-focusColor);
+      --treechildren-hoverSelectedImage: linear-gradient(rgb(205,232,255), rgb(205,232,255));
+    }
 
-  treechildren::-moz-tree-cell(dropOn) {
-    background-image: none;
-    background-color: transparent;
-    border-radius: 0;
-  }
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row {
+      height: 1.8em;
+      color: -moz-FieldText;
+      margin-inline-start: 1px;
+      margin-inline-end: 1px;
+      border-width: 1px;
+      border-color: transparent;
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+    }
 
-  treechildren::-moz-tree-cell-text(primary, dropOn) {
-    color: -moz-FieldText;
-  }
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row(selected) {
+      -moz-border-top-colors: var(--treechildren-selectedBorder);
+      -moz-border-right-colors: var(--treechildren-selectedBorder);
+      -moz-border-left-colors: var(--treechildren-selectedBorder);
+      -moz-border-bottom-colors: var(--treechildren-selectedBottomBorder);
+      background-image: var(--treechildren-selectedImage);
+      background-color: var(--treechildren-selectedBackground);
+      outline: var(--treechildren-outline);
+    }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-cell-text {
-    padding-bottom: initial;
-    border-color: transparent;
-    background-color: transparent;
-  }
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row(current, focus) {
+      border-style: solid;
+      -moz-border-top-colors: var(--treechildren-currentFocusBorder);
+      -moz-border-right-colors: var(--treechildren-currentFocusBorder);
+      -moz-border-left-colors: var(--treechildren-currentFocusBorder);
+      -moz-border-bottom-colors: var(--treechildren-currentFocusBottomBorder);
+      outline: var(--treechildren-outline);
+    }
 
-  treechildren:not(.autocomplete-treebody)::-moz-tree-cell-text(selected, focus) {
-    color: -moz-DialogText;
-  }
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row(selected, focus),
+    treechildren::-moz-tree-row(dropOn) {
+      -moz-border-top-colors: var(--treechildren-selectedFocusBorder);
+      -moz-border-right-colors: var(--treechildren-selectedFocusBorder);
+      -moz-border-left-colors: var(--treechildren-selectedFocusBorder);
+      -moz-border-bottom-colors: var(--treechildren-selectedFocusBottomBorder);
+      background-image: var(--treechildren-selectedFocusImage);
+      background-color: var(--treechildren-selectedFocusBackground);
+    }
 
-  @media (-moz-os-version: windows-win7) {
-    treechildren {
-      --treechildren-outline: 1px solid var(--treechildren-2ndBorderColor);
-      --treechildren-2ndBottomBorderColor: rgba(255,255,255,.6);
-      --treechildren-selectedBorder: var(--treechildren-selectedColor) var(--treechildren-2ndBorderColor);
-      --treechildren-selectedBottomBorder: var(--treechildren-selectedColor) var(--treechildren-2ndBottomBorderColor);
-      --treechildren-selectedImage: linear-gradient(rgba(190,190,190,.1), rgba(190,190,190,.4));
-      --treechildren-currentFocusBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
-      --treechildren-currentFocusBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
-      --treechildren-selectedFocusBorder: rgb(132,172,221) var(--treechildren-2ndBorderColor);
-      --treechildren-selectedFocusBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
-      --treechildren-selectedFocusImage: linear-gradient(rgba(131,183,249,.16), rgba(131,183,249,.375));
-      --treechildren-selectedFocusBackground: transparent;
-      --treechildren-selectedFocusCurrentBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
-      --treechildren-selectedFocusCurrentBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
-      --treechildren-selectedFocusCurrentImage: linear-gradient(rgba(131,183,249,.28), rgba(131,183,249,.5));
-      --treechildren-hoverBorder: rgb(184,214,251) var(--treechildren-2ndBorderColor);
-      --treechildren-hoverBottomBorder: rgb(184,214,251) var(--treechildren-2ndBottomBorderColor);
-      --treechildren-hoverImage: linear-gradient(rgba(131,183,249,.05), rgba(131,183,249,.16));
-      --treechildren-hoverCurrentBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
-      --treechildren-hoverCurrentBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
-      --treechildren-hoverCurrentImage: linear-gradient(rgba(131,183,249,.05), rgba(131,183,249,.16));
-      --treechildren-hoverSelectedBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
-      --treechildren-hoverSelectedBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
-      --treechildren-hoverSelectedImage: linear-gradient(rgba(131,183,249,.28), rgba(131,183,249,.5));
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row(selected, current, focus) {
+      border-style: solid;
+      -moz-border-top-colors: var(--treechildren-selectedFocusCurrentBorder);
+      -moz-border-right-colors: var(--treechildren-selectedFocusCurrentBorder);
+      -moz-border-left-colors: var(--treechildren-selectedFocusCurrentBorder);
+      -moz-border-bottom-colors: var(--treechildren-selectedFocusCurrentBottomBorder);
+      background-image: var(--treechildren-selectedFocusCurrentImage);
     }
 
-    treechildren:not(.autocomplete-treebody)::-moz-tree-row {
-      border-width: 2px;
-      border-radius: 3px;
-      -moz-outline-radius: 3px;
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row(hover) {
+      -moz-border-top-colors: var(--treechildren-hoverBorder);
+      -moz-border-right-colors: var(--treechildren-hoverBorder);
+      -moz-border-left-colors: var(--treechildren-hoverBorder);
+      -moz-border-bottom-colors: var(--treechildren-hoverBottomBorder);
+      background-image: var(--treechildren-hoverImage);
+      outline: var(--treechildren-outline);
     }
-  }
 
-  @media (-moz-os-version: windows-win8) {
-    treechildren {
-      --treechildren-outline: 1px solid var(--treechildren-2ndBorderColor);
-      --treechildren-selectedBorder: var(--treechildren-selectedColor);
-      --treechildren-selectedBottomBorder: var(--treechildren-selectedColor);
-      --treechildren-selectedImage: linear-gradient(rgba(190,190,190,.4), rgba(190,190,190,.4));
-      --treechildren-currentFocusBorder: var(--treechildren-currentColor);
-      --treechildren-currentFocusBottomBorder: var(--treechildren-currentColor);
-      --treechildren-selectedFocusBorder: rgb(132,172,221) var(--treechildren-2ndBorderColor);
-      --treechildren-selectedFocusBottomBorder: var(--treechildren-currentColor);
-      --treechildren-selectedFocusImage: linear-gradient(rgba(131,183,249,.375), rgba(131,183,249,.375));
-      --treechildren-selectedFocusBackground: transparent;
-      --treechildren-selectedFocusCurrentBorder: var(--treechildren-currentColor);
-      --treechildren-selectedFocusCurrentBottomBorder: var(--treechildren-currentColor);
-      --treechildren-selectedFocusCurrentImage: linear-gradient(rgba(131,183,249,.5), rgba(131,183,249,.5));
-      --treechildren-hoverBorder: rgb(184,214,251);
-      --treechildren-hoverBottomBorder: rgb(184,214,251);
-      --treechildren-hoverImage: linear-gradient(rgba(131,183,249,.16), rgba(131,183,249,.16));
-      --treechildren-hoverSelectedBorder: var(--treechildren-currentColor);
-      --treechildren-hoverSelectedBottomBorder: var(--treechildren-currentColor);
-      --treechildren-hoverSelectedImage: linear-gradient(rgba(131,183,249,.5), rgba(131,183,249,.5));
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row(hover, current) {
+      -moz-border-top-colors: var(--treechildren-hoverCurrentBorder);
+      -moz-border-right-colors: var(--treechildren-hoverCurrentBorder);
+      -moz-border-left-colors: var(--treechildren-hoverCurrentBorder);
+      -moz-border-bottom-colors: var(--treechildren-hoverCurrentBottomBorder);
+      background-image: var(--treechildren-hoverCurrentImage);
+    }
+
+    treechildren:not(.autocomplete-treebody)::-moz-tree-row(hover, selected) {
+      -moz-border-top-colors: var(--treechildren-hoverSelectedBorder);
+      -moz-border-right-colors: var(--treechildren-hoverSelectedBorder);
+      -moz-border-left-colors: var(--treechildren-hoverSelectedBorder);
+      -moz-border-bottom-colors: var(--treechildren-hoverSelectedBottomBorder);
+      background-image: var(--treechildren-hoverSelectedImage);
+    }
+
+    tree[disabled="true"] > treechildren::-moz-tree-row {
+      background: none;
+      -moz-border-top-colors: transparent;
+      -moz-border-right-colors: transparent;
+      -moz-border-left-colors: transparent;
+      -moz-border-bottom-colors: transparent;
+    }
+
+    treechildren::-moz-tree-cell(dropOn) {
+      background-image: none;
+      background-color: transparent;
+      border-radius: 0;
+    }
+
+    treechildren::-moz-tree-cell-text(primary, dropOn) {
+      color: -moz-FieldText;
+    }
+
+    treechildren:not(.autocomplete-treebody)::-moz-tree-cell-text {
+      padding-bottom: initial;
+      border-color: transparent;
+      background-color: transparent;
+    }
+
+    treechildren:not(.autocomplete-treebody)::-moz-tree-cell-text(selected, focus) {
+      color: -moz-DialogText;
+    }
+
+    @media (-moz-os-version: windows-vista),
+           (-moz-os-version: windows-win7) {
+      treechildren {
+        --treechildren-outline: 1px solid var(--treechildren-2ndBorderColor);
+        --treechildren-2ndBottomBorderColor: rgba(255,255,255,.6);
+        --treechildren-selectedBorder: var(--treechildren-selectedColor) var(--treechildren-2ndBorderColor);
+        --treechildren-selectedBottomBorder: var(--treechildren-selectedColor) var(--treechildren-2ndBottomBorderColor);
+        --treechildren-selectedImage: linear-gradient(rgba(190,190,190,.1), rgba(190,190,190,.4));
+        --treechildren-currentFocusBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
+        --treechildren-currentFocusBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
+        --treechildren-selectedFocusBorder: rgb(132,172,221) var(--treechildren-2ndBorderColor);
+        --treechildren-selectedFocusBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
+        --treechildren-selectedFocusImage: linear-gradient(rgba(131,183,249,.16), rgba(131,183,249,.375));
+        --treechildren-selectedFocusBackground: transparent;
+        --treechildren-selectedFocusCurrentBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
+        --treechildren-selectedFocusCurrentBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
+        --treechildren-selectedFocusCurrentImage: linear-gradient(rgba(131,183,249,.28), rgba(131,183,249,.5));
+        --treechildren-hoverBorder: rgb(184,214,251) var(--treechildren-2ndBorderColor);
+        --treechildren-hoverBottomBorder: rgb(184,214,251) var(--treechildren-2ndBottomBorderColor);
+        --treechildren-hoverImage: linear-gradient(rgba(131,183,249,.05), rgba(131,183,249,.16));
+        --treechildren-hoverCurrentBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
+        --treechildren-hoverCurrentBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
+        --treechildren-hoverCurrentImage: linear-gradient(rgba(131,183,249,.05), rgba(131,183,249,.16));
+        --treechildren-hoverSelectedBorder: var(--treechildren-currentColor) var(--treechildren-2ndBorderColor);
+        --treechildren-hoverSelectedBottomBorder: var(--treechildren-currentColor) var(--treechildren-2ndBottomBorderColor);
+        --treechildren-hoverSelectedImage: linear-gradient(rgba(131,183,249,.28), rgba(131,183,249,.5));
+      }
+
+      treechildren:not(.autocomplete-treebody)::-moz-tree-row {
+        border-width: 2px;
+        border-radius: 3px;
+        -moz-outline-radius: 3px;
+      }
+    }
+
+    @media (-moz-os-version: windows-win8) {
+      treechildren {
+        --treechildren-outline: 1px solid var(--treechildren-2ndBorderColor);
+        --treechildren-selectedBorder: var(--treechildren-selectedColor);
+        --treechildren-selectedBottomBorder: var(--treechildren-selectedColor);
+        --treechildren-selectedImage: linear-gradient(rgba(190,190,190,.4), rgba(190,190,190,.4));
+        --treechildren-currentFocusBorder: var(--treechildren-currentColor);
+        --treechildren-currentFocusBottomBorder: var(--treechildren-currentColor);
+        --treechildren-selectedFocusBorder: rgb(132,172,221) var(--treechildren-2ndBorderColor);
+        --treechildren-selectedFocusBottomBorder: var(--treechildren-currentColor);
+        --treechildren-selectedFocusImage: linear-gradient(rgba(131,183,249,.375), rgba(131,183,249,.375));
+        --treechildren-selectedFocusBackground: transparent;
+        --treechildren-selectedFocusCurrentBorder: var(--treechildren-currentColor);
+        --treechildren-selectedFocusCurrentBottomBorder: var(--treechildren-currentColor);
+        --treechildren-selectedFocusCurrentImage: linear-gradient(rgba(131,183,249,.5), rgba(131,183,249,.5));
+        --treechildren-hoverBorder: rgb(184,214,251);
+        --treechildren-hoverBottomBorder: rgb(184,214,251);
+        --treechildren-hoverImage: linear-gradient(rgba(131,183,249,.16), rgba(131,183,249,.16));
+        --treechildren-hoverSelectedBorder: var(--treechildren-currentColor);
+        --treechildren-hoverSelectedBottomBorder: var(--treechildren-currentColor);
+        --treechildren-hoverSelectedImage: linear-gradient(rgba(131,183,249,.5), rgba(131,183,249,.5));
+      }
     }
   }
 }
diff --git a/toolkit/themes/windows/mozapps/jar.mn b/toolkit/themes/windows/mozapps/jar.mn
index 29203811f..5986f18f1 100644
--- a/toolkit/themes/windows/mozapps/jar.mn
+++ b/toolkit/themes/windows/mozapps/jar.mn
@@ -22,8 +22,16 @@ toolkit.jar:
   skin/classic/mozapps/extensions/localeGeneric.png          (webextensions/localeGeneric.png)
   skin/classic/mozapps/extensions/heart.png                  (webextensions/heart.png)
 * skin/classic/mozapps/extensions/newaddon.css               (webextensions/newaddon.css)
+  skin/classic/mozapps/extensions/category-discover-XP.png   (webextensions/category-discover-XP.png)
+  skin/classic/mozapps/extensions/category-plugins-XP.png    (webextensions/category-plugins-XP.png)
+  skin/classic/mozapps/extensions/category-recent-XP.png     (webextensions/category-recent-XP.png)
+  skin/classic/mozapps/extensions/category-available-XP.png  (webextensions/category-available-XP.png)
+  skin/classic/mozapps/extensions/extensionGeneric-16-XP.png (webextensions/extensionGeneric-16-XP.png)
+  skin/classic/mozapps/extensions/themeGeneric-XP.png        (webextensions/themeGeneric-XP.png)
+  skin/classic/mozapps/extensions/themeGeneric-16-XP.png     (webextensions/themeGeneric-16-XP.png)
+  skin/classic/mozapps/extensions/localeGeneric-XP.png       (webextensions/localeGeneric-XP.png)
 #else
-  skin/classic/mozapps/extensions/about.css                  (extensions/about.css)
+ skin/classic/mozapps/extensions/about.css                  (extensions/about.css)
   skin/classic/mozapps/extensions/blocklist.css              (extensions/blocklist.css)
 * skin/classic/mozapps/extensions/extensions.css             (extensions/extensions.css)
 * skin/classic/mozapps/extensions/selectAddons.css           (extensions/selectAddons.css)
@@ -74,9 +82,33 @@ toolkit.jar:
   skin/classic/mozapps/profile/profileicon.png               (profile/profileicon.png)
   skin/classic/mozapps/update/updates.css                    (update/updates.css)
   skin/classic/mozapps/viewsource/viewsource.css             (viewsource/viewsource.css)
+  skin/classic/mozapps/downloads/downloadButtons-XP.png      (downloads/downloadButtons-XP.png)
+  skin/classic/mozapps/downloads/downloadIcon-XP.png         (downloads/downloadIcon-XP.png)
+  skin/classic/mozapps/plugins/pluginGeneric-XP.png          (plugins/pluginGeneric-XP.png)
+  skin/classic/mozapps/plugins/pluginBlocked-XP.png          (plugins/pluginBlocked-XP.png)
+  skin/classic/mozapps/plugins/pluginGeneric-16-XP.png       (plugins/pluginGeneric-16-XP.png)
+  skin/classic/mozapps/profile/profileicon-XP.png            (profile/profileicon-XP.png)
+  skin/classic/mozapps/update/downloadButtons-XP.png         (update/downloadButtons-XP.png)
 
 #ifdef MOZ_PHOENIX
 [browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 #elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
 [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 #endif
+% override chrome://mozapps/skin/downloads/downloadButtons.png            chrome://mozapps/skin/downloads/downloadButtons-XP.png        osversion<6
+% override chrome://mozapps/skin/downloads/downloadIcon.png               chrome://mozapps/skin/downloads/downloadIcon-XP.png           osversion<6
+#ifdef MOZ_WEBEXTENSIONS
+% override chrome://mozapps/skin/extensions/category-discover.png         chrome://mozapps/skin/extensions/category-discover-XP.png     osversion<6
+% override chrome://mozapps/skin/extensions/category-plugins.png          chrome://mozapps/skin/extensions/category-plugins-XP.png      osversion<6
+% override chrome://mozapps/skin/extensions/category-recent.png           chrome://mozapps/skin/extensions/category-recent-XP.png       osversion<6
+% override chrome://mozapps/skin/extensions/category-available.png        chrome://mozapps/skin/extensions/category-available-XP.png    osversion<6
+% override chrome://mozapps/skin/extensions/extensionGeneric-16.png       chrome://mozapps/skin/extensions/extensionGeneric-16-XP.png   osversion<6
+% override chrome://mozapps/skin/extensions/themeGeneric.png              chrome://mozapps/skin/extensions/themeGeneric-XP.png          osversion<6
+% override chrome://mozapps/skin/extensions/themeGeneric-16.png           chrome://mozapps/skin/extensions/themeGeneric-16-XP.png       osversion<6
+% override chrome://mozapps/skin/extensions/localeGeneric.png             chrome://mozapps/skin/extensions/localeGeneric-XP.png         osversion<6
+#endif
+% override chrome://mozapps/skin/plugins/pluginGeneric.png                chrome://mozapps/skin/plugins/pluginGeneric-XP.png            osversion<6
+% override chrome://mozapps/skin/plugins/pluginBlocked.png                chrome://mozapps/skin/plugins/pluginBlocked-XP.png            osversion<6
+% override chrome://mozapps/skin/plugins/pluginGeneric-16.png             chrome://mozapps/skin/plugins/pluginGeneric-16-XP.png         osversion<6
+% override chrome://mozapps/skin/profile/profileicon.png                  chrome://mozapps/skin/profile/profileicon-XP.png              osversion<6
+% override chrome://mozapps/skin/update/downloadButtons.png               chrome://mozapps/skin/update/downloadButtons-XP.png           osversion<6
diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
index 4a1d3046f..4979e1652 100644
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -98,6 +98,7 @@
 #include <intrin.h>
 #include <math.h>
 #include "cairo/cairo-features.h"
+#include "mozilla/WindowsVersion.h"
 #include "mozilla/mscom/MainThreadRuntime.h"
 #include "mozilla/widget/AudioSession.h"
 
@@ -3105,7 +3106,10 @@ XREMain::XRE_mainInit(bool* aExitFlag)
     // manual font file I/O on _all_ system fonts.  To avoid this, load the
     // dwrite library and create a factory as early as possible so that the
     // FntCache service is ready by the time it's needed.
-    CreateThread(nullptr, 0, &InitDwriteBG, nullptr, 0, nullptr);
+
+    if (IsVistaOrLater()) {
+      CreateThread(nullptr, 0, &InitDwriteBG, nullptr, 0, nullptr);
+    }
   }
 #endif
 
@@ -4831,7 +4835,7 @@ enum {
   kE10sDisabledForAddons = 7,
   kE10sForceDisabled = 8,
   // kE10sDisabledForXPAcceleration = 9, removed in bug 1296353
-  // kE10sDisabledForOperatingSystem = 10, removed due to xp-eol
+  kE10sDisabledForOperatingSystem = 10,
 };
 
 const char* kAccessibilityLastRunDatePref = "accessibility.lastLoadDate";
@@ -4908,6 +4912,19 @@ MultiprocessBlockPolicy() {
   }
 #endif
 
+  /**
+   * Avoids enabling e10s for Windows XP users on the release channel.
+   */
+#if defined(XP_WIN)
+  if (!IsVistaOrLater()) {
+    nsAdoptingCString channelName = Preferences::GetDefaultCString("app.update.channel");
+    if (channelName.EqualsLiteral("release") || channelName.EqualsLiteral("esr")) {
+      gMultiprocessBlockPolicy = kE10sDisabledForOperatingSystem;
+      return gMultiprocessBlockPolicy;
+    }
+  }
+#endif // XP_WIN
+
   /*
    * None of the blocking policies matched, so e10s is allowed to run.
    * Cache the information and return 0, indicating success.
diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp
index 1e67ea7ce..0e85532b9 100644
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -24,7 +24,6 @@
 
 #ifdef XP_WIN
 #include <process.h>
-#include <shobjidl.h>
 #include "mozilla/ipc/WindowsMessageLoop.h"
 #endif
 
@@ -120,6 +119,10 @@ using mozilla::startup::sChildProcessType;
 
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
+#ifdef XP_WIN
+static const wchar_t kShellLibraryName[] =  L"shell32.dll";
+#endif
+
 nsresult
 XRE_LockProfileDirectory(nsIFile* aDirectory,
                          nsISupports* *aLockObject)
@@ -267,9 +270,26 @@ XRE_SetRemoteExceptionHandler(const char* aPipe/*= 0*/)
 void
 SetTaskbarGroupId(const nsString& aId)
 {
-    if (FAILED(SetCurrentProcessExplicitAppUserModelID(aId.get()))) {
+    typedef HRESULT (WINAPI * SetCurrentProcessExplicitAppUserModelIDPtr)(PCWSTR AppID);
+
+    SetCurrentProcessExplicitAppUserModelIDPtr funcAppUserModelID = nullptr;
+
+    HMODULE hDLL = ::LoadLibraryW(kShellLibraryName);
+
+    funcAppUserModelID = (SetCurrentProcessExplicitAppUserModelIDPtr)
+                          GetProcAddress(hDLL, "SetCurrentProcessExplicitAppUserModelID");
+
+    if (!funcAppUserModelID) {
+        ::FreeLibrary(hDLL);
+        return;
+    }
+
+    if (FAILED(funcAppUserModelID(aId.get()))) {
         NS_WARNING("SetCurrentProcessExplicitAppUserModelID failed for child process.");
     }
+
+    if (hDLL)
+        ::FreeLibrary(hDLL);
 }
 #endif
 
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
index 09168319f..2fbd324b7 100644
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -48,6 +48,7 @@
 #ifdef XP_WIN
 #include <windows.h>
 #include <shlobj.h>
+#include "mozilla/WindowsVersion.h"
 #endif
 #ifdef XP_MACOSX
 #include "nsILocalFileMac.h"
@@ -761,12 +762,15 @@ nsXREDirProvider::LoadContentProcessTempDir()
 static bool
 IsContentSandboxDisabled()
 {
-  bool isSandboxDisabled = false;
   if (!BrowserTabsRemoteAutostart()) {
     return false;
   }
-#if defined(XP_WIN) || defined(XP_MACOSX)
-  isSandboxDisabled = Preferences::GetInt("security.sandbox.content.level") < 1;
+#if defined(XP_WIN)
+  const bool isSandboxDisabled = !mozilla::IsVistaOrLater() ||
+    (Preferences::GetInt("security.sandbox.content.level") < 1);
+#elif defined(XP_MACOSX)
+  const bool isSandboxDisabled =
+    Preferences::GetInt("security.sandbox.content.level") < 1;
 #endif
   return isSandboxDisabled;
 }
diff --git a/toolkit/xre/test/win/TestDllInterceptor.cpp b/toolkit/xre/test/win/TestDllInterceptor.cpp
index 57d68ea77..dff71817f 100644
--- a/toolkit/xre/test/win/TestDllInterceptor.cpp
+++ b/toolkit/xre/test/win/TestDllInterceptor.cpp
@@ -2,6 +2,11 @@
  * 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/. */
 
+#if _WIN32_WINNT < 0x0600
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
+
 #include <shlobj.h>
 #include <stdio.h>
 
diff --git a/widget/GfxInfoBase.cpp b/widget/GfxInfoBase.cpp
index 5c8693957..e53db69c5 100644
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -245,7 +245,13 @@ RemovePrefForDriverVersion()
 static OperatingSystem
 BlacklistOSToOperatingSystem(const nsAString& os)
 {
-  if (os.EqualsLiteral("WINNT 6.1"))
+  if (os.EqualsLiteral("WINNT 5.1"))
+    return OperatingSystem::WindowsXP;
+  else if (os.EqualsLiteral("WINNT 5.2"))
+    return OperatingSystem::WindowsServer2003;
+  else if (os.EqualsLiteral("WINNT 6.0"))
+    return OperatingSystem::WindowsVista;
+  else if (os.EqualsLiteral("WINNT 6.1"))
     return OperatingSystem::Windows7;
   else if (os.EqualsLiteral("WINNT 6.2"))
     return OperatingSystem::Windows8;
diff --git a/widget/LookAndFeel.h b/widget/LookAndFeel.h
index cf84b3308..e2502c559 100644
--- a/widget/LookAndFeel.h
+++ b/widget/LookAndFeel.h
@@ -440,7 +440,9 @@ public:
    * Operating system versions.
    */
   enum OperatingSystemVersion {
-    eOperatingSystemVersion_Windows7 = 2,
+    eOperatingSystemVersion_WindowsXP = 0,
+    eOperatingSystemVersion_WindowsVista,
+    eOperatingSystemVersion_Windows7,
     eOperatingSystemVersion_Windows8,
     eOperatingSystemVersion_Windows10,
     eOperatingSystemVersion_Unknown
diff --git a/widget/windows/GfxInfo.cpp b/widget/windows/GfxInfo.cpp
index bfea41851..0cbd323de 100644
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -241,6 +241,9 @@ ParseIDFromDeviceID(const nsAString &key, const char *prefix, int length)
 // based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
 enum {
   kWindowsUnknown = 0,
+  kWindowsXP = 0x50001,
+  kWindowsServer2003 = 0x50002,
+  kWindowsVista = 0x60000,
   kWindows7 = 0x60001,
   kWindows8 = 0x60002,
   kWindows8_1 = 0x60003,
@@ -823,6 +826,12 @@ static OperatingSystem
 WindowsVersionToOperatingSystem(int32_t aWindowsVersion)
 {
   switch(aWindowsVersion) {
+    case kWindowsXP:
+      return OperatingSystem::WindowsXP;
+    case kWindowsServer2003:
+      return OperatingSystem::WindowsServer2003;
+    case kWindowsVista:
+      return OperatingSystem::WindowsVista;
     case kWindows7:
       return OperatingSystem::Windows7;
     case kWindows8:
@@ -851,6 +860,11 @@ GfxInfo::GetGfxDriverInfo()
     /*
      * NVIDIA entries
      */
+    APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP,
+      (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
+      GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
+      DRIVER_LESS_THAN_OR_EQUAL, V(6,14,11,8745), "FEATURE_FAILURE_NV_XP", "nVidia driver > 187.45" );
+
     /*
      * The last 5 digit of the NVIDIA driver version maps to the version that
      * NVIDIA uses. The minor version (15, 16, 17) corresponds roughtly to the
@@ -861,17 +875,33 @@ GfxInfo::GetGfxDriverInfo()
      * 187.45 (late October 2009) and earlier contain a bug which can cause us
      * to crash on shutdown.
      */
+    APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista,
+      (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
+      GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
+      DRIVER_LESS_THAN_OR_EQUAL, V(8,15,11,8745),
+      "FEATURE_FAILURE_NV_VISTA_15", "nVidia driver > 187.45" );
     APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::Windows7,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
       GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
       DRIVER_LESS_THAN_OR_EQUAL, V(8,15,11,8745),
       "FEATURE_FAILURE_NV_W7_15", "nVidia driver > 187.45" );
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::WindowsVista,
+      (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
+      GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
+      DRIVER_BETWEEN_INCLUSIVE_START, V(8,16,10,0000), V(8,16,11,8745),
+      "FEATURE_FAILURE_NV_VISTA_16", "nVidia driver > 187.45" );
     APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::Windows7,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
       GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
       DRIVER_BETWEEN_INCLUSIVE_START, V(8,16,10,0000), V(8,16,11,8745),
       "FEATURE_FAILURE_NV_W7_16", "nVidia driver > 187.45" );
     // Telemetry doesn't show any driver in this range so it might not even be required.
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::WindowsVista,
+      (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
+      GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
+      DRIVER_BETWEEN_INCLUSIVE_START, V(8,17,10,0000), V(8,17,11,8745),
+      "FEATURE_FAILURE_NV_VISTA_17", "nVidia driver > 187.45" );
+    // Telemetry doesn't show any driver in this range so it might not even be required.
     APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::Windows7,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
       GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
@@ -969,6 +999,13 @@ GfxInfo::GetGfxDriverInfo()
         nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,                                               \
         DRIVER_BUILD_ID_LESS_THAN, driverVer, ruleId )
 
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA500,   1006, "FEATURE_FAILURE_594877_1");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA900,   GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_594877_2");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA950,   1504, "FEATURE_FAILURE_594877_3");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMA3150,  2124, "FEATURE_FAILURE_594877_4");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelGMAX3000, 1666, "FEATURE_FAILURE_594877_5");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::WindowsVista, IntelHDGraphicsToSandyBridge, 2202, "FEATURE_FAILURE_594877_6");
+
     IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7, IntelGMA500,   2026, "FEATURE_FAILURE_594877_7");
     IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7, IntelGMA900,   GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_594877_8");
     IMPLEMENT_INTEL_DRIVER_BLOCKLIST_D2D(OperatingSystem::Windows7, IntelGMA950,   1930, "FEATURE_FAILURE_594877_9");
@@ -985,6 +1022,31 @@ GfxInfo::GetGfxDriverInfo()
       nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
       DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_1180379");
 
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA500,   V(3,0,20,3200), "FEATURE_FAILURE_INTEL_1");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA900,   V(6,14,10,4764), "FEATURE_FAILURE_INTEL_2");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA950,   V(6,14,10,4926), "FEATURE_FAILURE_INTEL_3");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMA3150,  V(6,14,10,5134), "FEATURE_FAILURE_INTEL_4");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMAX3000, V(6,14,10,5218), "FEATURE_FAILURE_INTEL_5");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelGMAX4500HD, V(6,14,10,4969), "FEATURE_FAILURE_INTEL_6");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsXP, IntelHDGraphicsToSandyBridge, V(6,14,10,4969), "FEATURE_FAILURE_INTEL_7");
+
+    // StrechRect seems to suffer from precision issues which leads to artifacting
+    // during content drawing starting with at least version 6.14.10.5082
+    // and going until 6.14.10.5218. See bug 919454 and bug 949275 for more info.
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::WindowsXP,
+      const_cast<nsAString&>(GfxDriverInfo::GetDeviceVendor(VendorIntel)),
+      const_cast<GfxDeviceFamily*>(GfxDriverInfo::GetDeviceFamily(IntelGMAX4500HD)),
+      GfxDriverInfo::allFeatures, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
+      DRIVER_BETWEEN_EXCLUSIVE, V(6,14,10,5076), V(6,14,10,5218), "FEATURE_FAILURE_INTEL_8", "6.14.10.5218");
+
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA500,   V(3,0,20,3200), "FEATURE_FAILURE_INTEL_9");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA900,   GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_INTEL_10");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA950,   V(7,14,10,1504), "FEATURE_FAILURE_INTEL_11");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMA3150,  V(7,14,10,1910), "FEATURE_FAILURE_INTEL_12");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMAX3000, V(7,15,10,1666), "FEATURE_FAILURE_INTEL_13");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelGMAX4500HD, V(7,15,10,1666), "FEATURE_FAILURE_INTEL_14");
+    IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::WindowsVista, IntelHDGraphicsToSandyBridge, V(7,15,10,1666), "FEATURE_FAILURE_INTEL_15");
+
     IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::Windows7, IntelGMA500,   V(5,0,0,2026), "FEATURE_FAILURE_INTEL_16");
     IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::Windows7, IntelGMA900,   GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_INTEL_17");
     IMPLEMENT_INTEL_DRIVER_BLOCKLIST(OperatingSystem::Windows7, IntelGMA950,   V(8,15,10,1930), "FEATURE_FAILURE_INTEL_18");
@@ -1238,6 +1300,23 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
       return NS_OK;
     }
 
+    // special-case the WinXP test slaves: they have out-of-date drivers, but we still want to
+    // whitelist them, actually we do know that this combination of device and driver version
+    // works well.
+    if (mWindowsVersion == kWindowsXP &&
+        adapterVendorID.Equals(GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), nsCaseInsensitiveStringComparator()) &&
+        adapterDeviceID.LowerCaseEqualsLiteral("0x0861") && // GeForce 9400
+        driverVersion == V(6,14,11,7756))
+    {
+      *aStatus = FEATURE_STATUS_OK;
+      return NS_OK;
+    }
+
+    // Windows Server 2003 should be just like Windows XP for present purpose, but still has a different version number.
+    // OTOH Windows Server 2008 R1 and R2 already have the same version numbers as Vista and Seven respectively
+    if (os == OperatingSystem::WindowsServer2003)
+      os = OperatingSystem::WindowsXP;
+
     if (mHasDriverVersionMismatch) {
       *aStatus = nsIGfxInfo::FEATURE_BLOCKED_MISMATCHED_VERSION;
       return NS_OK;
diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp
index 341a40c18..11f657874 100644
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -1363,6 +1363,34 @@ NativeKey::InitWithKeyChar()
         break;
       }
 
+      if (!CanComputeVirtualKeyCodeFromScanCode()) {
+        // The right control key and the right alt key are extended keys.
+        // Therefore, we never get VK_RCONTRL and VK_RMENU for the result of
+        // MapVirtualKeyEx() on WinXP or WinServer2003.
+        //
+        // If VK_SHIFT, VK_CONTROL or VK_MENU key message is caused by well
+        // known scan code, we should decide it as Right key.  Otherwise,
+        // decide it as Left key.
+        switch (mOriginalVirtualKeyCode) {
+          case VK_CONTROL:
+            mVirtualKeyCode =
+              mIsExtended && mScanCode == 0x1D ? VK_RCONTROL : VK_LCONTROL;
+            break;
+          case VK_MENU:
+            mVirtualKeyCode =
+              mIsExtended && mScanCode == 0x38 ? VK_RMENU : VK_LMENU;
+            break;
+          case VK_SHIFT:
+            // Neither left shift nor right shift is an extended key,
+            // let's use VK_LSHIFT for unknown mapping.
+            mVirtualKeyCode = VK_LSHIFT;
+            break;
+          default:
+            MOZ_CRASH("Unsupported mOriginalVirtualKeyCode");
+        }
+        break;
+      }
+
       NS_ASSERTION(!mVirtualKeyCode,
                    "mVirtualKeyCode has been computed already");
 
@@ -1419,6 +1447,11 @@ NativeKey::InitWithKeyChar()
       //       scancode, we cannot compute virtual keycode.  I.e., with such
       //       applications, we cannot generate proper KeyboardEvent.code value.
 
+      // We cannot compute the virtual key code from WM_CHAR message on WinXP
+      // if it's caused by an extended key.
+      if (!CanComputeVirtualKeyCodeFromScanCode()) {
+        break;
+      }
       mVirtualKeyCode = mOriginalVirtualKeyCode =
         ComputeVirtualKeyCodeFromScanCodeEx();
       NS_ASSERTION(mVirtualKeyCode, "Failed to compute virtual keycode");
@@ -1836,6 +1869,18 @@ NativeKey::GetKeyLocation() const
   }
 }
 
+bool
+NativeKey::CanComputeVirtualKeyCodeFromScanCode() const
+{
+  // Vista or later supports ScanCodeEx.
+  if (IsVistaOrLater()) {
+    return true;
+  }
+  // Otherwise, MapVirtualKeyEx() can compute virtual keycode only with
+  // non-extended key.
+  return !mIsExtended;
+}
+
 uint8_t
 NativeKey::ComputeVirtualKeyCodeFromScanCode() const
 {
@@ -1849,6 +1894,12 @@ NativeKey::ComputeVirtualKeyCodeFromScanCodeEx() 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 the other hand, neither WinXP nor WinServer2003 doesn't support 0xE000.
+  // Therefore, we have no way to get virtual keycode from scan code of
+  // extended keys.
+  if (NS_WARN_IF(!CanComputeVirtualKeyCodeFromScanCode())) {
+    return 0;
+  }
   return static_cast<uint8_t>(
            ::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(), MAPVK_VSC_TO_VK_EX,
                              mKeyboardLayout));
@@ -1859,7 +1910,8 @@ NativeKey::ComputeScanCodeExFromVirtualKeyCode(UINT aVirtualKeyCode) const
 {
   return static_cast<uint16_t>(
            ::MapVirtualKeyEx(aVirtualKeyCode,
-                             MAPVK_VK_TO_VSC_EX,
+                             IsVistaOrLater() ? MAPVK_VK_TO_VSC_EX :
+                                                MAPVK_VK_TO_VSC,
                              mKeyboardLayout));
 }
 
@@ -4293,7 +4345,8 @@ KeyboardLayout::LoadLayout(HKL aLayout)
 
   if (MOZ_LOG_TEST(sKeyboardLayoutLogger, LogLevel::Verbose)) {
     static const UINT kExtendedScanCode[] = { 0x0000, 0xE000 };
-    static const UINT kMapType = MAPVK_VSC_TO_VK_EX;
+    static const UINT kMapType =
+      IsVistaOrLater() ? MAPVK_VSC_TO_VK_EX : MAPVK_VSC_TO_VK;
     MOZ_LOG(sKeyboardLayoutLogger, LogLevel::Verbose,
       ("Logging virtual keycode values for scancode (0x%p)...",
        mKeyboardLayout));
@@ -4305,6 +4358,11 @@ KeyboardLayout::LoadLayout(HKL aLayout)
         MOZ_LOG(sKeyboardLayoutLogger, LogLevel::Verbose,
           ("0x%04X, %s", scanCode, kVirtualKeyName[virtualKeyCode]));
       }
+      // XP and Server 2003 don't support 0xE0 prefix of the scancode.
+      // Therefore, we don't need to continue on them.
+      if (!IsVistaOrLater()) {
+        break;
+      }
     }
   }
 }
diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h
index 70aacc80e..dd2ac0bfc 100644
--- a/widget/windows/KeyboardLayout.h
+++ b/widget/windows/KeyboardLayout.h
@@ -559,6 +559,11 @@ private:
    */
   bool GetFollowingCharMessage(MSG& aCharMsg);
 
+  /**
+   * Whether the key event can compute virtual keycode from the scancode value.
+   */
+  bool CanComputeVirtualKeyCodeFromScanCode() const;
+
   /**
    * Wraps MapVirtualKeyEx() with MAPVK_VSC_TO_VK.
    */
diff --git a/widget/windows/LSPAnnotator.cpp b/widget/windows/LSPAnnotator.cpp
index 97f6e5b50..de4a40d2a 100644
--- a/widget/windows/LSPAnnotator.cpp
+++ b/widget/windows/LSPAnnotator.cpp
@@ -11,6 +11,11 @@
  * on machines with several LSPs.
  */
 
+#if _WIN32_WINNT < 0x0600
+// Redefining _WIN32_WINNT for some Vista APIs that we call
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
 #include "nsICrashReporter.h"
 #include "nsISupportsImpl.h"
 #include "nsServiceManagerUtils.h"
diff --git a/widget/windows/TSFTextStore.cpp b/widget/windows/TSFTextStore.cpp
index 7224126b8..fb0505aa3 100644
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -5762,7 +5762,8 @@ TSFTextStore::Initialize()
     return;
   }
 
-  bool enableTsf = Preferences::GetBool(kPrefNameEnableTSF, false);
+  bool enableTsf =
+    IsVistaOrLater() && Preferences::GetBool(kPrefNameEnableTSF, false);
   MOZ_LOG(sTextStoreLog, LogLevel::Info,
     ("  TSFTextStore::Initialize(), TSF is %s",
      enableTsf ? "enabled" : "disabled"));
diff --git a/widget/windows/TaskbarPreview.cpp b/widget/windows/TaskbarPreview.cpp
index 6c15df2e0..c897af021 100644
--- a/widget/windows/TaskbarPreview.cpp
+++ b/widget/windows/TaskbarPreview.cpp
@@ -28,9 +28,7 @@
 #include "mozilla/Telemetry.h"
 
 // Defined in dwmapi in a header that needs a higher numbered _WINNT #define
-#ifndef DWM_SIT_DISPLAYFRAME
 #define DWM_SIT_DISPLAYFRAME 0x1
-#endif
 
 namespace mozilla {
 namespace widget {
diff --git a/widget/windows/WinMouseScrollHandler.cpp b/widget/windows/WinMouseScrollHandler.cpp
index e157b1be2..10937ba51 100644
--- a/widget/windows/WinMouseScrollHandler.cpp
+++ b/widget/windows/WinMouseScrollHandler.cpp
@@ -992,7 +992,10 @@ MouseScrollHandler::SystemSettings::InitScrollChars()
                                      &mScrollChars, 0)) {
     MOZ_LOG(gMouseScrollLog, LogLevel::Info,
       ("MouseScroll::SystemSettings::InitScrollChars(): ::SystemParametersInfo("
-       "SPI_GETWHEELSCROLLCHARS) failed, this is unexpected on Vista or later"));
+       "SPI_GETWHEELSCROLLCHARS) failed, %s",
+       IsVistaOrLater() ?
+         "this is unexpected on Vista or later" :
+         "but on XP or earlier, this is not a problem"));
     // XXX Should we use DefaultScrollChars()?
     mScrollChars = 1;
   }
@@ -1078,7 +1081,7 @@ bool
 MouseScrollHandler::SystemSettings::IsOverridingSystemScrollSpeedAllowed()
 {
   return mScrollLines == DefaultScrollLines() &&
-         mScrollChars == DefaultScrollChars();
+         (!IsVistaOrLater() || mScrollChars == DefaultScrollChars());
 }
 
 /******************************************************************************
diff --git a/widget/windows/WinTaskbar.cpp b/widget/windows/WinTaskbar.cpp
index 530cfd5b9..698b7ec0e 100644
--- a/widget/windows/WinTaskbar.cpp
+++ b/widget/windows/WinTaskbar.cpp
@@ -34,6 +34,8 @@
 #include <propkey.h>
 #include <shellapi.h>
 
+const wchar_t kShellLibraryName[] =  L"shell32.dll";
+
 static NS_DEFINE_CID(kJumpListBuilderCID, NS_WIN_JUMPLISTBUILDER_CID);
 
 namespace {
@@ -75,14 +77,30 @@ SetWindowAppUserModelProp(mozIDOMWindow *aParent,
   if (!toplevelHWND)
     return NS_ERROR_INVALID_ARG;
 
-  RefPtr<IPropertyStore> pPropStore;
-  if (FAILED(SHGetPropertyStoreForWindow(toplevelHWND, IID_IPropertyStore,
-                                         getter_AddRefs(pPropStore)))) {
+  typedef HRESULT (WINAPI * SHGetPropertyStoreForWindowPtr)
+                    (HWND hwnd, REFIID riid, void** ppv);
+  SHGetPropertyStoreForWindowPtr funcGetProStore = nullptr;
+
+  HMODULE hDLL = ::LoadLibraryW(kShellLibraryName);
+  funcGetProStore = (SHGetPropertyStoreForWindowPtr)
+    GetProcAddress(hDLL, "SHGetPropertyStoreForWindow");
+
+  if (!funcGetProStore) {
+    FreeLibrary(hDLL);
+    return NS_ERROR_NO_INTERFACE;
+  }
+
+  IPropertyStore* pPropStore;
+  if (FAILED(funcGetProStore(toplevelHWND,
+                             IID_PPV_ARGS(&pPropStore)))) {
+    FreeLibrary(hDLL);
     return NS_ERROR_INVALID_ARG;
   }
 
   PROPVARIANT pv;
   if (FAILED(InitPropVariantFromString(aIdentifier.get(), &pv))) {
+    pPropStore->Release();
+    FreeLibrary(hDLL);
     return NS_ERROR_UNEXPECTED;
   }
 
@@ -93,6 +111,8 @@ SetWindowAppUserModelProp(mozIDOMWindow *aParent,
   }
 
   PropVariantClear(&pv);
+  pPropStore->Release();
+  FreeLibrary(hDLL);
 
   return rv;
 }
@@ -319,18 +339,40 @@ WinTaskbar::GetDefaultGroupId(nsAString & aDefaultGroupId) {
 // (static) Called from AppShell
 bool
 WinTaskbar::RegisterAppUserModelID() {
+  if (!IsWin7OrLater())
+    return false;
+
+  SetCurrentProcessExplicitAppUserModelIDPtr funcAppUserModelID = nullptr;
+  bool retVal = false;
+
   nsAutoString uid;
   if (!GetAppUserModelID(uid))
     return false;
 
-  return SUCCEEDED(SetCurrentProcessExplicitAppUserModelID(uid.get()));
+  HMODULE hDLL = ::LoadLibraryW(kShellLibraryName);
+
+  funcAppUserModelID = (SetCurrentProcessExplicitAppUserModelIDPtr)
+                        GetProcAddress(hDLL, "SetCurrentProcessExplicitAppUserModelID");
+
+  if (!funcAppUserModelID) {
+    ::FreeLibrary(hDLL);
+    return false;
+  }
+
+  if (SUCCEEDED(funcAppUserModelID(uid.get())))
+    retVal = true;
+
+  if (hDLL)
+    ::FreeLibrary(hDLL);
+
+  return retVal;
 }
 
 NS_IMETHODIMP
 WinTaskbar::GetAvailable(bool *aAvailable) {
   // ITaskbarList4::HrInit() may fail with shell extensions like blackbox
   // installed. Initialize early to return available=false in those cases.
-  *aAvailable = Initialize();
+  *aAvailable = IsWin7OrLater() && Initialize();
 
   return NS_OK;
 }
diff --git a/widget/windows/WinUtils.cpp b/widget/windows/WinUtils.cpp
index 0a57ad439..149513b2f 100644
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -462,7 +462,7 @@ static NtTestAlertPtr sNtTestAlert = nullptr;
 void
 WinUtils::Initialize()
 {
-  if (!sDwmDll) {
+  if (!sDwmDll && IsVistaOrLater()) {
     sDwmDll = ::LoadLibraryW(kDwmLibraryName);
 
     if (sDwmDll) {
@@ -601,7 +601,7 @@ WinUtils::SystemScaleFactor()
   return systemScale;
 }
 
-#if WINVER < 0x603
+#ifndef WM_DPICHANGED
 typedef enum {
   MDT_EFFECTIVE_DPI = 0,
   MDT_ANGULAR_DPI = 1,
@@ -628,14 +628,16 @@ GETPROCESSDPIAWARENESSPROC sGetProcessDpiAwareness;
 static bool
 SlowIsPerMonitorDPIAware()
 {
-  // Intentionally leak the handle.
-  HMODULE shcore =
-    LoadLibraryEx(L"shcore", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
-  if (shcore) {
-    sGetDpiForMonitor =
-      (GETDPIFORMONITORPROC) GetProcAddress(shcore, "GetDpiForMonitor");
-    sGetProcessDpiAwareness =
-      (GETPROCESSDPIAWARENESSPROC) GetProcAddress(shcore, "GetProcessDpiAwareness");
+  if (IsVistaOrLater()) {
+    // Intentionally leak the handle.
+    HMODULE shcore =
+      LoadLibraryEx(L"shcore", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+    if (shcore) {
+      sGetDpiForMonitor =
+        (GETDPIFORMONITORPROC) GetProcAddress(shcore, "GetDpiForMonitor");
+      sGetProcessDpiAwareness =
+        (GETPROCESSDPIAWARENESSPROC) GetProcAddress(shcore, "GetProcessDpiAwareness");
+    }
   }
   PROCESS_DPI_AWARENESS dpiAwareness;
   return sGetDpiForMonitor && sGetProcessDpiAwareness &&
@@ -758,7 +760,7 @@ static DWORD
 GetWaitFlags()
 {
   DWORD result = MWMO_INPUTAVAILABLE;
-  if (XRE_IsContentProcess()) {
+  if (IsVistaOrLater() && XRE_IsContentProcess()) {
     result |= MWMO_ALERTABLE;
   }
   return result;
@@ -1876,7 +1878,7 @@ WinUtils::IsTouchDeviceSupportPresent()
 uint32_t
 WinUtils::GetMaxTouchPoints()
 {
-  if (IsTouchDeviceSupportPresent()) {
+  if (IsWin7OrLater() && IsTouchDeviceSupportPresent()) {
     return GetSystemMetrics(SM_MAXIMUMTOUCHES);
   }
   return 0;
@@ -1891,6 +1893,11 @@ typedef DWORD (WINAPI * GetFinalPathNameByHandlePtr)(HANDLE hFile,
 bool
 WinUtils::ResolveJunctionPointsAndSymLinks(std::wstring& aPath)
 {
+  // Users folder was introduced with Vista.
+  if (!IsVistaOrLater()) {
+    return true;
+  }
+
   wchar_t path[MAX_PATH] = { 0 };
 
   nsAutoHandle handle(
@@ -2018,19 +2025,21 @@ WinUtils::GetAppInitDLLs(nsAString& aOutput)
   }
   nsAutoRegKey key(hkey);
   LONG status;
-  const wchar_t kLoadAppInitDLLs[] = L"LoadAppInit_DLLs";
-  DWORD loadAppInitDLLs = 0;
-  DWORD loadAppInitDLLsLen = sizeof(loadAppInitDLLs);
-  status = RegQueryValueExW(hkey, kLoadAppInitDLLs, nullptr,
-                            nullptr, (LPBYTE)&loadAppInitDLLs,
-                            &loadAppInitDLLsLen);
-  if (status != ERROR_SUCCESS) {
-    return false;
-  }
-  if (!loadAppInitDLLs) {
-    // If loadAppInitDLLs is zero then AppInit_DLLs is disabled.
-    // In this case we'll return true along with an empty output string.
-    return true;
+  if (IsVistaOrLater()) {
+    const wchar_t kLoadAppInitDLLs[] = L"LoadAppInit_DLLs";
+    DWORD loadAppInitDLLs = 0;
+    DWORD loadAppInitDLLsLen = sizeof(loadAppInitDLLs);
+    status = RegQueryValueExW(hkey, kLoadAppInitDLLs, nullptr,
+                              nullptr, (LPBYTE)&loadAppInitDLLs,
+                              &loadAppInitDLLsLen);
+    if (status != ERROR_SUCCESS) {
+      return false;
+    }
+    if (!loadAppInitDLLs) {
+      // If loadAppInitDLLs is zero then AppInit_DLLs is disabled.
+      // In this case we'll return true along with an empty output string.
+      return true;
+    }
   }
   DWORD numBytes = 0;
   const wchar_t kAppInitDLLs[] = L"AppInit_DLLs";
diff --git a/widget/windows/WindowsUIUtils.cpp b/widget/windows/WindowsUIUtils.cpp
index 1c270b5ec..223511859 100644
--- a/widget/windows/WindowsUIUtils.cpp
+++ b/widget/windows/WindowsUIUtils.cpp
@@ -5,8 +5,7 @@
 
 #include <windows.h>
 #include <winsdkver.h>
-#include <wrl.h>
-
+#include "mozwrlbase.h"
 #include "nsServiceManagerUtils.h"
 
 #include "WindowsUIUtils.h"
@@ -180,3 +179,4 @@ WindowsUIUtils::UpdateTabletModeState()
 
   return NS_OK;
 }
+
diff --git a/widget/windows/nsDataObj.cpp b/widget/windows/nsDataObj.cpp
index 02ec3b2fe..fc45968ae 100644
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.cpp
@@ -1148,7 +1148,8 @@ nsDataObj :: GetFileContentsInternetShortcut ( FORMATETC& aFE, STGMEDIUM& aSTG )
   const char *shortcutFormatStr;
   int totalLen;
   nsCString path;
-  if (!Preferences::GetBool(kShellIconPref, true)) {
+  if (!Preferences::GetBool(kShellIconPref, true) ||
+      !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
diff --git a/widget/windows/nsFilePicker.cpp b/widget/windows/nsFilePicker.cpp
index 4e942968a..53857cf5e 100644
--- a/widget/windows/nsFilePicker.cpp
+++ b/widget/windows/nsFilePicker.cpp
@@ -28,6 +28,7 @@
 #include "nsPIDOMWindow.h"
 #include "GeckoProfiler.h"
 
+using mozilla::IsVistaOrLater;
 using mozilla::IsWin8OrLater;
 using mozilla::MakeUnique;
 using mozilla::mscom::EnsureMTA;
@@ -218,6 +219,191 @@ STDMETHODIMP nsFilePicker::QueryInterface(REFIID refiid, void** ppvResult)
   return E_NOINTERFACE;
 }
 
+/*
+ * XP picker callbacks
+ */
+
+// Show - Display the file dialog
+int CALLBACK
+BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+{
+  if (uMsg == BFFM_INITIALIZED)
+  {
+    char16_t * filePath = (char16_t *) lpData;
+    if (filePath)
+      ::SendMessageW(hwnd, BFFM_SETSELECTIONW,
+                     TRUE /* true because lpData is a path string */,
+                     lpData);
+  }
+  return 0;
+}
+
+static void
+EnsureWindowVisible(HWND hwnd) 
+{
+  // Obtain the monitor which has the largest area of intersection 
+  // with the window, or nullptr if there is no intersection.
+  HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
+  if (!monitor) {
+    // The window is not visible, we should reposition it to the same place as its parent
+    HWND parentHwnd = GetParent(hwnd);
+    RECT parentRect;
+    GetWindowRect(parentHwnd, &parentRect);
+    SetWindowPos(hwnd, nullptr, parentRect.left, parentRect.top, 0, 0,
+                 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
+  }
+}
+
+// Callback hook which will ensure that the window is visible. Currently
+// only in use on os <= XP.
+UINT_PTR CALLBACK
+nsFilePicker::FilePickerHook(HWND hwnd,
+                             UINT msg,
+                             WPARAM wParam,
+                             LPARAM lParam) 
+{
+  switch(msg) {
+    case WM_NOTIFY:
+      {
+        LPOFNOTIFYW lpofn = (LPOFNOTIFYW) lParam;
+        if (!lpofn || !lpofn->lpOFN) {
+          return 0;
+        }
+        
+        if (CDN_INITDONE == lpofn->hdr.code) {
+          // The Window will be automatically moved to the last position after
+          // CDN_INITDONE.  We post a message to ensure the window will be visible
+          // so it will be done after the automatic last position window move.
+          PostMessage(hwnd, MOZ_WM_ENSUREVISIBLE, 0, 0);
+        }
+      }
+      break;
+    case MOZ_WM_ENSUREVISIBLE:
+      EnsureWindowVisible(GetParent(hwnd));
+      break;
+    case WM_INITDIALOG:
+      {
+        OPENFILENAMEW* pofn = reinterpret_cast<OPENFILENAMEW*>(lParam);
+        SetProp(hwnd, kDialogPtrProp, (HANDLE)pofn->lCustData);
+        nsFilePicker* picker = reinterpret_cast<nsFilePicker*>(pofn->lCustData);
+        if (picker) {
+          picker->SetDialogHandle(hwnd);
+          SetTimer(hwnd, kDialogTimerID, kDialogTimerTimeout, nullptr);
+        }
+      }
+      break;
+    case WM_TIMER:
+      {
+        // Check to see if our parent has been torn down, if so, we close too.
+        if (wParam == kDialogTimerID) {
+          nsFilePicker* picker = 
+            reinterpret_cast<nsFilePicker*>(GetProp(hwnd, kDialogPtrProp));
+          if (picker && picker->ClosePickerIfNeeded(true)) {
+            KillTimer(hwnd, kDialogTimerID);
+          }
+        }
+      }
+      break;
+  }
+  return 0;
+}
+
+
+// Callback hook which will dynamically allocate a buffer large enough
+// for the file picker dialog.  Currently only in use on  os <= XP.
+UINT_PTR CALLBACK
+nsFilePicker::MultiFilePickerHook(HWND hwnd,
+                                  UINT msg,
+                                  WPARAM wParam,
+                                  LPARAM lParam)
+{
+  switch (msg) {
+    case WM_INITDIALOG:
+      {
+        // Finds the child drop down of a File Picker dialog and sets the 
+        // maximum amount of text it can hold when typed in manually.
+        // A wParam of 0 mean 0x7FFFFFFE characters.
+        HWND comboBox = FindWindowEx(GetParent(hwnd), nullptr, 
+                                     L"ComboBoxEx32", nullptr );
+        if(comboBox)
+          SendMessage(comboBox, CB_LIMITTEXT, 0, 0);
+        // Store our nsFilePicker ptr for future use
+        OPENFILENAMEW* pofn = reinterpret_cast<OPENFILENAMEW*>(lParam);
+        SetProp(hwnd, kDialogPtrProp, (HANDLE)pofn->lCustData);
+        nsFilePicker* picker =
+          reinterpret_cast<nsFilePicker*>(pofn->lCustData);
+        if (picker) {
+          picker->SetDialogHandle(hwnd);
+          SetTimer(hwnd, kDialogTimerID, kDialogTimerTimeout, nullptr);
+        }
+      }
+      break;
+    case WM_NOTIFY:
+      {
+        LPOFNOTIFYW lpofn = (LPOFNOTIFYW) lParam;
+        if (!lpofn || !lpofn->lpOFN) {
+          return 0;
+        }
+        // CDN_SELCHANGE is sent when the selection in the list box of the file
+        // selection dialog changes
+        if (lpofn->hdr.code == CDN_SELCHANGE) {
+          HWND parentHWND = GetParent(hwnd);
+
+          // Get the required size for the selected files buffer
+          UINT newBufLength = 0; 
+          int requiredBufLength = CommDlg_OpenSave_GetSpecW(parentHWND, 
+                                                            nullptr, 0);
+          if(requiredBufLength >= 0)
+            newBufLength += requiredBufLength;
+          else
+            newBufLength += MAX_PATH;
+
+          // If the user selects multiple files, the buffer contains the 
+          // current directory followed by the file names of the selected 
+          // files. So make room for the directory path.  If the user
+          // selects a single file, it is no harm to add extra space.
+          requiredBufLength = CommDlg_OpenSave_GetFolderPathW(parentHWND, 
+                                                              nullptr, 0);
+          if(requiredBufLength >= 0)
+            newBufLength += requiredBufLength;
+          else
+            newBufLength += MAX_PATH;
+
+          // Check if lpstrFile and nMaxFile are large enough
+          if (newBufLength > lpofn->lpOFN->nMaxFile) {
+            if (lpofn->lpOFN->lpstrFile)
+              delete[] lpofn->lpOFN->lpstrFile;
+
+            // We allocate FILE_BUFFER_SIZE more bytes than is needed so that
+            // if the user selects a file and holds down shift and down to 
+            // select  additional items, we will not continuously reallocate
+            newBufLength += FILE_BUFFER_SIZE;
+
+            wchar_t* filesBuffer = new wchar_t[newBufLength];
+            ZeroMemory(filesBuffer, newBufLength * sizeof(wchar_t));
+
+            lpofn->lpOFN->lpstrFile = filesBuffer;
+            lpofn->lpOFN->nMaxFile  = newBufLength;
+          }
+        }
+      }
+      break;
+    case WM_TIMER:
+      {
+        // Check to see if our parent has been torn down, if so, we close too.
+        if (wParam == kDialogTimerID) {
+          nsFilePicker* picker =
+            reinterpret_cast<nsFilePicker*>(GetProp(hwnd, kDialogPtrProp));
+          if (picker && picker->ClosePickerIfNeeded(true)) {
+            KillTimer(hwnd, kDialogTimerID);
+          }
+        }
+      }
+      break;
+  }
+
+  return FilePickerHook(hwnd, msg, wParam, lParam);
+}
 
 /*
  * Vista+ callbacks
@@ -290,18 +476,25 @@ nsFilePicker::OnOverwrite(IFileDialog *pfd,
  */
 
 bool
-nsFilePicker::ClosePickerIfNeeded()
+nsFilePicker::ClosePickerIfNeeded(bool aIsXPDialog)
 {
   if (!mParentWidget || !mDlgWnd)
     return false;
 
   nsWindow *win = static_cast<nsWindow *>(mParentWidget.get());
-  if (IsWindow(mDlgWnd) && IsWindowVisible(mDlgWnd) && win->DestroyCalled()) {
+  // Note, the xp callbacks hand us an inner window, so we have to step up
+  // one to get the actual dialog.
+  HWND dlgWnd;
+  if (aIsXPDialog)
+    dlgWnd = GetParent(mDlgWnd);
+  else
+    dlgWnd = mDlgWnd;
+  if (IsWindow(dlgWnd) && IsWindowVisible(dlgWnd) && win->DestroyCalled()) {
     wchar_t className[64];
     // Make sure we have the right window
-    if (GetClassNameW(mDlgWnd, className, mozilla::ArrayLength(className)) &&
+    if (GetClassNameW(dlgWnd, className, mozilla::ArrayLength(className)) &&
         !wcscmp(className, L"#32770") &&
-        DestroyWindow(mDlgWnd)) {
+        DestroyWindow(dlgWnd)) {
       mDlgWnd = nullptr;
       return true;
     }
@@ -313,7 +506,7 @@ void
 nsFilePicker::PickerCallbackTimerFunc(nsITimer *aTimer, void *aCtx)
 {
   nsFilePicker* picker = (nsFilePicker*)aCtx;
-  if (picker->ClosePickerIfNeeded()) {
+  if (picker->ClosePickerIfNeeded(false)) {
     aTimer->Cancel();
   }
 }
@@ -330,15 +523,62 @@ nsFilePicker::SetDialogHandle(HWND aWnd)
  * Folder picker invocation
  */
 
+// Open the older XP style folder picker dialog. We end up in this call
+// on XP systems or when platform is built without the longhorn SDK.
+bool
+nsFilePicker::ShowXPFolderPicker(const nsString& aInitialDir)
+{
+  bool result = false;
+
+  auto dirBuffer = MakeUnique<wchar_t[]>(FILE_BUFFER_SIZE);
+  wcsncpy(dirBuffer.get(), aInitialDir.get(), FILE_BUFFER_SIZE);
+  dirBuffer[FILE_BUFFER_SIZE-1] = '\0';
+
+  AutoDestroyTmpWindow adtw((HWND)(mParentWidget.get() ?
+    mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : nullptr));
+
+  BROWSEINFOW browserInfo = {0};
+  browserInfo.pidlRoot       = nullptr;
+  browserInfo.pszDisplayName = dirBuffer.get();
+  browserInfo.lpszTitle      = mTitle.get();
+  browserInfo.ulFlags        = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
+  browserInfo.hwndOwner      = adtw.get(); 
+  browserInfo.iImage         = 0;
+  browserInfo.lParam         = reinterpret_cast<LPARAM>(this);
+
+  if (!aInitialDir.IsEmpty()) {
+    // the dialog is modal so that |initialDir.get()| will be valid in 
+    // BrowserCallbackProc. Thus, we don't need to clone it.
+    browserInfo.lParam = (LPARAM) aInitialDir.get();
+    browserInfo.lpfn   = &BrowseCallbackProc;
+  } else {
+    browserInfo.lParam = 0;
+    browserInfo.lpfn   = nullptr;
+  }
+
+  LPITEMIDLIST list = ::SHBrowseForFolderW(&browserInfo);
+  if (list) {
+    result = ::SHGetPathFromIDListW(list, dirBuffer.get());
+    if (result)
+      mUnicodeFile.Assign(static_cast<const wchar_t*>(dirBuffer.get()));
+    // free PIDL
+    CoTaskMemFree(list);
+  }
+
+  return result;
+}
+
 /*
- * Show a folder picker.
- *
+ * Show a folder picker post Windows XP
+ * 
  * @param aInitialDir   The initial directory, the last used directory will be
  *                      used if left blank.
+ * @param aWasInitError Out parameter will hold true if there was an error
+ *                      before the folder picker is shown.
  * @return true if a file was selected successfully.
 */
 bool
-nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
+nsFilePicker::ShowFolderPicker(const nsString& aInitialDir, bool &aWasInitError)
 {
   if (!IsWin8OrLater()) {
     // Some Windows 7 users are experiencing a race condition when some dlls
@@ -353,8 +593,10 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
   if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC,
                               IID_IFileOpenDialog,
                               getter_AddRefs(dialog)))) {
+    aWasInitError = true;
     return false;
   }
+  aWasInitError = false;
 
   // hook up event callbacks
   dialog->Advise(this, &mFDECookie);
@@ -416,15 +658,233 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
  * File open and save picker invocation
  */
 
+/* static */ bool
+nsFilePicker::GetFileNameWrapper(OPENFILENAMEW* ofn, PickerType aType)
+{
+  MOZ_SEH_TRY {
+    if (aType == PICKER_TYPE_OPEN)
+      return ::GetOpenFileNameW(ofn);
+    else if (aType == PICKER_TYPE_SAVE)
+      return ::GetSaveFileNameW(ofn);
+  } MOZ_SEH_EXCEPT(true) {
+    NS_ERROR("nsFilePicker GetFileName win32 call generated an exception! This is bad!");
+  }
+  return false;
+}
+
+bool
+nsFilePicker::FilePickerWrapper(OPENFILENAMEW* ofn, PickerType aType)
+{
+  if (!ofn)
+    return false;
+  AutoWidgetPickerState awps(mParentWidget);
+  return GetFileNameWrapper(ofn, aType);
+}
+
+bool
+nsFilePicker::ShowXPFilePicker(const nsString& aInitialDir)
+{
+  OPENFILENAMEW ofn = {0};
+  ofn.lStructSize = sizeof(ofn);
+  nsString filterBuffer = mFilterList;
+                                
+  auto fileBuffer = MakeUnique<wchar_t[]>(FILE_BUFFER_SIZE);
+  wcsncpy(fileBuffer.get(),  mDefaultFilePath.get(), FILE_BUFFER_SIZE);
+  fileBuffer[FILE_BUFFER_SIZE-1] = '\0'; // null terminate in case copy truncated
+
+  if (!aInitialDir.IsEmpty()) {
+    ofn.lpstrInitialDir = aInitialDir.get();
+  }
+
+  AutoDestroyTmpWindow adtw((HWND) (mParentWidget.get() ?
+    mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : nullptr));
+
+  ofn.lpstrTitle   = (LPCWSTR)mTitle.get();
+  ofn.lpstrFilter  = (LPCWSTR)filterBuffer.get();
+  ofn.nFilterIndex = mSelectedType;
+  ofn.lpstrFile    = fileBuffer.get();
+  ofn.nMaxFile     = FILE_BUFFER_SIZE;
+  ofn.hwndOwner    = adtw.get();
+  ofn.lCustData    = reinterpret_cast<LPARAM>(this);
+  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 (!IsVistaOrLater()) {
+    ofn.lpfnHook = FilePickerHook;
+    ofn.Flags |= OFN_ENABLEHOOK;
+  }
+
+  // Handle add to recent docs settings
+  if (IsPrivacyModeEnabled() || !mAddToRecentDocs) {
+    ofn.Flags |= OFN_DONTADDTORECENT;
+  }
+
+  NS_NAMED_LITERAL_STRING(htmExt, "html");
+
+  if (!mDefaultExtension.IsEmpty()) {
+    ofn.lpstrDefExt = mDefaultExtension.get();
+  } else if (IsDefaultPathHtml()) {
+    // Get file extension from suggested filename to detect if we are
+    // saving an html file.
+    // This is supposed to append ".htm" if user doesn't supply an
+    // extension but the behavior is sort of weird:
+    // - Often appends ".html" even if you have an extension
+    // - It obeys your extension if you put quotes around name
+    ofn.lpstrDefExt = htmExt.get();
+  }
+
+  // When possible, instead of using OFN_NOCHANGEDIR to ensure the current
+  // working directory will not change from this call, we will retrieve the
+  // current working directory before the call and restore it after the 
+  // call.  This flag causes problems on Windows XP for paths that are
+  // selected like  C:test.txt where the user is currently at C:\somepath
+  // In which case expected result should be C:\somepath\test.txt
+  AutoRestoreWorkingPath restoreWorkingPath;
+  // If we can't get the current working directory, the best case is to
+  // use the OFN_NOCHANGEDIR flag
+  if (!restoreWorkingPath.HasWorkingPath()) {
+    ofn.Flags |= OFN_NOCHANGEDIR;
+  }
+
+  bool result = false;
+
+  switch(mMode) {
+    case modeOpen:
+      // FILE MUST EXIST!
+      ofn.Flags |= OFN_FILEMUSTEXIST;
+      result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
+      break;
+
+    case modeOpenMultiple:
+      ofn.Flags |= OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT;
+
+      // The hook set here ensures that the buffer returned will always be
+      // large enough to hold all selected files.  The hook may modify the
+      // 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 (!IsVistaOrLater()) {
+        ofn.lpfnHook = MultiFilePickerHook;
+        fileBuffer.release();
+        result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
+        fileBuffer.reset(ofn.lpstrFile);
+      } else {
+        result = FilePickerWrapper(&ofn, PICKER_TYPE_OPEN);
+      }
+      break;
+
+    case modeSave:
+      {
+        ofn.Flags |= OFN_NOREADONLYRETURN;
+
+        // Don't follow shortcuts when saving a shortcut, this can be used
+        // to trick users (bug 271732)
+        if (IsDefaultPathLink())
+          ofn.Flags |= OFN_NODEREFERENCELINKS;
+
+        result = FilePickerWrapper(&ofn, PICKER_TYPE_SAVE);
+        if (!result) {
+          // Error, find out what kind.
+          if (GetLastError() == ERROR_INVALID_PARAMETER ||
+              CommDlgExtendedError() == FNERR_INVALIDFILENAME) {
+            // Probably the default file name is too long or contains illegal
+            // characters. Try again, without a starting file name.
+            ofn.lpstrFile[0] = L'\0';
+            result = FilePickerWrapper(&ofn, PICKER_TYPE_SAVE);
+          }
+        }
+      }
+      break;
+
+    default:
+      NS_NOTREACHED("unsupported file picker mode");
+      return false;
+  }
+
+  if (!result)
+    return false;
+
+  // Remember what filter type the user selected
+  mSelectedType = (int16_t)ofn.nFilterIndex;
+
+  // Single file selection, we're done
+  if (mMode != modeOpenMultiple) {
+    GetQualifiedPath(fileBuffer.get(), mUnicodeFile);
+    return true;
+  }
+
+  // Set user-selected location of file or directory.  From msdn's "Open and
+  // Save As Dialog Boxes" section:
+  // If you specify OFN_EXPLORER, the directory and file name strings are '\0'
+  // separated, with an extra '\0' character after the last file name. This
+  // format enables the Explorer-style dialog boxes to return long file names
+  // that include spaces. 
+  wchar_t *current = fileBuffer.get();
+  
+  nsAutoString dirName(current);
+  // Sometimes dirName contains a trailing slash and sometimes it doesn't:
+  if (current[dirName.Length() - 1] != '\\')
+    dirName.Append((char16_t)'\\');
+  
+  while (current && *current && *(current + wcslen(current) + 1)) {
+    current = current + wcslen(current) + 1;
+    
+    nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
+    NS_ENSURE_TRUE(file, false);
+
+    // Only prepend the directory if the path specified is a relative path
+    nsAutoString path;
+    if (PathIsRelativeW(current)) {
+      path = dirName + nsDependentString(current);
+    } else {
+      path = current;
+    }
+
+    nsAutoString canonicalizedPath;
+    GetQualifiedPath(path.get(), canonicalizedPath);
+    if (NS_FAILED(file->InitWithPath(canonicalizedPath)) ||
+        !mFiles.AppendObject(file))
+      return false;
+  }
+  
+  // Handle the case where the user selected just one file. From msdn: If you
+  // specify OFN_ALLOWMULTISELECT and the user selects only one file the
+  // lpstrFile string does not have a separator between the path and file name.
+  if (current && *current && (current == fileBuffer.get())) {
+    nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
+    NS_ENSURE_TRUE(file, false);
+    
+    nsAutoString canonicalizedPath;
+    GetQualifiedPath(current, canonicalizedPath);
+    if (NS_FAILED(file->InitWithPath(canonicalizedPath)) ||
+        !mFiles.AppendObject(file))
+      return false;
+  }
+
+  return true;
+}
+
 /*
- * Show a file picker.
- *
+ * Show a file picker post Windows XP
+ * 
  * @param aInitialDir   The initial directory, the last used directory will be
  *                      used if left blank.
+ * @param aWasInitError Out parameter will hold true if there was an error
+ *                      before the file picker is shown.
  * @return true if a file was selected successfully.
 */
 bool
-nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
+nsFilePicker::ShowFilePicker(const nsString& aInitialDir, bool &aWasInitError)
 {
   PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
 
@@ -442,15 +902,18 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
     if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC,
                                 IID_IFileOpenDialog,
                                 getter_AddRefs(dialog)))) {
+      aWasInitError = true;
       return false;
     }
   } else {
     if (FAILED(CoCreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_INPROC,
                                 IID_IFileSaveDialog,
                                 getter_AddRefs(dialog)))) {
+      aWasInitError = true;
       return false;
     }
   }
+  aWasInitError = false;
 
   // hook up event callbacks
   dialog->Advise(this, &mFDECookie);
@@ -617,11 +1080,22 @@ nsFilePicker::ShowW(int16_t *aReturnVal)
   // with our context set temporarily to system-dpi-aware
   WinUtils::AutoSystemDpiAware dpiAwareness;
 
-  bool result = false;
+  // 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) {
-    result = ShowFolderPicker(initialDir);
+    if (IsVistaOrLater())
+      result = ShowFolderPicker(initialDir, wasInitError);
+    if (!result && wasInitError)
+      result = ShowXPFolderPicker(initialDir);
   } else {
-    result = ShowFilePicker(initialDir);
+    if (IsVistaOrLater())
+      result = ShowFilePicker(initialDir, wasInitError);
+    if (!result && wasInitError)
+      result = ShowXPFilePicker(initialDir);
   }
 
   // exit, and return returnCancel in aReturnVal
@@ -773,10 +1247,48 @@ nsFilePicker::InitNative(nsIWidget *aParent,
   mTitle.Assign(aTitle);
 }
 
+void 
+nsFilePicker::GetQualifiedPath(const wchar_t *aInPath, nsString &aOutPath)
+{
+  // Prefer a qualified path over a non qualified path.
+  // Things like c:file.txt would be accepted in Win XP but would later
+  // fail to open from the download manager.
+  wchar_t qualifiedFileBuffer[MAX_PATH];
+  if (PathSearchAndQualifyW(aInPath, qualifiedFileBuffer, MAX_PATH)) {
+    aOutPath.Assign(qualifiedFileBuffer);
+  } else {
+    aOutPath.Assign(aInPath);
+  }
+}
+
+void
+nsFilePicker::AppendXPFilter(const nsAString& aTitle, const nsAString& aFilter)
+{
+  mFilterList.Append(aTitle);
+  mFilterList.Append(char16_t('\0'));
+
+  if (aFilter.EqualsLiteral("..apps"))
+    mFilterList.AppendLiteral("*.exe;*.com");
+  else
+  {
+    nsAutoString filter(aFilter);
+    filter.StripWhitespace();
+    if (filter.EqualsLiteral("*"))
+      filter.AppendLiteral(".*");
+    mFilterList.Append(filter);
+  }
+
+  mFilterList.Append(char16_t('\0'));
+}
+
 NS_IMETHODIMP
 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
 {
-  mComFilterList.Append(aTitle, aFilter);
+  if (IsVistaOrLater()) {
+    mComFilterList.Append(aTitle, aFilter);
+  } else {
+    AppendXPFilter(aTitle, aFilter);
+  }
   return NS_OK;
 }
 
diff --git a/widget/windows/nsFilePicker.h b/widget/windows/nsFilePicker.h
index 740f07a7d..90d8c15bc 100644
--- a/widget/windows/nsFilePicker.h
+++ b/widget/windows/nsFilePicker.h
@@ -9,6 +9,17 @@
 
 #include <windows.h>
 
+// For Vista IFileDialog interfaces which aren't exposed
+// unless _WIN32_WINNT >= _WIN32_WINNT_LONGHORN.
+#if _WIN32_WINNT < _WIN32_WINNT_LONGHORN
+#define _WIN32_WINNT_bak _WIN32_WINNT
+#undef _WIN32_WINNT
+#define _WIN32_WINNT _WIN32_WINNT_LONGHORN
+#define _WIN32_IE_bak _WIN32_IE
+#undef _WIN32_IE
+#define _WIN32_IE _WIN32_IE_IE70
+#endif
+
 #include "nsIFile.h"
 #include "nsITimer.h"
 #include "nsISimpleEnumerator.h"
@@ -76,19 +87,32 @@ public:
   HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *pfd, IShellItem *psi, FDE_OVERWRITE_RESPONSE *pResponse);
 
 protected:
+  enum PickerType {
+    PICKER_TYPE_OPEN,
+    PICKER_TYPE_SAVE,
+  };
+
   /* method from nsBaseFilePicker */
   virtual void InitNative(nsIWidget *aParent,
                           const nsAString& aTitle);
+  static void GetQualifiedPath(const wchar_t *aInPath, nsString &aOutPath);
   void GetFilterListArray(nsString& aFilterList);
-  bool ShowFolderPicker(const nsString& aInitialDir);
-  bool ShowFilePicker(const nsString& aInitialDir);
+  static bool GetFileNameWrapper(OPENFILENAMEW* ofn, PickerType aType);
+  bool FilePickerWrapper(OPENFILENAMEW* ofn, PickerType aType);
+  bool ShowXPFolderPicker(const nsString& aInitialDir);
+  bool ShowXPFilePicker(const nsString& aInitialDir);
+  bool ShowFolderPicker(const nsString& aInitialDir, bool &aWasInitError);
+  bool ShowFilePicker(const nsString& aInitialDir, bool &aWasInitError);
+  void AppendXPFilter(const nsAString& aTitle, const nsAString& aFilter);
   void RememberLastUsedDirectory();
   bool IsPrivacyModeEnabled();
   bool IsDefaultPathLink();
   bool IsDefaultPathHtml();
   void SetDialogHandle(HWND aWnd);
-  bool ClosePickerIfNeeded();
+  bool ClosePickerIfNeeded(bool aIsXPDialog);
   static void PickerCallbackTimerFunc(nsITimer *aTimer, void *aPicker);
+  static UINT_PTR CALLBACK MultiFilePickerHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+  static UINT_PTR CALLBACK FilePickerHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
   nsCOMPtr<nsILoadContext> mLoadContext;
   nsCOMPtr<nsIWidget>    mParentWidget;
@@ -130,4 +154,11 @@ protected:
   DWORD                  mFDECookie;
 };
 
+#if defined(_WIN32_WINNT_bak)
+#undef _WIN32_WINNT
+#define _WIN32_WINNT _WIN32_WINNT_bak
+#undef _WIN32_IE
+#define _WIN32_IE _WIN32_IE_bak
+#endif
+
 #endif // nsFilePicker_h__
diff --git a/widget/windows/nsLookAndFeel.cpp b/widget/windows/nsLookAndFeel.cpp
index 06eee3771..e649802b1 100644
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -32,8 +32,12 @@ nsLookAndFeel::GetOperatingSystemVersion()
     version = eOperatingSystemVersion_Windows10;
   } else if (IsWin8OrLater()) {
     version = eOperatingSystemVersion_Windows8;
-  } else {
+  } else if (IsWin7OrLater()) {
     version = eOperatingSystemVersion_Windows7;
+  } else if (IsVistaOrLater()) {
+    version = eOperatingSystemVersion_WindowsVista;
+  } else {
+    version = eOperatingSystemVersion_WindowsXP;
   }
 
   return version;
@@ -179,7 +183,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
       idx = COLOR_HIGHLIGHT;
       break;
     case eColorID__moz_menubarhovertext:
-      if (!IsAppThemed()) {
+      if (!IsVistaOrLater() || !IsAppThemed())
+      {
         idx = nsUXThemeData::sFlatMenus ?
                 COLOR_HIGHLIGHTTEXT :
                 COLOR_MENUTEXT;
@@ -187,7 +192,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
       }
       // Fall through
     case eColorID__moz_menuhovertext:
-      if (IsAppThemed()) {
+      if (IsVistaOrLater() && IsAppThemed())
+      {
         res = ::GetColorFromTheme(eUXMenu,
                                   MENU_POPUPITEM, MPI_HOT, TMT_TEXTCOLOR, aColor);
         if (NS_SUCCEEDED(res))
@@ -279,7 +285,7 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
       aColor = NS_RGB(0, 0, 0);
       return NS_OK;
     case eColorID__moz_win_mediatext:
-      if (IsAppThemed()) {
+      if (IsVistaOrLater() && IsAppThemed()) {
         res = ::GetColorFromTheme(eUXMediaToolbar,
                                   TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
         if (NS_SUCCEEDED(res))
@@ -289,7 +295,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
       idx = COLOR_WINDOWTEXT;
       break;
     case eColorID__moz_win_communicationstext:
-      if (IsAppThemed()) {
+      if (IsVistaOrLater() && IsAppThemed())
+      {
         res = ::GetColorFromTheme(eUXCommunicationsToolbar,
                                   TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
         if (NS_SUCCEEDED(res))
diff --git a/widget/windows/nsLookAndFeel.h b/widget/windows/nsLookAndFeel.h
index a77808322..6200541f5 100644
--- a/widget/windows/nsLookAndFeel.h
+++ b/widget/windows/nsLookAndFeel.h
@@ -5,7 +5,6 @@
 
 #ifndef __nsLookAndFeel
 #define __nsLookAndFeel
-
 #include "nsXPLookAndFeel.h"
 #include "nsIWindowsRegKey.h"
 
@@ -29,6 +28,18 @@
 #ifndef SM_SYSTEMDOCKED
 #define SM_CONVERTIBLESLATEMODE 0x00002003
 #define SM_SYSTEMDOCKED         0x00002004
+typedef enum _AR_STATE
+{
+  AR_ENABLED        = 0x0,
+  AR_DISABLED       = 0x1,
+  AR_SUPPRESSED     = 0x2,
+  AR_REMOTESESSION  = 0x4,
+  AR_MULTIMON       = 0x8,
+  AR_NOSENSOR       = 0x10,
+  AR_NOT_SUPPORTED  = 0x20,
+  AR_DOCKED         = 0x40,
+  AR_LAPTOP         = 0x80
+} AR_STATE, *PAR_STATE;
 #endif
 
 class nsLookAndFeel: public nsXPLookAndFeel {
diff --git a/widget/windows/nsNativeThemeWin.cpp b/widget/windows/nsNativeThemeWin.cpp
index 8950dcf90..4ff6b0af9 100644
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -39,6 +39,7 @@
 #include "nsUXThemeConstants.h"
 #include <algorithm>
 
+using mozilla::IsVistaOrLater;
 using namespace mozilla;
 using namespace mozilla::widget;
 
@@ -300,6 +301,10 @@ DrawThemeBGRTLAware(HANDLE aTheme, HDC aHdc, int aPart, int aState,
  *  aero basic max          0        2        1        2
  *  aero basic close        1        2        1        2
  *
+ *  xp theme min            0        2        0        2
+ *  xp theme max            0        2        1        2
+ *  xp theme close          1        2        2        2
+ *
  *  'cold' button padding - generic button padding, should
  *  be handled in css.
  *                       left      top    right   bottom
@@ -310,11 +315,16 @@ DrawThemeBGRTLAware(HANDLE aTheme, HDC aHdc, int aPart, int aState,
  *  aero basic min          0        0        1        0
  *  aero basic max          1        0        0        0
  *  aero basic close        0        0        0        0
+ *
+ *  xp theme min            0        0        1        0
+ *  xp theme max            1        0        0        0
+ *  xp theme close          0        0        0        0
  */
 
 enum CaptionDesktopTheme {
   CAPTION_CLASSIC = 0,
   CAPTION_BASIC,
+  CAPTION_XPTHEME,
 };
 
 enum CaptionButton {
@@ -348,6 +358,8 @@ AddPaddingRect(LayoutDeviceIntSize* aSize, CaptionButton button) {
   RECT offset;
   if (!IsAppThemed())
     offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
+  else if (!IsVistaOrLater())
+    offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
   else
     offset = buttonData[CAPTION_BASIC].hotPadding[button];
   aSize->width += offset.left + offset.right;
@@ -361,6 +373,8 @@ OffsetBackgroundRect(RECT& rect, CaptionButton button) {
   RECT offset;
   if (!IsAppThemed())
     offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
+  else if (!IsVistaOrLater())
+    offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
   else
     offset = buttonData[CAPTION_BASIC].hotPadding[button];
   rect.left += offset.left;
@@ -405,7 +419,9 @@ OffsetBackgroundRect(RECT& rect, CaptionButton button) {
 static const double kProgressDeterminateTimeSpan = 3.0;
 static const double kProgressIndeterminateTimeSpan = 5.0;
 // The width of the overlay used to animate the horizontal progress bar (Vista and later).
-static const int32_t kProgressHorizontalOverlaySize = 120;
+static const int32_t kProgressHorizontalVistaOverlaySize = 120;
+// The width of the overlay used for the horizontal indeterminate progress bars on XP.
+static const int32_t kProgressHorizontalXPOverlaySize = 55;
 // The height of the overlay used to animate the vertical progress bar (Vista and later).
 static const int32_t kProgressVerticalOverlaySize = 45;
 // The height of the overlay used for the vertical indeterminate progress bar (Vista and later).
@@ -419,8 +435,18 @@ static const int32_t kProgressClassicOverlaySize = 40;
  */
 static int32_t
 GetProgressOverlayStyle(bool aIsVertical)
-{
-  return aIsVertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY;
+{ 
+  if (aIsVertical) {
+    if (IsVistaOrLater()) {
+      return PP_MOVEOVERLAYVERT;
+    }
+    return PP_CHUNKVERT;
+  } else {
+    if (IsVistaOrLater()) {
+      return PP_MOVEOVERLAY;
+    }
+    return PP_CHUNK;
+  }
 }
 
 /*
@@ -431,11 +457,14 @@ GetProgressOverlayStyle(bool aIsVertical)
 static int32_t
 GetProgressOverlaySize(bool aIsVertical, bool aIsIndeterminate)
 {
-  if (aIsVertical) {
-    return aIsIndeterminate ? kProgressVerticalIndeterminateOverlaySize
-                            : kProgressVerticalOverlaySize;
+  if (IsVistaOrLater()) {
+    if (aIsVertical) {
+      return aIsIndeterminate ? kProgressVerticalIndeterminateOverlaySize
+                              : kProgressVerticalOverlaySize;
+    }
+    return kProgressHorizontalVistaOverlaySize;
   }
-  return kProgressHorizontalOverlaySize;
+  return kProgressHorizontalXPOverlaySize;
 }
 
 /*
@@ -524,6 +553,87 @@ nsNativeThemeWin::CalculateProgressOverlayRect(nsIFrame* aFrame,
   return overlayRect;
 }
 
+/*
+ * DrawChunkProgressMeter - renders an xp style chunked progress meter. Called
+ * by DrawProgressMeter.
+ *
+ * @param aTheme       progress theme handle
+ * @param aHdc         hdc returned by gfxWindowsNativeDrawing
+ * @param aPart        the PP_X progress part
+ * @param aState       the theme state
+ * @param aFrame       the elements frame
+ * @param aWidgetRect  bounding rect for the widget
+ * @param aClipRect    dirty rect that needs drawing.
+ * @param aAppUnits    app units per device pixel
+ * @param aIsIndeterm  is an indeterminate progress?
+ * @param aIsVertical  render a vertical progress?
+ * @param aIsRtl       direction is rtl
+ */
+static void
+DrawChunkProgressMeter(HTHEME aTheme, HDC aHdc, int aPart,
+                       int aState, nsIFrame* aFrame, RECT* aWidgetRect,
+                       RECT* aClipRect, gfxFloat aAppUnits, bool aIsIndeterm,
+                       bool aIsVertical, bool aIsRtl)
+{
+  NS_ASSERTION(aTheme, "Bad theme.");
+  NS_ASSERTION(aHdc, "Bad hdc.");
+  NS_ASSERTION(aWidgetRect, "Bad rect.");
+  NS_ASSERTION(aClipRect, "Bad clip rect.");
+  NS_ASSERTION(aFrame, "Bad frame.");
+
+  // For horizontal meters, the theme lib paints the right graphic but doesn't
+  // paint the chunks, so we do that manually. For vertical meters, the theme
+  // library draws everything correctly.
+  if (aIsVertical) {
+    DrawThemeBackground(aTheme, aHdc, aPart, aState, aWidgetRect, aClipRect);
+    return;
+  }
+
+  // query for the proper chunk metrics
+  int chunkSize, spaceSize;
+  if (FAILED(GetThemeMetric(aTheme, aHdc, aPart, aState,
+                            TMT_PROGRESSCHUNKSIZE, &chunkSize)) ||
+      FAILED(GetThemeMetric(aTheme, aHdc, aPart, aState,
+                            TMT_PROGRESSSPACESIZE, &spaceSize))) {
+    DrawThemeBackground(aTheme, aHdc, aPart, aState, aWidgetRect, aClipRect);
+    return;
+  }
+
+  // render chunks
+  if (!aIsRtl || aIsIndeterm) {
+    for (int chunk = aWidgetRect->left; chunk <= aWidgetRect->right;
+         chunk += (chunkSize+spaceSize)) {
+      if (!aIsIndeterm && ((chunk + chunkSize) > aWidgetRect->right)) {
+        // aWidgetRect->right represents the end of the meter. Partial blocks
+        // don't get rendered with one exception, so exit here if we don't have
+        // a full chunk to draw.
+        // The above is true *except* when the meter is at 100% fill, in which
+        // case Windows renders any remaining partial block. Query the parent
+        // frame to find out if we're at 100%.
+        if (!IsProgressMeterFilled(aFrame)) {
+          break;
+        }
+      }
+      RECT bounds =
+        { chunk, aWidgetRect->top, chunk + chunkSize, aWidgetRect->bottom };
+      DrawThemeBackground(aTheme, aHdc, aPart, aState, &bounds, aClipRect);
+    }
+  } else {
+    // rtl needs to grow in the opposite direction to look right.
+    for (int chunk = aWidgetRect->right; chunk >= aWidgetRect->left;
+         chunk -= (chunkSize+spaceSize)) {
+      if ((chunk - chunkSize) < aWidgetRect->left) {
+        if (!IsProgressMeterFilled(aFrame)) {
+          break;
+        }
+      }
+      RECT bounds =
+        { chunk - chunkSize, aWidgetRect->top, chunk, aWidgetRect->bottom };
+      DrawThemeBackground(aTheme, aHdc, aPart, aState, &bounds, aClipRect);
+    }
+  }
+}
+
 /*
  * DrawProgressMeter - render an appropriate progress meter based on progress
  * meter style, orientation, and os. Note, this does not render the underlying
@@ -543,7 +653,8 @@ void
 nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
                                           HANDLE aTheme, HDC aHdc,
                                           int aPart, int aState,
-                                          RECT* aWidgetRect, RECT* aClipRect)
+                                          RECT* aWidgetRect, RECT* aClipRect,
+                                          gfxFloat aAppUnits)
 {
   if (!aFrame || !aTheme || !aHdc)
     return;
@@ -554,6 +665,12 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
   RECT adjWidgetRect, adjClipRect;
   adjWidgetRect = *aWidgetRect;
   adjClipRect = *aClipRect;
+  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) {
@@ -568,13 +685,20 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
   bool indeterminate = IsIndeterminateProgress(parentFrame, eventStates);
   bool animate = indeterminate;
 
-  // 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;
-  }
+  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) {
+    // XP progress meters are 'chunk' style.
+    DrawChunkProgressMeter(aTheme, aHdc, aPart, aState, aFrame,
+                           &adjWidgetRect, &adjClipRect, aAppUnits,
+                           indeterminate, vertical, IsFrameRTL(aFrame));
+  }    
 
   if (animate) {
     // Indeterminate rendering
@@ -582,8 +706,14 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
     RECT overlayRect =
       CalculateProgressOverlayRect(aFrame, &adjWidgetRect, vertical,
                                    indeterminate, false);
-    DrawThemeBackground(aTheme, aHdc, overlayPart, aState, &overlayRect,
-                        &adjClipRect);
+    if (IsVistaOrLater()) {
+      DrawThemeBackground(aTheme, aHdc, overlayPart, aState, &overlayRect,
+                          &adjClipRect);
+    } else {
+      DrawChunkProgressMeter(aTheme, aHdc, overlayPart, aState, aFrame,
+                             &overlayRect, &adjClipRect, aAppUnits,
+                             indeterminate, vertical, IsFrameRTL(aFrame));
+    }
 
     if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 60)) {
       NS_WARNING("unable to animate progress widget!");
@@ -594,6 +724,15 @@ nsNativeThemeWin::DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
 HANDLE
 nsNativeThemeWin::GetTheme(uint8_t aWidgetType)
 { 
+  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_MENULIST)
+      aWidgetType = NS_THEME_TEXTFIELD;
+  }
+
   switch (aWidgetType) {
     case NS_THEME_BUTTON:
     case NS_THEME_RADIO:
@@ -606,7 +745,9 @@ nsNativeThemeWin::GetTheme(uint8_t aWidgetType)
     case NS_THEME_FOCUS_OUTLINE:
       return nsUXThemeData::GetTheme(eUXEdit);
     case NS_THEME_TOOLTIP:
-      return nsUXThemeData::GetTheme(eUXTooltip);
+      // XP/2K3 should force a classic treatment of tooltips
+      return !IsVistaOrLater() ?
+        nullptr : nsUXThemeData::GetTheme(eUXTooltip);
     case NS_THEME_TOOLBOX:
       return nsUXThemeData::GetTheme(eUXRebar);
     case NS_THEME_WIN_MEDIA_TOOLBOX:
@@ -733,6 +874,12 @@ nsresult
 nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, 
                                        int32_t& aPart, int32_t& aState)
 {
+  if (!IsVistaOrLater()) {
+    // See GetTheme
+    if (aWidgetType == NS_THEME_MENULIST)
+      aWidgetType = NS_THEME_TEXTFIELD;
+  }
+
   switch (aWidgetType) {
     case NS_THEME_BUTTON: {
       aPart = BP_BUTTON;
@@ -805,43 +952,63 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
     case NS_THEME_TEXTFIELD_MULTILINE: {
       EventStates eventState = GetContentState(aFrame, aWidgetType);
 
-      /* 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.
-       */
-      aPart = TFP_EDITBORDER_NOSCROLL;
+      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.
+         */
+        aPart = TFP_EDITBORDER_NOSCROLL;
 
-      if (!aFrame) {
-        aState = TFS_EDITBORDER_NORMAL;
-      } else if (IsDisabled(aFrame, eventState)) {
-        aState = TFS_EDITBORDER_DISABLED;
-      } else if (IsReadOnly(aFrame)) {
-        /* no special read-only state */
-        aState = TFS_EDITBORDER_NORMAL;
-      } else {
-        nsIContent* content = aFrame->GetContent();
+        if (!aFrame) {
+          aState = TFS_EDITBORDER_NORMAL;
+        } else if (IsDisabled(aFrame, eventState)) {
+          aState = TFS_EDITBORDER_DISABLED;
+        } else if (IsReadOnly(aFrame)) {
+          /* no special read-only state */
+          aState = TFS_EDITBORDER_NORMAL;
+        } else {
+          nsIContent* content = aFrame->GetContent();
 
-        /* XUL textboxes don't get focused themselves, because they have child
-         * html:input.. but we can check the XUL focused attributes on them
-         */
-        if (content && content->IsXULElement() && IsFocused(aFrame))
-          aState = TFS_EDITBORDER_FOCUSED;
-        else if (eventState.HasAtLeastOneOfStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS))
-          aState = TFS_EDITBORDER_FOCUSED;
-        else if (eventState.HasState(NS_EVENT_STATE_HOVER))
-          aState = TFS_EDITBORDER_HOVER;
+          /* XUL textboxes don't get focused themselves, because they have child
+           * html:input.. but we can check the XUL focused attributes on them
+           */
+          if (content && content->IsXULElement() && IsFocused(aFrame))
+            aState = TFS_EDITBORDER_FOCUSED;
+          else if (eventState.HasAtLeastOneOfStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS))
+            aState = TFS_EDITBORDER_FOCUSED;
+          else if (eventState.HasState(NS_EVENT_STATE_HOVER))
+            aState = TFS_EDITBORDER_HOVER;
+          else
+            aState = TFS_EDITBORDER_NORMAL;
+        }
+      } else {
+        aPart = TFP_TEXTFIELD;
+        
+        if (!aFrame)
+          aState = TS_NORMAL;
+        else if (IsDisabled(aFrame, eventState))
+          aState = TS_DISABLED;
+        else if (IsReadOnly(aFrame))
+          aState = TFS_READONLY;
         else
-          aState = TFS_EDITBORDER_NORMAL;
+          aState = StandardGetState(aFrame, aWidgetType, true);
       }
 
       return NS_OK;
     }
     case NS_THEME_FOCUS_OUTLINE: {
-      // XXX the EDITBORDER values don't respect DTBG_OMITCONTENT
-      aPart = TFP_TEXTFIELD; //TFP_EDITBORDER_NOSCROLL;
-      aState = TS_FOCUSED; //TFS_EDITBORDER_FOCUSED;
+      if (IsVistaOrLater()) {
+        // XXX the EDITBORDER values don't respect DTBG_OMITCONTENT
+        aPart = TFP_TEXTFIELD; //TFP_EDITBORDER_NOSCROLL;
+        aState = TS_FOCUSED; //TFS_EDITBORDER_FOCUSED;
+      } else {
+        aPart = TFP_TEXTFIELD;
+        aState = TS_FOCUSED;
+      }
       return NS_OK;
     }
     case NS_THEME_TOOLTIP: {
@@ -865,9 +1032,11 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
       nsIFrame* parentFrame = aFrame->GetParent();
       if (aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL ||
           IsVerticalProgress(parentFrame)) {
-        aPart = PP_FILLVERT;
+        aPart = IsVistaOrLater() ?
+          PP_FILLVERT : PP_CHUNKVERT;
       } else {
-        aPart = PP_FILL;
+        aPart = IsVistaOrLater() ?
+          PP_FILL : PP_CHUNK;
       }
 
       aState = PBBVS_NORMAL;
@@ -931,7 +1100,8 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
           aState += TS_ACTIVE;
         else if (eventState.HasState(NS_EVENT_STATE_HOVER))
           aState += TS_HOVER;
-        else if (parentState.HasState(NS_EVENT_STATE_HOVER))
+        else if (IsVistaOrLater() &&
+                 parentState.HasState(NS_EVENT_STATE_HOVER))
           aState = (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE;
         else
           aState += TS_NORMAL;
@@ -1034,7 +1204,14 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
     case NS_THEME_SCROLLBAR:
     case NS_THEME_SCROLLBAR_SMALL: {
       aState = 0;
-      aPart = RP_BACKGROUND;
+      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;
     }
     case NS_THEME_TOOLBAR: {
@@ -1159,7 +1336,8 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
         aFrame = parentFrame;
 
       EventStates eventState = GetContentState(aFrame, aWidgetType);
-      aPart = CBP_DROPMARKER_VISTA;
+      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
@@ -1179,25 +1357,28 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
       else
         isOpen = IsOpenButton(aFrame);
 
-      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.
+      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.
+             */
+            aState = TS_HOVER;
+            return NS_OK;
+          }
+        } else {
+          /* On Vista, the dropdown indicator on a menulist button in  
+           * chrome is not given a hover effect. When the frame isn't
+           * isn't HTML content, we cheat and force the dropdown state
+           * to be normal. (Bug 430434)
            */
-          aState = TS_HOVER;
+          aState = TS_NORMAL;
           return NS_OK;
         }
-      } else {
-        /* The dropdown indicator on a menulist button in chrome is not given a
-         * hover effect. When the frame isn't isn't HTML content, we cheat and
-         * force the dropdown state to be normal. (Bug 430434)
-         */
-        aState = TS_NORMAL;
-        return NS_OK;
       }
 
       aState = TS_NORMAL;
@@ -1698,7 +1879,7 @@ RENDER_AGAIN:
   else if (aWidgetType == NS_THEME_PROGRESSCHUNK ||
            aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL) {
     DrawThemedProgressMeter(aFrame, aWidgetType, theme, hdc, part, state,
-                            &widgetRect, &clipRect);
+                            &widgetRect, &clipRect, p2a);
   }
   else if (aWidgetType == NS_THEME_FOCUS_OUTLINE) {
     // Inflate 'widgetRect' with the focus outline size.
@@ -1964,39 +2145,41 @@ nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext,
     return ok;
   }
 
-  if (aWidgetType == NS_THEME_NUMBER_INPUT ||
-      aWidgetType == NS_THEME_TEXTFIELD ||
-      aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
-      aWidgetType == NS_THEME_MENULIST)
-  {
-    // 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;
-  }
+  if (IsVistaOrLater()) {
+    if (aWidgetType == NS_THEME_NUMBER_INPUT ||
+        aWidgetType == NS_THEME_TEXTFIELD ||
+        aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
+        aWidgetType == NS_THEME_MENULIST)
+    {
+      /* 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;
+    }
 
-  /* textfields need extra pixels on all sides, otherwise they wrap their
-   * content too tightly.  The actual border is drawn 1px inside the specified
-   * rectangle, so Gecko will end up making the contents look too small.
-   * Instead, we add 2px padding for the contents and fix this. (Used to be 1px
-   * added, see bug 430212)
-   */
-  if (aWidgetType == NS_THEME_NUMBER_INPUT ||
-      aWidgetType == NS_THEME_TEXTFIELD ||
-      aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
-    aResult->top = aResult->bottom = 2;
-    aResult->left = aResult->right = 2;
-    ScaleForFrameDPI(aResult, aFrame);
-    return ok;
-  } else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_MENULIST) {
-    /* For content menulist controls, we need an extra pixel so that we have
-     * room to draw our focus rectangle stuff. Otherwise, the focus rect might
-     * overlap the control's border.
+    /* textfields need extra pixels on all sides, otherwise they
+     * wrap their content too tightly.  The actual border is drawn 1px
+     * inside the specified rectangle, so Gecko will end up making the
+     * contents look too small.  Instead, we add 2px padding for the
+     * contents and fix this. (Used to be 1px added, see bug 430212)
      */
-    aResult->top = aResult->bottom = 1;
-    aResult->left = aResult->right = 1;
-    ScaleForFrameDPI(aResult, aFrame);
-    return ok;
+    if (aWidgetType == NS_THEME_NUMBER_INPUT ||
+        aWidgetType == NS_THEME_TEXTFIELD ||
+        aWidgetType == NS_THEME_TEXTFIELD_MULTILINE) {
+      aResult->top = aResult->bottom = 2;
+      aResult->left = aResult->right = 2;
+      ScaleForFrameDPI(aResult, aFrame);
+      return ok;
+    } else if (IsHTMLContent(aFrame) && aWidgetType == NS_THEME_MENULIST) {
+      /* For content menulist controls, we need an extra pixel so
+       * that we have room to draw our focus rectangle stuff.
+       * Otherwise, the focus rect might overlap the control's
+       * border.
+       */
+      aResult->top = aResult->bottom = 1;
+      aResult->left = aResult->right = 1;
+      ScaleForFrameDPI(aResult, aFrame);
+      return ok;
+    }
   }
 
   int32_t right, left, top, bottom;
@@ -2061,21 +2244,23 @@ nsNativeThemeWin::GetWidgetOverflow(nsDeviceContext* aContext,
    * a border only shows up if the widget is being hovered.
    */
 #if 0
-  /* 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_MENULIST_BUTTON &&
-      IsHTMLContent(aFrame) &&
-      !IsWidgetStyled(aFrame->GetParent()->PresContext(),
-                      aFrame->GetParent(),
-                      NS_THEME_MENULIST))
-  {
-    int32_t p2a = aContext->AppUnitsPerDevPixel();
-    /* Note: no overflow on the left */
-    nsMargin m(p2a, p2a, p2a, 0);
-    aOverflowRect->Inflate (m);
-    return true;
+  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_MENULIST_BUTTON &&
+        IsHTMLContent(aFrame) &&
+        !IsWidgetStyled(aFrame->GetParent()->PresContext(),
+                        aFrame->GetParent(),
+                        NS_THEME_MENULIST))
+    {
+      int32_t p2a = aContext->AppUnitsPerDevPixel();
+      /* Note: no overflow on the left */
+      nsMargin m(p2a, p2a, p2a, 0);
+      aOverflowRect->Inflate (m);
+      return true;
+    }
   }
 #endif
 
@@ -2199,18 +2384,22 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
     case NS_THEME_SCALETHUMB_VERTICAL:
     {
       *aIsOverridable = false;
-      // On Vista, GetThemePartAndState returns odd values for
+      // on Vista, GetThemePartAndState returns odd values for
       // scale thumbs, so use a hardcoded size instead.
-      if (aWidgetType == NS_THEME_SCALETHUMB_HORIZONTAL ||
-          (aWidgetType == NS_THEME_RANGE_THUMB && IsRangeHorizontal(aFrame))) {
-        aResult->width = 12;
-        aResult->height = 20;
-      } else {
-        aResult->width = 20;
-        aResult->height = 12;
+      if (IsVistaOrLater()) {
+        if (aWidgetType == NS_THEME_SCALETHUMB_HORIZONTAL ||
+            (aWidgetType == NS_THEME_RANGE_THUMB && IsRangeHorizontal(aFrame))) {
+          aResult->width = 12;
+          aResult->height = 20;
+        }
+        else {
+          aResult->width = 20;
+          aResult->height = 12;
+        }
+        ScaleForFrameDPI(aResult, aFrame);
+        return rv;
       }
-      ScaleForFrameDPI(aResult, aFrame);
-      return rv;
+      break;
     }
 
     case NS_THEME_SCROLLBAR:
@@ -2249,6 +2438,11 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
       // 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 (!IsVistaOrLater()) {
+        aResult->width -= 4;
+        aResult->height -= 4;
+      }
       AddPaddingRect(aResult, CAPTIONBUTTON_RESTORE);
       *aIsOverridable = false;
       return rv;
@@ -2256,6 +2450,10 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
     case NS_THEME_WINDOW_BUTTON_MINIMIZE:
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_MINIMIZE].cy;
+      if (!IsVistaOrLater()) {
+        aResult->width -= 4;
+        aResult->height -= 4;
+      }
       AddPaddingRect(aResult, CAPTIONBUTTON_MINIMIZE);
       *aIsOverridable = false;
       return rv;
@@ -2263,6 +2461,10 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
     case NS_THEME_WINDOW_BUTTON_CLOSE:
       aResult->width = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cx;
       aResult->height = nsUXThemeData::sCommandButtons[CMDBUTTONIDX_CLOSE].cy;
+      if (!IsVistaOrLater()) {
+        aResult->width -= 4;
+        aResult->height -= 4;
+      }
       AddPaddingRect(aResult, CAPTIONBUTTON_CLOSE);
       *aIsOverridable = false;
       return rv;
@@ -2392,9 +2594,18 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
     return NS_OK;
   }
 
+  // On Vista, the scrollbar buttons need to change state when the track has/doesn't have hover
+  if (!IsVistaOrLater() &&
+      (aWidgetType == NS_THEME_SCROLLBAR_VERTICAL || 
+      aWidgetType == NS_THEME_SCROLLBAR_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 ((aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_MENULIST_BUTTON) &&
+  if (IsVistaOrLater() &&
+      (aWidgetType == NS_THEME_MENULIST || aWidgetType == NS_THEME_MENULIST_BUTTON) &&
       IsHTMLContent(aFrame))
   {
     *aShouldRepaint = true;
diff --git a/widget/windows/nsNativeThemeWin.h b/widget/windows/nsNativeThemeWin.h
index 32b82b1e1..f20649444 100644
--- a/widget/windows/nsNativeThemeWin.h
+++ b/widget/windows/nsNativeThemeWin.h
@@ -117,7 +117,8 @@ protected:
   void DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType,
                                HANDLE aTheme, HDC aHdc,
                                int aPart, int aState,
-                               RECT* aWidgetRect, RECT* aClipRect);
+                               RECT* aWidgetRect, RECT* aClipRect,
+                               gfxFloat aAppUnits);
 
 private:
   TimeStamp mProgressDeterminateTimeStamp;
diff --git a/widget/windows/nsUXThemeConstants.h b/widget/windows/nsUXThemeConstants.h
index ba7afde82..731dcedf2 100644
--- a/widget/windows/nsUXThemeConstants.h
+++ b/widget/windows/nsUXThemeConstants.h
@@ -67,7 +67,7 @@
 #define SP_GRIPPERHOR      8
 #define SP_GRIPPERVERT     9
 
-// Implicit hover state.
+// Vista only; implict hover state.
 // BASE + 0 = UP, + 1 = DOWN, etc.
 #define SP_BUTTON_IMPLICIT_HOVER_BASE   17
 
diff --git a/widget/windows/nsUXThemeData.cpp b/widget/windows/nsUXThemeData.cpp
index 4d9ac9570..bcbd32484 100644
--- a/widget/windows/nsUXThemeData.cpp
+++ b/widget/windows/nsUXThemeData.cpp
@@ -143,8 +143,10 @@ nsUXThemeData::InitTitlebarInfo()
   sCommandButtons[3].cx = sCommandButtons[0].cx * 3;
   sCommandButtons[3].cy = sCommandButtons[0].cy;
 
-  // Trigger a refresh on the next layout.
-  sTitlebarInfoPopulatedAero = sTitlebarInfoPopulatedThemed = false;
+  // Use system metrics for pre-vista, otherwise trigger a
+  // refresh on the next layout.
+  sTitlebarInfoPopulatedAero = sTitlebarInfoPopulatedThemed =
+    !IsVistaOrLater();
 }
 
 // static
@@ -304,7 +306,7 @@ void
 nsUXThemeData::UpdateNativeThemeInfo()
 {
   // Trigger a refresh of themed button metrics if needed
-  sTitlebarInfoPopulatedThemed = false;
+  sTitlebarInfoPopulatedThemed = !IsVistaOrLater();
 
   sIsDefaultWindowsTheme = false;
   sThemeId = LookAndFeel::eWindowsTheme_Generic;
diff --git a/widget/windows/nsWinGesture.h b/widget/windows/nsWinGesture.h
index fdd1588b6..24c1f6b2d 100644
--- a/widget/windows/nsWinGesture.h
+++ b/widget/windows/nsWinGesture.h
@@ -17,6 +17,155 @@
 #include "mozilla/EventForwards.h"
 #include "mozilla/TouchEvents.h"
 
+// Desktop builds target apis for 502. Win8 Metro builds target 602.
+#if WINVER < 0x0602
+
+DECLARE_HANDLE(HGESTUREINFO);
+
+/*
+ * Gesture flags - GESTUREINFO.dwFlags
+ */
+#define GF_BEGIN                        0x00000001
+#define GF_INERTIA                      0x00000002
+#define GF_END                          0x00000004
+
+/*
+ * Gesture configuration structure
+ *   - Used in SetGestureConfig and GetGestureConfig
+ *   - Note that any setting not included in either GESTURECONFIG.dwWant or
+ *     GESTURECONFIG.dwBlock will use the parent window's preferences or
+ *     system defaults.
+ */
+typedef struct tagGESTURECONFIG {
+    DWORD dwID;                     // gesture ID
+    DWORD dwWant;                   // settings related to gesture ID that are to be turned on
+    DWORD dwBlock;                  // settings related to gesture ID that are to be turned off
+} GESTURECONFIG, *PGESTURECONFIG;
+
+/*
+ * Gesture information structure
+ *   - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the
+ *     GetGestureInfo function to retrieve this information.
+ *   - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE
+ *     message lParam into the GetGestureExtraArgs function to retrieve extended
+ *     argument information.
+ */
+typedef struct tagGESTUREINFO {
+    UINT cbSize;                    // size, in bytes, of this structure (including variable length Args field)
+    DWORD dwFlags;                  // see GF_* flags
+    DWORD dwID;                     // gesture ID, see GID_* defines
+    HWND hwndTarget;                // handle to window targeted by this gesture
+    POINTS ptsLocation;             // current location of this gesture
+    DWORD dwInstanceID;             // internally used
+    DWORD dwSequenceID;             // internally used
+    ULONGLONG ullArguments;         // arguments for gestures whose arguments fit in 8 BYTES
+    UINT cbExtraArgs;               // size, in bytes, of extra arguments, if any, that accompany this gesture
+} GESTUREINFO, *PGESTUREINFO;
+typedef GESTUREINFO const * PCGESTUREINFO;
+
+/*
+ * Gesture notification structure
+ *   - The WM_GESTURENOTIFY message lParam contains a pointer to this structure.
+ *   - The WM_GESTURENOTIFY message notifies a window that gesture recognition is
+ *     in progress and a gesture will be generated if one is recognized under the
+ *     current gesture settings.
+ */
+typedef struct tagGESTURENOTIFYSTRUCT {
+    UINT cbSize;                    // size, in bytes, of this structure
+    DWORD dwFlags;                  // unused
+    HWND hwndTarget;                // handle to window targeted by the gesture
+    POINTS ptsLocation;             // starting location
+    DWORD dwInstanceID;             // internally used
+} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT;
+
+
+/*
+ * Gesture argument helpers
+ *   - Angle should be a double in the range of -2pi to +2pi
+ *   - Argument should be an unsigned 16-bit value
+ */
+#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_)     ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0))
+#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_)   ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265)
+
+/*
+ * Gesture configuration flags
+ */
+#define GC_ALLGESTURES                              0x00000001
+
+#define GC_ZOOM                                     0x00000001
+
+#define GC_PAN                                      0x00000001
+#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY        0x00000002
+#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY      0x00000004
+#define GC_PAN_WITH_GUTTER                          0x00000008
+#define GC_PAN_WITH_INERTIA                         0x00000010
+
+#define GC_ROTATE                                   0x00000001
+
+#define GC_TWOFINGERTAP                             0x00000001
+
+#define GC_PRESSANDTAP                              0x00000001
+
+/*
+ * Gesture IDs
+ */
+#define GID_BEGIN                       1
+#define GID_END                         2
+#define GID_ZOOM                        3
+#define GID_PAN                         4
+#define GID_ROTATE                      5
+#define GID_TWOFINGERTAP                6
+#define GID_PRESSANDTAP                 7
+
+// Maximum number of gestures that can be included
+// in a single call to SetGestureConfig / GetGestureConfig
+#define GESTURECONFIGMAXCOUNT           256
+
+// If specified, GetGestureConfig returns consolidated configuration
+// for the specified window and it's parent window chain
+#define GCF_INCLUDE_ANCESTORS           0x00000001
+
+// Window events we need to respond to or receive
+#define WM_GESTURE                         0x0119
+#define WM_GESTURENOTIFY                   0x011A
+
+typedef struct _TOUCHINPUT {
+  LONG      x;
+  LONG      y;
+  HANDLE    hSource;
+  DWORD     dwID;
+  DWORD     dwFlags;
+  DWORD     dwMask;
+  DWORD     dwTime;
+  ULONG_PTR dwExtraInfo;
+  DWORD     cxContact;
+  DWORD     cyContact;
+} TOUCHINPUT, *PTOUCHINPUT;
+
+typedef HANDLE HTOUCHINPUT;
+
+#define WM_TOUCH 0x0240
+
+#define TOUCHEVENTF_MOVE       0x0001
+#define TOUCHEVENTF_DOWN       0x0002
+#define TOUCHEVENTF_UP         0x0004
+#define TOUCHEVENTF_INRANGE    0x0008
+#define TOUCHEVENTF_PRIMARY    0x0010
+#define TOUCHEVENTF_NOCOALESCE 0x0020
+#define TOUCHEVENTF_PEN        0x0040
+#define TOUCHEVENTF_PALM       0x0080
+
+#define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001
+#define TOUCHINPUTMASKF_EXTRAINFO      0x0002
+#define TOUCHINPUTMASKF_CONTACTAREA    0x0004
+
+#define TOUCH_COORD_TO_PIXEL(C) (C/100)
+
+#define TWF_FINETOUCH          0x0001
+#define TWF_WANTPALM           0x0002
+
+#endif // WINVER < 0x0602
+
 // WM_TABLET_QUERYSYSTEMGESTURESTATUS return values
 #define TABLET_ROTATE_GESTURE_ENABLE    0x02000000
 
@@ -56,7 +205,7 @@ public:
   bool GetTouchInputInfo(HTOUCHINPUT hTouchInput, uint32_t cInputs, PTOUCHINPUT pInputs);
   bool CloseTouchInputHandle(HTOUCHINPUT hTouchInput);
   bool IsAvailable();
-
+  
   // Simple gesture process
   bool ProcessGestureMessage(HWND hWnd, WPARAM wParam, LPARAM lParam, mozilla::WidgetSimpleGestureEvent& evt);
 
@@ -67,7 +216,7 @@ public:
   void UpdatePanFeedbackX(HWND hWnd, int32_t scrollOverflow, bool& endFeedback);
   void UpdatePanFeedbackY(HWND hWnd, int32_t scrollOverflow, bool& endFeedback);
   void PanFeedbackFinalize(HWND hWnd, bool endFeedback);
-
+  
 public:
   // Helpers
   bool GetGestureInfo(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo);
@@ -135,3 +284,5 @@ private:
 };
 
 #endif /* WinGesture_h__ */
+
+
diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp
index b2bb59bd3..a8923f78e 100644
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -266,7 +266,8 @@ LONG            nsWindow::sLastMouseDownTime      = 0L;
 LONG            nsWindow::sLastClickCount         = 0L;
 BYTE            nsWindow::sLastMouseButton        = 0;
 
-bool            nsWindow::sHaveInitializedPrefs   = false;
+// Trim heap on minimize. (initialized, but still true.)
+int             nsWindow::sTrimOnMinimize         = 2;
 
 TriStateBool nsWindow::sHasBogusPopupsDropShadowOnMultiMonitor = TRI_UNKNOWN;
 
@@ -782,7 +783,7 @@ nsWindow::Create(nsIWidget* aParent,
       parent = nullptr;
     }
 
-    if (!IsWin8OrLater() &&
+    if (IsVistaOrLater() && !IsWin8OrLater() &&
         HasBogusPopupsDropShadowOnMultiMonitor()) {
       extendedStyle |= WS_EX_COMPOSITED;
     }
@@ -907,13 +908,20 @@ nsWindow::Create(nsIWidget* aParent,
   mDefaultIMC.Init(this);
   IMEHandler::InitInputContext(this, mInputContext);
 
-  // Do some initialization work, but only if (a) it hasn't already been done,
-  // and (b) this is the hidden window (which is conveniently created before
-  // any visible windows but after the profile has been initialized).
-  if (!sHaveInitializedPrefs && mWindowType == eWindowType_invisible) {
+  // If the internal variable set by the config.trim_on_minimize pref has not
+  // been initialized, and if this is the hidden window (conveniently created
+  // before any visible windows, and after the profile has been initialized),
+  // 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",
+        IsVistaOrLater() ? 1 : 0);
     sSwitchKeyboardLayout =
       Preferences::GetBool("intl.keyboard.per_window_layout", false);
-    sHaveInitializedPrefs = true;
   }
 
   // Query for command button metric data for rendering the titlebar. We
@@ -1639,10 +1647,9 @@ bool nsWindow::IsVisible() const
 
 // 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.
-// XXX this is apparently still needed in Windows 7 and later
 void nsWindow::ClearThemeRegion()
 {
-  if (!HasGlass() &&
+  if (IsVistaOrLater() && !HasGlass() &&
       (mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
        (mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
     SetWindowRgn(mWnd, nullptr, false);
@@ -1656,7 +1663,7 @@ void nsWindow::SetThemeRegion()
   // 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 (!HasGlass() &&
+  if (IsVistaOrLater() && !HasGlass() &&
       (mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
        (mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
     HRGN hRgn = nullptr;
@@ -2073,7 +2080,13 @@ nsWindow::SetSizeMode(nsSizeMode aMode)
         break;
 
       case nsSizeMode_Minimized :
-        mode = SW_MINIMIZE;
+        // Using SW_SHOWMINIMIZED prevents the working set from being trimmed but
+        // keeps the window active in the tray. So after the window is minimized,
+        // windows will fire WM_WINDOWPOSCHANGED (OnWindowPosChanged) at which point
+        // we will do some additional processing to get the active window set right.
+        // If sTrimOnMinimize is set, we let windows handle minimization normally
+        // using SW_MINIMIZE.
+        mode = sTrimOnMinimize ? SW_MINIMIZE : SW_SHOWMINIMIZED;
         break;
 
       default :
@@ -5815,6 +5828,12 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
     case WM_SYSCOMMAND:
     {
       WPARAM filteredWParam = (wParam &0xFFF0);
+      // prevent Windows from trimming the working set. bug 76831
+      if (!sTrimOnMinimize && filteredWParam == SC_MINIMIZE) {
+        ::ShowWindow(mWnd, SW_SHOWMINIMIZED);
+        result = true;
+      }
+
       if (mSizeMode == nsSizeMode_Fullscreen &&
           filteredWParam == SC_RESTORE &&
           GetCurrentShowCmd(mWnd) != SW_SHOWMINIMIZED) {
@@ -6432,6 +6451,14 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp)
     else
       mSizeMode = nsSizeMode_Normal;
 
+    // If !sTrimOnMinimize, we minimize windows using SW_SHOWMINIMIZED (See
+    // SetSizeMode for internal calls, and WM_SYSCOMMAND for external). This
+    // prevents the working set from being trimmed but keeps the window active.
+    // After the window is minimized, we need to do some touch up work on the
+    // active window. (bugs 76831 & 499816)
+    if (!sTrimOnMinimize && nsSizeMode_Minimized == mSizeMode)
+      ActivateOtherWindowHelper(mWnd);
+
 #ifdef WINSTATE_DEBUG_OUTPUT
     switch (mSizeMode) {
       case nsSizeMode_Normal:
@@ -6552,6 +6579,31 @@ void nsWindow::OnWindowPosChanged(WINDOWPOS* wp)
   }
 }
 
+// static
+void nsWindow::ActivateOtherWindowHelper(HWND aWnd)
+{
+  // Find the next window that is enabled, visible, and not minimized.
+  HWND hwndBelow = ::GetNextWindow(aWnd, GW_HWNDNEXT);
+  while (hwndBelow && (!::IsWindowEnabled(hwndBelow) || !::IsWindowVisible(hwndBelow) ||
+                       ::IsIconic(hwndBelow))) {
+    hwndBelow = ::GetNextWindow(hwndBelow, GW_HWNDNEXT);
+  }
+
+  // Push ourselves to the bottom of the stack, then activate the
+  // next window.
+  ::SetWindowPos(aWnd, HWND_BOTTOM, 0, 0, 0, 0,
+                 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+  if (hwndBelow)
+    ::SetForegroundWindow(hwndBelow);
+
+  // Play the minimize sound while we're here, since that is also
+  // forgotten when we use SW_SHOWMINIMIZED.
+  nsCOMPtr<nsISound> sound(do_CreateInstance("@mozilla.org/sound;1"));
+  if (sound) {
+    sound->PlaySystemSound(NS_LITERAL_STRING("Minimize"));
+  }
+}
+
 void nsWindow::OnWindowPosChanging(LPWINDOWPOS& info)
 {
   // Update non-client margins if the frame size is changing, and let the
diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h
index 199500e9c..248978bd7 100644
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -486,6 +486,7 @@ protected:
                                               bool aIntersectWithExisting) override;
   nsIntRegion             GetRegionToPaint(bool aForceFullRepaint,
                                            PAINTSTRUCT ps, HDC aDC);
+  static void             ActivateOtherWindowHelper(HWND aWnd);
   void                    ClearCachedResources();
   nsIWidgetListener*      GetPaintListener();
 
@@ -551,7 +552,7 @@ protected:
   static bool           sJustGotDeactivate;
   static bool           sJustGotActivate;
   static bool           sIsInMouseCapture;
-  static bool           sHaveInitializedPrefs;
+  static int            sTrimOnMinimize;
 
   // Always use the helper method to read this property.  See bug 603793.
   static TriStateBool   sHasBogusPopupsDropShadowOnMultiMonitor;
diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp
index 6ead5cdc7..c72ea48d7 100644
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -111,6 +111,7 @@ extern nsresult nsStringInputStreamConstructor(nsISupports*, REFNSIID, void**);
 #include "SpecialSystemDirectory.h"
 
 #if defined(XP_WIN)
+#include "mozilla/WindowsVersion.h"
 #include "nsWindowsRegKey.h"
 #endif
 
@@ -583,6 +584,8 @@ NS_InitXPCOM2(nsIServiceManager** aResult,
 
   NS_StartupLocalFile();
 
+  StartupSpecialSystemDirectory();
+
   nsDirectoryService::RealInit();
 
   bool value;
diff --git a/xpcom/glue/nsThreadUtils.cpp b/xpcom/glue/nsThreadUtils.cpp
index 2f2383fd8..287ada7be 100644
--- a/xpcom/glue/nsThreadUtils.cpp
+++ b/xpcom/glue/nsThreadUtils.cpp
@@ -20,10 +20,15 @@
 
 #ifdef XP_WIN
 #include <windows.h>
+#include "mozilla/WindowsVersion.h"
+using mozilla::IsVistaOrLater;
 #elif defined(XP_MACOSX)
 #include <sys/resource.h>
 #endif
 
+#include <pratom.h>
+#include <prthread.h>
+
 using namespace mozilla;
 
 #ifndef XPCOM_GLUE_AVOID_NSPR
@@ -438,7 +443,8 @@ nsThreadPoolNaming::SetThreadPoolName(const nsACString& aPoolName,
 nsAutoLowPriorityIO::nsAutoLowPriorityIO()
 {
 #if defined(XP_WIN)
-  lowIOPrioritySet = SetThreadPriority(GetCurrentThread(),
+  lowIOPrioritySet = IsVistaOrLater() &&
+                     SetThreadPriority(GetCurrentThread(),
                                        THREAD_MODE_BACKGROUND_BEGIN);
 #elif defined(XP_MACOSX)
   oldPriority = getiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD);
diff --git a/xpcom/io/SpecialSystemDirectory.cpp b/xpcom/io/SpecialSystemDirectory.cpp
index ab65d38f9..9ce8eb85b 100644
--- a/xpcom/io/SpecialSystemDirectory.cpp
+++ b/xpcom/io/SpecialSystemDirectory.cpp
@@ -12,6 +12,7 @@
 #if defined(XP_WIN)
 
 #include <windows.h>
+#include <shlobj.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -19,6 +20,9 @@
 #include <shlobj.h>
 #include <knownfolders.h>
 #include <guiddef.h>
+#include "mozilla/WindowsVersion.h"
+
+using mozilla::IsWin7OrLater;
 
 #elif defined(XP_UNIX)
 
@@ -47,17 +51,40 @@
 #endif
 #endif
 
+#ifdef XP_WIN
+typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
+                                               DWORD dwFlags,
+                                               HANDLE hToken,
+                                               PWSTR* ppszPath);
+
+static nsGetKnownFolderPath gGetKnownFolderPath = nullptr;
+#endif
+
+void
+StartupSpecialSystemDirectory()
+{
+#if defined (XP_WIN)
+  // SHGetKnownFolderPath is only available on Windows Vista
+  // so that we need to use GetProcAddress to get the pointer.
+  HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll");
+  if (hShell32DLLInst) {
+    gGetKnownFolderPath = (nsGetKnownFolderPath)
+      GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath");
+  }
+#endif
+}
+
 #if defined (XP_WIN)
 
 static nsresult
 GetKnownFolder(GUID* aGuid, nsIFile** aFile)
 {
-  if (!aGuid) {
+  if (!aGuid || !gGetKnownFolderPath) {
     return NS_ERROR_FAILURE;
   }
 
   PWSTR path = nullptr;
-  SHGetKnownFolderPath(*aGuid, 0, nullptr, &path);
+  gGetKnownFolderPath(*aGuid, 0, nullptr, &path);
 
   if (!path) {
     return NS_ERROR_FAILURE;
@@ -112,13 +139,19 @@ SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode,
 }
 
 /*
- * Return the default save-to location for the Windows Library passed in
- * through aFolderId.
+ * Check to see if we're on Win7 and up, and if so, returns the default
+ * save-to location for the Windows Library passed in through aFolderId.
+ * Otherwise falls back on pre-win7 GetWindowsFolder.
  */
 static nsresult
 GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
                      nsIFile** aFile)
 {
+  // Skip off checking for library support if the os is Vista or lower.
+  if (!IsWin7OrLater()) {
+    return GetWindowsFolder(aFallbackFolderId, aFile);
+  }
+
   RefPtr<IShellLibrary> shellLib;
   RefPtr<IShellItem> savePath;
   HRESULT hr =
@@ -707,6 +740,8 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
     }
 #if defined(MOZ_CONTENT_SANDBOX)
     case Win_LocalAppdataLow: {
+      // This should only really fail on versions pre-Vista, in which case this
+      // shouldn't have been used in the first place.
       GUID localAppDataLowGuid = FOLDERID_LocalAppDataLow;
       return GetKnownFolder(&localAppDataLowGuid, aFile);
     }
diff --git a/xpcom/io/SpecialSystemDirectory.h b/xpcom/io/SpecialSystemDirectory.h
index 7c7f8fa42..dd3d88379 100644
--- a/xpcom/io/SpecialSystemDirectory.h
+++ b/xpcom/io/SpecialSystemDirectory.h
@@ -16,6 +16,9 @@
 #include "prenv.h"
 #endif
 
+extern void StartupSpecialSystemDirectory();
+
+
 enum SystemDirectories {
   OS_DriveDirectory         =   1,
   OS_TemporaryDirectory     =   2,
diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp
index 66e267807..3a7e570f5 100644
--- a/xpcom/io/nsLocalFileWin.cpp
+++ b/xpcom/io/nsLocalFileWin.cpp
@@ -7,6 +7,7 @@
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/UniquePtrExtensions.h"
+#include "mozilla/WindowsVersion.h"
 
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
@@ -1969,11 +1970,13 @@ nsLocalFile::CopySingleFile(nsIFile* aSourceFile, nsIFile* aDestParent,
   // So we only use COPY_FILE_NO_BUFFERING when we have a remote drive.
   int copyOK;
   DWORD dwCopyFlags = COPY_FILE_ALLOW_DECRYPTED_DESTINATION;
-  bool path1Remote, path2Remote;
-  if (!IsRemoteFilePath(filePath.get(), path1Remote) ||
-      !IsRemoteFilePath(destPath.get(), path2Remote) ||
-      path1Remote || path2Remote) {
-    dwCopyFlags |= COPY_FILE_NO_BUFFERING;
+  if (IsVistaOrLater()) {
+    bool path1Remote, path2Remote;
+    if (!IsRemoteFilePath(filePath.get(), path1Remote) ||
+        !IsRemoteFilePath(destPath.get(), path2Remote) ||
+        path1Remote || path2Remote) {
+      dwCopyFlags |= COPY_FILE_NO_BUFFERING;
+    }
   }
 
   if (!move) {
