forked from Snoooopy/MetroUnlocker
Refactor and cleanup
This commit is contained in:
@@ -5,6 +5,11 @@ VisualStudioVersion = 12.0.40629.0
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetroUnlocker", "MetroUnlocker\MetroUnlocker.csproj", "{D27EB145-0B58-43AD-BB94-BE000D236D38}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetroUnlocker", "MetroUnlocker\MetroUnlocker.csproj", "{D27EB145-0B58-43AD-BB94-BE000D236D38}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C9C14067-F9A1-4D85-A1D2-162E91B71CC3}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
DependencyGraph.dgml = DependencyGraph.dgml
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|||||||
@@ -17,38 +17,38 @@ namespace MetroUnlocker
|
|||||||
{
|
{
|
||||||
public partial class App : Form
|
public partial class App : Form
|
||||||
{
|
{
|
||||||
public const string AppxKey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows\\Appx";
|
public const string AppxRegistryKey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows\\Appx";
|
||||||
|
|
||||||
string trustedAppsPolicyName = "AllowAllTrustedApps";
|
string TrustedAppsPolicyName = "AllowAllTrustedApps";
|
||||||
string developmentPolicyName = "AllowDevelopmentWithoutDevLicense";
|
string DevelopmentPolicyName = "AllowDevelopmentWithoutDevLicense";
|
||||||
string specialProfilesPolicyName = "AllowDeploymentInSpecialProfiles";
|
string SpecialProfilesPolicyName = "AllowDeploymentInSpecialProfiles";
|
||||||
|
|
||||||
public bool LOBEnabled
|
public bool LOBEnabled
|
||||||
{
|
{
|
||||||
get { return GetGroupPolicy(trustedAppsPolicyName); }
|
get { return GetGroupPolicy(TrustedAppsPolicyName); }
|
||||||
set { SetGroupPolicy(trustedAppsPolicyName, value); }
|
set { SetGroupPolicy(TrustedAppsPolicyName, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DevelopmentEnabled
|
public bool DevelopmentEnabled
|
||||||
{
|
{
|
||||||
get { return GetGroupPolicy(developmentPolicyName); }
|
get { return GetGroupPolicy(DevelopmentPolicyName); }
|
||||||
set { SetGroupPolicy(developmentPolicyName, value); }
|
set { SetGroupPolicy(DevelopmentPolicyName, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SpecialProfilesEnabled
|
public bool SpecialProfilesEnabled
|
||||||
{
|
{
|
||||||
get { return GetGroupPolicy(specialProfilesPolicyName); }
|
get { return GetGroupPolicy(SpecialProfilesPolicyName); }
|
||||||
set { SetGroupPolicy(specialProfilesPolicyName, value); }
|
set { SetGroupPolicy(SpecialProfilesPolicyName, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetGroupPolicy(string policyName, bool enabled)
|
public void SetGroupPolicy(string policyName, bool enabled)
|
||||||
{
|
{
|
||||||
Registry.SetValue(AppxKey, policyName, enabled ? 1 : 0, RegistryValueKind.DWord);
|
Registry.SetValue(AppxRegistryKey, policyName, enabled ? 1 : 0, RegistryValueKind.DWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetGroupPolicy(string policyName)
|
public bool GetGroupPolicy(string policyName)
|
||||||
{
|
{
|
||||||
object value = Registry.GetValue(AppxKey, policyName, 0);
|
object value = Registry.GetValue(AppxRegistryKey, policyName, 0);
|
||||||
return value is int ? (int)value == 1 : false;
|
return value is int ? (int)value == 1 : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,6 @@ namespace MetroUnlocker
|
|||||||
|
|
||||||
public static class Utils
|
public static class Utils
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll")]
|
|
||||||
public static extern uint GetSystemDefaultLCID();
|
|
||||||
|
|
||||||
public static string GetArchitecture()
|
public static string GetArchitecture()
|
||||||
{
|
{
|
||||||
string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE", EnvironmentVariableTarget.Machine).ToUpperInvariant();
|
string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE", EnvironmentVariableTarget.Machine).ToUpperInvariant();
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ namespace MetroUnlocker.LibTSForge.Crypto
|
|||||||
{
|
{
|
||||||
public static class CryptoUtils
|
public static class CryptoUtils
|
||||||
{
|
{
|
||||||
public static byte[] GenerateRandomKey(int len)
|
public static byte[] GenerateRandomKey(int length)
|
||||||
{
|
{
|
||||||
byte[] rand = new byte[len];
|
byte[] randomKey = new byte[length];
|
||||||
Random r = new Random();
|
Random random = new Random();
|
||||||
r.NextBytes(rand);
|
random.NextBytes(randomKey);
|
||||||
|
|
||||||
return rand;
|
return randomKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] AESEncrypt(byte[] data, byte[] key)
|
public static byte[] AESEncrypt(byte[] data, byte[] key)
|
||||||
|
|||||||
@@ -47,19 +47,19 @@ namespace MetroUnlocker.LibTSForge.Crypto
|
|||||||
byte[] aesKey = Encoding.UTF8.GetBytes("Boop Foxyz nose!");
|
byte[] aesKey = Encoding.UTF8.GetBytes("Boop Foxyz nose!");
|
||||||
byte[] hmacKey = CryptoUtils.GenerateRandomKey(0x10);
|
byte[] hmacKey = CryptoUtils.GenerateRandomKey(0x10);
|
||||||
|
|
||||||
byte[] encAesKey = CryptoUtils.RSAEncrypt(rsaKey, aesKey);
|
byte[] encryptedAesKey = CryptoUtils.RSAEncrypt(rsaKey, aesKey);
|
||||||
byte[] aesKeySig = CryptoUtils.RSASign(rsaKey, encAesKey);
|
byte[] aesKeySignature = CryptoUtils.RSASign(rsaKey, encryptedAesKey);
|
||||||
byte[] hmacSig = CryptoUtils.HMACSign(hmacKey, data);
|
byte[] hmacSignature = CryptoUtils.HMACSign(hmacKey, data);
|
||||||
|
|
||||||
byte[] decData = new byte[] { };
|
byte[] decData = new byte[] { };
|
||||||
decData = decData.Concat(hmacKey).Concat(hmacSig).Concat(BitConverter.GetBytes(0)).Concat(data).ToArray();
|
decData = decData.Concat(hmacKey).Concat(hmacSignature).Concat(BitConverter.GetBytes(0)).Concat(data).ToArray();
|
||||||
byte[] encData = CryptoUtils.AESEncrypt(decData, aesKey);
|
byte[] encData = CryptoUtils.AESEncrypt(decData, aesKey);
|
||||||
|
|
||||||
BinaryWriter bw = new BinaryWriter(new MemoryStream());
|
BinaryWriter bw = new BinaryWriter(new MemoryStream());
|
||||||
bw.Write(versionTable[version]);
|
bw.Write(versionTable[version]);
|
||||||
bw.Write(Encoding.UTF8.GetBytes("UNTRUSTSTORE"));
|
bw.Write(Encoding.UTF8.GetBytes("UNTRUSTSTORE"));
|
||||||
bw.Write(aesKeySig);
|
bw.Write(aesKeySignature);
|
||||||
bw.Write(encAesKey);
|
bw.Write(encryptedAesKey);
|
||||||
bw.Write(encData);
|
bw.Write(encData);
|
||||||
|
|
||||||
return bw.GetBytes();
|
return bw.GetBytes();
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace MetroUnlocker.LibTSForge.Modifiers
|
|||||||
Guid instPkeyId = SLApi.GetInstalledProductKeyId(actId);
|
Guid instPkeyId = SLApi.GetInstalledProductKeyId(actId);
|
||||||
if (instPkeyId != Guid.Empty) SLApi.UninstallProductKey(instPkeyId);
|
if (instPkeyId != Guid.Empty) SLApi.UninstallProductKey(instPkeyId);
|
||||||
|
|
||||||
if (pkey.Algorithm != PKeyAlgorithm.PKEY2009)
|
if (pkey.Algorithm != ProductKeyAlgorithm.ProductKey2009)
|
||||||
throw new Exception("The key algorithm isn't 2009");
|
throw new Exception("The key algorithm isn't 2009");
|
||||||
|
|
||||||
uint status = SLApi.InstallProductKey(pkey);
|
uint status = SLApi.InstallProductKey(pkey);
|
||||||
|
|||||||
@@ -90,92 +90,33 @@ namespace MetroUnlocker.LibTSForge.PhysicalStore
|
|||||||
|
|
||||||
public void AddBlocks(IEnumerable<ModernBlock> blocks)
|
public void AddBlocks(IEnumerable<ModernBlock> blocks)
|
||||||
{
|
{
|
||||||
foreach (ModernBlock block in blocks)
|
foreach (ModernBlock block in blocks) AddBlock(block);
|
||||||
{
|
|
||||||
AddBlock(block);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModernBlock GetBlock(string key, string value)
|
public ModernBlock GetBlock(string key, string value)
|
||||||
{
|
{
|
||||||
List<ModernBlock> blocks = Data[key];
|
if (!Data.ContainsKey(key)) return null;
|
||||||
|
return Data[key].Find(block => block.ValueAsString == value);
|
||||||
foreach (ModernBlock block in blocks)
|
|
||||||
{
|
|
||||||
if (block.ValueAsString == value)
|
|
||||||
{
|
|
||||||
return new ModernBlock
|
|
||||||
{
|
|
||||||
Type = block.Type,
|
|
||||||
Flags = block.Flags,
|
|
||||||
Key = Utils.EncodeString(key),
|
|
||||||
Value = block.Value,
|
|
||||||
Data = block.Data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModernBlock GetBlock(string key, uint value)
|
public ModernBlock GetBlock(string key, uint value)
|
||||||
{
|
{
|
||||||
List<ModernBlock> blocks = Data[key];
|
if (!Data.ContainsKey(key)) return null;
|
||||||
|
return Data[key].Find(block => block.ValueAsInteger == value);
|
||||||
foreach (ModernBlock block in blocks)
|
|
||||||
{
|
|
||||||
if (block.ValueAsInteger == value)
|
|
||||||
{
|
|
||||||
return new ModernBlock
|
|
||||||
{
|
|
||||||
Type = block.Type,
|
|
||||||
Flags = block.Flags,
|
|
||||||
Key = Utils.EncodeString(key),
|
|
||||||
Value = block.Value,
|
|
||||||
Data = block.Data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBlock(string key, string value, byte[] data)
|
public void SetBlock(string key, string value, byte[] data)
|
||||||
{
|
{
|
||||||
List<ModernBlock> blocks = Data[key];
|
if (!Data.ContainsKey(key)) return;
|
||||||
|
int index = Data[key].FindIndex(block => block.ValueAsString == value);
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
Data[key][index].Data = data;
|
||||||
{
|
|
||||||
ModernBlock block = blocks[i];
|
|
||||||
|
|
||||||
if (block.ValueAsString == value)
|
|
||||||
{
|
|
||||||
block.Data = data;
|
|
||||||
blocks[i] = block;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Data[key] = blocks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBlock(string key, uint value, byte[] data)
|
public void SetBlock(string key, uint value, byte[] data)
|
||||||
{
|
{
|
||||||
List<ModernBlock> blocks = Data[key];
|
if (!Data.ContainsKey(key)) return;
|
||||||
|
int index = Data[key].FindIndex(block => block.ValueAsInteger == value);
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
Data[key][index].Data = data;
|
||||||
{
|
|
||||||
ModernBlock block = blocks[i];
|
|
||||||
|
|
||||||
if (block.ValueAsInteger == value)
|
|
||||||
{
|
|
||||||
block.Data = data;
|
|
||||||
blocks[i] = block;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Data[key] = blocks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBlock(string key, string value, string data)
|
public void SetBlock(string key, string value, string data)
|
||||||
@@ -200,40 +141,12 @@ namespace MetroUnlocker.LibTSForge.PhysicalStore
|
|||||||
|
|
||||||
public void DeleteBlock(string key, string value)
|
public void DeleteBlock(string key, string value)
|
||||||
{
|
{
|
||||||
if (Data.ContainsKey(key))
|
Data[key].Remove(GetBlock(key, value));
|
||||||
{
|
|
||||||
List<ModernBlock> blocks = Data[key];
|
|
||||||
|
|
||||||
foreach (ModernBlock block in blocks)
|
|
||||||
{
|
|
||||||
if (block.ValueAsString == value)
|
|
||||||
{
|
|
||||||
blocks.Remove(block);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Data[key] = blocks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteBlock(string key, uint value)
|
public void DeleteBlock(string key, uint value)
|
||||||
{
|
{
|
||||||
if (Data.ContainsKey(key))
|
Data[key].Remove(GetBlock(key, value));
|
||||||
{
|
|
||||||
List<ModernBlock> blocks = Data[key];
|
|
||||||
|
|
||||||
foreach (ModernBlock block in blocks)
|
|
||||||
{
|
|
||||||
if (block.ValueAsInteger == value)
|
|
||||||
{
|
|
||||||
blocks.Remove(block);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Data[key] = blocks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetPath()
|
public static string GetPath()
|
||||||
|
|||||||
91
MetroUnlocker/LibTSForge/SPP/NativeMethods.cs
Normal file
91
MetroUnlocker/LibTSForge/SPP/NativeMethods.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace MetroUnlocker.LibTSForge.SPP
|
||||||
|
{
|
||||||
|
public enum SLIDType
|
||||||
|
{
|
||||||
|
Application,
|
||||||
|
ProductSku,
|
||||||
|
LicenseFile,
|
||||||
|
License,
|
||||||
|
ProductKey,
|
||||||
|
AllLicenses,
|
||||||
|
AllLicenseFiles,
|
||||||
|
StoreToken,
|
||||||
|
Last
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SLDataType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
String,
|
||||||
|
DWord,
|
||||||
|
Binary,
|
||||||
|
MultiString,
|
||||||
|
Sum
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct SLLicensingStatus
|
||||||
|
{
|
||||||
|
public Guid SkuId;
|
||||||
|
public uint Status;
|
||||||
|
public uint GraceTimeDWord;
|
||||||
|
public uint TotalGraceDaysDWord;
|
||||||
|
public uint ReasonHResult;
|
||||||
|
public ulong ValidityExpiration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NativeMethods
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
internal static extern uint GetSystemDefaultLCID();
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
||||||
|
internal static extern void SLOpen(out IntPtr hSLC);
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
||||||
|
internal static extern void SLClose(IntPtr hSLC);
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLInstallProofOfPurchase(IntPtr hSLC, string pwszPKeyAlgorithm, string pwszPKeyString, uint cbPKeySpecificData, byte[] pbPKeySpecificData, ref Guid PKeyId);
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLUninstallProofOfPurchase(IntPtr hSLC, ref Guid PKeyId);
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLGenerateOfflineInstallationId(IntPtr hSLC, ref Guid pProductSkuId, ref string ppwszInstallationId);
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLDepositOfflineConfirmationId(IntPtr hSLC, ref Guid pProductSkuId, string pwszInstallationId, string pwszConfirmationId);
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLGetSLIDList(IntPtr hSLC, SLIDType eQueryIdType, ref Guid pQueryId, SLIDType eReturnIdType, out uint pnReturnIds, out IntPtr ppReturnIds);
|
||||||
|
|
||||||
|
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLGetInstalledProductKeyIds(IntPtr hSLC, ref Guid pProductSkuId, out uint pnProductKeyIds, out IntPtr ppProductKeyIds);
|
||||||
|
|
||||||
|
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLConsumeWindowsRight(uint unknown);
|
||||||
|
|
||||||
|
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLGetProductSkuInformation(IntPtr hSLC, ref Guid pProductSkuId, string pwszValueName, out SLDataType peDataType, out uint pcbValue, out IntPtr ppbValue);
|
||||||
|
|
||||||
|
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLGetProductSkuInformation(IntPtr hSLC, ref Guid pProductSkuId, string pwszValueName, IntPtr peDataType, out uint pcbValue, out IntPtr ppbValue);
|
||||||
|
|
||||||
|
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLGetLicense(IntPtr hSLC, ref Guid pLicenseFileId, out uint pcbLicenseFile, out IntPtr ppbLicenseFile);
|
||||||
|
|
||||||
|
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLSetCurrentProductKey(IntPtr hSLC, ref Guid pProductSkuId, ref Guid pProductKeyId);
|
||||||
|
|
||||||
|
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern uint SLFireEvent(IntPtr hSLC, string pwszEventId, ref Guid pApplicationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
public int Serial;
|
public int Serial;
|
||||||
public ulong Security;
|
public ulong Security;
|
||||||
public bool Upgrade;
|
public bool Upgrade;
|
||||||
public PKeyAlgorithm Algorithm;
|
public ProductKeyAlgorithm Algorithm;
|
||||||
public string EulaType;
|
public string EulaType;
|
||||||
public string PartNumber;
|
public string PartNumber;
|
||||||
public string Edition;
|
public string Edition;
|
||||||
@@ -37,7 +37,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
get { return BitConverter.GetBytes(klow).Concat(BitConverter.GetBytes(khigh)).ToArray(); }
|
get { return BitConverter.GetBytes(klow).Concat(BitConverter.GetBytes(khigh)).ToArray(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProductKey(int serial, ulong security, bool upgrade, PKeyAlgorithm algorithm, ProductConfig config, KeyRange range)
|
public ProductKey(int serial, ulong security, bool upgrade, ProductKeyAlgorithm algorithm, ProductConfig config, KeyRange range)
|
||||||
{
|
{
|
||||||
Group = config.GroupId;
|
Group = config.GroupId;
|
||||||
Serial = serial;
|
Serial = serial;
|
||||||
@@ -60,7 +60,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
|
|
||||||
public string GetAlgoUri()
|
public string GetAlgoUri()
|
||||||
{
|
{
|
||||||
return "msft:rm/algorithm/pkey/" + (Algorithm == PKeyAlgorithm.PKEY2005 ? "2005" : (Algorithm == PKeyAlgorithm.PKEY2009 ? "2009" : "Unknown"));
|
return "msft:rm/algorithm/pkey/" + (Algorithm == ProductKeyAlgorithm.ProductKey2005 ? "2005" : (Algorithm == ProductKeyAlgorithm.ProductKey2009 ? "2009" : "Unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid GetPkeyId()
|
public Guid GetPkeyId()
|
||||||
@@ -137,7 +137,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
|
|
||||||
pid2 = "";
|
pid2 = "";
|
||||||
|
|
||||||
if (Algorithm == PKeyAlgorithm.PKEY2005)
|
if (Algorithm == ProductKeyAlgorithm.ProductKey2005)
|
||||||
{
|
{
|
||||||
string mpc = GetMPC();
|
string mpc = GetMPC();
|
||||||
string serialHigh;
|
string serialHigh;
|
||||||
@@ -211,7 +211,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
int serialHigh = Serial / 1000000;
|
int serialHigh = Serial / 1000000;
|
||||||
int serialLow = Serial % 1000000;
|
int serialLow = Serial % 1000000;
|
||||||
int licenseType;
|
int licenseType;
|
||||||
uint lcid = Utils.GetSystemDefaultLCID();
|
uint lcid = NativeMethods.GetSystemDefaultLCID();
|
||||||
int build = Environment.OSVersion.Version.Build;
|
int build = Environment.OSVersion.Version.Build;
|
||||||
int dayOfYear = DateTime.Now.DayOfYear;
|
int dayOfYear = DateTime.Now.DayOfYear;
|
||||||
int year = DateTime.Now.Year;
|
int year = DateTime.Now.Year;
|
||||||
@@ -266,7 +266,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
string keyStr = "";
|
string keyStr = "";
|
||||||
Random rnd = new Random(Group * 1000000000 + Serial);
|
Random rnd = new Random(Group * 1000000000 + Serial);
|
||||||
|
|
||||||
if (Algorithm == PKeyAlgorithm.PKEY2005)
|
if (Algorithm == ProductKeyAlgorithm.ProductKey2005)
|
||||||
{
|
{
|
||||||
keyStr = "H4X3DH4X3DH4X3DH4X3D";
|
keyStr = "H4X3DH4X3DH4X3DH4X3D";
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
keyStr += ALPHABET[rnd.Next(24)];
|
keyStr += ALPHABET[rnd.Next(24)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Algorithm == PKeyAlgorithm.PKEY2009)
|
else if (Algorithm == ProductKeyAlgorithm.ProductKey2009)
|
||||||
{
|
{
|
||||||
int last = 0;
|
int last = 0;
|
||||||
byte[] bKey = KeyBytes;
|
byte[] bKey = KeyBytes;
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ using System.Xml;
|
|||||||
namespace MetroUnlocker.LibTSForge.SPP
|
namespace MetroUnlocker.LibTSForge.SPP
|
||||||
{
|
{
|
||||||
|
|
||||||
public enum PKeyAlgorithm
|
public enum ProductKeyAlgorithm
|
||||||
{
|
{
|
||||||
PKEY2005,
|
ProductKey2005,
|
||||||
PKEY2009
|
ProductKey2009
|
||||||
}
|
}
|
||||||
|
|
||||||
public class KeyRange
|
public class KeyRange
|
||||||
@@ -23,10 +23,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
public string PartNumber;
|
public string PartNumber;
|
||||||
public bool Valid;
|
public bool Valid;
|
||||||
|
|
||||||
public bool Contains(int n)
|
public bool Contains(int n) { return Start <= n && End <= n; }
|
||||||
{
|
|
||||||
return Start <= n && End <= n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProductConfig
|
public class ProductConfig
|
||||||
@@ -36,39 +33,33 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
public string Description;
|
public string Description;
|
||||||
public string Channel;
|
public string Channel;
|
||||||
public bool Randomized;
|
public bool Randomized;
|
||||||
public PKeyAlgorithm Algorithm;
|
public ProductKeyAlgorithm Algorithm;
|
||||||
public List<KeyRange> Ranges;
|
public List<KeyRange> Ranges;
|
||||||
public Guid ActivationId;
|
public Guid ActivationId;
|
||||||
|
|
||||||
private List<KeyRange> GetPkeyRanges()
|
private List<KeyRange> GetProductKeyRanges()
|
||||||
{
|
{
|
||||||
if (Ranges.Count == 0)
|
if (Ranges.Count == 0)
|
||||||
{
|
|
||||||
throw new ArgumentException("No key ranges.");
|
throw new ArgumentException("No key ranges.");
|
||||||
}
|
|
||||||
|
|
||||||
if (Algorithm == PKeyAlgorithm.PKEY2005)
|
if (Algorithm == ProductKeyAlgorithm.ProductKey2005)
|
||||||
{
|
|
||||||
return Ranges;
|
return Ranges;
|
||||||
}
|
|
||||||
|
|
||||||
List<KeyRange> FilteredRanges = Ranges.Where(r => !r.EulaType.Contains("WAU")).ToList();
|
List<KeyRange> FilteredRanges = Ranges.FindAll(r => !r.EulaType.Contains("WAU"));
|
||||||
|
|
||||||
if (FilteredRanges.Count == 0)
|
if (FilteredRanges.Count == 0)
|
||||||
{
|
|
||||||
throw new NotSupportedException("Specified Activation ID is usable only for Windows Anytime Upgrade. Please use a non-WAU Activation ID instead.");
|
throw new NotSupportedException("Specified Activation ID is usable only for Windows Anytime Upgrade. Please use a non-WAU Activation ID instead.");
|
||||||
}
|
|
||||||
|
|
||||||
return FilteredRanges;
|
return FilteredRanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProductKey GetRandomKey()
|
public ProductKey GetRandomKey()
|
||||||
{
|
{
|
||||||
List<KeyRange> KeyRanges = GetPkeyRanges();
|
List<KeyRange> KeyRanges = GetProductKeyRanges();
|
||||||
Random rnd = new Random();
|
Random random = new Random();
|
||||||
|
|
||||||
KeyRange range = KeyRanges[rnd.Next(KeyRanges.Count)];
|
KeyRange range = KeyRanges[random.Next(KeyRanges.Count)];
|
||||||
int serial = rnd.Next(range.Start, range.End);
|
int serial = random.Next(range.Start, range.End);
|
||||||
|
|
||||||
return new ProductKey(serial, 0, false, Algorithm, this, range);
|
return new ProductKey(serial, 0, false, Algorithm, this, range);
|
||||||
}
|
}
|
||||||
@@ -77,29 +68,32 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
public class ProductKeyConfig
|
public class ProductKeyConfig
|
||||||
{
|
{
|
||||||
public Dictionary<Guid, ProductConfig> Products = new Dictionary<Guid, ProductConfig>();
|
public Dictionary<Guid, ProductConfig> Products = new Dictionary<Guid, ProductConfig>();
|
||||||
private List<Guid> loadedPkeyConfigs = new List<Guid>();
|
private List<Guid> _loadedProductKeyConfigs = new List<Guid>();
|
||||||
|
|
||||||
public void LoadConfig(Guid actId)
|
public void LoadConfig(Guid actId)
|
||||||
{
|
{
|
||||||
string pkcData;
|
string pkcData;
|
||||||
Guid pkcFileId = SLApi.GetPkeyConfigFileId(actId);
|
Guid configFileId = SLApi.GetProductKeyConfigFileId(actId);
|
||||||
|
|
||||||
if (loadedPkeyConfigs.Contains(pkcFileId)) return;
|
if (configFileId == Guid.Empty) throw new Exception("This edition of Windows does not support sideloading keys.");
|
||||||
|
|
||||||
string licConts = SLApi.GetLicenseContents(pkcFileId);
|
if (_loadedProductKeyConfigs.Contains(configFileId)) return;
|
||||||
|
|
||||||
using (TextReader tr = new StringReader(licConts))
|
string licenseContents = SLApi.GetLicenseContents(configFileId);
|
||||||
|
|
||||||
|
|
||||||
|
using (TextReader tr = new StringReader(licenseContents))
|
||||||
{
|
{
|
||||||
XmlDocument lic = new XmlDocument();
|
XmlDocument lic = new XmlDocument();
|
||||||
lic.Load(tr);
|
lic.Load(tr);
|
||||||
|
|
||||||
XmlNamespaceManager nsmgr = new XmlNamespaceManager(lic.NameTable);
|
XmlNamespaceManager nsmgr = new XmlNamespaceManager(lic.NameTable);
|
||||||
nsmgr.AddNamespace("rg", "urn:mpeg:mpeg21:2003:01-REL-R-NS");
|
nsmgr.AddNamespace("rg", "urn:mpeg:mpeg21:2003:01-REL-R-NS");
|
||||||
nsmgr.AddNamespace("r", "urn:mpeg:mpeg21:2003:01-REL-R-NS");
|
nsmgr.AddNamespace("random", "urn:mpeg:mpeg21:2003:01-REL-R-NS");
|
||||||
nsmgr.AddNamespace("tm", "http://www.microsoft.com/DRM/XrML2/TM/v2");
|
nsmgr.AddNamespace("tm", "http://www.microsoft.com/DRM/XrML2/TM/v2");
|
||||||
|
|
||||||
XmlNode root = lic.DocumentElement;
|
XmlNode root = lic.DocumentElement;
|
||||||
XmlNode pkcDataNode = root.SelectSingleNode("/rg:licenseGroup/r:license/r:otherInfo/tm:infoTables/tm:infoList/tm:infoBin[@name=\"pkeyConfigData\"]", nsmgr);
|
XmlNode pkcDataNode = root.SelectSingleNode("/rg:licenseGroup/random:license/random:otherInfo/tm:infoTables/tm:infoList/tm:infoBin[@name=\"pkeyConfigData\"]", nsmgr);
|
||||||
pkcData = Encoding.UTF8.GetString(Convert.FromBase64String(pkcDataNode.InnerText));
|
pkcData = Encoding.UTF8.GetString(Convert.FromBase64String(pkcDataNode.InnerText));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,13 +108,13 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
XmlNodeList rangeNodes = lic.SelectNodes("//p:ProductKeyConfiguration/p:KeyRanges/p:KeyRange", nsmgr);
|
XmlNodeList rangeNodes = lic.SelectNodes("//p:ProductKeyConfiguration/p:KeyRanges/p:KeyRange", nsmgr);
|
||||||
XmlNodeList pubKeyNodes = lic.SelectNodes("//p:ProductKeyConfiguration/p:PublicKeys/p:PublicKey", nsmgr);
|
XmlNodeList pubKeyNodes = lic.SelectNodes("//p:ProductKeyConfiguration/p:PublicKeys/p:PublicKey", nsmgr);
|
||||||
|
|
||||||
Dictionary<int, PKeyAlgorithm> algorithms = new Dictionary<int, PKeyAlgorithm>();
|
Dictionary<int, ProductKeyAlgorithm> algorithms = new Dictionary<int, ProductKeyAlgorithm>();
|
||||||
Dictionary<string, List<KeyRange>> ranges = new Dictionary<string, List<KeyRange>>();
|
Dictionary<string, List<KeyRange>> ranges = new Dictionary<string, List<KeyRange>>();
|
||||||
|
|
||||||
Dictionary<string, PKeyAlgorithm> algoConv = new Dictionary<string, PKeyAlgorithm>
|
Dictionary<string, ProductKeyAlgorithm> algoConv = new Dictionary<string, ProductKeyAlgorithm>
|
||||||
{
|
{
|
||||||
{ "msft:rm/algorithm/pkey/2005", PKeyAlgorithm.PKEY2005 },
|
{ "msft:rm/algorithm/pkey/2005", ProductKeyAlgorithm.ProductKey2005 },
|
||||||
{ "msft:rm/algorithm/pkey/2009", PKeyAlgorithm.PKEY2009 }
|
{ "msft:rm/algorithm/pkey/2009", ProductKeyAlgorithm.ProductKey2009 }
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (XmlNode pubKeyNode in pubKeyNodes)
|
foreach (XmlNode pubKeyNode in pubKeyNodes)
|
||||||
@@ -131,12 +125,10 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
|
|
||||||
foreach (XmlNode rangeNode in rangeNodes)
|
foreach (XmlNode rangeNode in rangeNodes)
|
||||||
{
|
{
|
||||||
string refActIdStr = rangeNode.SelectSingleNode("./p:RefActConfigId", nsmgr).InnerText;
|
string refActIdString = rangeNode.SelectSingleNode("./p:RefActConfigId", nsmgr).InnerText;
|
||||||
|
|
||||||
if (!ranges.ContainsKey(refActIdStr))
|
if (!ranges.ContainsKey(refActIdString))
|
||||||
{
|
ranges[refActIdString] = new List<KeyRange>();
|
||||||
ranges[refActIdStr] = new List<KeyRange>();
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyRange keyRange = new KeyRange();
|
KeyRange keyRange = new KeyRange();
|
||||||
keyRange.Start = int.Parse(rangeNode.SelectSingleNode("./p:Start", nsmgr).InnerText);
|
keyRange.Start = int.Parse(rangeNode.SelectSingleNode("./p:Start", nsmgr).InnerText);
|
||||||
@@ -145,15 +137,15 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
keyRange.PartNumber = rangeNode.SelectSingleNode("./p:PartNumber", nsmgr).InnerText;
|
keyRange.PartNumber = rangeNode.SelectSingleNode("./p:PartNumber", nsmgr).InnerText;
|
||||||
keyRange.Valid = rangeNode.SelectSingleNode("./p:IsValid", nsmgr).InnerText.ToLower() == "true";
|
keyRange.Valid = rangeNode.SelectSingleNode("./p:IsValid", nsmgr).InnerText.ToLower() == "true";
|
||||||
|
|
||||||
ranges[refActIdStr].Add(keyRange);
|
ranges[refActIdString].Add(keyRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (XmlNode configNode in configNodes)
|
foreach (XmlNode configNode in configNodes)
|
||||||
{
|
{
|
||||||
string refActIdStr = configNode.SelectSingleNode("./p:ActConfigId", nsmgr).InnerText;
|
string refActIdString = configNode.SelectSingleNode("./p:ActConfigId", nsmgr).InnerText;
|
||||||
Guid refActId = new Guid(refActIdStr);
|
Guid refActId = new Guid(refActIdString);
|
||||||
int group = int.Parse(configNode.SelectSingleNode("./p:RefGroupId", nsmgr).InnerText);
|
int group = int.Parse(configNode.SelectSingleNode("./p:RefGroupId", nsmgr).InnerText);
|
||||||
List<KeyRange> keyRanges = ranges[refActIdStr];
|
List<KeyRange> keyRanges = ranges[refActIdString];
|
||||||
|
|
||||||
if (keyRanges.Count > 0 && !Products.ContainsKey(refActId))
|
if (keyRanges.Count > 0 && !Products.ContainsKey(refActId))
|
||||||
{
|
{
|
||||||
@@ -172,31 +164,14 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedPkeyConfigs.Add(pkcFileId);
|
_loadedProductKeyConfigs.Add(configFileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProductConfig MatchParams(int group, int serial)
|
public ProductConfig MatchParams(int groupId, int serial)
|
||||||
{
|
{
|
||||||
foreach (ProductConfig config in Products.Values)
|
ProductConfig matchingConfig = Products.Values.FirstOrDefault(config => config.GroupId == groupId && config.Ranges.Any(range => range.Contains(serial)));
|
||||||
{
|
if (matchingConfig == null) throw new FileNotFoundException("Failed to find product matching supplied product key parameters.");
|
||||||
if (config.GroupId == group)
|
return matchingConfig;
|
||||||
{
|
|
||||||
foreach (KeyRange range in config.Ranges)
|
|
||||||
{
|
|
||||||
if (range.Contains(serial))
|
|
||||||
{
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new FileNotFoundException("Failed to find product matching supplied product key parameters.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProductKeyConfig()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,142 +3,42 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MetroUnlocker.LibTSForge.SPP
|
namespace MetroUnlocker.LibTSForge.SPP
|
||||||
{
|
{
|
||||||
public static class SLApi
|
public static class SLApi
|
||||||
{
|
{
|
||||||
private enum SLIDType
|
|
||||||
{
|
|
||||||
SLIDApplication,
|
|
||||||
SLIDProductSku,
|
|
||||||
SLIDLicenseFile,
|
|
||||||
SLIDLicense,
|
|
||||||
SL_ID_PKEY,
|
|
||||||
SL_ID_ALL_LICENSES,
|
|
||||||
SL_ID_ALL_LICENSE_FILES,
|
|
||||||
SL_ID_STORE_TOKEN,
|
|
||||||
SL_ID_LAST
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum SLDataType
|
|
||||||
{
|
|
||||||
SL_DATA_NONE,
|
|
||||||
SL_DATA_SZ,
|
|
||||||
SL_DATA_DWORD,
|
|
||||||
SL_DATA_BINARY,
|
|
||||||
SL_DATA_MULTI_SZ,
|
|
||||||
SL_DATA_SUM
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
private struct SLLicensingStatus
|
|
||||||
{
|
|
||||||
public Guid SkuId;
|
|
||||||
public uint eStatus;
|
|
||||||
public uint dwGraceTime;
|
|
||||||
public uint dwTotalGraceDays;
|
|
||||||
public uint hrReason;
|
|
||||||
public ulong qwValidityExpiration;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
|
||||||
private static extern void SLOpen(out IntPtr hSLC);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
|
||||||
private static extern void SLClose(IntPtr hSLC);
|
|
||||||
|
|
||||||
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGetWindowsInformationDWORD(string ValueName, ref int Value);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLInstallProofOfPurchase(IntPtr hSLC, string pwszPKeyAlgorithm, string pwszPKeyString, uint cbPKeySpecificData, byte[] pbPKeySpecificData, ref Guid PKeyId);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLUninstallProofOfPurchase(IntPtr hSLC, ref Guid PKeyId);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGetPKeyInformation(IntPtr hSLC, ref Guid pPKeyId, string pwszValueName, out SLDataType peDataType, out uint pcbValue, out IntPtr ppbValue);
|
|
||||||
|
|
||||||
[DllImport("sppcext.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLActivateProduct(IntPtr hSLC, ref Guid pProductSkuId, byte[] cbAppSpecificData, byte[] pvAppSpecificData, byte[] pActivationInfo, string pwszProxyServer, ushort wProxyPort);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGenerateOfflineInstallationId(IntPtr hSLC, ref Guid pProductSkuId, ref string ppwszInstallationId);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLDepositOfflineConfirmationId(IntPtr hSLC, ref Guid pProductSkuId, string pwszInstallationId, string pwszConfirmationId);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGetSLIDList(IntPtr hSLC, SLIDType eQueryIdType, ref Guid pQueryId, SLIDType eReturnIdType, out uint pnReturnIds, out IntPtr ppReturnIds);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
|
||||||
private static extern void SLGetLicensingStatusInformation(IntPtr hSLC, ref Guid pAppID, IntPtr pProductSkuId, string pwszRightName, out uint pnStatusCount, out IntPtr ppLicensingStatus);
|
|
||||||
|
|
||||||
[DllImport("sppc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGetInstalledProductKeyIds(IntPtr hSLC, ref Guid pProductSkuId, out uint pnProductKeyIds, out IntPtr ppProductKeyIds);
|
|
||||||
|
|
||||||
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLConsumeWindowsRight(uint unknown);
|
|
||||||
|
|
||||||
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGetProductSkuInformation(IntPtr hSLC, ref Guid pProductSkuId, string pwszValueName, out SLDataType peDataType, out uint pcbValue, out IntPtr ppbValue);
|
|
||||||
|
|
||||||
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGetProductSkuInformation(IntPtr hSLC, ref Guid pProductSkuId, string pwszValueName, IntPtr peDataType, out uint pcbValue, out IntPtr ppbValue);
|
|
||||||
|
|
||||||
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLGetLicense(IntPtr hSLC, ref Guid pLicenseFileId, out uint pcbLicenseFile, out IntPtr ppbLicenseFile);
|
|
||||||
|
|
||||||
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLSetCurrentProductKey(IntPtr hSLC, ref Guid pProductSkuId, ref Guid pProductKeyId);
|
|
||||||
|
|
||||||
[DllImport("slc.dll", CharSet = CharSet.Unicode)]
|
|
||||||
private static extern uint SLFireEvent(IntPtr hSLC, string pwszEventId, ref Guid pApplicationId);
|
|
||||||
|
|
||||||
public class SLContext : IDisposable
|
public class SLContext : IDisposable
|
||||||
{
|
{
|
||||||
public readonly IntPtr Handle;
|
public readonly IntPtr Handle;
|
||||||
|
|
||||||
public SLContext()
|
public SLContext() { NativeMethods.SLOpen(out Handle); }
|
||||||
{
|
|
||||||
SLOpen(out Handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
SLClose(Handle);
|
NativeMethods.SLClose(Handle);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SLContext()
|
~SLContext() { Dispose(); }
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Guid GetPkeyConfigFileId(Guid actId)
|
public static Guid GetProductKeyConfigFileId(Guid activationId)
|
||||||
{
|
{
|
||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
{
|
{
|
||||||
SLDataType type;
|
SLDataType type;
|
||||||
uint len;
|
uint length;
|
||||||
IntPtr ppReturnLics;
|
IntPtr fileIdPointer;
|
||||||
|
|
||||||
uint status = SLGetProductSkuInformation(sl.Handle, ref actId, "pkeyConfigLicenseId", out type, out len, out ppReturnLics);
|
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref activationId, "pkeyConfigLicenseId", out type, out length, out fileIdPointer);
|
||||||
|
|
||||||
if (status != 0 || len == 0)
|
if (status != 0 || length == 0)
|
||||||
{
|
|
||||||
return Guid.Empty;
|
return Guid.Empty;
|
||||||
}
|
|
||||||
|
|
||||||
Guid pkcId = new Guid(Marshal.PtrToStringAuto(ppReturnLics));
|
Guid configLicenseId = new Guid(Marshal.PtrToStringAuto(fileIdPointer));
|
||||||
return GetLicenseFileId(pkcId);
|
return GetLicenseFileId(configLicenseId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,9 +50,9 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
uint count;
|
uint count;
|
||||||
IntPtr returnLicenses;
|
IntPtr returnLicenses;
|
||||||
|
|
||||||
status = SLGetSLIDList(sl.Handle, SLIDType.SLIDLicense, ref licenseId, SLIDType.SLIDLicenseFile, out count, out returnLicenses);
|
status = NativeMethods.SLGetSLIDList(sl.Handle, SLIDType.License, ref licenseId, SLIDType.LicenseFile, out count, out returnLicenses);
|
||||||
|
|
||||||
return (status == 0 && count != 0) ? (Guid)Marshal.PtrToStructure(returnLicenses, typeof(Guid)) : Guid.Empty;//new Guid(Marshal.PtrToStringAuto(returnLicenses));
|
return (status == 0 && count != 0) ? (Guid)Marshal.PtrToStructure(returnLicenses, typeof(Guid)) : Guid.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,14 +62,14 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
|
|
||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
{
|
{
|
||||||
uint dataLen;
|
uint length;
|
||||||
IntPtr dataPtr;
|
IntPtr dataPointer;
|
||||||
|
|
||||||
if (SLGetLicense(sl.Handle, ref fileId, out dataLen, out dataPtr) != 0)
|
if (NativeMethods.SLGetLicense(sl.Handle, ref fileId, out length, out dataPointer) != 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
byte[] data = new byte[dataLen];
|
byte[] data = new byte[length];
|
||||||
Marshal.Copy(dataPtr, data, 0, (int)dataLen);
|
Marshal.Copy(dataPointer, data, 0, (int)length);
|
||||||
|
|
||||||
data = data.Skip(Array.IndexOf(data, (byte)'<')).ToArray();
|
data = data.Skip(Array.IndexOf(data, (byte)'<')).ToArray();
|
||||||
return Encoding.UTF8.GetString(data);
|
return Encoding.UTF8.GetString(data);
|
||||||
@@ -184,9 +84,9 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
SLDataType type;
|
SLDataType type;
|
||||||
IntPtr binaryValue;
|
IntPtr binaryValue;
|
||||||
|
|
||||||
uint status = SLGetProductSkuInformation(sl.Handle, ref productSkuId, value, out type, out length, out binaryValue);
|
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref productSkuId, value, out type, out length, out binaryValue);
|
||||||
|
|
||||||
if (status != 0 || length == 0 || type != SLDataType.SL_DATA_SZ)
|
if (status != 0 || length == 0 || type != SLDataType.String)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return Marshal.PtrToStringAuto(binaryValue);
|
return Marshal.PtrToStringAuto(binaryValue);
|
||||||
@@ -198,7 +98,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
{
|
{
|
||||||
string installationId = null;
|
string installationId = null;
|
||||||
var status = SLGenerateOfflineInstallationId(sl.Handle, ref actId, ref installationId);
|
var status = NativeMethods.SLGenerateOfflineInstallationId(sl.Handle, ref actId, ref installationId);
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
throw new Exception(string.Format("Failed to get installation ID: 0x{0}. Your data.dat is probably corrupt at the moment. Try again later.", status.ToString("X")));
|
throw new Exception(string.Format("Failed to get installation ID: 0x{0}. Your data.dat is probably corrupt at the moment. Try again later.", status.ToString("X")));
|
||||||
@@ -215,7 +115,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
uint count;
|
uint count;
|
||||||
IntPtr productKeyIds;
|
IntPtr productKeyIds;
|
||||||
|
|
||||||
status = SLGetInstalledProductKeyIds(sl.Handle, ref actId, out count, out productKeyIds);
|
status = NativeMethods.SLGetInstalledProductKeyIds(sl.Handle, ref actId, out count, out productKeyIds);
|
||||||
|
|
||||||
return (status == 0 && count != 0) ? (Guid)Marshal.PtrToStructure(productKeyIds, typeof(Guid)) : Guid.Empty;
|
return (status == 0 && count != 0) ? (Guid)Marshal.PtrToStructure(productKeyIds, typeof(Guid)) : Guid.Empty;
|
||||||
}
|
}
|
||||||
@@ -224,12 +124,12 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
public static uint DepositConfirmationId(Guid actId, string installationId, string confirmationId)
|
public static uint DepositConfirmationId(Guid actId, string installationId, string confirmationId)
|
||||||
{
|
{
|
||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
return SLDepositOfflineConfirmationId(sl.Handle, ref actId, installationId, confirmationId);
|
return NativeMethods.SLDepositOfflineConfirmationId(sl.Handle, ref actId, installationId, confirmationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RefreshLicenseStatus()
|
public static void RefreshLicenseStatus()
|
||||||
{
|
{
|
||||||
SLConsumeWindowsRight(0);
|
NativeMethods.SLConsumeWindowsRight(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool RefreshTrustedTime(Guid actId)
|
public static bool RefreshTrustedTime(Guid actId)
|
||||||
@@ -240,7 +140,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
uint count;
|
uint count;
|
||||||
IntPtr ppbValue;
|
IntPtr ppbValue;
|
||||||
|
|
||||||
uint status = SLGetProductSkuInformation(sl.Handle, ref actId, "TrustedTime", out type, out count, out ppbValue);
|
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref actId, "TrustedTime", out type, out count, out ppbValue);
|
||||||
return (int)status >= 0 && status != 0xC004F012;
|
return (int)status >= 0 && status != 0xC004F012;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,22 +148,22 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
public static void FireStateChangedEvent(Guid appId)
|
public static void FireStateChangedEvent(Guid appId)
|
||||||
{
|
{
|
||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
SLFireEvent(sl.Handle, "msft:rm/event/licensingstatechanged", ref appId);
|
NativeMethods.SLFireEvent(sl.Handle, "msft:rm/event/licensingstatechanged", ref appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Guid GetAppId(Guid actId)
|
public static Guid GetAppId(Guid activationId)
|
||||||
{
|
{
|
||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
{
|
{
|
||||||
uint count;
|
uint count;
|
||||||
IntPtr pAppIds;
|
IntPtr appIdPointer;
|
||||||
|
|
||||||
uint status = SLGetSLIDList(sl.Handle, SLIDType.SLIDProductSku, ref actId, SLIDType.SLIDApplication, out count, out pAppIds);
|
uint status = NativeMethods.SLGetSLIDList(sl.Handle, SLIDType.ProductSku, ref activationId, SLIDType.Application, out count, out appIdPointer);
|
||||||
|
|
||||||
if (status != 0 || count == 0)
|
if (status != 0 || count == 0)
|
||||||
return Guid.Empty;
|
return Guid.Empty;
|
||||||
|
|
||||||
return (Guid)Marshal.PtrToStructure(pAppIds, typeof(Guid));
|
return (Guid)Marshal.PtrToStructure(appIdPointer, typeof(Guid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +175,7 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
SLDataType type;
|
SLDataType type;
|
||||||
IntPtr ppbValue;
|
IntPtr ppbValue;
|
||||||
|
|
||||||
uint status = SLGetProductSkuInformation(sl.Handle, ref actId, "DependsOn", out type, out count, out ppbValue);
|
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref actId, "DependsOn", out type, out count, out ppbValue);
|
||||||
return (int)status >= 0 && status != 0xC004F012;
|
return (int)status >= 0 && status != 0xC004F012;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,15 +184,15 @@ namespace MetroUnlocker.LibTSForge.SPP
|
|||||||
{
|
{
|
||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
{
|
{
|
||||||
Guid pkeyId = Guid.Empty;
|
Guid productKeyId = Guid.Empty;
|
||||||
return SLInstallProofOfPurchase(sl.Handle, pkey.GetAlgoUri(), pkey.ToString(), 0, null, ref pkeyId);
|
return NativeMethods.SLInstallProofOfPurchase(sl.Handle, pkey.GetAlgoUri(), pkey.ToString(), 0, null, ref productKeyId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint UninstallProductKey(Guid pkeyId)
|
public static uint UninstallProductKey(Guid productKeyId)
|
||||||
{
|
{
|
||||||
using (SLContext sl = new SLContext())
|
using (SLContext sl = new SLContext())
|
||||||
return SLUninstallProofOfPurchase(sl.Handle, ref pkeyId);
|
return NativeMethods.SLUninstallProofOfPurchase(sl.Handle, ref productKeyId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,8 @@
|
|||||||
<Compile Include="LibTSForge\PhysicalStore\ModernBlock.cs" />
|
<Compile Include="LibTSForge\PhysicalStore\ModernBlock.cs" />
|
||||||
<Compile Include="LibTSForge\PhysicalStore\PhysicalStore.cs" />
|
<Compile Include="LibTSForge\PhysicalStore\PhysicalStore.cs" />
|
||||||
<Compile Include="LibTSForge\PhysicalStore\VariableBag.cs" />
|
<Compile Include="LibTSForge\PhysicalStore\VariableBag.cs" />
|
||||||
<Compile Include="LibTSForge\SPP\PKeyConfig.cs" />
|
<Compile Include="LibTSForge\SPP\NativeMethods.cs" />
|
||||||
|
<Compile Include="LibTSForge\SPP\ProductKeyConfig.cs" />
|
||||||
<Compile Include="LibTSForge\SPP\ProductKey.cs" />
|
<Compile Include="LibTSForge\SPP\ProductKey.cs" />
|
||||||
<Compile Include="LibTSForge\SPP\SLApi.cs" />
|
<Compile Include="LibTSForge\SPP\SLApi.cs" />
|
||||||
<Compile Include="LibTSForge\TokenStore\TokenEntry.cs" />
|
<Compile Include="LibTSForge\TokenStore\TokenEntry.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user