|
@@ -23,6 +23,8 @@
|
|
|
#include "obs-internal.h"
|
|
|
|
|
|
#include <windows.h>
|
|
|
+#include <wscapi.h>
|
|
|
+#include <iwscapi.h>
|
|
|
|
|
|
static uint32_t win_ver = 0;
|
|
|
|
|
@@ -247,6 +249,130 @@ static void log_gaming_features(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static const char *get_str_for_state(int state)
|
|
|
+{
|
|
|
+ switch (state) {
|
|
|
+ case WSC_SECURITY_PRODUCT_STATE_ON:
|
|
|
+ return "enabled";
|
|
|
+ case WSC_SECURITY_PRODUCT_STATE_OFF:
|
|
|
+ return "disabled";
|
|
|
+ case WSC_SECURITY_PRODUCT_STATE_SNOOZED:
|
|
|
+ return "temporarily disabled";
|
|
|
+ case WSC_SECURITY_PRODUCT_STATE_EXPIRED:
|
|
|
+ return "expired";
|
|
|
+ default:
|
|
|
+ return "unknown";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static const char *get_str_for_type(int type)
|
|
|
+{
|
|
|
+ switch (type) {
|
|
|
+ case WSC_SECURITY_PROVIDER_ANTIVIRUS:
|
|
|
+ return "AV";
|
|
|
+ case WSC_SECURITY_PROVIDER_FIREWALL:
|
|
|
+ return "FW";
|
|
|
+ case WSC_SECURITY_PROVIDER_ANTISPYWARE:
|
|
|
+ return "ASW";
|
|
|
+ default:
|
|
|
+ return "unknown";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void log_security_products_by_type(IWSCProductList *prod_list, int type)
|
|
|
+{
|
|
|
+ HRESULT hr;
|
|
|
+ LONG count = 0;
|
|
|
+ IWscProduct *prod;
|
|
|
+ BSTR name;
|
|
|
+ WSC_SECURITY_PRODUCT_STATE prod_state;
|
|
|
+
|
|
|
+ hr = prod_list->lpVtbl->Initialize(prod_list, type);
|
|
|
+
|
|
|
+ if (FAILED(hr))
|
|
|
+ return;
|
|
|
+
|
|
|
+ hr = prod_list->lpVtbl->get_Count(prod_list, &count);
|
|
|
+ if (FAILED(hr)) {
|
|
|
+ prod_list->lpVtbl->Release(prod_list);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < count; i++) {
|
|
|
+ hr = prod_list->lpVtbl->get_Item(prod_list, i, &prod);
|
|
|
+ if (FAILED(hr))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ hr = prod->lpVtbl->get_ProductName(prod, &name);
|
|
|
+ if (FAILED(hr))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ hr = prod->lpVtbl->get_ProductState(prod, &prod_state);
|
|
|
+ if (FAILED(hr)) {
|
|
|
+ SysFreeString(name);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ blog(LOG_INFO, "\t%S: %s (%s)", name,
|
|
|
+ get_str_for_state(prod_state),
|
|
|
+ get_str_for_type(type));
|
|
|
+
|
|
|
+ SysFreeString(name);
|
|
|
+ prod->lpVtbl->Release(prod);
|
|
|
+ }
|
|
|
+
|
|
|
+ prod_list->lpVtbl->Release(prod_list);
|
|
|
+}
|
|
|
+
|
|
|
+static void log_security_products(void)
|
|
|
+{
|
|
|
+ IWSCProductList *prod_list = NULL;
|
|
|
+ HMODULE h_wsc;
|
|
|
+ HRESULT hr;
|
|
|
+
|
|
|
+ /* We load the DLL rather than import wcsapi.lib because the clsid /
|
|
|
+ * iid only exists on Windows 8 or higher. */
|
|
|
+
|
|
|
+ h_wsc = LoadLibraryW(L"wscapi.dll");
|
|
|
+ if (!h_wsc)
|
|
|
+ return;
|
|
|
+
|
|
|
+ const CLSID *prod_list_clsid =
|
|
|
+ (const CLSID *)GetProcAddress(h_wsc, "CLSID_WSCProductList");
|
|
|
+ const IID *prod_list_iid =
|
|
|
+ (const IID *)GetProcAddress(h_wsc, "IID_IWSCProductList");
|
|
|
+
|
|
|
+ if (prod_list_clsid && prod_list_iid) {
|
|
|
+ blog(LOG_INFO, "Sec. Software Status:");
|
|
|
+
|
|
|
+ hr = CoCreateInstance(prod_list_clsid, NULL,
|
|
|
+ CLSCTX_INPROC_SERVER, prod_list_iid,
|
|
|
+ &prod_list);
|
|
|
+ if (!FAILED(hr)) {
|
|
|
+ log_security_products_by_type(prod_list,
|
|
|
+ WSC_SECURITY_PROVIDER_ANTIVIRUS);
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = CoCreateInstance(prod_list_clsid, NULL,
|
|
|
+ CLSCTX_INPROC_SERVER, prod_list_iid,
|
|
|
+ &prod_list);
|
|
|
+ if (!FAILED(hr)) {
|
|
|
+ log_security_products_by_type(prod_list,
|
|
|
+ WSC_SECURITY_PROVIDER_FIREWALL);
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = CoCreateInstance(prod_list_clsid, NULL,
|
|
|
+ CLSCTX_INPROC_SERVER, prod_list_iid,
|
|
|
+ &prod_list);
|
|
|
+ if (!FAILED(hr)) {
|
|
|
+ log_security_products_by_type(prod_list,
|
|
|
+ WSC_SECURITY_PROVIDER_ANTISPYWARE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ FreeLibrary(h_wsc);
|
|
|
+}
|
|
|
+
|
|
|
void log_system_info(void)
|
|
|
{
|
|
|
struct win_version_info ver;
|
|
@@ -261,6 +387,7 @@ void log_system_info(void)
|
|
|
log_admin_status();
|
|
|
log_aero();
|
|
|
log_gaming_features();
|
|
|
+ log_security_products();
|
|
|
}
|
|
|
|
|
|
|