Skip to content

Commit

Permalink
Cleanup code
Browse files Browse the repository at this point in the history
  • Loading branch information
gus33000 committed Nov 15, 2021
1 parent 19ae8d9 commit 021d7b2
Show file tree
Hide file tree
Showing 33 changed files with 1,921 additions and 1,642 deletions.
95 changes: 49 additions & 46 deletions Windows Build Identifier/Comparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,69 +16,70 @@ public static void CompareBuilds(string xml1, string xml2)
FileItem[] build2 = Deserialize(xml2);

Console.WriteLine("Getting paths 1");
var build1Paths = build1.Select(x => Sanitize(x.Location)).Where(x => !ExcludedFromChecks(x)).ToHashSet();
HashSet<string> build1Paths = build1.Select(x => Sanitize(x.Location)).Where(x => !ExcludedFromChecks(x)).ToHashSet();
Console.WriteLine("Getting paths 2");
var build2Paths = build2.Select(x => Sanitize(x.Location)).Where(x => !ExcludedFromChecks(x)).ToHashSet();
HashSet<string> build2Paths = build2.Select(x => Sanitize(x.Location)).Where(x => !ExcludedFromChecks(x)).ToHashSet();

Console.WriteLine("Getting common paths");
var commonPaths = build1Paths.Intersect(build2Paths).ToHashSet();
HashSet<string> commonPaths = build1Paths.Intersect(build2Paths).ToHashSet();

Console.WriteLine("Getting unique paths 1");
var uniqueBuild1 = build1Paths.Where(x => !commonPaths.Contains(x)).ToHashSet();
HashSet<string> uniqueBuild1 = build1Paths.Where(x => !commonPaths.Contains(x)).ToHashSet();
Console.WriteLine("Getting unique paths 2");
var uniqueBuild2 = build2Paths.Where(x => !commonPaths.Contains(x)).ToHashSet();
HashSet<string> uniqueBuild2 = build2Paths.Where(x => !commonPaths.Contains(x)).ToHashSet();

