Пример #1
0
        private static Byte[] ReconstructRawData(IconDirectory dir, FileIconDirectoryEntry[] ents, IconCursorImageResourceData[] images, ResourceSource source)
        {
            Int32 sizeOfIconDirectory = Marshal.SizeOf(typeof(IconDirectory));
            Int32 sizeOfResIconDirEnt = Marshal.SizeOf(typeof(ResIconDirectoryEntry));

            Int32 sizeOfData =
                sizeOfIconDirectory +
                sizeOfResIconDirEnt * dir.wCount;

            IntPtr p = Marshal.AllocHGlobal(sizeOfData);

            Marshal.StructureToPtr(dir, p, true);

            IntPtr q = Inc(p, Marshal.SizeOf(typeof(IconDirectory)));

            for (int i = 0; i < ents.Length; i++)
            {
                FileIconDirectoryEntry e = ents[i];

                ResourceTypeIdentifier iconImageTypeId = new ResourceTypeIdentifier(new IntPtr((int)Win32ResourceType.IconImage));
                ResourceIdentifier     nameId          = source.GetUnusedName(iconImageTypeId);
                source.Add(iconImageTypeId, nameId, 1033, images[i]);

                ResIconDirectoryEntry d = new ResIconDirectoryEntry()
                {
                    bWidth       = e.bWidth,
                    bHeight      = e.bHeight,
                    bColorCount  = e.bColorCount,
                    bReserved    = e.bReserved,
                    wPlanes      = e.wPlanes,
                    wBitCount    = e.wPlanes,
                    dwBytesInRes = e.dwBytesInRes,
                    wId          = (ushort)images[i].Lang.Name.Identifier.NativeId
                };

                Marshal.StructureToPtr(d, q, true);
                q = Inc(q, sizeOfResIconDirEnt);
            }

            Byte[] data = new Byte[sizeOfData];
            Marshal.Copy(p, data, 0, sizeOfData);

            Marshal.FreeHGlobal(p);

            return(data);

            // Major problem:
            // RawData of a directory contains the ResourceNames of the entries in the ResourceSource
            // seeming as this source does not exist, what should go in their place?

            // idea:
            // when a ResourceData is created from a file it is passed the current ResourceSource which it can 'preliminarily add' the datas to
            //	a UI will need to be presented to prompt the user for details if not in Simple Mode. A UI is presented anyway, so this works.

            // this way the IconCursorImageResourceData has been added to the ResourceSource (with the Action.Add property) and this method can
            //	just query ResourceName. Simple (sort-of)
        }
Пример #2
0
        /// <summary>Recreates the byte array that is used for the IconDirectoryResourceData's RawData</summary>
        public Byte[] GetRawData()
        {
            if (!_updated)
            {
                return(_rawData);
            }

            _members.Sort();             // I assume this uses the IconDirectoryMember comparatoer

            Int32 sizeOfIconDirectory = Marshal.SizeOf(typeof(IconDirectory));
            Int32 sizeOfResIconDirEnt = Marshal.SizeOf(typeof(ResIconDirectoryEntry));

            IconDirectory dir = new IconDirectory();

            dir.wReserved = 0;
            dir.wType     = (ushort)(IsIcon ? 1 : 2);         // 1 for icons, 2 for cursors
            dir.wCount    = (ushort)_members.Count;

            Int32 sizeOfData =
                sizeOfIconDirectory +
                sizeOfResIconDirEnt * dir.wCount;

            IntPtr p = Marshal.AllocHGlobal(sizeOfData);

            Marshal.StructureToPtr(dir, p, true);

            IntPtr q = Inc(p, Marshal.SizeOf(typeof(IconDirectory)));

            foreach (IconDirectoryMember member in _members)
            {
                ResIconDirectoryEntry d = new ResIconDirectoryEntry()
                {
                    bWidth       = GetDimension(member.Dimensions.Width),
                    bHeight      = GetDimension(member.Dimensions.Height),
                    bColorCount  = member.ColorCount,
                    bReserved    = member.Reserved,
                    wPlanes      = member.Planes,
                    wBitCount    = member.BitCount,
                    dwBytesInRes = member.Size,
                    wId          = (ushort)member.ResourceData.Lang.Name.Identifier.NativeId
                };

                Marshal.StructureToPtr(d, q, true);
                q = Inc(q, sizeOfResIconDirEnt);
            }

            _rawData = new Byte[sizeOfData];
            Marshal.Copy(p, _rawData, 0, sizeOfData);

            Marshal.FreeHGlobal(p);

            return(_rawData);
        }
