Archived
1
1
This repository has been archived on 2026-03-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
RTUnlocker/MetroUnlocker/LibTSForge/SPP/SLAPI.cs
2025-05-22 02:52:38 +02:00

199 lines
6.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace MetroUnlocker.LibTSForge.SPP
{
public static class SLApi
{
public class SLContext : IDisposable
{
public readonly IntPtr Handle;
public SLContext() { NativeMethods.SLOpen(out Handle); }
public void Dispose()
{
NativeMethods.SLClose(Handle);
GC.SuppressFinalize(this);
}
~SLContext() { Dispose(); }
}
public static Guid GetProductKeyConfigFileId(Guid activationId)
{
using (SLContext sl = new SLContext())
{
SLDataType type;
uint length;
IntPtr fileIdPointer;
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref activationId, "pkeyConfigLicenseId", out type, out length, out fileIdPointer);
if (status != 0 || length == 0)
return Guid.Empty;
Guid configLicenseId = new Guid(Marshal.PtrToStringAuto(fileIdPointer));
return GetLicenseFileId(configLicenseId);
}
}
public static Guid GetLicenseFileId(Guid licenseId)
{
using (SLContext sl = new SLContext())
{
uint status;
uint count;
IntPtr 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;
}
}
public static string GetLicenseContents(Guid fileId)
{
if (fileId == Guid.Empty) throw new ArgumentException("License contents could not be retrieved.");
using (SLContext sl = new SLContext())
{
uint length;
IntPtr dataPointer;
if (NativeMethods.SLGetLicense(sl.Handle, ref fileId, out length, out dataPointer) != 0)
return null;
byte[] data = new byte[length];
Marshal.Copy(dataPointer, data, 0, (int)length);
data = data.Skip(Array.IndexOf(data, (byte)'<')).ToArray();
return Encoding.UTF8.GetString(data);
}
}
public static string GetMetaStr(Guid productSkuId, string value)
{
using (SLContext sl = new SLContext())
{
uint length;
SLDataType type;
IntPtr binaryValue;
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref productSkuId, value, out type, out length, out binaryValue);
if (status != 0 || length == 0 || type != SLDataType.String)
return null;
return Marshal.PtrToStringAuto(binaryValue);
}
}
public static string GetInstallationId(Guid actId)
{
using (SLContext sl = new SLContext())
{
string installationId = null;
var status = NativeMethods.SLGenerateOfflineInstallationId(sl.Handle, ref actId, ref installationId);
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")));
return installationId;
}
}
public static Guid GetInstalledProductKeyId(Guid actId)
{
using (SLContext sl = new SLContext())
{
uint status;
uint count;
IntPtr 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;
}
}
public static uint DepositConfirmationId(Guid actId, string installationId, string confirmationId)
{
using (SLContext sl = new SLContext())
return NativeMethods.SLDepositOfflineConfirmationId(sl.Handle, ref actId, installationId, confirmationId);
}
public static void RefreshLicenseStatus()
{
NativeMethods.SLConsumeWindowsRight(0);
}
public static bool RefreshTrustedTime(Guid actId)
{
using (SLContext sl = new SLContext())
{
SLDataType type;
uint count;
IntPtr ppbValue;
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref actId, "TrustedTime", out type, out count, out ppbValue);
return (int)status >= 0 && status != 0xC004F012;
}
}
public static void FireStateChangedEvent(Guid appId)
{
using (SLContext sl = new SLContext())
NativeMethods.SLFireEvent(sl.Handle, "msft:rm/event/licensingstatechanged", ref appId);
}
public static Guid GetAppId(Guid activationId)
{
using (SLContext sl = new SLContext())
{
uint count;
IntPtr appIdPointer;
uint status = NativeMethods.SLGetSLIDList(sl.Handle, SLIDType.ProductSku, ref activationId, SLIDType.Application, out count, out appIdPointer);
if (status != 0 || count == 0)
return Guid.Empty;
return (Guid)Marshal.PtrToStructure(appIdPointer, typeof(Guid));
}
}
public static bool IsAddon(Guid actId)
{
using (SLContext sl = new SLContext())
{
uint count;
SLDataType type;
IntPtr ppbValue;
uint status = NativeMethods.SLGetProductSkuInformation(sl.Handle, ref actId, "DependsOn", out type, out count, out ppbValue);
return (int)status >= 0 && status != 0xC004F012;
}
}
public static uint InstallProductKey(ProductKey pkey)
{
using (SLContext sl = new SLContext())
{
Guid productKeyId = Guid.Empty;
return NativeMethods.SLInstallProofOfPurchase(sl.Handle, pkey.GetAlgoUri(), pkey.ToString(), 0, null, ref productKeyId);
}
}
public static uint UninstallProductKey(Guid productKeyId)
{
using (SLContext sl = new SLContext())
return NativeMethods.SLUninstallProofOfPurchase(sl.Handle, ref productKeyId);
}
}
}