예제 #1
0
            public static MenuOrderRecord Deserialize(Stream stream)
            {
                MenuOrderRecord result = new MenuOrderRecord();
                BinaryReader    br     = new BinaryReader(stream);

                long   recordPosition = stream.Position;
                UInt32 lengthOfRecord = br.ReadUInt32();

                try
                {
                    result.Order = br.ReadInt32();

                    UInt16 subRecord0Size = br.ReadUInt16();
                    UInt16 flags          = br.ReadUInt16();
                    result.RecordType = ((flags & 2) == 2) ? FavoritesNodeType.Url : FavoritesNodeType.Folder;
                    bool   isUnicode           = ((flags & 4) == 4);
                    UInt32 unknown1            = br.ReadUInt32();
                    UInt32 unknown2            = br.ReadUInt32();
                    UInt16 stringLengthOrFlags = br.ReadUInt16();

                    result.Name83 = Utilities.ReadZeroTerminatedString(stream, isUnicode ? Encoding.Unicode : Encoding.ASCII);
                    if ((stream.Position & 1) > 0)
                    {
                        stream.Position++;
                    }

                    // jump to the position of the subRecord1Index word
                    stream.Position = recordPosition + lengthOfRecord - 8;
                    UInt32 subRecord1Index = br.ReadUInt16();  // index to subrecord1, which is where the long name is

                    // calculate position of subRecord1
                    stream.Position = recordPosition + 8 + subRecord1Index;

                    // read subrecord1 size
                    UInt16 subRecord1Size = br.ReadUInt16();

                    // skip 18 bytes on xp, 36 bytes on vista
                    if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor > 0)
                    {
                        stream.Position += 18;
                    }
                    else
                    {
                        stream.Position += 36;
                    }

                    result.LongName    = Utilities.ReadZeroTerminatedString(stream, Encoding.Unicode);
                    result.DisplayName = result.LongName;

                    if ((stringLengthOrFlags & 1) == 1)
                    {
                        string resourceString = Utilities.GetStringResource(Utilities.ReadZeroTerminatedString(stream, Encoding.Unicode));
                        if (resourceString != null && resourceString != "")
                        {
                            result.DisplayName = resourceString;
                        }
                    }

                    // validate the record by checking if the subrecord sizes add up
                    if ((subRecord1Size + subRecord1Index) != subRecord0Size)
                    {
                        throw new Exception("Invalid record format");
                    }

                    //Console.WriteLine("");
                    //Console.WriteLine("flags           : {0:x}", flags);
                    //Console.WriteLine("flags2          : {0:x}", stringLengthOrFlags);
                    //Console.WriteLine("longname        : {0}", result.LongName);
                    //Console.WriteLine("name83          : {0}", result.Name83);
                    //Console.WriteLine("longname        : {0}", result.LongName);
                }
                finally
                {
                    stream.Seek(recordPosition + lengthOfRecord, SeekOrigin.Begin);
                }

                return(result);
            }
예제 #2
0
        private static FavoritesNode LoadFolderNodeFromRegistry(FavoritesNode parent, string dirName, string displayName, RegistryKey registryKey, int order)
        {
            FavoritesNode result = new FavoritesNode();

            result.parent      = parent;
            result.order       = order;
            result.displayName = displayName;
            result.systemName  = dirName;
            result.nodeType    = FavoritesNodeType.Folder;

            byte[] registryData = registryKey.GetValue("Order") as byte[];

            if (registryData != null)
            {
                MemoryStream ms = new MemoryStream(registryData);
                BinaryReader br = new BinaryReader(ms);

                UInt32 headerId0       = br.ReadUInt32();
                UInt32 headerId1       = br.ReadUInt32();
                UInt32 totalSize       = br.ReadUInt32();
                UInt32 headerId2       = br.ReadUInt32();
                UInt32 numberOfRecords = br.ReadUInt32();

                if (headerId0 == 0x00000008 &&
                    headerId1 == 0x00000002 &&
                    headerId2 == 0x00000001)
                {
                    //Console.WriteLine("=================");
                    //Console.WriteLine("headerId0       : {0:x}", headerId0);
                    //Console.WriteLine("headerId1       : {0:x}", headerId1);
                    //Console.WriteLine("totalSize       : {0:x}", totalSize);
                    //Console.WriteLine("headerId2       : {0:x}", headerId2);
                    //Console.WriteLine("numberOfRecords : {0:x}", numberOfRecords);

                    for (uint t = 0; t < numberOfRecords; t++)
                    {
                        try
                        {
                            FavoritesNode   childNode = null;
                            MenuOrderRecord record    = MenuOrderRecord.Deserialize(br.BaseStream);

                            if (record.RecordType == FavoritesNodeType.Folder)
                            {
                                // apparently in the registry it always uses the display name
                                RegistryKey childKey = registryKey.OpenSubKey(record.DisplayName);
                                if (childKey != null)
                                {
                                    childNode = LoadFolderNodeFromRegistry(result, record.LongName, record.DisplayName, childKey, record.Order);
                                    childKey.Close();
                                }
                                else
                                {
                                    childNode = LoadFolderNodeFromFileSystem(result, record.LongName, record.DisplayName, record.Order);
                                }
                            }
                            else
                            {
                                childNode = FavoritesNode.LoadURLNodeFromFileSystem(result, Path.GetFileNameWithoutExtension(record.LongName), record.Order);
                            }
                            result.children.Add(childNode);
                        }
                        catch
                        {
                        }
                    }

                    result.children.Sort(
                        delegate(FavoritesNode a, FavoritesNode b)
                    {
                        if (a.order < 0 && b.order < 0)
                        {
                            // both items are unordered.. sort the items according to their name
                            return(string.Compare(a.displayName, b.displayName));
                        }
                        else if (a.order < 0 || b.order < 0)
                        {
                            // one of the items is unordered. The negative one should go after the positive one.
                            return(b.order - a.order);
                        }
                        // both items are ordered, sort normally
                        return(a.order - b.order);
                    }
                        );
                }
            }
            return(result);
        }