public void ProcessValues(RegistryKey key)
        {
            _values.Clear();
            Errors.Clear();

            var valuesList = new List <ValuesOut>();

            var currentKey = string.Empty;


            try
            {
                currentKey = key.KeyName;

                //get MRU key and read it in

                var mruVal = key.Values.SingleOrDefault(t => t.ValueName == "MRUListEx");

                var mruListOrder = new ArrayList();

                if (mruVal != null)
                {
                    var index  = 0;
                    var mruPos = 0;

                    while (index < mruVal.ValueDataRaw.Length)
                    {
                        mruPos = BitConverter.ToInt32(mruVal.ValueDataRaw, index);
                        index += 4;

                        if (mruPos != -1)
                        {
                            mruListOrder.Add(mruPos);
                        }
                    }
                }


                foreach (var keyValue in key.Values)
                {
                    if (keyValue.ValueName == "MRUListEx")
                    {
                        continue;
                    }

                    bags = new List <ShellBag>();

                    var shellItemsRaw = new List <byte[]>();

                    var mru = mruListOrder.IndexOf(int.Parse(keyValue.ValueName));  //(int) mruListOrder[int.Parse(keyValue.BatchValueName)];

                    try
                    {
                        var det = new StringBuilder();

                        var index = 0;

                        //first is a unicode executable name
                        var exeName = Encoding.Unicode.GetString(keyValue.ValueDataRaw).Split('\0').First();

                        //update index to end of exename + null terminator
                        index = exeName.Length * 2 + 2;

                        //pull out shell items
                        while (index < keyValue.ValueDataRaw.Length)
                        {
                            var size = BitConverter.ToInt16(keyValue.ValueDataRaw, index);

                            if (size == 0)
                            {
                                break;
                            }

                            var shellRaw = new byte[size];
                            Buffer.BlockCopy(keyValue.ValueDataRaw, index, shellRaw, 0, size);

                            shellItemsRaw.Add(shellRaw);

                            index += size;
                        }

                        ShellBag bag = null;

                        foreach (var bytese in shellItemsRaw)
                        {
                            switch (bytese[2])
                            {
                            case 0x00:
                                bag = new ShellBag0X00(bytese);

                                break;

                            case 0x1f:
                                bag = new ShellBag0X1F(bytese);

                                break;

                            case 0x2f:
                                bag = new ShellBag0X2F(bytese);

                                break;

                            case 0x2e:
                                bag = new ShellBag0X2E(bytese);

                                break;

                            case 0xb1:
                            case 0x31:
                            case 0x35:
                            case 0x36:
                                bag = new ShellBag0X31(bytese);

                                break;

                            case 0x32:
                                bag = new ShellBag0X32(bytese);

                                break;

                            case 0x3a:
                                bag = new ShellBag0X3A(bytese);

                                break;


                            case 0x71:
                                bag = new ShellBag0X71(bytese);

                                break;

                            case 0x74:
                                bag = new ShellBag0X74(bytese);

                                break;

                            case 0x40:
                                bag = new ShellBag0X40(bytese);

                                break;

                            case 0x61:
                                bag = new ShellBag0X61(bytese);

                                break;

                            case 0xc3:
                                bag = new ShellBag0Xc3(bytese);

                                break;

                            default:
                                det.AppendLine(
                                    $"Key: {key.KeyName}, Value name: {keyValue.ValueName}, Message: **** Unsupported ShellID: 0x{bytese[2]:x2}. Send this ID to [email protected] so support can be added!! ****");

                                Errors.Add(
                                    $"Key: {key.KeyName}, Value name: {keyValue.ValueName}, Message: **** Unsupported ShellID: 0x{bytese[2]:x2}. Send this ID to [email protected] so support can be added!! ****");
                                break;
                            }

                            if (bag != null)
                            {
                                det.AppendLine(bag.ToString());
                                bags.Add(bag);
                            }
                        }

                        DateTimeOffset?openedOn = null;

                        if (mru == 0)
                        {
                            openedOn = key.LastWriteTime;
                        }

                        var v = new ValuesOut(exeName,
                                              $"{GetAbsolutePathFromTargetIDs(bags)}", det.ToString(), keyValue.ValueName, mru, openedOn);

                        v.BatchKeyPath   = key.KeyPath;
                        v.BatchValueName = keyValue.ValueName;

                        valuesList.Add(v);
                    }
                    catch (Exception ex)
                    {
                        Errors.Add(
                            $"Key: {key.KeyName}, Value name: {keyValue.ValueName}, message: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                Errors.Add($"Error processing OpenSavePidlMRU subkey {currentKey}: {ex.Message}");
            }

            if (Errors.Count > 0)
            {
                AlertMessage = "Errors detected. See Errors information in lower right corner of plugin window";
            }


            var v1 = valuesList.OrderBy(t => t.MruPosition);

            foreach (var source in v1.ToList())
            {
                _values.Add(source);
            }
        }
Beispiel #2
0
        public LnkFile(byte[] rawBytes, string sourceFile)
        {
            RawBytes   = rawBytes;
            SourceFile = Path.GetFullPath(sourceFile);
            var headerBytes = new byte[76];

            Buffer.BlockCopy(rawBytes, 0, headerBytes, 0, 76);

            Header = new Header(headerBytes);

            var fi = new FileInfo(sourceFile);

            SourceCreated  = new DateTimeOffset(fi.CreationTimeUtc);
            SourceModified = new DateTimeOffset(fi.LastWriteTimeUtc);
            SourceAccessed = new DateTimeOffset(fi.LastAccessTimeUtc);

            if (SourceCreated.Value.Year == 1601)
            {
                SourceCreated = null;
            }

            if (SourceModified.Value.Year == 1601)
            {
                SourceModified = null;
            }

            if (SourceAccessed.Value.Year == 1601)
            {
                SourceAccessed = null;
            }

            var index = 76;

            TargetIDs = new List <ShellBag>();

            if ((Header.DataFlags & Header.DataFlag.HasTargetIdList) == Header.DataFlag.HasTargetIdList)
            {
                //process shell items
                var shellItemSize = BitConverter.ToInt16(rawBytes, index);
                index += 2;

                var shellItemBytes = new byte[shellItemSize];
                Buffer.BlockCopy(rawBytes, index, shellItemBytes, 0, shellItemSize);

                var shellItemsRaw  = new List <byte[]>();
                var shellItemIndex = 0;

                while (shellItemIndex < shellItemBytes.Length)
                {
                    var shellSize = BitConverter.ToUInt16(shellItemBytes, shellItemIndex);

                    if (shellSize == 0)
                    {
                        break;
                    }
                    var itemBytes = new byte[shellSize];
                    Buffer.BlockCopy(shellItemBytes, shellItemIndex, itemBytes, 0, shellSize);

                    shellItemsRaw.Add(itemBytes);
                    shellItemIndex += shellSize;
                }

                //TODO try catch and add placeholder for shellitem when exeption happens? or ?
                foreach (var shellItem in shellItemsRaw)
                {
                    if (shellItem.Length >= 0x28)
                    {
                        var sig1 = BitConverter.ToInt64(shellItem, 0x8);
                        var sig2 = BitConverter.ToInt64(shellItem, 0x18);

                        if (sig1 == 0 && sig2 == 0
                            ) // if ((sig1 == zip1_0 && sig2 == zip2_0) || sig2 == zip2_1 || (sig1 == zip1_1 && sig2 == zip2_0))
                        {
                            //double check
                            if (shellItem[0x28] == 0x2f || shellItem[0x26] == 0x2f || shellItem[0x1a] == 0x2f ||
                                shellItem[0x1c] == 0x2f)
                            // forward slash in date or N / A
                            {
                                //zip?
                                var zz = new ShellBagZipContents(shellItem);

                                TargetIDs.Add(zz);
                                continue;
                            }
                        }
                    }

                    switch (shellItem[2])
                    {
                    case 0x1f:
                        var f = new ShellBag0X1F(shellItem);
                        TargetIDs.Add(f);
                        break;

                    case 0x23:
                        var two3 = new ShellBag0X23(shellItem);
                        TargetIDs.Add(two3);
                        break;

                    case 0x2f:
                        var ff = new ShellBag0X2F(shellItem);
                        TargetIDs.Add(ff);
                        break;

                    case 0x2e:
                        var ee = new ShellBag0X2E(shellItem);
                        TargetIDs.Add(ee);
                        break;

                    case 0xb1:
                    case 0x31:
                    case 0x35:
                    case 0x36:
                        var d = new ShellBag0X31(shellItem);
                        TargetIDs.Add(d);
                        break;

                    case 0x32:
                        var d2 = new ShellBag0X32(shellItem);
                        TargetIDs.Add(d2);
                        break;

                    case 0x00:
                        var v0 = new ShellBag0X00(shellItem);
                        TargetIDs.Add(v0);
                        break;

                    case 0x01:
                        var one = new ShellBag0X01(shellItem);
                        TargetIDs.Add(one);
                        break;

                    case 0x71:
                        var sevenone = new ShellBag0X71(shellItem);
                        TargetIDs.Add(sevenone);
                        break;

                    case 0x61:
                        var sixone = new ShellBag0X61(shellItem);
                        TargetIDs.Add(sixone);
                        break;

                    case 0xC3:
                        var c3 = new ShellBag0Xc3(shellItem);
                        TargetIDs.Add(c3);
                        break;

                    case 0x74:
                    case 0x77:
                        var sev = new ShellBag0X74(shellItem);
                        TargetIDs.Add(sev);
                        break;

                    case 0xae:
                    case 0xaa:
                    case 0x79:
                        var ae = new ShellBagZipContents(shellItem);
                        TargetIDs.Add(ae);
                        break;

                    case 0x41:
                    case 0x42:
                    case 0x43:
                    case 0x46:
                    case 0x47:
                        var forty = new ShellBag0X40(shellItem);
                        TargetIDs.Add(forty);
                        break;

                    case 0x4C:
                        var fc = new ShellBag0X4C(shellItem);
                        TargetIDs.Add(fc);
                        break;

                    default:
                        throw new Exception(
                                  $"Unknown shell item ID: 0x{shellItem[2]:X}. Please send to [email protected] so support can be added.");
                    }
                }

                //TODO tie back extra block for SpecialFolderDataBlock and KnownFolderDataBlock??

                index += shellItemSize;
            }

            if ((Header.DataFlags & Header.DataFlag.HasLinkInfo) == Header.DataFlag.HasLinkInfo)
            {
                var locationItemSize = BitConverter.ToInt32(rawBytes, index);
                var locationBytes    = new byte[locationItemSize];
                Buffer.BlockCopy(rawBytes, index, locationBytes, 0, locationItemSize);

                if (locationBytes.Length > 20)
                {
                    var locationInfoHeaderSize = BitConverter.ToInt32(locationBytes, 4);

                    LocationFlags = (LocationFlag)BitConverter.ToInt32(locationBytes, 8);

                    var volOffset = BitConverter.ToInt32(locationBytes, 12);
                    var vbyteSize = BitConverter.ToInt32(locationBytes, volOffset);
                    var volBytes  = new byte[vbyteSize];
                    Buffer.BlockCopy(locationBytes, volOffset, volBytes, 0, vbyteSize);

                    if (volOffset > 0)
                    {
                        VolumeInfo = new VolumeInfo(volBytes);
                    }

                    var localPathOffset    = BitConverter.ToInt32(locationBytes, 16);
                    var networkShareOffset = BitConverter.ToInt32(locationBytes, 20);

                    if ((LocationFlags & LocationFlag.VolumeIdAndLocalBasePath) ==
                        LocationFlag.VolumeIdAndLocalBasePath)
                    {
                        LocalPath = Encoding.GetEncoding(1252)
                                    .GetString(locationBytes, localPathOffset, locationBytes.Length - localPathOffset)
                                    .Split('\0')
                                    .First();
                    }
                    if ((LocationFlags & LocationFlag.CommonNetworkRelativeLinkAndPathSuffix) ==
                        LocationFlag.CommonNetworkRelativeLinkAndPathSuffix)
                    {
                        var networkShareSize = BitConverter.ToInt32(locationBytes, networkShareOffset);
                        var networkBytes     = new byte[networkShareSize];
                        Buffer.BlockCopy(locationBytes, networkShareOffset, networkBytes, 0, networkShareSize);

                        NetworkShareInfo = new NetworkShareInfo(networkBytes);
                    }

                    var commonPathOffset = BitConverter.ToInt32(locationBytes, 24);

                    CommonPath = Encoding.GetEncoding(1252)
                                 .GetString(locationBytes, commonPathOffset, locationBytes.Length - commonPathOffset)
                                 .Split('\0')
                                 .First();

                    if (locationInfoHeaderSize > 28)
                    {
                        var uniLocalOffset = BitConverter.ToInt32(locationBytes, 28);

                        var unicodeLocalPath = Encoding.Unicode
                                               .GetString(locationBytes, uniLocalOffset, locationBytes.Length - uniLocalOffset)
                                               .Split('\0')
                                               .First();
                        LocalPath = unicodeLocalPath;
                    }

                    if (locationInfoHeaderSize > 32)
                    {
                        var uniCommonOffset = BitConverter.ToInt32(locationBytes, 32);

                        var unicodeCommonPath = Encoding.Unicode
                                                .GetString(locationBytes, uniCommonOffset, locationBytes.Length - uniCommonOffset)
                                                .Split('\0')
                                                .First();
                        CommonPath = unicodeCommonPath;
                    }
                }


                index += locationItemSize;
            }

            if ((Header.DataFlags & Header.DataFlag.HasName) == Header.DataFlag.HasName)
            {
                var nameLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    Name   = Encoding.Unicode.GetString(rawBytes, index, nameLen * 2);
                    index += nameLen;
                }
                else
                {
                    Name = Encoding.GetEncoding(1252).GetString(rawBytes, index, nameLen);
                }
                index += nameLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasRelativePath) == Header.DataFlag.HasRelativePath)
            {
                var relLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    RelativePath = Encoding.Unicode.GetString(rawBytes, index, relLen * 2);
                    index       += relLen;
                }
                else
                {
                    RelativePath = Encoding.GetEncoding(1252).GetString(rawBytes, index, relLen);
                }
                index += relLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasWorkingDir) == Header.DataFlag.HasWorkingDir)
            {
                var workLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    WorkingDirectory = Encoding.Unicode.GetString(rawBytes, index, workLen * 2);
                    index           += workLen;
                }
                else
                {
                    WorkingDirectory = Encoding.GetEncoding(1252).GetString(rawBytes, index, workLen);
                }
                index += workLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasArguments) == Header.DataFlag.HasArguments)
            {
                var argLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    Arguments = Encoding.Unicode.GetString(rawBytes, index, argLen * 2);
                    index    += argLen;
                }
                else
                {
                    Arguments = Encoding.GetEncoding(1252).GetString(rawBytes, index, argLen);
                }
                index += argLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasIconLocation) == Header.DataFlag.HasIconLocation)
            {
                var icoLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    IconLocation = Encoding.Unicode.GetString(rawBytes, index, icoLen * 2);
                    index       += icoLen;
                }
                else
                {
                    IconLocation = Encoding.GetEncoding(1252).GetString(rawBytes, index, icoLen);
                }
                index += icoLen;
            }


            var extraByteBlocks = new List <byte[]>();

            //extra blocks
            while (index < rawBytes.Length)
            {
                var extraSize = BitConverter.ToInt32(rawBytes, index);
                if (extraSize == 0)
                {
                    break;
                }

                if (extraSize > rawBytes.Length - index)
                {
                    extraSize = rawBytes.Length - index;
                }

                var extraBytes = new byte[extraSize];
                Buffer.BlockCopy(rawBytes, index, extraBytes, 0, extraSize);

                extraByteBlocks.Add(extraBytes);

                index += extraSize;
            }

            ExtraBlocks = new List <ExtraDataBase>();

            foreach (var extraBlock in extraByteBlocks)
            {
                try
                {
                    var sig = (ExtraDataTypes)BitConverter.ToInt32(extraBlock, 4);

                    switch (sig)
                    {
                    case ExtraDataTypes.TrackerDataBlock:
                        var tb = new TrackerDataBaseBlock(extraBlock);
                        ExtraBlocks.Add(tb);
                        break;

                    case ExtraDataTypes.ConsoleDataBlock:
                        var cdb = new ConsoleDataBlock(extraBlock);
                        ExtraBlocks.Add(cdb);
                        break;

                    case ExtraDataTypes.ConsoleFeDataBlock:
                        var cfeb = new ConsoleFeDataBlock(extraBlock);
                        ExtraBlocks.Add(cfeb);
                        break;

                    case ExtraDataTypes.DarwinDataBlock:
                        var db = new DarwinDataBlock(extraBlock);
                        ExtraBlocks.Add(db);
                        break;

                    case ExtraDataTypes.EnvironmentVariableDataBlock:
                        var eb = new EnvironmentVariableDataBlock(extraBlock);
                        ExtraBlocks.Add(eb);
                        break;

                    case ExtraDataTypes.IconEnvironmentDataBlock:
                        var ib = new IconEnvironmentDataBlock(extraBlock);
                        ExtraBlocks.Add(ib);
                        break;

                    case ExtraDataTypes.KnownFolderDataBlock:
                        var kf = new KnownFolderDataBlock(extraBlock);
                        ExtraBlocks.Add(kf);
                        break;

                    case ExtraDataTypes.PropertyStoreDataBlock:
                        var ps = new PropertyStoreDataBlock(extraBlock);

                        ExtraBlocks.Add(ps);
                        break;

                    case ExtraDataTypes.ShimDataBlock:
                        var sd = new KnownFolderDataBlock(extraBlock);
                        ExtraBlocks.Add(sd);
                        break;

                    case ExtraDataTypes.SpecialFolderDataBlock:
                        var sf = new SpecialFolderDataBlock(extraBlock);
                        ExtraBlocks.Add(sf);
                        break;

                    case ExtraDataTypes.VistaAndAboveIdListDataBlock:
                        var vid = new VistaAndAboveIdListDataBlock(extraBlock);
                        ExtraBlocks.Add(vid);
                        break;

                    default:
                        throw new Exception(
                                  $"Unknown extra data block signature: 0x{sig:X}. Please send lnk file to [email protected] so support can be added");
                    }
                }
                catch (Exception e)
                {
                    var dmg = new DamagedDataBlock(extraBlock, e.Message);
                    ExtraBlocks.Add(dmg);
                }
            }
        }
        public VistaAndAboveIdListDataBlock(byte[] rawBytes)
        {
            Signature = ExtraDataTypes.VistaAndAboveIdListDataBlock;

            Size = BitConverter.ToUInt32(rawBytes, 0);

            var index = 8;
            //process shell items
            var shellItemSize = BitConverter.ToInt16(rawBytes, index);

            var shellItemBytes = new byte[shellItemSize];

            Buffer.BlockCopy(rawBytes, index, shellItemBytes, 0, shellItemSize);

            var shellItemsRaw  = new List <byte[]>();
            var shellItemIndex = 0;

            while (shellItemIndex < shellItemBytes.Length)
            {
                var shellSize = BitConverter.ToUInt16(shellItemBytes, shellItemIndex);

                if (shellSize == 0)
                {
                    break;
                }
                var itemBytes = new byte[shellSize];
                Buffer.BlockCopy(shellItemBytes, shellItemIndex, itemBytes, 0, shellSize);

                shellItemsRaw.Add(itemBytes);
                shellItemIndex += shellSize;
            }


            TargetIDs = new List <ShellBag>();

            foreach (var bytese in shellItemsRaw)
            {
                switch (bytese[2])
                {
                case 0x1f:
                    var f = new ShellBag0X1F(bytese);
                    TargetIDs.Add(f);
                    break;

                case 0x2f:
                    var ff = new ShellBag0X2F(bytese);
                    TargetIDs.Add(ff);
                    break;

                case 0x2e:
                    var ee = new ShellBag0X2E(bytese);
                    TargetIDs.Add(ee);
                    break;

                case 0xb1:
                case 0x31:
                case 0x35:
                    var d = new ShellBag0X31(bytese);
                    TargetIDs.Add(d);
                    break;

                case 0x32:
                    var d2 = new ShellBag0X32(bytese);
                    TargetIDs.Add(d2);
                    break;

                case 0x00:
                    var v0 = new ShellBag0X00(bytese);
                    TargetIDs.Add(v0);
                    break;

                case 0x01:
                    var one = new ShellBag0X01(bytese);
                    TargetIDs.Add(one);
                    break;

                case 0x71:
                    var sevenone = new ShellBag0X71(bytese);
                    TargetIDs.Add(sevenone);
                    break;

                case 0x61:
                    var sixone = new ShellBag0X61(bytese);
                    TargetIDs.Add(sixone);
                    break;

                case 0xC3:
                    var c3 = new ShellBag0Xc3(bytese);
                    TargetIDs.Add(c3);
                    break;

                case 0x74:
                case 0x77:
                    var sev = new ShellBag0X74(bytese);
                    TargetIDs.Add(sev);
                    break;

                case 0x41:
                case 0x42:
                case 0x43:
                case 0x46:
                case 0x47:
                    var forty = new ShellBag0X40(bytese);
                    TargetIDs.Add(forty);
                    break;

                default:
                    throw new Exception($"Unknown item ID: 0x{bytese[2]:X}");
                }
            }
        }
