WMI Security Center productState clarification - windows-7

I'm querying the WMI for "SELECT * FROM AntivirusProduct" on SecurityCenter2 (I'm on Windows 7 at the moment).
I'm having a hard time trying to find what do the numbers on productState mean, including AntiSpyware and Firewall aswell. Is there any reference for this out there? I want to make sure I can get the correct product states on any Vista or 7 machine (In case these numbers vary from machine to machine).

There's no official documentation on the productState values. The only info I could find is this article which makes assumptions about the productState value meaning based on the byte-by-byte analysis of the value.

The productState values seem to be a bit set that is not documented except through an NDA with Microsoft. It should be possible to map the values returned with the products installed and their state. You could install a single AV product, record its state, then have its virus definitions go out of date, then check how the value changes. There seems to be a limited set of typical values.
Reference: https://bigfix.me/analysis/details/2998358
Here are the productState values I have found from 34 different AV products across over 10000 endpoints which could help reverse engineer the meaning:
( Decimal, Hex, Bit Set )
262144, 40000, 1000000000000000000
262160, 40010, 1000000000000010000
266240, 41000, 1000001000000000000
270336, 42000, 1000010000000000000
327680, 50000, 1010000000000000000
327696, 50010, 1010000000000010000
331776, 51000, 1010001000000000000
344064, 54000, 1010100000000000000
393216, 60000, 1100000000000000000
393232, 60010, 1100000000000010000
393472, 60100, 1100000000100000000
393488, 60110, 1100000000100010000
397312, 61000, 1100001000000000000
397328, 61010, 1100001000000010000
397568, 61100, 1100001000100000000
397584, 61110, 1100001000100010000
458752, 70000, 1110000000000000000
458768, 70010, 1110000000000010000
462848, 71000, 1110001000000000000
462864, 71010, 1110001000000010000

For anyone else, I've found that when converted to Hex, the third character pretty reliably indicates whether or not any particular antivirus product is enabled. (1 = Enabled, 0 = Disabled)
Here's a PowerShell one-liner I wrote to determine if Windows Defender is Enabled or not. You can replace the string to match whichever antivirus product you want.
Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct | ForEach-Object {if($($_.displayName) -eq "Windows Defender"){if("$($([Convert]::ToString($($_.productState), 16)).PadLeft(6,""0""))".Substring(2,1) -eq "1"){Write-Host "Windows Defender is Enabled"}else{Write-Host "Windows Defender is Disabled"}}}
I can't say for certain that every antivirus product correctly reports its product state, but I imagine all the mainstream ones must. I can confirm this also works with Symantec Endpoint Protection.

Related

GetSystemIdForPublisher doesn't return unique ID

I use GetSystemIdForPublisher() to identify machine IDs. According to the documentation they are unique, but I have a handful of machines which return the same ID. These machines are completely unrelated and have no common history. They are located in different countries and belong to different users. The Windows version of these machines is the latest Windows 1909 10.0.18363 update.
The documentation clearly states:
The method will first attempt to use the Trusted Platform Module
(TPM), if present, to get an ID. If a TPM is not present, the method
will try to get an ID from the Unified Extensible Firmware Interface
(UEFI). If neither of these sources is available, this method will
return an ID that is backed by the Windows registry. In the case of
the Windows registry, the ID will not satisfy all the above
guarantees. For example, if a system does not have a TPM or UEFI
support, and thus an ID was obtained from the registry, a clean
install of Windows will result in a new, different ID being returned.
Callers of this method should refer to the Source property of the
returned SystemIdentificationInfo to determine where the ID was
obtained from in order to understand the guarantees provided.
As far as I can see, none of these statements explain to me what is happening here. Does anyone else have an idea whats going on? Any help is highly appreciated!
Addendum:
we got feedback in form of a cpu-z report from 2 persons on 2 different continents with the same machine id:
user A:
Mainboard Model Z87M Extreme4 (0x00000444 - 0xECE9B6D4)
UEFI Yes
BIOS Vendor American Megatrends Inc.
BIOS MSG 63-0100-000001-00101111-1xxxx5-Chipset
BIOS Date 12/10/15
Mainboard Vendor 000001
user B:
Mainboard Model 151-BE-E097 (0x0000025D - 0x0A74C7F0)
UEFI Yes
BIOS Vendor American Megatrends Inc.
BIOS MSG 63-0100-000001-00101111-0XXXX5-Chipset
BIOS Date 09/10/15
Mainboard Vendor 000001
both got the same identifier when calling GetSystemIdForPublisher():
XlPRXXXlAPXk-yFXXXJUv3-XXXXXXXXXXXXX = [source is UEFI, ]
==> X included for obfuscation
We have around 60 customers worldwide whose computers return this exact ID.

