Example #1
0
 public ICONDIRENTRY(RESOURCE_ICONDIRENTRY resentry, uint offset)
 {
     bWidth        = resentry.bWidth;
     bHeight       = resentry.bHeight;
     bColorCount   = resentry.bColorCount;
     bReserved     = resentry.bReserved;
     wPlanes       = resentry.wPlanes;
     wBitCount     = resentry.wBitCount;
     dwBytesInRes  = resentry.dwBytesInRes;
     dwImageOffset = offset;
 }
Example #2
0
        private static Icon LoadIconFromResource(UIntPtr lpIconName)
        {
            HandleRef hmodule = new HandleRef(null, GetModuleHandle(null));

            uint totalsize;

            RESOURCE_ICONDIRENTRY[] entries;
            SafeResourceBuffer[]    entrybuffers;
            RESOURCE_ICONDIR        dir;

            using (SafeResourceBuffer buffer = GetResourceBuffer(hmodule, lpIconName, MAKEINTRESOURCE(RT_GROUP_ICON)))
            {
                dir = buffer.Read <RESOURCE_ICONDIR>(0);
                if (dir.idReserved != 0 || dir.idType != IMAGE_ICON || dir.idCount == 0)
                {
                    throw new InvalidDataException("There is no icon directory in resource data.");
                }

                entries      = new RESOURCE_ICONDIRENTRY[dir.idCount];
                entrybuffers = new SafeResourceBuffer[dir.idCount];
                uint  entrysize = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIRENTRY));
                ulong offset    = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIR)) - entrysize;
                totalsize = (uint)(Marshal.SizeOf(typeof(ICONDIR)) + (Marshal.SizeOf(typeof(ICONDIRENTRY)) * (dir.idCount - 1)));

                entries[0] = dir.idEntries;
                for (int i = 0; i < dir.idCount; i++, offset += entrysize)
                {
                    if (i > 0)
                    {
                        entries[i] = buffer.Read <RESOURCE_ICONDIRENTRY>(offset);
                    }

                    uint iconsize = entries[i].dwBytesInRes;
                    SafeResourceBuffer entrybuffer = GetResourceBuffer(hmodule, MAKEINTRESOURCE(entries[i].nID), MAKEINTRESOURCE(RT_ICON));
                    if (iconsize != entrybuffer.ByteLength)
                    {
                        throw new InvalidDataException("Reported resource size is not equal to the icon size.");
                    }

                    entrybuffers[i] = entrybuffer;
                    totalsize      += iconsize;
                }
            }

            using (SafeLocalAllocHandle iconbuffer = SafeLocalAlloc(LMEM_ZEROINIT | LMEM_FIXED, totalsize))
            {
                using (UnmanagedMemoryStream outstream = iconbuffer.ToStream(FileAccess.ReadWrite))
                {
                    ICONDIR icondir = new ICONDIR(dir);
                    iconbuffer.Write(0, icondir);

                    uint iconoffset = icondir.idEntries.dwImageOffset;
                    outstream.Position = iconoffset;
                    uint         entrysize = (uint)Marshal.SizeOf(typeof(ICONDIRENTRY));
                    ulong        offset    = (uint)Marshal.SizeOf(typeof(ICONDIR));
                    ICONDIRENTRY entry     = icondir.idEntries;
                    for (int i = 0; i < dir.idCount; i++, offset += entrysize)
                    {
                        if (i > 0)
                        {
                            entry = new ICONDIRENTRY(entries[i], iconoffset);
                            iconbuffer.Write(offset, entry);
                        }

                        using (UnmanagedMemoryStream instream = entrybuffers[i].ToStream())
                        {
                            instream.CopyTo(outstream);
                        }

                        if (outstream.Position != (iconoffset + entry.dwBytesInRes))
                        {
                            throw new InvalidOperationException();
                        }

                        iconoffset += entry.dwBytesInRes;
                    }

                    outstream.Position = 0;
                    return(new Icon(outstream));
                }
            }
        }