Thread: EnumResourceTypes Error

  1. #1
    Registered User
    Join Date
    Aug 2004
    Posts
    6

    EnumResourceTypes Error

    I've compiled a ver simple Windows program in C which uses a resource. I can find the resource easily just doing:
    Code:
    byte* data;
    HRSRC hResInfo = FindResource(NULL, "RCDATA_0", RT_RCDATA);
    if (hResInfo==NULL) {
        MessageBox(NULL, "FindResource has failed!", "", MB_OK);    
        return -1;
    }
    HGLOBAL hResData = LoadResource(NULL, hResInfo);
    if (hResData==NULL) {
        MessageBox(NULL, "LoadResource has failed!", "", MB_OK);    
        return -1;
    }
    data = LockResource(hResData);
    if (data==NULL) {
        MessageBox(NULL, "LockResource has failed!", "", MB_OK);
        return -1;
    }
    For testing purpose I'm executing the previous code when I clic a simple button, and it all works perfectly.


    But now I want to create a resource list, and I'm getting an error using EnumResourceTypes. This is the way I'm using this function:
    Code:
    if (EnumResourceTypes(NULL, (ENUMRESTYPEPROC)EnumResTypeProc, 0)==0) {
        MessageBox(NULL, "EnumResourceTypes has failed!", "", MB_OK);
        return -1;
    }
    And this is the callback function:
    Code:
    BOOL CALLBACK EnumResTypeProc(HMODULE hModule, LPTSTR lpszType, LONG_PTR lParam)
    {
        MessageBox(NULL, lpszType, "", MB_OK);
        return TRUE;
    }
    The GetLastError function returns 998, "Invalid access to memory location". What is the problem?

  2. #2
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Looking at the MSDN Docs for the callback function

    Code:
    BOOL CALLBACK EnumResTypeProc(          HMODULE hModule,
        LPTSTR lpszType,
        LONG_PTR lParam
    );
    If IS_INTRESOURCE( lpszType) is TRUE, lpszType specifies the integer identifier of the given resource. Otherwise, it is a pointer to a null-terminated string. If the first character of the string is a pound sign ( #), the remaining characters represent a decimal number that specifies the integer identifier of the resource. For example, the string " #258" represents the identifier 258.
    I guess this is one situation where a string isnt always a string!

  3. #3
    Registered User
    Join Date
    Aug 2004
    Posts
    6
    Error occurs when EnumResourceTypes is executed. EnumResTypeProc isn't even called.

  4. #4
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Probably because you are calling it with 0 as the first param

    Code:
    #include <windows.h>
    #include <tchar.h>
    #include <sstream>
    
    BOOL CALLBACK EnumResTypeProc(HMODULE hModule, LPTSTR lpszType, LONG_PTR lParam)
    {	
    	if(IS_INTRESOURCE(lpszType))
    	{
    		std::basic_stringstream<TCHAR> StringStream;
    		StringStream << reinterpret_cast<INT>(lpszType);
    		MessageBox(0, StringStream.str().c_str(),_T("Type Found"), MB_OK);
    	}
    	else
    	{
    		MessageBox(0, lpszType,_T("Type Found"), MB_OK);
    	}
        return TRUE;
    }
    
    
    int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int)
    {
    	OPENFILENAME OpenFileName = {sizeof(OPENFILENAME)};
    	TCHAR NameBuff[MAX_PATH + 1] = {0};
    	
    	OpenFileName.lpstrFile = NameBuff;
        OpenFileName.nMaxFile = MAX_PATH;
    	OpenFileName.lpstrFilter = _T("Programs\0*.exe\0DLLs\0*.dll\0");
    	OpenFileName.nFilterIndex = 1;
    	OpenFileName.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    
    	if(!GetOpenFileName(&OpenFileName))
    		return -1;
    
    	HMODULE Module = LoadLibrary(NameBuff);
    	if(Module == 0)
    	{
    		MessageBox(0,_T("Unable to load!"),_T(""), MB_OK);
    		return -1;
    	}
    
    	if(EnumResourceTypes(Module,EnumResTypeProc, 0)==0)
    	{
    		MessageBox(0,_T("EnumResourceTypes has failed!"),_T(""), MB_OK);
    		FreeLibrary(Module);
    		return -1;
    	}
    	FreeLibrary(Module);
    	return 0;
    }

  5. #5
    Registered User
    Join Date
    Aug 2004
    Posts
    6
    First parameter of EnumResourceTypes is NULL because the resource is within the current process (a rc file compiled and linked with the application)

    The question is:
    Why does FindResource(NULL, "RCDATA_0", RT_RCDATA); work but
    EnumResourceTypes(NULL, (ENUMRESTYPEPROC)EnumResTypeProc, 0) fail?

  6. #6
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Dont know, but I got it to work for me in the above example.

    Try substituting the NULL in the first param with GetModuleHandle(0). See if that fares any better

  7. #7
    Registered User
    Join Date
    Aug 2004
    Posts
    6
    I've tried it, but it still doesn´t work

  8. #8
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Well I dont know what your doing wrong.


    Here's an example that works fine

  9. #9
    Registered User
    Join Date
    Aug 2004
    Posts
    6
    Here is my example. If you use the enumRCDATAResources function you get an error, but if you use the handleRCDATAResources function, the resource is accesed without errors

  10. #10
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Go back and read Fordy's first post and the sample in his second post, or even the sample in his fourth post!

    Code:
        MessageBox(NULL, lpszType, "", MB_OK);
    The GetLastError function returns 998, "Invalid access to memory location"
    1. You call MessageBox() with an invalid 'string' pointer.
    2. EnumResourceTypes() is kind enough to catch the resulting exception.
    3. It returns failure with the accurate error "Invalid access to memory location".

    >> EnumResTypeProc isn't even called. <<

    Yes it is. A correct call to MessageBox() or a debug breakpoint would confirm this.

  11. #11
    Registered User
    Join Date
    May 2011
    Posts
    1
    The problem is in EnumResTypeProc. You cannot assume that lpszType is a string, it might be INT_RESOURCE.
    INT_RESOURCE is an integer disguised inside a string pointer - ugly but there you have it.

    So the proper implementation of EnumResTypeProc would be:

    Code:
    BOOL CALLBACK EnumResTypeProc(HMODULE hModule, LPTSTR lpszType, LONG_PTR lParam)
    {
        if (! IS_INTRESOURCE(lpszType))
        {
            MessageBox(NULL, lpszType, "", MB_OK);
        }
        
        return TRUE;
    }
    Last edited by TrickyDicky; 05-05-2011 at 10:14 AM. Reason: spelling error

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    The thread you replied to is 7 years old... I'm guessing he's solved the problem by now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. An error is driving me nuts!
    By ulillillia in forum C Programming
    Replies: 5
    Last Post: 04-04-2009, 09:15 PM
  3. Making C DLL using MSVC++ 2005
    By chico1st in forum C Programming
    Replies: 26
    Last Post: 05-28-2008, 01:17 PM
  4. Learning OpenGL
    By HQSneaker in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2004, 08:57 AM
  5. Couple C questions :)
    By Divx in forum C Programming
    Replies: 5
    Last Post: 01-28-2003, 01:10 AM