Beispiel #4
0
        public void ProcessValues(RegistryKey key)
        {
            _values.Clear();
            Errors.Clear();

            var valuesList = new List <ValuesOut>();

            var vn = string.Empty;

            try
            {
                var fav = key.Values.SingleOrDefault(t => t.ValueName == "Favorites");

                if (fav == null)
                {
                    return;
                }

                var br = new BinaryReader(new MemoryStream(fav.ValueDataRaw));

                var chunks     = new List <byte[]>();
                var shellItems = new List <byte[]>();

                var unk = br.ReadByte(); //

                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    var size = br.ReadInt32();
                    br.BaseStream.Seek(-4, SeekOrigin.Current);

                    var b = br.ReadBytes(size);

                    chunks.Add(b);

                    var marker = br.ReadBytes(5);
                }

                foreach (var chunk in chunks)
                {
                    var chunkstream = new BinaryReader(new MemoryStream(chunk));

                    var chunksize = chunkstream.ReadInt32();

                    while (chunkstream.BaseStream.Position < chunkstream.BaseStream.Length)
                    {
                        var siSize = chunkstream.ReadInt16();

                        chunkstream.BaseStream.Seek(-2, SeekOrigin.Current);

                        var siBytes = chunkstream.ReadBytes(siSize);

                        shellItems.Add(siBytes);
                    }
                }


                var det = new StringBuilder();

                bags = new List <ShellBag>();


                ShellBag bag = null;

                foreach (var bytese in shellItems)
                {
                    try
                    {
                        switch (bytese[2])
                        {
                        case 0x00:
                            bag = new ShellBag0X00(bytese);

                            break;

                        case 0x1f:
                            bag = new ShellBag0X1F(bytese);

                            break;

                        case 0x2f:
                            bag = new ShellBag0X2F(bytese);

                            break;

                        case 0x2e:
                            bag = new ShellBag0X2E(bytese);

                            break;

                        case 0xb1:
                        case 0x31:
                        case 0x35:
                        case 0x36:
                            bag = new ShellBag0X31(bytese);

                            break;

                        case 0x32:
                            bag = new ShellBag0X32(bytese);

                            break;

                        case 0x3a:
                            bag = new ShellBag0X3A(bytese);
                            break;

                        case 0x71:
                            bag = new ShellBag0X71(bytese);

                            break;

                        case 0x74:
                            bag = new ShellBag0X74(bytese);

                            break;

                        case 0x40:
                            bag = new ShellBag0X40(bytese);

                            break;

                        case 0x61:
                            bag = new ShellBag0X61(bytese);

                            break;

                        case 0xc3:
                            bag = new ShellBag0Xc3(bytese);

                            break;

                        default:
                            det.AppendLine(
                                $"Key: {key.KeyName}, Value name: {fav.ValueName}, Message: **** Unsupported ShellID: 0x{bytese[2]:x2}. Send this ID to [email protected] so support can be added!! ****");

                            Errors.Add(
                                $"Key: {key.KeyName}, Value name: {fav.ValueName}, Message: **** Unsupported ShellID: 0x{bytese[2]:x2}. Send this ID to [email protected] so support can be added!! ****");
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        Errors.Add($"Error processing Favorites value '{vn}': {e.Message}");
                    }


                    if (bag != null)
                    {
                        det.AppendLine(bag.ToString());
                        bags.Add(bag);
                    }
                }

                foreach (var shellBag in bags)
                {
                    var exe = "(unknown)";
                    var ed  = shellBag.ExtensionBlocks.SingleOrDefault(t => t is ExtensionBlocks.Beef001d);

                    if (ed != null)
                    {
                        exe = ((Beef001d)ed).Executable;
                    }

                    var pp = shellBag.ExtensionBlocks.SingleOrDefault(t => t is ExtensionBlocks.Beef001e);

                    var pt = "(unknown)";
                    if (pp != null)
                    {
                        pt = ((Beef001e)pp).PinType;
                    }

                    if (shellBag.FriendlyName == "Directory")
                    {
                        exe = "(Directory)";
                        pt  = "(Directory)";
                    }

                    var v = new ValuesOut(shellBag.Value, exe, pt);
                    v.BatchKeyPath   = key.KeyPath;
                    v.BatchValueName = fav.ValueName;

                    valuesList.Add(v);
                }
            }
            catch (Exception ex)
            {
                Errors.Add($"Error processing Favorites value '{vn}': {ex.Message}");
            }


            if (Errors.Count > 0)
            {
                AlertMessage = "Errors detected. See Errors information in lower right corner of plugin window";
            }


            var v1 = valuesList;

            foreach (var source in v1.ToList())
            {
                _values.Add(source);
            }
        }