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) }
/// <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); }
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()); }
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); } } }
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(); }
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); } } }
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()); }
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); }
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); }