public unsafe MultiIcon Load(Stream stream) { // LoadLibraryEx only can load files from File System, lets create a tmp file string tmpFile = null; IntPtr hLib = IntPtr.Zero; try { stream.Position = 0; // Find a tmp file where to dump the DLL stream, later we will remove this file tmpFile = Path.GetTempFileName(); FileStream fs = new FileStream(tmpFile, FileMode.Create, FileAccess.Write); byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); fs.Write(buffer, 0, buffer.Length); fs.Close(); hLib = Win32.LoadLibraryEx(tmpFile, IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE); if (hLib == IntPtr.Zero) { throw new InvalidFileException(); } List <string> iconsIDs; lock (typeof(PEFormat)) { mIconsIDs = new List <string>(); bool bResult = Win32.EnumResourceNames(hLib, (IntPtr)ResourceType.RT_GROUP_ICON, new Win32.EnumResNameProc(EnumResNameProc), IntPtr.Zero); if (bResult == false) { // No Resources in this file } iconsIDs = new List <string>(mIconsIDs); } MultiIcon multiIcon = new MultiIcon(); for (int index = 0; index < iconsIDs.Count; index++) { string id = iconsIDs[index]; IntPtr hRsrc = IntPtr.Zero; if (Win32.IS_INTRESOURCE(id)) { hRsrc = Win32.FindResource(hLib, int.Parse(id), (IntPtr)ResourceType.RT_GROUP_ICON); } else { hRsrc = Win32.FindResource(hLib, id, (IntPtr)ResourceType.RT_GROUP_ICON); } if (hRsrc == IntPtr.Zero) { throw new InvalidFileException(); } IntPtr hGlobal = Win32.LoadResource(hLib, hRsrc); if (hGlobal == IntPtr.Zero) { throw new InvalidFileException(); } MEMICONDIR *pDirectory = (MEMICONDIR *)Win32.LockResource(hGlobal); if (pDirectory->wCount != 0) { MEMICONDIRENTRY *pEntry = &(pDirectory->arEntries); SingleIcon singleIcon = new SingleIcon(id); for (int i = 0; i < pDirectory->wCount; i++) { IntPtr hIconInfo = Win32.FindResource(hLib, (IntPtr)pEntry[i].wId, (IntPtr)ResourceType.RT_ICON); if (hIconInfo == IntPtr.Zero) { throw new InvalidFileException(); } IntPtr hIconRes = Win32.LoadResource(hLib, hIconInfo); if (hIconRes == IntPtr.Zero) { throw new InvalidFileException(); } IntPtr dibBits = Win32.LockResource(hIconRes); if (dibBits == IntPtr.Zero) { throw new InvalidFileException(); } buffer = new byte[Win32.SizeofResource(hLib, hIconInfo)]; Marshal.Copy(dibBits, buffer, 0, buffer.Length); MemoryStream ms = new MemoryStream(buffer); IconImage iconImage = new IconImage(ms, buffer.Length); singleIcon.Add(iconImage); } multiIcon.Add(singleIcon); } } // If everything went well then lets return the multiIcon. return(multiIcon); } catch (Exception) { throw new InvalidFileException(); } finally { if (hLib != null) { Win32.FreeLibrary(hLib); } if (tmpFile != null) { File.Delete(tmpFile); } } }
public static MemoryStream GetIconMemoryStreamFromExeFile(string exeFilePath, int iconIndex, ref MemoryStream imageMemoryStream) { IntPtr iconHandle = IntPtr.Zero; IntPtr libraryHandle = IntPtr.Zero; try { //Load executable file library Debug.WriteLine("Loading exe icon: " + exeFilePath); libraryHandle = LoadLibraryEx(exeFilePath, IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE); if (libraryHandle == IntPtr.Zero) { Debug.WriteLine("Failed to load icon from exe: " + exeFilePath); return(null); } //Enumerate all icon groups List <string> iconGroups = new List <string>(); EnumResNameProcDelegate EnumResourceNamesCallback = (IntPtr hModule, ResourceTypes lpType, IntPtr lpEnumFunc, IntPtr lParam) => { try { string intPtrString = IntPtrToString(lpEnumFunc); if (!string.IsNullOrWhiteSpace(intPtrString)) { iconGroups.Add(intPtrString); return(true); } } catch { } return(false); }; EnumResourceNames(libraryHandle, ResourceTypes.GROUP_ICON, EnumResourceNamesCallback, IntPtr.Zero); //Select target icon group string iconGroup = string.Empty; int iconGroupsCount = iconGroups.Count; //Debug.WriteLine("Total icon groups: " + iconGroupsCount); if (iconGroupsCount > 0 && iconGroupsCount >= iconIndex) { iconGroup = iconGroups[iconIndex]; } else { Debug.WriteLine("No exe icon found to load."); return(null); } //Get all icons from group List <MEMICONDIRENTRY> iconDirEntryList = new List <MEMICONDIRENTRY>(); IntPtr iconDirIntPtr = GetResourceDataIntPtrFromString(libraryHandle, iconGroup, ResourceTypes.GROUP_ICON); unsafe { MEMICONDIR * iconDir = (MEMICONDIR *)iconDirIntPtr; MEMICONDIRENTRY *iconDirEntryArray = &iconDir->idEntriesArray; //Debug.WriteLine("Total icons in group: " + iconDir->idCount); for (int entryId = 0; entryId < iconDir->idCount; entryId++) { try { iconDirEntryList.Add(iconDirEntryArray[entryId]); } catch { } } } //Select largest icon MEMICONDIRENTRY iconDirEntry = iconDirEntryList.OrderByDescending(x => x.wBitCount).ThenByDescending(x => x.dwBytesInRes).FirstOrDefault(); //Get icon bitmap data byte[] iconBytes = GetResourceDataBytesFromIntPtr(libraryHandle, (IntPtr)iconDirEntry.nIdentifier, ResourceTypes.ICON); //Encode icon bitmap frame if (iconBytes[0] == 0x28) { //Debug.WriteLine("BMP image: " + iconBytes.Length); //Create icon from the resource iconHandle = CreateIconFromResourceEx(iconBytes, (uint)iconBytes.Length, true, IconVersion.Windows3x, iconDirEntry.bWidth, iconDirEntry.bHeight, IconResourceFlags.LR_DEFAULTCOLOR); //Convert image data to bitmap Bitmap bitmapImage = Icon.FromHandle(iconHandle).ToBitmap(); //Write bitmap to memorystream bitmapImage.Save(imageMemoryStream, ImageFormat.Png); imageMemoryStream.Seek(0, SeekOrigin.Begin); return(imageMemoryStream); } else { //Debug.WriteLine("PNG image: " + iconBytes.Length); using (MemoryStream memoryStream = new MemoryStream(iconBytes)) { //Convert image data to bitmap Bitmap bitmapImage = new Bitmap(memoryStream); //Write bitmap to memorystream bitmapImage.Save(imageMemoryStream, ImageFormat.Png); imageMemoryStream.Seek(0, SeekOrigin.Begin); return(imageMemoryStream); } } } catch (Exception ex) { Debug.WriteLine("Failed to load exe icon: " + ex.Message); return(null); } finally { if (libraryHandle != IntPtr.Zero) { FreeLibrary(libraryHandle); } if (iconHandle != IntPtr.Zero) { DestroyIcon(iconHandle); } } }