Bug 1418131: Part 1 - Add Windows Security Center info to nsSystemInfo; r?jimm, r?erahm
MozReview-Commit-ID: 7XUAIesDpRu
--- 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);
}