summaryrefslogtreecommitdiff
path: root/LibTSforge/Modifiers/KMSHostCharge.cs
blob: b10a864c9ff6a7243c19420bb2dec6bdb6187300 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
namespace LibTSforge.Modifiers
{
    using System;
    using System.IO;
    using LibTSforge.PhysicalStore;
    using LibTSforge.SPP;

    public static class KMSHostCharge
    {
        public static void Charge(PSVersion version, bool production, Guid actId)
        {
            if (version == PSVersion.Vista) throw new NotSupportedException("This feature is not supported on Windows Vista/Server 2008.");

            if (actId == Guid.Empty)
            {
                actId = SLApi.GetDefaultActivationID(SLApi.WINDOWS_APP_ID, true);

                if (actId == Guid.Empty)
                {
                    throw new NotSupportedException("No applicable activation IDs found.");
                }
            }

            if (SLApi.GetPKeyChannel(SLApi.GetInstalledPkeyID(actId)) != "Volume:CSVLK")
            {
                throw new NotSupportedException("Non-Volume:CSVLK product key installed.");
            }

            Guid appId = SLApi.GetAppId(actId);
            int totalClients = 50;
            int currClients = 25;
            byte[] hwidBlock = Constants.UniversalHWIDBlock;
            string key = string.Format("SPPSVC\\{0}", appId);
            long ldapTimestamp = DateTime.Now.ToFileTime();

            BinaryWriter writer = new BinaryWriter(new MemoryStream());

            for (int i = 0; i < currClients; i++)
            {
                writer.Write(ldapTimestamp - (10 * (i + 1)));
                writer.Write(Guid.NewGuid().ToByteArray());
            }

            byte[] cmidGuids = writer.GetBytes();

            writer = new BinaryWriter(new MemoryStream());

            writer.Write(new byte[40]);

            writer.Seek(4, SeekOrigin.Begin);
            writer.Write((byte)currClients);

            writer.Seek(24, SeekOrigin.Begin);
            writer.Write((byte)currClients);
            byte[] reqCounts = writer.GetBytes();

            SPPUtils.KillSPP(version);

            Logger.WriteLine("Writing TrustedStore data...");

            using (IPhysicalStore store = SPPUtils.GetStore(version, production))
            {
                VariableBag kmsCountData = new VariableBag(version);
                kmsCountData.Blocks.AddRange(new CRCBlockModern[]
                {
                    new CRCBlockModern
                    {
                        DataType = CRCBlockType.BINARY,
                        KeyAsStr = "SppBindingLicenseData",
                        Value = hwidBlock
                    },
                    new CRCBlockModern
                    {
                        DataType = CRCBlockType.UINT,
                        Key = new byte[] { },
                        ValueAsInt = (uint)totalClients
                    },
                    new CRCBlockModern
                    {
                        DataType = CRCBlockType.UINT,
                        Key = new byte[] { },
                        ValueAsInt = 1051200000
                    },
                    new CRCBlockModern
                    {
                        DataType = CRCBlockType.UINT,
                        Key = new byte[] { },
                        ValueAsInt = (uint)currClients
                    },
                    new CRCBlockModern
                    {
                        DataType = CRCBlockType.BINARY,
                        Key = new byte[] { },
                        Value = cmidGuids
                    },
                    new CRCBlockModern
                    {
                        DataType = CRCBlockType.BINARY,
                        Key = new byte[] { },
                        Value = reqCounts
                    }
                });

                byte[] kmsChargeData = kmsCountData.Serialize();
                string countVal = string.Format("msft:spp/kms/host/2.0/store/counters/{0}", appId);

                store.DeleteBlock(key, countVal);
                store.AddBlock(new PSBlock
                {
                    Type = BlockType.NAMED,
                    Flags = (version == PSVersion.WinModern) ? (uint)0x400 : 0,
                    KeyAsStr = key,
                    ValueAsStr = countVal,
                    Data = kmsChargeData
                });

                Logger.WriteLine(string.Format("Set charge count to {0} successfully.", currClients));
            }
        }
    }
}