0
votes

I am trying to use the Win32 FindResource() function to load an embedded resource into a buffer. I am adding a resource compile time, in Visual Studio 2015 IDE:

enter image description here

As you can see using a PE editor like CFFexplorer or ResHacker, resource gets added correctly: enter image description here

The problem comes when I try to use the FindResource() function to load it on runtime, at the start of a DLL project:

  INT WINAPI DllMain( HINSTANCE hInstDLL, DWORD dwReason, LPVOID lpReserved )
{
    HRSRC ResLocation = 0;

    switch( dwReason ) 
    { 
        case DLL_PROCESS_ATTACH:

            // Show debug console
            AllocConsole();
            freopen("CONOUT$", "w", stdout);  

            //Locate our resource
            ResLocation = FindResource(hInstDLL, "RESFILE", "RESFILE");

            // FindResource returns NULL with error 1813: ERROR_RESOURCE_TYPE_NOT_FOUND
            printf("TEST RESULT: reslocation: %i error %i\n", ResLocation, GetLastError());

            StartProc();
            break;
        case DLL_PROCESS_DETACH:
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
    }
    return 1;
}

FindResource returns NULL with error 1813: ERROR_RESOURCE_TYPE_NOT_FOUND. Any idea on why it doesn't manage to load the resource? Thank you

3
You should not be doing all of that in DllMain! AllocConsole is an obvious no-no. - Cody Gray
Why not? Could you elaborate a bit more please - Flavio
@FlavioM.Foglia: DLLMain shouldn't do anything that might cause more code to load, synchronization objects to be locked, etc. msdn.microsoft.com/en-us/library/windows/desktop/… - Adrian McCarthy
Adrian covered it. The general rule is to do essentially nothing in DllMain, just to be on the safe side. The documentation contains a list of things that are expressly forbidden, but calling any complex APIs or third-party code is inherently tricky because you have no way of knowing what they do. The goal is to keep DllMain an empty stub, using lazy initialization for everything. If you absolutely need to do more, have your DLL provide and export an Initialize (or similar) function that applications would call. The Windows libraries all do this, like COM, GDI+, etc. - Cody Gray

3 Answers

1
votes

I found what the problem was.

There was another executable which wrote another resource on the same dll at runtime. It did this using BeginUpdateResource().

The problem was BeginUpdateResource() second parameter, which was set to true: when adding new resource, it would delete the old one, which I added at design time. Setting this parameter to false, solved my problem.

0
votes

The FindResource()/LoadResource() is AFAIK not to find/load the entire resource "file" (in the fact there is no such file, the resources are embedded in the dll), but a specific resource (string, bitmap, icon etc. as specified by the resource src file).

"RESFILE" is none of the allowed resource types, for the list see ResourceTypes.

0
votes

It looks like your third parameter is wrong.

From MSDN:

HRSRC WINAPI FindResource(
  _In_opt_ HMODULE hModule,
  _In_     LPCTSTR lpName,
  _In_     LPCTSTR lpType
);

lpType [in]

The resource type. Alternately, rather than a pointer, this parameter can be MAKEINTRESOURCE(ID), where ID is the integer identifier of the given resource type. For standard resource types, see Resource Types. For more information, see the Remarks section below.

Use the link above to find your resource type and use that instead of "RESFILE".

E.g.

ResLocation = FindResource(hInstDLL, "RESFILE", MAKEINTRESOURCE(RT_VERSION));