summaryrefslogtreecommitdiff
path: root/LibTSforge/PhysicalStore
diff options
context:
space:
mode:
Diffstat (limited to 'LibTSforge/PhysicalStore')
-rw-r--r--LibTSforge/PhysicalStore/Common.cs7
-rw-r--r--LibTSforge/PhysicalStore/PhysicalStoreModern.cs4
-rw-r--r--LibTSforge/PhysicalStore/PhysicalStoreVista.cs356
-rw-r--r--LibTSforge/PhysicalStore/PhysicalStoreWin7.cs4
-rw-r--r--LibTSforge/PhysicalStore/VariableBag.cs102
5 files changed, 451 insertions, 22 deletions
diff --git a/LibTSforge/PhysicalStore/Common.cs b/LibTSforge/PhysicalStore/Common.cs
index f73f022..d0ad4fe 100644
--- a/LibTSforge/PhysicalStore/Common.cs
+++ b/LibTSforge/PhysicalStore/Common.cs
@@ -18,4 +18,11 @@ namespace LibTSforge.PhysicalStore
public ulong Time2;
public ulong Expiry;
}
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct VistaTimer
+ {
+ public ulong Time;
+ public ulong Expiry;
+ }
}
diff --git a/LibTSforge/PhysicalStore/PhysicalStoreModern.cs b/LibTSforge/PhysicalStore/PhysicalStoreModern.cs
index f697bea..9d8bb73 100644
--- a/LibTSforge/PhysicalStore/PhysicalStoreModern.cs
+++ b/LibTSforge/PhysicalStore/PhysicalStoreModern.cs
@@ -320,7 +320,7 @@ namespace LibTSforge.PhysicalStore
public PhysicalStoreModern(string tsPath, bool production, PSVersion version)
{
TSFile = File.Open(tsPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
- Deserialize(PhysStoreCrypto.DecryptPhysicalStore(TSFile.ReadAllBytes(), production));
+ Deserialize(PhysStoreCrypto.DecryptPhysicalStore(TSFile.ReadAllBytes(), production, version));
TSFile.Seek(0, SeekOrigin.Begin);
Version = version;
Production = production;
@@ -340,7 +340,7 @@ namespace LibTSforge.PhysicalStore
public byte[] ReadRaw()
{
- byte[] data = PhysStoreCrypto.DecryptPhysicalStore(TSFile.ReadAllBytes(), Production);
+ byte[] data = PhysStoreCrypto.DecryptPhysicalStore(TSFile.ReadAllBytes(), Production, Version);
TSFile.Seek(0, SeekOrigin.Begin);
return data;
}
diff --git a/LibTSforge/PhysicalStore/PhysicalStoreVista.cs b/LibTSforge/PhysicalStore/PhysicalStoreVista.cs
new file mode 100644
index 0000000..809be77
--- /dev/null
+++ b/LibTSforge/PhysicalStore/PhysicalStoreVista.cs
@@ -0,0 +1,356 @@
+namespace LibTSforge.PhysicalStore
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using LibTSforge.Crypto;
+
+ public class VistaBlock
+ {
+ public BlockType Type;
+ public uint Flags;
+ public byte[] Value;
+ public string ValueAsStr
+ {
+ get
+ {
+ return Utils.DecodeString(Value);
+ }
+ set
+ {
+ Value = Utils.EncodeString(value);
+ }
+ }
+ public uint ValueAsInt
+ {
+ get
+ {
+ return BitConverter.ToUInt32(Value, 0);
+ }
+ set
+ {
+ Value = BitConverter.GetBytes(value);
+ }
+ }
+ public byte[] Data;
+ public string DataAsStr
+ {
+ get
+ {
+ return Utils.DecodeString(Data);
+ }
+ set
+ {
+ Data = Utils.EncodeString(value);
+ }
+ }
+ public uint DataAsInt
+ {
+ get
+ {
+ return BitConverter.ToUInt32(Data, 0);
+ }
+ set
+ {
+ Data = BitConverter.GetBytes(value);
+ }
+ }
+
+ internal void Encode(BinaryWriter writer)
+ {
+ writer.Write((uint)Type);
+ writer.Write(Flags);
+ writer.Write(Value.Length);
+ writer.Write(Data.Length);
+ writer.Write(Value);
+ writer.Write(Data);
+ }
+
+ internal static VistaBlock Decode(BinaryReader reader)
+ {
+ uint type = reader.ReadUInt32();
+ uint flags = reader.ReadUInt32();
+
+ int valueLen = reader.ReadInt32();
+ int dataLen = reader.ReadInt32();
+
+ byte[] value = reader.ReadBytes(valueLen);
+ byte[] data = reader.ReadBytes(dataLen);
+ return new VistaBlock
+ {
+ Type = (BlockType)type,
+ Flags = flags,
+ Value = value,
+ Data = data,
+ };
+ }
+ }
+
+ public sealed class PhysicalStoreVista : IPhysicalStore
+ {
+ private byte[] PreHeaderBytes = new byte[] { };
+ private readonly List<VistaBlock> Blocks = new List<VistaBlock>();
+ private readonly FileStream TSPrimary;
+ private readonly FileStream TSSecondary;
+ private readonly bool Production;
+
+ public byte[] Serialize()
+ {
+ BinaryWriter writer = new BinaryWriter(new MemoryStream());
+ writer.Write(PreHeaderBytes);
+
+ foreach (VistaBlock block in Blocks)
+ {
+ block.Encode(writer);
+ writer.Align(4);
+ }
+
+ return writer.GetBytes();
+ }
+
+ public void Deserialize(byte[] data)
+ {
+ int len = data.Length;
+
+ BinaryReader reader = new BinaryReader(new MemoryStream(data));
+ PreHeaderBytes = reader.ReadBytes(8);
+
+ while (reader.BaseStream.Position < len - 0x14)
+ {
+ Blocks.Add(VistaBlock.Decode(reader));
+ reader.Align(4);
+ }
+ }
+
+ public void AddBlock(PSBlock block)
+ {
+ Blocks.Add(new VistaBlock
+ {
+ Type = block.Type,
+ Flags = block.Flags,
+ Value = block.Value,
+ Data = block.Data
+ });
+ }
+
+ public void AddBlocks(IEnumerable<PSBlock> blocks)
+ {
+ foreach (PSBlock block in blocks)
+ {
+ AddBlock(block);
+ }
+ }
+
+ public PSBlock GetBlock(string key, string value)
+ {
+ foreach (VistaBlock block in Blocks)
+ {
+ if (block.ValueAsStr == value)
+ {
+ return new PSBlock
+ {
+ Type = block.Type,
+ Flags = block.Flags,
+ Key = new byte[0],
+ Value = block.Value,
+ Data = block.Data
+ };
+ }
+ }
+
+ return null;
+ }
+
+ public PSBlock GetBlock(string key, uint value)
+ {
+ foreach (VistaBlock block in Blocks)
+ {
+ if (block.ValueAsInt == value)
+ {
+ return new PSBlock
+ {
+ Type = block.Type,
+ Flags = block.Flags,
+ Key = new byte[0],
+ Value = block.Value,
+ Data = block.Data
+ };
+ }
+ }
+
+ return null;
+ }
+
+ public void SetBlock(string key, string value, byte[] data)
+ {
+ for (int i = 0; i < Blocks.Count; i++)
+ {
+ VistaBlock block = Blocks[i];
+
+ if (block.ValueAsStr == value)
+ {
+ block.Data = data;
+ Blocks[i] = block;
+ break;
+ }
+ }
+ }
+
+ public void SetBlock(string key, uint value, byte[] data)
+ {
+ for (int i = 0; i < Blocks.Count; i++)
+ {
+ VistaBlock block = Blocks[i];
+
+ if (block.ValueAsInt == value)
+ {
+ block.Data = data;
+ Blocks[i] = block;
+ break;
+ }
+ }
+ }
+
+ public void SetBlock(string key, string value, string data)
+ {
+ SetBlock(key, value, Utils.EncodeString(data));
+ }
+
+ public void SetBlock(string key, string value, uint data)
+ {
+ SetBlock(key, value, BitConverter.GetBytes(data));
+ }
+
+ public void SetBlock(string key, uint value, string data)
+ {
+ SetBlock(key, value, Utils.EncodeString(data));
+ }
+
+ public void SetBlock(string key, uint value, uint data)
+ {
+ SetBlock(key, value, BitConverter.GetBytes(data));
+ }
+
+ public void DeleteBlock(string key, string value)
+ {
+ foreach (VistaBlock block in Blocks)
+ {
+ if (block.ValueAsStr == value)
+ {
+ Blocks.Remove(block);
+ return;
+ }
+ }
+ }
+
+ public void DeleteBlock(string key, uint value)
+ {
+ foreach (VistaBlock block in Blocks)
+ {
+ if (block.ValueAsInt == value)
+ {
+ Blocks.Remove(block);
+ return;
+ }
+ }
+ }
+
+ public PhysicalStoreVista(string primaryPath, bool production)
+ {
+ TSPrimary = File.Open(primaryPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
+ TSSecondary = File.Open(primaryPath.Replace("-0.", "-1."), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
+ Production = production;
+
+ Deserialize(PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), production, PSVersion.Vista));
+ TSPrimary.Seek(0, SeekOrigin.Begin);
+ }
+
+ public void Dispose()
+ {
+ if (TSPrimary.CanWrite && TSSecondary.CanWrite)
+ {
+ byte[] data = PhysStoreCrypto.EncryptPhysicalStore(Serialize(), Production, PSVersion.Vista);
+
+ TSPrimary.SetLength(data.LongLength);
+ TSSecondary.SetLength(data.LongLength);
+
+ TSPrimary.Seek(0, SeekOrigin.Begin);
+ TSSecondary.Seek(0, SeekOrigin.Begin);
+
+ TSPrimary.WriteAllBytes(data);
+ TSSecondary.WriteAllBytes(data);
+
+ TSPrimary.Close();
+ TSSecondary.Close();
+ }
+ }
+
+ public byte[] ReadRaw()
+ {
+ byte[] data = PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), Production, PSVersion.Vista);
+ TSPrimary.Seek(0, SeekOrigin.Begin);
+ return data;
+ }
+
+ public void WriteRaw(byte[] data)
+ {
+ byte[] encrData = PhysStoreCrypto.EncryptPhysicalStore(data, Production, PSVersion.Vista);
+
+ TSPrimary.SetLength(encrData.LongLength);
+ TSSecondary.SetLength(encrData.LongLength);
+
+ TSPrimary.Seek(0, SeekOrigin.Begin);
+ TSSecondary.Seek(0, SeekOrigin.Begin);
+
+ TSPrimary.WriteAllBytes(encrData);
+ TSSecondary.WriteAllBytes(encrData);
+
+ TSPrimary.Close();
+ TSSecondary.Close();
+ }
+
+ public IEnumerable<PSBlock> FindBlocks(string valueSearch)
+ {
+ List<PSBlock> results = new List<PSBlock>();
+
+ foreach (VistaBlock block in Blocks)
+ {
+ if (block.ValueAsStr.Contains(valueSearch))
+ {
+ results.Add(new PSBlock
+ {
+ Type = block.Type,
+ Flags = block.Flags,
+ Key = new byte[0],
+ Value = block.Value,
+ Data = block.Data
+ });
+ }
+ }
+
+ return results;
+ }
+
+ public IEnumerable<PSBlock> FindBlocks(uint valueSearch)
+ {
+ List<PSBlock> results = new List<PSBlock>();
+
+ foreach (VistaBlock block in Blocks)
+ {
+ if (block.ValueAsInt == valueSearch)
+ {
+ results.Add(new PSBlock
+ {
+ Type = block.Type,
+ Flags = block.Flags,
+ Key = new byte[0],
+ Value = block.Value,
+ Data = block.Data
+ });
+ }
+ }
+
+ return results;
+ }
+ }
+}
diff --git a/LibTSforge/PhysicalStore/PhysicalStoreWin7.cs b/LibTSforge/PhysicalStore/PhysicalStoreWin7.cs
index c1af391..d03bf9a 100644
--- a/LibTSforge/PhysicalStore/PhysicalStoreWin7.cs
+++ b/LibTSforge/PhysicalStore/PhysicalStoreWin7.cs
@@ -279,7 +279,7 @@ namespace LibTSforge.PhysicalStore
TSSecondary = File.Open(primaryPath.Replace("-0.", "-1."), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
Production = production;
- Deserialize(PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), production));
+ Deserialize(PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), production, PSVersion.Win7));
TSPrimary.Seek(0, SeekOrigin.Begin);
}
@@ -305,7 +305,7 @@ namespace LibTSforge.PhysicalStore
public byte[] ReadRaw()
{
- byte[] data = PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), Production);
+ byte[] data = PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), Production, PSVersion.Win7);
TSPrimary.Seek(0, SeekOrigin.Begin);
return data;
}
diff --git a/LibTSforge/PhysicalStore/VariableBag.cs b/LibTSforge/PhysicalStore/VariableBag.cs
index ddc2efe..76098a9 100644
--- a/LibTSforge/PhysicalStore/VariableBag.cs
+++ b/LibTSforge/PhysicalStore/VariableBag.cs
@@ -3,6 +3,7 @@ namespace LibTSforge.PhysicalStore
using System;
using System.Collections.Generic;
using System.IO;
+ using System.Runtime.CompilerServices;
public enum CRCBlockType : uint
{
@@ -11,7 +12,7 @@ namespace LibTSforge.PhysicalStore
BINARY = 1 << 2
}
- public class CRCBlock
+ public abstract class CRCBlock
{
public CRCBlockType DataType;
public byte[] Key;
@@ -50,7 +51,57 @@ namespace LibTSforge.PhysicalStore
}
}
- public void Encode(BinaryWriter writer)
+ public abstract void Encode(BinaryWriter writer);
+ public abstract void Decode(BinaryReader reader);
+ public abstract uint CRC();
+ }
+
+ public class CRCBlockVista : CRCBlock
+ {
+ public override void Encode(BinaryWriter writer)
+ {
+ uint crc = CRC();
+ writer.Write((uint)DataType);
+ writer.Write(0);
+ writer.Write(Key.Length);
+ writer.Write(Value.Length);
+ writer.Write(crc);
+
+ writer.Write(Key);
+
+ writer.Write(Value);
+ }
+
+ public override void Decode(BinaryReader reader)
+ {
+ uint type = reader.ReadUInt32();
+ uint unk_zero = reader.ReadUInt32();
+ uint lenName = reader.ReadUInt32();
+ uint lenVal = reader.ReadUInt32();
+ uint crc = reader.ReadUInt32();
+
+ byte[] key = reader.ReadBytes((int)lenName);
+ byte[] value = reader.ReadBytes((int)lenVal);
+
+ DataType = (CRCBlockType)type;
+ Key = key;
+ Value = value;
+
+ if (CRC() != crc)
+ {
+ throw new InvalidDataException("Invalid CRC in variable bag.");
+ }
+ }
+
+ public override uint CRC()
+ {
+ return Utils.CRC32(Value);
+ }
+ }
+
+ public class CRCBlockModern : CRCBlock
+ {
+ public override void Encode(BinaryWriter writer)
{
uint crc = CRC();
writer.Write(crc);
@@ -65,7 +116,7 @@ namespace LibTSforge.PhysicalStore
writer.Align(8);
}
- public static CRCBlock Decode(BinaryReader reader)
+ public override void Decode(BinaryReader reader)
{
uint crc = reader.ReadUInt32();
uint type = reader.ReadUInt32();
@@ -78,22 +129,17 @@ namespace LibTSforge.PhysicalStore
byte[] value = reader.ReadBytes((int)lenVal);
reader.Align(8);
- CRCBlock block = new CRCBlock
- {
- DataType = (CRCBlockType)type,
- Key = key,
- Value = value,
- };
+ DataType = (CRCBlockType)type;
+ Key = key;
+ Value = value;
- if (block.CRC() != crc)
+ if (CRC() != crc)
{
throw new InvalidDataException("Invalid CRC in variable bag.");
}
-
- return block;
}
- public uint CRC()
+ public override uint CRC()
{
BinaryWriter wtemp = new BinaryWriter(new MemoryStream());
wtemp.Write(0);
@@ -109,6 +155,7 @@ namespace LibTSforge.PhysicalStore
public class VariableBag
{
public List<CRCBlock> Blocks = new List<CRCBlock>();
+ private PSVersion Version;
public void Deserialize(byte[] data)
{
@@ -118,7 +165,19 @@ namespace LibTSforge.PhysicalStore
while (reader.BaseStream.Position < len - 0x10)
{
- Blocks.Add(CRCBlock.Decode(reader));
+ CRCBlock block;
+
+ if (Version == PSVersion.Vista)
+ {
+ block = new CRCBlockVista();
+ }
+ else
+ {
+ block = new CRCBlockModern();
+ }
+
+ block.Decode(reader);
+ Blocks.Add(block);
}
}
@@ -128,7 +187,13 @@ namespace LibTSforge.PhysicalStore
foreach (CRCBlock block in Blocks)
{
- block.Encode(writer);
+ if (Version == PSVersion.Vista)
+ {
+ ((CRCBlockVista)block).Encode(writer);
+ } else
+ {
+ ((CRCBlockModern)block).Encode(writer);
+ }
}
return writer.GetBytes();
@@ -174,14 +239,15 @@ namespace LibTSforge.PhysicalStore
}
}
- public VariableBag(byte[] data)
+ public VariableBag(byte[] data, PSVersion version)
{
+ Version = version;
Deserialize(data);
}
- public VariableBag()
+ public VariableBag(PSVersion version)
{
-
+ Version = version;
}
}
}