Пример #3
0
        public byte[] GetResDirectoryData()
        {
            // recreate the Icon Directory resource data

            var ms = new MemoryStream();

            var wtr = new BinaryWriter(ms);

            var dir = new IconDirectory
            {
                wReserved = 0,
                wType     = (ushort)(Type == IconType.Icon ? 1u : 2u),
                wCount    = (ushort)_images.Count
            };

            dir.Write(wtr);

            foreach (var directoryMember in _images)
            {
                var image = (IconImage)directoryMember;
                var entry = new ResIconDirectoryEntry
                {
                    bWidth       = (byte)image.Size.Width,
                    bHeight      = (byte)image.Size.Height,
                    bColorCount  = image.ColorCount,
                    bReserved    = 0,
                    wPlanes      = image.Planes,
                    wBitCount    = image.BitCount,
                    dwBytesInRes = (uint)image.ImageData.Length,
                    wId          = (ushort)image.ResourceData.Lang.Name.Identifier.NativeId.ToInt32()
                };


                // gotta love the load of dereferencing going on here

                entry.Write(wtr);
            }

            return(ms.ToArray());
        }
Пример #4
0
        private void Load(ResourceLang directoryLang, byte[] rawData)
        {
            DirectoryLang = directoryLang;

            using (var ms = new MemoryStream(rawData))
            {
                var rdr = new BinaryReader(ms);

                var dir = new IconDirectory(rdr);
                if (dir.wType == 1)
                {
                    Type = IconType.Icon;
                }
                if (dir.wType == 2)
                {
                    Type = IconType.Cursor;
                }

                var subImages = new ResIconDirectoryEntry[dir.wCount];
                for (var i = 0; i < subImages.Length; i++)
                {
                    subImages[i] = new ResIconDirectoryEntry(rdr);
                }

                //////////////////////////////////////////

                foreach (var entry in subImages)
                {
                    var rdata = GetRD(entry.wId);

                    var image = new IconImage(rdata.RawData, this, entry)
                    {
                        ResourceDataTyped = rdata
                    };

                    _images.Add(image);
                }
            }
        }
Пример #5
0
        internal IconImage(Byte[] data, IconGroup parentIcon, ResIconDirectoryEntry entry)
        {
            if (data.Length < 4)
            {
                throw new ArgumentException("IconImage data must be at least 4 bytes long", "data");
            }

            // in resources, the hotspot is the first 2 words of the data
            UInt16 hotspotX = (ushort)(data[0] | data[1] << 8);
            UInt16 hotspotY = (ushort)(data[2] | data[3] << 8);

            ImageData  = data;
            ParentIcon = parentIcon;

            Size    = new Size(entry.bWidth, entry.bHeight);
            Hotspot = new Point(hotspotX, hotspotY);

            ColorCount = entry.bColorCount;
            BitCount   = entry.wBitCount;
            Planes     = entry.wPlanes;

            Validate();
        }
Пример #6
0
        private void Load(ResourceLang directoryLang, Byte[] rawData)
        {
            this.DirectoryLang = directoryLang;

            using (MemoryStream ms = new MemoryStream(rawData)) {
                BinaryReader rdr = new BinaryReader(ms);

                IconDirectory dir = new IconDirectory(rdr);
                if (dir.wType == 1)
                {
                    Type = IconType.Icon;
                }
                if (dir.wType == 2)
                {
                    Type = IconType.Cursor;
                }

                ResIconDirectoryEntry[] subImages = new ResIconDirectoryEntry[dir.wCount];
                for (int i = 0; i < subImages.Length; i++)
                {
                    subImages[i] = new ResIconDirectoryEntry(rdr);
                }

                //////////////////////////////////////////

                foreach (ResIconDirectoryEntry entry in subImages)
                {
                    IconCursorImageResourceData rdata = GetRD(entry.wId);

                    IconImage image = new IconImage(rdata.RawData, this, entry);
                    image.ResourceDataTyped = rdata;

                    _images.Add(image);
                }
            }
        }
Пример #7
0
        public Byte[] GetResDirectoryData()
        {
            // recreate the Icon Directory resource data

            MemoryStream ms = new MemoryStream();

            BinaryWriter wtr = new BinaryWriter(ms);

            IconDirectory dir = new IconDirectory();

            dir.wReserved = 0;
            dir.wType     = (ushort)(Type == IconType.Icon ? 1u : 2u);
            dir.wCount    = (ushort)_images.Count;

            dir.Write(wtr);

            foreach (IconImage image in _images)
            {
                ResIconDirectoryEntry entry = new ResIconDirectoryEntry();
                entry.bWidth  = (byte)image.Size.Width;
                entry.bHeight = (byte)image.Size.Height;

                entry.bColorCount = image.ColorCount;
                entry.bReserved   = 0;

                entry.wPlanes   = image.Planes;
                entry.wBitCount = image.BitCount;

                entry.dwBytesInRes = (uint)image.ImageData.Length;
                entry.wId          = (ushort)image.ResourceData.Lang.Name.Identifier.NativeId.ToInt32();                 // gotta love the load of dereferencing going on here

                entry.Write(wtr);
            }

            return(ms.ToArray());
        }
