Bug 1418131: Part 1 - Add Windows Security Center info to nsSystemInfo; r=erahm,jimm
☠☠ backed out by 4ad0761df5db ☠ ☠
authorAaron Klotz <aklotz@mozilla.com>
Thu, 16 Nov 2017 17:59:51 -0700
changeset 399372 a0cf39ae0b3d4db3bf77e0b669258e7393288079
parent 399371 196006c746bde8b894252ec1310a4b5124e04c14
child 399373 a287c5db8be683855745e4367c801f057b842859
push id33261
push userapavel@mozilla.com
push dateTue, 16 Jan 2018 09:49:20 +0000
treeherdermozilla-central@a6004a75d2d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm, jimm
bugs1418131
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1418131: Part 1 - Add Windows Security Center info to nsSystemInfo; r=erahm,jimm MozReview-Commit-ID: 7XUAIesDpRu
xpcom/base/moz.build
xpcom/base/nsSystemInfo.cpp
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -84,16 +84,20 @@ EXPORTS += [
     'nsWeakPtr.h',
     'nsWeakReference.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS += [
         'nsWindowsHelpers.h',
     ]
+    if CONFIG['CC_TYPE'] != 'gcc':
+        OS_LIBS += [
+            'wscapi',
+        ]
 
 EXPORTS.mozilla += [
     'AutoRestore.h',
     'AvailableMemoryTracker.h',
     'ClearOnShutdown.h',
     'CountingAllocatorBase.h',
     'CycleCollectedJSContext.h',
     'CycleCollectedJSRuntime.h',
--- a/xpcom/base/nsSystemInfo.cpp
+++ b/xpcom/base/nsSystemInfo.cpp
@@ -9,25 +9,33 @@
 #include "nsSystemInfo.h"
 #include "prsystem.h"
 #include "prio.h"
 #include "mozilla/SSE.h"
 #include "mozilla/arm.h"
 #include "mozilla/Sprintf.h"
 
 #ifdef XP_WIN
+#include <comutil.h>
 #include <time.h>
+#ifndef __MINGW32__
+#include <iwscapi.h>
+#endif // __MINGW32__
 #include <windows.h>
 #include <winioctl.h>
+#ifndef __MINGW32__
+#include <wscapi.h>
+#endif // __MINGW32__
 #include "base/scoped_handle_win.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsIObserverService.h"
 #include "nsWindowsHelpers.h"
+
 #endif
 
 #ifdef XP_MACOSX
 #include "MacHelpers.h"
 #endif
 
 #ifdef MOZ_WIDGET_GTK
 #include <gtk/gtk.h>
@@ -230,16 +238,118 @@ nsresult GetCountryCode(nsAString& aCoun
   }
 
   // numChars includes null terminator
   aCountryCode.Truncate(numChars - 1);
   return NS_OK;
 }
 
 } // namespace