Console.WriteLine("Getting common resources");
var commonResources = commonPaths.Where(x => x.Contains(@"\.rsrc\")).ToHashSet();
HashSet<string> commonResources = commonPaths.Where(x => x.Contains(@"\.rsrc\")).ToHashSet();

Console.WriteLine($"{commonPaths.Count()} common paths");
Console.WriteLine($"{commonResources.Count()} common resources");
Console.WriteLine($"{uniqueBuild1.Count()} unique 1");
Console.WriteLine($"{uniqueBuild2.Count()} unique 2");
Console.WriteLine($"{commonPaths.Count} common paths");
Console.WriteLine($"{commonResources.Count} common resources");
Console.WriteLine($"{uniqueBuild1.Count} unique 1");
Console.WriteLine($"{uniqueBuild2.Count} unique 2");

Console.WriteLine("Processing common resources");
HashSet<string> modifiedResources = new HashSet<string>();
HashSet<string> modifiedResources = new();

long total = commonResources.Count;
long counter = 0;

foreach (var resource in commonResources)
foreach (string resource in commonResources)
{
Console.Title = $"Processing {counter}/{total}";
var item1 = GetFileItem(build1, resource);
var item2 = GetFileItem(build2, resource);
FileItem item1 = GetFileItem(build1, resource);
FileItem item2 = GetFileItem(build2, resource);

if (item1.Hash != null)
{
if (item1.Hash.SHA1 != item2.Hash.SHA1)
if (item1.Hash.Sha1 != item2.Hash.Sha1)
{
Console.WriteLine("modified");
modifiedResources.Add(item1.Location);
}
}

counter++;
}

Console.WriteLine();
Console.WriteLine("Files unique to build 1");
Console.WriteLine();
foreach (var file in uniqueBuild1)
foreach (string file in uniqueBuild1)
{
Console.WriteLine(file);
}

Console.WriteLine();
Console.WriteLine("Files unique to build 2");
Console.WriteLine();
foreach (var file in uniqueBuild2)
foreach (string file in uniqueBuild2)
{
Console.WriteLine(file);
}

Console.WriteLine();
Console.WriteLine("Modified resources between both builds");
Console.WriteLine();
foreach (var file in modifiedResources)
foreach (string file in modifiedResources)
{
Console.WriteLine(file);
}
Expand All @@ -88,77 +89,77 @@ private static string Sanitize(string path1)
{
if (path1.Contains(@"installedrepository\", StringComparison.InvariantCultureIgnoreCase))
{
var fold1t = path1.ToLower().Split(@"installedrepository\")[0];
var fold1 = path1.ToLower().Split(@"installedrepository\")[1];
string fold1T = path1.ToLower().Split(@"installedrepository\")[0];
string fold1 = path1.ToLower().Split(@"installedrepository\")[1];

var number = fold1.Count(x => x == '_');
int number = fold1.Count(x => x == '_');
if (number < 1)
{
return path1;
}

var fsplit1 = fold1.Split(@"\");
string[] fsplit1 = fold1.Split(@"\");

var san1 = string.Join("_", fsplit1[0].Split("_")[0..^1]);
string san1 = string.Join("_", fsplit1[0].Split("_")[..^1]);

if (fsplit1.Length < 2)
{
return san1;
}

var f1 = fold1t + "installedrepository\\" + san1 + "\\" + string.Join("\\", fsplit1[1..^0]);
string f1 = fold1T + "installedrepository\\" + san1 + "\\" + string.Join("\\", fsplit1[1..]);
return f1;
}
else if (path1.Contains(@"build\filerepository\", StringComparison.InvariantCultureIgnoreCase))

if (path1.Contains(@"build\filerepository\", StringComparison.InvariantCultureIgnoreCase))
{
var fold1t = path1.ToLower().Split(@"build\filerepository\")[0];
var fold1 = path1.ToLower().Split(@"build\filerepository\")[1];
string fold1T = path1.ToLower().Split(@"build\filerepository\")[0];
string fold1 = path1.ToLower().Split(@"build\filerepository\")[1];

var number = fold1.Count(x => x == '_');
int number = fold1.Count(x => x == '_');
if (number < 1)
{
return path1;
}

var fsplit1 = fold1.Split(@"\");
string[] fsplit1 = fold1.Split(@"\");

var san1 = string.Join("_", fsplit1[0].Split("_")[0..^1]);
string san1 = string.Join("_", fsplit1[0].Split("_")[..^1]);

if (fsplit1.Length < 2)
{
return san1;
}

var f1 = fold1t + "build\\filerepository\\" + san1 + "\\" + string.Join("\\", fsplit1[1..^0]);
string f1 = fold1T + "build\\filerepository\\" + san1 + "\\" + string.Join("\\", fsplit1[1..]);
return f1;
}
else if (path1.Contains(@"Windows\winsxs\", StringComparison.InvariantCultureIgnoreCase))

if (path1.Contains(@"Windows\winsxs\", StringComparison.InvariantCultureIgnoreCase))
{
var fold1t = path1.ToLower().Split(@"windows\winsxs\")[0];
var fold1 = path1.ToLower().Split(@"windows\winsxs\")[1];
string fold1T = path1.ToLower().Split(@"windows\winsxs\")[0];
string fold1 = path1.ToLower().Split(@"windows\winsxs\")[1];

var number = fold1.Count(x => x == '_');
int number = fold1.Count(x => x == '_');
if (number < 1)
{
return path1;
}

var fsplit1 = fold1.Split(@"\");
string[] fsplit1 = fold1.Split(@"\");

var san1 = string.Join("_", fsplit1[0].Split("_")[0..^1]);
string san1 = string.Join("_", fsplit1[0].Split("_")[..^1]);

if (fsplit1.Length < 2)
{
return san1;
}

var f1 = fold1t + "windows\\winsxs\\" + san1 + "\\" + string.Join("\\", fsplit1[1..^0]);
string f1 = fold1T + "windows\\winsxs\\" + san1 + "\\" + string.Join("\\", fsplit1[1..]);
return f1;
}
else
{
return path1;
}

return path1;
}

private static FileItem GetFileItem(FileItem[] array, string path)
Expand All @@ -171,7 +172,9 @@ private static bool ExcludedFromChecks(string path)
string index = @"install.wim\3\";

if (!path.Contains(index, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}

if (path.Contains(@"\.rsrc\"))
{
Expand All @@ -186,13 +189,13 @@ private static bool ExcludedFromChecks(string path)

private static FileItem[] Deserialize(string path)
{
XmlSerializer deserializer = new XmlSerializer(typeof(FileItem[]));
XmlSerializer deserializer = new(typeof(FileItem[]));
TextReader reader = new StreamReader(path);
object obj = deserializer.Deserialize(reader);
FileItem[] XmlData = (FileItem[])obj;
FileItem[] xmlData = (FileItem[])obj;
reader.Close();

return XmlData;
return xmlData;
}
}
}
}
92 changes: 55 additions & 37 deletions Windows Build Identifier/Crc32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,111 +9,129 @@
namespace WindowsBuildIdentifier
{
/// <summary>
/// Implements a 32-bit CRC hash algorithm compatible with Zip etc.
/// Implements a 32-bit CRC hash algorithm compatible with Zip etc.
/// </summary>
/// <remarks>
/// Crc32 should only be used for backward compatibility with older file formats
/// and algorithms. It is not secure enough for new applications.
/// If you need to call multiple times for the same data either use the HashAlgorithm
/// interface or remember that the result of one Compute call needs to be ~ (XOR) before
/// being passed in as the seed for the next Compute call.
/// Crc32 should only be used for backward compatibility with older file formats
/// and algorithms. It is not secure enough for new applications.
/// If you need to call multiple times for the same data either use the HashAlgorithm
/// interface or remember that the result of one Compute call needs to be ~ (XOR) before
/// being passed in as the seed for the next Compute call.
/// </remarks>
public sealed class Crc32 : HashAlgorithm
{
public const UInt32 DefaultPolynomial = 0xedb88320u;
public const UInt32 DefaultSeed = 0xffffffffu;
public const uint DefaultPolynomial = 0xedb88320u;
public const uint DefaultSeed = 0xffffffffu;

static UInt32[] defaultTable;
private static uint[] _defaultTable;

readonly UInt32 seed;
readonly UInt32[] table;
UInt32 hash;
private readonly uint _seed;
private readonly uint[] _table;
private uint _hash;

public Crc32()
: this(DefaultPolynomial, DefaultSeed)
{
}

public Crc32(UInt32 polynomial, UInt32 seed)
public Crc32(uint polynomial, uint seed)
{
if (!BitConverter.IsLittleEndian)
{
throw new PlatformNotSupportedException("Not supported on Big Endian processors");
}

table = InitializeTable(polynomial);
this.seed = hash = seed;
_table = InitializeTable(polynomial);
_seed = _hash = seed;
}

public override int HashSize => 32;

public override void Initialize()
{
hash = seed;
_hash = _seed;
}

protected override void HashCore(byte[] array, int ibStart, int cbSize)
{
hash = CalculateHash(table, hash, array, ibStart, cbSize);
_hash = CalculateHash(_table, _hash, array, ibStart, cbSize);
}

protected override byte[] HashFinal()
{
var hashBuffer = UInt32ToBigEndianBytes(~hash);
byte[] hashBuffer = UInt32ToBigEndianBytes(~_hash);
HashValue = hashBuffer;
return hashBuffer;
}

public override int HashSize { get { return 32; } }

public static UInt32 Compute(byte[] buffer)
public static uint Compute(byte[] buffer)
{
return Compute(DefaultSeed, buffer);
}

public static UInt32 Compute(UInt32 seed, byte[] buffer)
public static uint Compute(uint seed, byte[] buffer)
{
return Compute(DefaultPolynomial, seed, buffer);
}

public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
public static uint Compute(uint polynomial, uint seed, byte[] buffer)
{
return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
}

static UInt32[] InitializeTable(UInt32 polynomial)
private static uint[] InitializeTable(uint polynomial)
{
if (polynomial == DefaultPolynomial && defaultTable != null)
return defaultTable;
if (polynomial == DefaultPolynomial && _defaultTable != null)
{
return _defaultTable;
}

var createTable = new UInt32[256];
for (var i = 0; i < 256; i++)
uint[] createTable = new uint[256];
for (int i = 0; i < 256; i++)
{
var entry = (UInt32)i;
for (var j = 0; j < 8; j++)
uint entry = (uint)i;
for (int j = 0; j < 8; j++)
{
if ((entry & 1) == 1)
{
entry = (entry >> 1) ^ polynomial;
}
else
{
entry >>= 1;
}
}

createTable[i] = entry;
}

if (polynomial == DefaultPolynomial)
defaultTable = createTable;
{
_defaultTable = createTable;
}

return createTable;
}

static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList<byte> buffer, int start, int size)
private static uint CalculateHash(uint[] table, uint seed, IList<byte> buffer, int start, int size)
{
var hash = seed;
for (var i = start; i < start + size; i++)
hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff];
uint hash = seed;
for (int i = start; i < start + size; i++)
{
hash = (hash >> 8) ^ table[buffer[i] ^ (hash & 0xff)];
}

return hash;
}

static byte[] UInt32ToBigEndianBytes(UInt32 uint32)
private static byte[] UInt32ToBigEndianBytes(uint uint32)
{
var result = BitConverter.GetBytes(uint32);
byte[] result = BitConverter.GetBytes(uint32);

if (BitConverter.IsLittleEndian)
{
Array.Reverse(result);
}

return result;
}
Expand Down
Loading

0 comments on commit 021d7b2

Please sign in to comment.