Beispiel #1
0
        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);
                }
            }
        }