Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Loading resources...

Posted on 2004-03-26
4
Medium Priority
?
651 Views
Last Modified: 2008-01-09
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);
}

0
Comment
Question by:rossryan
  • 2
  • 2
4 Comments
 

Author Comment

by:rossryan
ID: 10691758
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 10694638
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
 
LVL 48

Accepted Solution

by:
AlexFM earned 2000 total points
ID: 10694653
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
 

Author Comment

by:rossryan
ID: 10696673
Excellent, and thanks.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question