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