Exemplo n.º 1
0
        private static int WriteText(bool noText, VlmcsdData[] idData, int index, VlmcsdDataText unknownText, IList <VlmcsdDataText> textData, KmsProduct item, ref ulong currentText)
        {
            if (noText)
            {
                idData[index].NameOffset = unknownText.Offset;
            }
            else
            {
                textData[index]          = new VlmcsdDataText(item.DisplayName, currentText);
                idData[index].NameOffset = currentText;
                currentText = textData[index].OffsetNext;
            }

            return(index + 1);
        }
Exemplo n.º 2
0
        public MemoryStream WriteData(bool includeAppItems, bool includeKmsItems, bool includeSkuItems, bool noText, bool includeBetaSkuItem)
        {
            fixed(byte *m = Magic)
            {
                m[0] = 0x4B;
                m[1] = 0x4D;
                m[2] = 0x44;
                m[3] = 0x00;
            }

            var exportedCsvlks = KmsLists.CsvlkItemList.Where(c => c.VlmcsdIndex >= 0).OrderBy(c => c.VlmcsdIndex).ToArray() as IReadOnlyList <CsvlkItem>;

            CsvlkCount = (byte)exportedCsvlks.Count;

            try
            {
                var ePid = new EPid(exportedCsvlks[0].EPid);
                Flags |= (byte)(ePid.OsBuild > 7601 ? VlmcsdOption.UseNdr64 : VlmcsdOption.None);
            }
            catch
            {
                // No valid host build
            }

            var kmsItemList = includeKmsItems ? KmsLists.KmsItemList.ToArray() : KmsLists.KmsItemList.Where(k => !k.CanMapToDefaultCsvlk).ToArray();

            var skuItemList   = KmsLists.SkuItemList.Where(s => includeBetaSkuItem || !s.KmsItem.IsPreview).ToArray();
            var csvlkDataSize = CsvlkData.Size * CsvlkCount;

            Version       = KmsLists.KmsData.Version.Full;
            AppItemOffset = Size + csvlkDataSize;
            AppItemCount  = includeAppItems ? (uint)KmsLists.AppItemList.Count : 0;
            KmsItemOffset = AppItemOffset + AppItemCount * VlmcsdData.Size;
            KmsItemCount  = (uint)kmsItemList.Length;
            SkuItemOffset = KmsItemOffset + KmsItemCount * VlmcsdData.Size;
            SkuItemCount  = includeSkuItems && includeKmsItems ? (uint)skuItemList.Length : 0;

            var idData        = new VlmcsdData[AppItemCount + KmsItemCount + SkuItemCount];
            var textData      = new VlmcsdDataText[idData.Length];
            var currentText   = (ulong)idData.Length * VlmcsdData.Size + Size + csvlkDataSize;
            var ePids         = new VlmcsdDataText[CsvlkCount];
            var iniFileNames  = new VlmcsdDataText[CsvlkCount];
            var csvlkDataList = new CsvlkData[CsvlkCount];

            ePids[0] = new VlmcsdDataText(exportedCsvlks[0].EPid, currentText);


            for (var i = 0; i < CsvlkCount; i++)
            {
                if (i != 0)
                {
                    ePids[i] = new VlmcsdDataText(exportedCsvlks[i].EPid, iniFileNames[i - 1].OffsetNext);
                }

                iniFileNames[i] = new VlmcsdDataText(exportedCsvlks[i].IniFileName, ePids[i].OffsetNext);

                csvlkDataList[i] = new CsvlkData
                {
                    EPidOffset       = ePids[i].Offset,
                    GroupId          = (uint)exportedCsvlks[i].GroupId,
                    MinKeyId         = (uint)exportedCsvlks[i].MinKeyId,
                    MaxKeyId         = (uint)exportedCsvlks[i].MaxKeyId,
                    MinActiveClients = 0,
                };
            }

            currentText = iniFileNames[CsvlkCount - 1].OffsetNext;

            var unknownText = new VlmcsdDataText("Unknown", currentText);

            if (noText)
            {
                currentText = unknownText.OffsetNext;
            }

            var index = 0;

            if (includeAppItems)
            {
                foreach (var appItem in KmsLists.AppItemList)
                {
                    var minActiveClients = (byte)appItem.MinActiveClients;

                    if (minActiveClients < 1)
                    {
                        minActiveClients = (byte)(appItem.KmsItems.Select(k => k.NCountPolicy).Max() << 1);
                    }

                    idData[index].Guid      = appItem.Guid;
                    idData[index].EPidIndex = (byte)appItem.VlmcsdIndex;
                    //TODO: Find out if client count is really per AppItem
                    idData[index].NCountPolicy = minActiveClients;
                    index = WriteText(noText, idData, index, unknownText, textData, appItem, ref currentText);
                }
            }

            foreach (var kmsItem in kmsItemList)
            {
                idData[index].Guid            = kmsItem.Guid;
                idData[index].IsPreview       = (byte)(kmsItem.IsPreview ? 1 : 0);
                idData[index].IsRetail        = (byte)(kmsItem.IsRetail ? 1 : 0);
                idData[index].NCountPolicy    = (byte)kmsItem.NCountPolicy;
                idData[index].ProtocolVersion = (byte)kmsItem.DefaultKmsProtocol.Major;
                idData[index].AppIndex        = (byte)(includeAppItems ? KmsLists.AppItemList.IndexOf(kmsItem.App) : 0);
                var csvlk = exportedCsvlks.SingleOrDefault(c => c.Activates[kmsItem.Guid] != null);

                if (csvlk != null)
                {
                    idData[index].EPidIndex = (byte)csvlk.VlmcsdIndex;
                }

                index = WriteText(noText, idData, index, unknownText, textData, kmsItem, ref currentText);
            }

            if (includeKmsItems && includeSkuItems)
            {
                foreach (var skuItem in skuItemList)
                {
                    idData[index].Guid            = skuItem.Guid;
                    idData[index].KmsIndex        = (byte)KmsLists.KmsItemList.IndexOf(skuItem.KmsItem);
                    idData[index].AppIndex        = (byte)KmsLists.AppItemList.IndexOf(skuItem.KmsItem.App);
                    idData[index].ProtocolVersion = (byte)skuItem.KmsItem.DefaultKmsProtocol.Major;
                    idData[index].NCountPolicy    = (byte)skuItem.KmsItem.NCountPolicy;
                    idData[index].IsPreview       = (byte)(skuItem.KmsItem.IsPreview ? 1 : 0);
                    idData[index].IsRetail        = (byte)(skuItem.KmsItem.IsRetail ? 1 : 0);
                    var csvlk = exportedCsvlks.SingleOrDefault(c => c.Activates[skuItem.KmsItem.Guid] != null);

                    if (csvlk != null)
                    {
                        idData[index].EPidIndex = (byte)csvlk.VlmcsdIndex;
                    }

                    index = WriteText(noText, idData, index, unknownText, textData, skuItem, ref currentText);
                }
            }

            var stream = new MemoryStream();

            stream.SetLength((long)currentText);
            stream.Seek(0, SeekOrigin.Begin);

            fixed(VlmcsdHeader *b = &this)
            {
                for (ulong i = 0; i < Size; i++)
                {
                    stream.WriteByte(((byte *)b)[i]);
                }
            }

            for (var i = 0; i < CsvlkCount; i++)
            {
                fixed(CsvlkData *b = &csvlkDataList[i])
                {
                    for (ulong j = 0; j < CsvlkData.Size; j++)
                    {
                        stream.WriteByte(((byte *)b)[j]);
                    }
                }
            }

            // ReSharper disable once ForCanBeConvertedToForeach
            for (var i = 0; i < idData.Length; i++)
            {
                fixed(VlmcsdData *b = &idData[i])
                {
                    for (ulong j = 0; j < VlmcsdData.Size; j++)
                    {
                        stream.WriteByte(((byte *)b)[j]);
                    }
                }
            }

            for (var i = 0; i < ePids.Length; i++)
            {
                stream.Write(ePids[i].Data, 0, ePids[i].Data.Length);
                stream.Write(iniFileNames[i].Data, 0, iniFileNames[i].Data.Length);
            }

            if (noText)
            {
                stream.Write(unknownText.Data, 0, unknownText.Data.Length);
            }
            else
            {
                foreach (var text in textData)
                {
                    stream.Write(text.Data, 0, text.Data.Length);
                }
            }

            return(stream);
        }