Loading resources...

Aright, I'm trying to load resources from a file, but I think the callback function is not working correctly. Care to take a look?

public class Resource
      {
            public Resource(string Filename)
            {
                  System.Diagnostics.Debug.WriteLine("Loading Resource...");
                  hModule = Kernel32.LoadLibraryEx(Filename, 0, Kernel32.LOAD_LIBRARY_AS_DATAFILE);
                  if(hModule == 0)
                  {
                        System.Diagnostics.Debug.WriteLine("Error loading library");
                  }
                  System.Diagnostics.Debug.WriteLine(hModule);
                  Kernel32.EnumResourceTypes(hModule, new Kernel32.EnumResTypeProc(EnumResTypeProc), 0);
                  Kernel32.FreeLibrary(hModule);
                  hModule = 0;

            }


            private long hModule;

            public static void EnumResTypeProc(long hModule, [MarshalAs(UnmanagedType.LPTStr)] string lpszType, long lParam)
            {            
                  System.Diagnostics.Debug.WriteLine("lpszType" + lpszType);
            }


      }

public class Kernel32
      {
            public const long DONT_RESOLVE_DLL_REFERENCES      = 0x00000001;
            public const long LOAD_LIBRARY_AS_DATAFILE            = 0x00000002;
            public const long LOAD_WITH_ALTERED_SEARCH_PATH      = 0x00000008;
            public const long LOAD_IGNORE_CODE_AUTHZ_LEVEL      = 0x00000010;


[DllImport("kernel32.dll")]
            public static extern long LoadLibraryEx(string lpfFileName,
                  long hFile, long dwFlags);

[DllImport("kernel32.dll")]
            public static extern bool EnumResourceTypes(long hModule, EnumResTypeProc callback, long lParam);

            public delegate void EnumResTypeProc(long hModule, [MarshalAs(UnmanagedType.LPTStr)] string lpszType, long lParam);
            [DllImport("kernel32.dll")]
            public static extern bool FreeLibrary(long hModule);
}

rossryanAsked:
Who is Participating?
 
AlexFMConnect With a Mentor Commented:
By the way, SetLastError=true parameter of DllImport allows to get last Win32 error of API call (like GetLastError). In your program it was 998 (invalid access to memory location). This happened when .NET marshaller tried to handle resource type 2 (bitmap) as string pointer.
LOAD_LIBRARY_AS_DATAFILE is OK, you can use it.
0
 
rossryanAuthor Commented:
Oh yeah, the file I am trying to load is explorer.exe, which has oodles of resources. I'm trying to check if the callback is working correctly by printing the lpszType string, but nothing appears, i.e. it never gets that far...
0
 
AlexFMCommented:
This is your program with some changes:

    public class Resource
    {
        public Resource(string Filename)
        {
            System.Diagnostics.Debug.WriteLine("Loading Resource...");
            hModule = Kernel32.LoadLibraryEx(Filename, 0, 0); //Kernel32.LOAD_LIBRARY_AS_DATAFILE);
            if(hModule == IntPtr.Zero)
            {
                System.Diagnostics.Debug.WriteLine("Error loading library");
            }
            System.Diagnostics.Debug.WriteLine(hModule);
            Int32 n = Kernel32.EnumResourceTypes(hModule, new Kernel32.EnumResTypeProc(EnumResTypeProc), 0);
            int nError = Marshal.GetLastWin32Error();
            Kernel32.FreeLibrary(hModule);
            hModule = IntPtr.Zero;
        }

        private IntPtr hModule;

        public static Int32 EnumResTypeProc(IntPtr hModule,
            IntPtr lpszType, long lParam)
        {
            System.Diagnostics.Debug.WriteLine(lpszType);
            return 1;
        }
    }

    public class Kernel32
    {
        public const long DONT_RESOLVE_DLL_REFERENCES     = 0x00000001;
        public const long LOAD_LIBRARY_AS_DATAFILE          = 0x00000002;
        public const long LOAD_WITH_ALTERED_SEARCH_PATH     = 0x00000008;
        public const long LOAD_IGNORE_CODE_AUTHZ_LEVEL     = 0x00000010;


        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibraryEx(string lpfFileName,
            long hFile, long dwFlags);

        [DllImport("kernel32.dll", SetLastError=true)]
        public static extern Int32 EnumResourceTypes(IntPtr hModule, EnumResTypeProc callback, long lParam);

        public delegate Int32 EnumResTypeProc(IntPtr hModule, IntPtr lpszType, long lParam);
        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
    }

It gets the following results for explorer.exe:
126615552             <- module handle
2
3
4
5
6
9
14
16

lpszType parameter of EnumResTypeProc is integer value which can be one of predefined types:
RT_ACCELERATOR, RT_ANICURSOR, RT_ANIICON ... (see details in MSDN topic EnumResTypeProc). Only if lpszType is not equal to none of these values, it points to the string which contains custom resource name. Predefined resource types from winuser.h:

#define RT_CURSOR           MAKEINTRESOURCE(1)             // == 1
#define RT_BITMAP           MAKEINTRESOURCE(2)              // == 2
#define RT_ICON             MAKEINTRESOURCE(3)               // ...
#define RT_MENU             MAKEINTRESOURCE(4)
#define RT_DIALOG           MAKEINTRESOURCE(5)
#define RT_STRING           MAKEINTRESOURCE(6)
#define RT_FONTDIR          MAKEINTRESOURCE(7)
#define RT_FONT             MAKEINTRESOURCE(8)
#define RT_ACCELERATOR      MAKEINTRESOURCE(9)
#define RT_RCDATA           MAKEINTRESOURCE(10)
#define RT_MESSAGETABLE     MAKEINTRESOURCE(11)
#define RT_VERSION      MAKEINTRESOURCE(16)
#define RT_DLGINCLUDE   MAKEINTRESOURCE(17)
#define RT_PLUGPLAY     MAKEINTRESOURCE(19)
#define RT_VXD          MAKEINTRESOURCE(20)
#define RT_ANICURSOR    MAKEINTRESOURCE(21)
#define RT_ANIICON      MAKEINTRESOURCE(22)
#define RT_HTML         MAKEINTRESOURCE(23)
#define RT_MANIFEST                        24

Change EnumResTypeProc by the following way. If lpszType is one of predefined resource types, handle it as integer value. Otherwise get custom resource name using Marshal.PtrToStringAuto Method.
0
 
rossryanAuthor Commented:
Excellent, and thanks.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.