How to identify PC (motherboard) in win32 api? [duplicate]

How to uniquely identify computer (mainboard) using C#(.Net/Mono, local application)?
Edition. We can identify mainboard in .Net using something like this (see Get Unique System Identifiers in C#):
using System.Management;
...
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_MotherboardDevice");
...
But unfortunately Mono does not support System.Management. How to do it under Mono for Linux? - I don't know :(
Write a function that takes a few unique hardware parameters as input and generates a hash out of them.
For example, Windows activation looks at the following hardware characteristics:
Display Adapter
SCSI Adapter
IDE Adapter (effectively the motherboard)
Network Adapter (NIC) and its MAC Address
RAM Amount Range (i.e., 0-64mb, 64-128mb, etc.)
Processor Type
Processor Serial Number
Hard Drive Device
Hard Drive Volume Serial Number (VSN)
CD-ROM / CD-RW / DVD-ROM
You can pick up a few of them to generate your unique computer identifier.
Please see: Get Unique System Identifiers in C#
You realistically have MotherboardID, CPUID, Disk Serial and MAC address, from experience none of them are 100%.
Our stats show
Disk serial Is missing 0.1 %
MAC Is missing 1.3 %
Motherboard ID Is missing 30 %
CPUID Is missing 99 %
0.04% of machines tested yielded no information, we couldn't even read the computer name. It maybe that these were some kind of virtual PC, HyperV or VMWare instance, or maybe just very locked down? In any case your design has to be able to cope with these cases.
Disk serial is the most reliable, but easy to change, mac can be changed and depending on the filtering applied when reading it can change if device drivers are added (hyperv, wireshark etc).
Motherboard and CPUID sometimes return values that are invalid "NONE", "AAAA..", "XXXX..." etc.
You should also note that these functions can be very slow to call (they may take a few seconds even on a fast PC), so it may be worth kicking them off on a background thread as early as possible, you ideally don't want to be blocking on them.
Try this:
http://carso-owen.blogspot.com/2007/02/how-to-get-my-motherboard-serial-number.html
Personally though, I'd go with hard drive serial number. If a mainboard dies and is replaced, that PC isn't valid any more. If the HDD drive is replaced, it doesn't matter too much because the software was on it.
Of course, on the other hand, if the HDD is just moved elsewhere, the information goes with it, so you might want to look at a combination of serial numbers, depending what you want it for.
How about the MAC address of the network card?

Zero Opengl 3.2 pixelformat matches found?

Today I finally found out what has been stalling my development process: Even though no errorcode is set, the function wglChoosePixelFormatARB returns 0 pixelformats.
I am trying to set up an OpenGL context in my C++ application and I have managed to retrieve the function pointers for the extensions.
glGetIntegerv(GL_MAJOR_VERSION, &maj)
returns 4 so, naturally, I assumed it would be possible to create an OpenGL 3.2 context. However, after finding out there were no matches, I started to comment out some of my requirements to go in the attribList parameter. There were no matches whatsoever.
Only when I, just to be certain, commented out
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
I finally got matches. Out of the 8 matching pixel formats that the other requirements meet, not ONE of them seems to support version 3 of OGL.
Has anyone ever run into this? I have tried updating/reinstalling my video drivers, but nothing has changed. I am running this on Windows 7, MS Visual Studio 2008, and my graphics card is one from the AMD Radeon HD 7700 Series.
The WGL_CONTEXT_MAJOR_VERSION_ARB, WGL_CONTEXT_MINOR_VERSION_ARB and related attributes are not attributes of the Windows Pixelformat.
You must not use them with wglChoosePixelFormatARB().
Those options belong into the attribute list of wglCreateContextAttribsARB as defined by the WGL_ARB_create_context extension.

After CreateProcessWithLogonW switch language with alt shift stops working

I encountered a strange problem:
When our application spawns child process with CreateProcessWithLogonW
switch language with alt-shift stops working in the windows of the new process.
What might be the problem? The OS is XP SP3. The same setup is ok on Win 7.
Additional thing I discovered: This problem only occurs on Win XP Hebrew.
On English XP it works fine.
As Hans Passant has said CreateProcessWithLogonW requires the LOGON_WITH_PROFILE to be set as dwLogonFlags which is the fourth argument of the function in order to load the user registry hive into HKEY_USERS. This will ensure that access to information in the HKEY_CURRENT_USER registry key will produce results that are consistent with a normal interactive logon.
Alternately you can call the LoadUserProfile function beforecalling CreateProcessWithLogonW.
Registry settings you will want to verify exist for the user whose profile you are loading include
[HKEY_CURRENT_USER\Keyboard Layout\Toggle]
"Hotkey"="3"
"Language Hotkey"="3"
"Layout Hotkey"="3"
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
"1"="00000809"
"2"="e00e0804"
[HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar]
"ShowStatus"=dword:00000000"
The values of [HKEY_CURRENT_USER\Keyboard Layout\Toggle] are
1 Key Sequence enabled; use Left-ALT+SHIFT to switch between locales.
2 Key Sequence enabled; use CTRL+SHIFT to switch between locales.
3 Key Sequences disabled.
4 If the default locale is Thai, the accent grave key toggles input locales; otherwise key sequences are disabled.
The values of [HKEY_CURRENT_USER\Keyboard Layout\Preload] are listed here under the KeyName column.
The values of [HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar] are
0 Floating on desktop
4 Docked on the taskbar
3 when set to Hidden which is the default.
Relevant resources include
Similar Stack Overflow Question
CreateProcessWithLogonW function MSDN Reference
Managed CreateProcessWithLogonW

Get number of cores on a XP 64 bit system

Hej,
I wrote a function that should give me the number of cores of a windows system. It works on all systems except XP 64 bit. Here's the way I get the information:
$objWMIItems = $objWMIService.ExecQuery ("SELECT * FROM Win32_Processor")
If (0 == IsObj($objWMIItems)) Then
;~ errorhandling
Else
For $objElement In $objWMIItems
$nCoreNumber = $objElement.NumberOfCores
Next
Regarding "NumberOfCores", Microsofts MSDN page tells me "Windows Server 2003, Windows XP, and Windows 2000: This property is not available". Somewhere I read, it is possible with having SP3 installed. I suppose that's true, because it works that way on XP 32 bit systems. But there is no SP3 for XP 64...
Is there another way to get the information?
Thanks
I think it's easiest to read the NUMBER_OF_PROCESSORS environment variable.
Do you want "cores" or "number of logical processors including hyperthreading"? (In other words, do you want to count hyperthreading as a "core")?
In any case, copying my answer from a similar question a while back:
If you actually need to distinguish between actual cores, chips, and
logical processors, the API to call is
GetLogicalProcessInformation
GetSystemInfo if just want to know how many logical processors on
a machine (with no differentiation for hyperthreading.).

Resources