Last active
December 22, 2015 23:00
-
-
Save Blizzardo1/bc6e11c4ea5c8b2a1191 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MUST COMPILE WITH UNSAFE | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Microsoft.Win32; | |
namespace ProductPolicy | |
{ | |
#region Classes | |
public static class Extensions | |
{ | |
public static bool IsNull ( this object o ) => o == null; | |
} | |
public class ProductPolicyProgram | |
{ | |
private const string KeyName = @"SYSTEM\CurrentControlSet\Control\ProductOptions"; | |
private const string ValueName = @"ProductPolicy"; | |
private static readonly RegistryKey _system = Registry.LocalMachine; | |
/// <summary> | |
/// Entry-Point for our program | |
/// </summary> | |
/// <remarks>This Program takes no Parameters.</remarks> | |
[STAThread] | |
internal unsafe static void Main ( ) | |
{ | |
RegistryKey _key; | |
List<ProductPolicyObject> objs = new List<ProductPolicyObject> ( ); | |
byte [ ] byteData = null; | |
// Open Registry SubKey( HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions | |
// If this is null... immediately kill off the program. | |
if ( ( _key = _system.OpenSubKey ( KeyName, false ) ).IsNull ( ) ) | |
Error ( "Key does not exist." ); | |
// Then get the Value from within ProductOptions (ProductPolicy) | |
byteData = ( byte [ ] ) _key.GetValue ( ValueName ); | |
if ( byteData.IsNull ( ) ) | |
Error ( "No Byte Data." ); | |
// After capturing the Data from the SubKey, read the data | |
// This block was originally written by Hounsell | |
fixed(byte* bytePtr = byteData) | |
{ | |
TProductPolicyHeader* header = ( TProductPolicyHeader* ) bytePtr; | |
uint position = ( uint ) sizeof ( TProductPolicyHeader ); | |
while ( ( byteData.Length - header->cbEndMarker ) > position ) | |
{ | |
uint startPosition = position; | |
ProductPolicyObject pObj = new ProductPolicyObject ( ); | |
byte* recordPtr = bytePtr + position; | |
TProductPolicyValue* pValue = ( TProductPolicyValue* ) recordPtr; | |
pObj.Record = *pValue; | |
position += ( uint ) sizeof ( TProductPolicyValue ); | |
char* recordNamePtr = ( char* ) ( bytePtr + position ); | |
pObj.Name = new string ( recordNamePtr, 0, ( pValue->cbName / sizeof ( char ) ) ); | |
position += pValue->cbName; | |
switch ( pValue->SlDatatype ) | |
{ | |
case LicensingDataType.Binary: | |
{ | |
byte [ ] data = new byte [ pValue->cbData ]; | |
for ( int i = 0; i < pValue->cbData; i++ ) | |
data [ i ] = *( bytePtr + position + i ); | |
pObj.Data = data; | |
break; | |
} | |
case LicensingDataType.Integer: | |
{ | |
pObj.Data = *( ( int* ) ( bytePtr + position ) ); | |
break; | |
} | |
case LicensingDataType.MultiString: | |
{ | |
break; | |
} | |
case LicensingDataType.String: | |
{ | |
char* recordData = ( char* ) ( bytePtr + position ); | |
pObj.Data = new string ( recordData, 0, ( pValue->cbData / sizeof ( char ) ) ).TrimEnd ( '\0' ); | |
break; | |
} | |
} | |
position = startPosition += pValue->cbSize; | |
objs.Add ( pObj ); | |
} | |
} | |
// Block End | |
// Get the max length string(Name) from within the List | |
int maxStringSize = objs.Aggregate ( ( x, y ) => x.Name.Length > y.Name.Length ? x : y ).Name.Length; | |
Console.WriteLine ( $"{"Name".PadRight ( maxStringSize + 5 )} | {"Data".PadLeft ( 20 )} | {"Type".PadLeft ( 10 )}" ); | |
foreach(ProductPolicyObject obj in objs) | |
{ | |
Console.WriteLine ( $"{obj.Name.PadRight(maxStringSize + 5)} | {obj.Data,20} | {obj.Record.SlDatatype, 10}" ); | |
} | |
Console.ReadKey ( true ); | |
// Clean up our crap | |
byteData = null; | |
_key.Close ( ); | |
_system.Close ( ); | |
objs.Clear ( ); | |
objs = null; | |
} | |
private static void Error ( string message ) | |
{ | |
Console.Write ( message ); | |
Console.ReadKey ( true ); | |
Environment.Exit ( -1 ); | |
} | |
} | |
public class ProductPolicyObject | |
{ | |
public TProductPolicyValue Record { get; set; } | |
public string Name { get; set; } | |
public object Data { get; set; } | |
public string DataString | |
{ | |
get | |
{ | |
byte [ ] dataBytes = Data as byte [ ]; | |
if ( dataBytes != null ) | |
{ | |
StringBuilder sb = new StringBuilder ( ); | |
for ( int i = 0; i < dataBytes.Length; i++ ) | |
{ | |
sb.Append ( dataBytes [ i ].ToString ( "X2" ) ); | |
} | |
return sb.ToString ( ); | |
} | |
else | |
{ | |
return Data?.ToString ( ); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Enums | |
public enum LicensingDataType : short | |
{ | |
None = -1, | |
String = 1, | |
Binary = 3, | |
Integer = 4, | |
MultiString = 7, | |
Sum = 100 | |
} | |
#endregion | |
#region Structures | |
public struct TProductPolicyHeader | |
{ | |
public uint cbSize { get; set; } | |
public uint cbDataSize { get; set; } | |
public uint cbEndMarker { get; set; } | |
public uint Unknown1 { get; set; } | |
public uint Unknown2 { get; set; } | |
} | |
public struct TProductPolicyValue | |
{ | |
public ushort cbSize { get; set; } | |
public ushort cbName { get; set; } | |
public LicensingDataType SlDatatype { get; set; } | |
public ushort cbData { get; set; } | |
public uint Unknown1 { get; set; } | |
public uint Unknown2 { get; set; } | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment