[API] Win32 Resources - List Icon Resource Names



I wrote some code that is supposed to enumerate through the specified file's win32 resources and return a string-array of all icon names. When it runs, it returns a string-array with a bunch of numbers in sequential order (1-55 when ran against iexplore.exe).

When I open up iexplore.exe in Visual Studio, I see 23 icons. Each icon has 1 or more sizes of the icon...I'm assuming that there are, in fact, 55 icon resources in iexplore.exe, and the code I wrote is returning the indexes of the icons? If so, how do I get the names/identifiers for the icons?

The following is my code for the ResourceExtracter class that hopefully shows what I am trying to do...To use, just create a ResourceExtracter instance and call GetIconNames passing the path to an exe or dll file (C:\Program Files\Internet Explorer\iexplore.exe is the path I am using to test with).

Thanks in advance :)

-------------------------------------------------------------------------

using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.ComponentModel;

namespace Tests.Applications.ResourceViewer.UI
{
/// <summary>
/// Provides the methods to extract resources from a Win32 binary.
/// </summary>
public class ResourceExtracter
{

#region Private Members
// =================================================================
// Private Members
// =================================================================


           private enum ResourceType : int
           {
               Cursor      = 0x00000001,
               Bitmap      = 0x00000002,
               Icon        = 0x00000003,
               Menu        = 0x00000004,
               Dialog      = 0x00000005,
               String      = 0x00000006,
               FontDir     = 0x00000007,
               Font        = 0x00000008,
               Accelerator = 0x00000009,
               RcData      = 0x0000000a,
               MessageTable = 0x0000000b
           }

           private const int LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
           private const int ERROR_RESOURCE_TYPE_NOT_FOUND = 0x00000715;

           private string mFilePath = null;

           private delegate bool EnumResNameDelegate(
               IntPtr ModuleHandle,
               IntPtr Type,
               IntPtr Name,
               IntPtr Param
           );
       #endregion

#region API Declarations
// =================================================================
// API Declarations
// =================================================================


           [DllImport("kernel32.dll", SetLastError = true)]
           private static extern IntPtr LoadLibraryEx(
               string FileName,
               IntPtr FileHandle,
               uint Flags
           );

           [DllImport("kernel32.dll", SetLastError = true)]
           private static extern bool FreeLibrary(IntPtr ModuleHandle);

           [
               DllImport(
                   "kernel32.dll",
                   EntryPoint = "EnumResourceNamesW",
                   CharSet = CharSet.Unicode,
                   SetLastError = true
               )
           ]
           private static extern bool EnumResourceNamesWithName(
               IntPtr ModuleHandle,
               ResourceType Type,
               EnumResNameDelegate EnumFunc,
               IntPtr Param
           );

           [DllImport("kernel32.dll", SetLastError = true)]
           private static extern IntPtr FindResource(
               IntPtr ModuleHandle,
               string Name,
               string Type
           );

           [
               DllImport(
                   "kernel32.dll",
                   EntryPoint = "EnumResourceNamesW",
                   CharSet = CharSet.Unicode,
                   SetLastError = true
               )
           ]
           private static extern bool EnumResourceNamesWithID(
               IntPtr ModuleHandle,
               ResourceType Type,
               EnumResNameDelegate EnumFunc,
               IntPtr Param
           );
       #endregion

#region Constructors / Destructors
// =================================================================
// Constructors / Destructors
// =================================================================


/// <summary>
/// Creates a new instance of the <see cref="ResourceExtracter"/>
/// class.
/// </summary>
/// <param name="FilePath"></param>
public ResourceExtracter(string FilePath)
{
mFilePath = FilePath;
}
#endregion


#region Public Properties
// =================================================================
// Public Properties
// =================================================================


           /// <summary>
           /// Specifies the path of the Win32 binary.
           /// </summary>
           public string FilePath
           {
               get {
                   return mFilePath;
               }
               set {
                   mFilePath = value;
               }
           }
       #endregion

#region Public Methods
// =================================================================
// Public Methods
// =================================================================


           /// <summary>
           /// Gets the icon resource names for the current file.
           /// </summary>
           public string[] GetIconNames()
           {
               return GetResourceNames(ResourceType.Icon);
           }

           /// <summary>
           /// Gets the string resource names for the current file.
           /// </summary>
           public string[] GetStringNames()
           {
               return GetResourceNames(ResourceType.String);
           }
       #endregion

#region Private Methods
// =================================================================
// Private Methods
// =================================================================


           private string[] GetResourceNames(ResourceType Type)
           {
               ArrayList names = new ArrayList();

               // Get the handle to the library.
               IntPtr moduleHandle = GetLibraryModule(this.FilePath);

               try {
                   FillResourceNames(moduleHandle, Type, names);
               } finally {
                   // Cleanup.
                   FreeLibrary(moduleHandle);
               }

               // Convert the names into a string-array and return it.
               return (string[]) names.ToArray(typeof(string));
           }

/// <summary>
/// Load the specified library and return the handle.
/// </summary>
/// <param name="LibraryPath">
/// The path to the library to load (.dll or .exe).
/// </param>
/// <returns>
/// Returns an <see cref="IntPtr"/> that represents the handle to
/// the library module loaded.
/// </returns>
private IntPtr GetLibraryModule(string LibraryPath)
{
// Load the library.
IntPtr result = LoadLibraryEx(
LibraryPath,
IntPtr.Zero,
LOAD_LIBRARY_AS_DATAFILE
);


               if (result == IntPtr.Zero) {
                   // Error occurred.
                   throw new Win32Exception(Marshal.GetLastWin32Error());
               } else {
                   return result;
               }
           }

/// <summary>
/// Fills the <paramref name="List"/> with all of the resource names
/// of the specified <paramref name="ResourceType"/>.
/// </summary>
/// <param name="ModuleHandle">
/// The handle to the library module that contains the resource(s)
/// to retrieve.
/// </param>
/// <param name="Type">The type of resource to retrieve.</param>
/// <param name="List">
/// The <see cref="ArrayList"/> to place the results into.
/// </param>
private void FillResourceNames(
IntPtr ModuleHandle,
ResourceType Type,
ArrayList List
)
{
// Get the ptr to the ArrayList.
GCHandle listHandle = GCHandle.Alloc(List);


               try {
                   // Enumerate the resource names.
                   bool result = EnumResourceNamesWithID(
                       ModuleHandle,
                       Type,
                       new EnumResNameDelegate(EnumRes),
                       (IntPtr) listHandle
                   );

// Check for errors.
if (!result) {
int code = Marshal.GetLastWin32Error();
if (code != ERROR_RESOURCE_TYPE_NOT_FOUND) {
// Raise a Win32Exception for any errors except
// for when the specified resource type could not
// be found.
throw new Win32Exception(code);
}
}
} finally {
// Release the allocated ArrayList.
listHandle.Free();
}
}


           private static bool IsIntResource(IntPtr Value)
           {
               return (((ulong) Value) >> 16) == 0;
           }

           private bool EnumRes(
               IntPtr ModuleHandle,
               IntPtr Type,
               IntPtr Name,
               IntPtr Param
           )
           {
               GCHandle listHandle = (GCHandle) Param;
               ArrayList list = (ArrayList) listHandle.Target;

               string name = null;
               if (IsIntResource(Name)) {
                   name = ((int) Name).ToString();
               } else {
                   name = Marshal.PtrToStringAuto(Name);
               }

               list.Add(name);
               return true;
           }
       #endregion

   }
}

.



Relevant Pages

  • Re: Detecting a service that is running
    ... "OpenSCManagerA" (ByVal lpMachineName As String, ... public int dwControlsAccepted = 0; ... private static extern IntPtr OpenSCManager(string lpMachineName, ...
    (microsoft.public.vb.general.discussion)
  • Re: Detecting a service that is running
    ... "OpenSCManagerA" (ByVal lpMachineName As String, ... public int dwControlsAccepted = 0; ... private static extern IntPtr OpenSCManager(string lpMachineName, ...
    (microsoft.public.vb.winapi)
  • Re: List SQL servers in a network
    ... private static extern short SQLAllocHandle(short hType, IntPtr inputHandle, ... private static extern short SQLSetEnvAttr(IntPtr henv, int attribute, IntPtr ... public static string[] GetServers{ ... throw new ApplicationException("Unabled to aquire SQL Servers from ODBC ...
    (microsoft.public.dotnet.general)
  • Re: List SQL servers in a network
    ... > private static extern short SQLAllocHandle(short hType, IntPtr ... > public static string[] GetServers{ ... > throw new ApplicationException("Unabled to aquire SQL Servers from ODBC ...
    (microsoft.public.dotnet.general)
  • Re: UpdateResource being weird
    ... Public Shared Function UpdateResource(ByVal hUpdate As IntPtr, ... > for String Types. ... >> inspection using a resource viewer shows that the MSI file is being ...
    (microsoft.public.dotnet.languages.vb)