Storage of License Values

License values in Windows Vista are stored in the registry as the binary data for one registry value:

Key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ProductOptions
Value ProductPolicy
Type REG_BINARY

The binary data for the ProductPolicy value is interpreted by the kernel as providing data for an essentially arbitrary number of named license values. (The number is not quite arbitrary, however. The kernel imposes an upper limit of 0x0923 values. The derivation seems to be that the total size of ProductPolicy data is restricted to 64KB, and then since each value with a name and non-trivial data will need at least 0x1C bytes, there can be at most 0x0923 values.)

Though a handful of license values are meaningful to the kernel, most are held by the kernel as black boxes for whatever component may be interested. The kernel exports several functions for access to the license data and to manage a record of whether the license data has been tampered with:

The last of these, ZwQueryLicenseValue, is also callable from user mode through the NTDLL exports NtQueryLicenseValue and ZwQueryLicenseValue.

Data Format

The binary data for the ProductPolicy value is in three parts:

Header

The header provides the sizes of the two parts that follow it.

Offset Size Value
0x00 dword total size, including this header
0x04 dword size of values array that follows this header
0x08 dword size of end marker that follows the values array
0x0C dword unknown
0x10 dword must be 1, perhaps as version number

Values

Each value is described in three parts:

The sizes of both the value and its data are in the header:

Offset Size Value
0x00 word total size, including this header
0x02 word size of name
0x04 word type of data
0x06 word size of data
0x08 dword flags
0x0C dword unknown

The data type follows the familiar scheme for registry data: REG_SZ (0x01) for a string, REG_BINARY (0x03) for binary data and REG_DWORD (0x04) for a dword.

For the flags, only the 0x01 and 0x02 bits are valid. If the 0x01 bit is set, then the value requires something that is apparently called proxy support.

End Marker

The end marker is necessarily a dword with the value 0x45.