Пример #8
0
        public static ResIconDir FromResource(ResourceLang lang, Byte[] rawBytes)
        {
            Int32 sizeOfIconDir = Marshal.SizeOf(typeof(IconDirectory));
            Int32 sizeOfDirEntr = Marshal.SizeOf(typeof(ResIconDirectoryEntry));

            // the data in here is an ICONDIR structure

            IntPtr p = Marshal.AllocHGlobal(rawBytes.Length);

            Marshal.Copy(rawBytes, 0, p, rawBytes.Length);

            // this could be vastly simplified by correctly marshaling the member array of IconDirectory
            // but that's a can of worms, I'd rather not
            IconDirectory dir = (IconDirectory)Marshal.PtrToStructure(p, typeof(IconDirectory));

            Marshal.FreeHGlobal(p);

            if (dir.wType != 1 && dir.wType != 2)
            {
                throw new InvalidOperationException("Provided rawData is not an icon or cursor");
            }

            ResIconDirectoryEntry[] subImages = new ResIconDirectoryEntry[dir.wCount];

            for (int i = 0; i < dir.wCount; i++)
            {
                Int32 byteOffset = sizeOfIconDir + sizeOfDirEntr * i;

                p = Marshal.AllocHGlobal(sizeOfDirEntr);
                Marshal.Copy(rawBytes, byteOffset, p, sizeOfDirEntr);

                ResIconDirectoryEntry img = (ResIconDirectoryEntry)Marshal.PtrToStructure(p, typeof(ResIconDirectoryEntry));

                subImages[i] = img;
            }

            ResIconDir retval = new ResIconDir(dir.wType == 1, lang.LanguageId, lang.Name.Type.Source);

            // then we might be able to get the resourcedata for the subimages to include in the directory

            // find the Icon Image resource type
            ResourceType      imageType = null;
            Win32ResourceType desired   = dir.wType == 1 ? Win32ResourceType.IconImage : Win32ResourceType.CursorImage;

            foreach (ResourceType type in lang.Name.Type.Source.AllTypes)
            {
                if (type.Identifier.KnownType == desired)
                {
                    imageType = type;
                    break;
                }
            }

            if (imageType != null)
            {
                foreach (ResIconDirectoryEntry img in subImages)
                {
                    IconCursorImageResourceData rd = GetDataFromWid(imageType, lang, img.wId);

                    Size dimensions = new Size(img.bWidth == 0 ? 256 : img.bWidth, img.bHeight == 0 ? 256 : img.bHeight);
                    // cursors might have Height == 0, so it should copy the width rather than being set to 256

                    retval.Members.Add(new IconDirectoryMember(rd, dimensions, img.bColorCount, img.bReserved, img.wPlanes, img.wBitCount, img.dwBytesInRes));
                }
            }

            return(retval);
        }
Пример #9
0
        public static Boolean TryCreateFromRes(ResourceLang lang, Byte[] rawData, out IconDirectoryResourceData typed)
        {
            Int32 sizeOfIconDir = Marshal.SizeOf(typeof(IconDirectory));
            Int32 sizeOfDirEntr = Marshal.SizeOf(typeof(ResIconDirectoryEntry));

            // the data in here is an ICONDIR structure

            IntPtr p = Marshal.AllocHGlobal(rawData.Length);

            Marshal.Copy(rawData, 0, p, rawData.Length);

            // this could be vastly simplified by correctly marshaling the member array of IconDirectory
            // but that's a can of worms, I'd rather not
            IconDirectory dir = (IconDirectory)Marshal.PtrToStructure(p, typeof(IconDirectory));

            Marshal.FreeHGlobal(p);

            if (dir.wType != 1)
            {
                throw new InvalidOperationException("Provided rawData was not that of an icon's");
            }

            ResIconDirectoryEntry[] subImages = new ResIconDirectoryEntry[dir.wCount];

            for (int i = 0; i < dir.wCount; i++)
            {
                Int32 byteOffset = sizeOfIconDir + sizeOfDirEntr * i;

                p = Marshal.AllocHGlobal(sizeOfDirEntr);
                Marshal.Copy(rawData, byteOffset, p, sizeOfDirEntr);

                ResIconDirectoryEntry img = (ResIconDirectoryEntry)Marshal.PtrToStructure(p, typeof(ResIconDirectoryEntry));

                subImages[i] = img;
            }

            IconDirectoryResourceData retval = new IconDirectoryResourceData(lang, rawData);

            // then we might be able to get the resourcedata for the subimages to include in the directory

            // find the Icon Image resource type
            ResourceType iconType = null;

            foreach (ResourceType type in lang.Name.Type.Source.Types)
            {
                if (type.Identifier.KnownType == Win32ResourceType.IconImage)
                {
                    iconType = type;
                    break;
                }
            }

            if (iconType != null)
            {
                foreach (ResIconDirectoryEntry img in subImages)
                {
                    IconCursorImageResourceData rd = GetDataFromWid(iconType, lang, img.wId);

                    String description = String.Format(
                        Cult.InvariantCulture,
                        "{0}x{1} {2}-bit",
                        img.bWidth == 0 ? 256 : img.bWidth,
                        img.bHeight == 0 ? 256 : img.bHeight,
                        img.wBitCount
                        );

                    retval.UnderlyingMembers.Add(new IconDirectoryMember(description, rd));
                }
            }

            typed = retval;
            return(true);
        }