+
+#ifndef __MINGW32__
+
+static HRESULT
+EnumWSCProductList(nsAString& aOutput, NotNull<IWSCProductList*> aProdList)
+{
+  MOZ_ASSERT(aOutput.IsEmpty());
+
+  LONG count;
+  HRESULT hr = aProdList->get_Count(&count);
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  for (LONG index = 0; index < count; ++index) {
+    RefPtr<IWscProduct> product;
+    hr = aProdList->get_Item(index, getter_AddRefs(product));
+    if (FAILED(hr)) {
+      return hr;
+    }
+
+    WSC_SECURITY_PRODUCT_STATE state;
+    hr = product->get_ProductState(&state);
+    if (FAILED(hr)) {
+      return hr;
+    }
+
+    // We only care about products that are active
+    if (state == WSC_SECURITY_PRODUCT_STATE_OFF ||
+        state == WSC_SECURITY_PRODUCT_STATE_SNOOZED) {
+      continue;
+    }
+
+    _bstr_t bName;
+    hr = product->get_ProductName(bName.GetAddress());
+    if (FAILED(hr)) {
+      return hr;
+    }
+
+    if (!aOutput.IsEmpty()) {
+      aOutput.AppendLiteral(u";");
+    }
+
+    aOutput.Append((wchar_t*)bName, bName.length());
+  }
+
+  return S_OK;
+}
+
+static nsresult
+GetWindowsSecurityCenterInfo(nsAString& aAVInfo, nsAString& aAntiSpyInfo,
+                             nsAString& aFirewallInfo)
+{
+  aAVInfo.Truncate();
+  aAntiSpyInfo.Truncate();
+  aFirewallInfo.Truncate();
+
+  if (!XRE_IsParentProcess()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  const CLSID clsid = __uuidof(WSCProductList);
+  const IID iid = __uuidof(IWSCProductList);
+
+  // NB: A separate instance of IWSCProductList is needed for each distinct
+  // security provider type; MSDN says that we cannot reuse the same object
+  // and call Initialize() to pave over the previous data.
+
+  WSC_SECURITY_PROVIDER providerTypes[] = { WSC_SECURITY_PROVIDER_ANTIVIRUS,
+                                            WSC_SECURITY_PROVIDER_ANTISPYWARE,
+                                            WSC_SECURITY_PROVIDER_FIREWALL };
+
+  // Each output must match the corresponding entry in providerTypes.
+  nsAString* outputs[] = { &aAVInfo, &aAntiSpyInfo, &aFirewallInfo };
+
+  static_assert(ArrayLength(providerTypes) == ArrayLength(outputs),
+                "Length of providerTypes and outputs arrays must match");
+
+  for (uint32_t index = 0; index < ArrayLength(providerTypes); ++index) {
+    RefPtr<IWSCProductList> prodList;
+    HRESULT hr = ::CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, iid,
+                                    getter_AddRefs(prodList));
+    if (FAILED(hr)) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
+
+    hr = prodList->Initialize(providerTypes[index]);
+    if (FAILED(hr)) {
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    hr = EnumWSCProductList(*outputs[index], WrapNotNull(prodList.get()));
+    if (FAILED(hr)) {
+      return NS_ERROR_UNEXPECTED;
+    }
+  }
+
+  return NS_OK;
+}
+
+#endif // __MINGW32__
+
 #endif // defined(XP_WIN)
 
 #ifdef XP_MACOSX
 static nsresult GetAppleModelId(nsAutoCString& aModelId)
 {
   size_t numChars = 0;
   size_t result = sysctlbyname("hw.model", nullptr, &numChars, nullptr, 0);
   if (result != 0 || !numChars) {
@@ -687,16 +797,46 @@ nsSystemInfo::Init()
 
   uint32_t installYear = 0;
   if (NS_SUCCEEDED(GetInstallYear(installYear))) {
     rv = SetPropertyAsUint32(NS_LITERAL_STRING("installYear"), installYear);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
+
+#ifndef __MINGW32__
+  nsAutoString avInfo, antiSpyInfo, firewallInfo;
+  if (NS_SUCCEEDED(GetWindowsSecurityCenterInfo(avInfo, antiSpyInfo,
+                                                firewallInfo))) {
+    if (!avInfo.IsEmpty()) {
+      rv = SetPropertyAsAString(NS_LITERAL_STRING("registeredAntiVirus"),
+                                avInfo);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+    }
+
+    if (!antiSpyInfo.IsEmpty()) {
+      rv = SetPropertyAsAString(NS_LITERAL_STRING("registeredAntiSpyware"),
+                                antiSpyInfo);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+    }
+
+    if (!firewallInfo.IsEmpty()) {
+      rv = SetPropertyAsAString(NS_LITERAL_STRING("registeredFirewall"),
+                                firewallInfo);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+    }
+  }
+#endif // __MINGW32__
 #endif
 
 #if defined(XP_MACOSX)
   nsAutoString countryCode;
   if (NS_SUCCEEDED(GetSelectedCityInfo(countryCode))) {
     rv = SetPropertyAsAString(NS_LITERAL_STRING("countryCode"), countryCode);
     NS_ENSURE_SUCCESS(rv, rv);
   }