Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make LoadLibrary to show error dialog when there are missing dependencies

Suppose we have two dynamic libraries libfoo.dll and libbar.dll, given that libbar.dll depends on libfoo.dll. Further we compile an executable test.exe that loads our libbar.dll using WinAPI function LoadLibrary().

If we run text.exe on Windows XP with missing libfoo.dll, LoadLibrary() shows dialog box alerting than libfoo.dll is actually missing and sets LastError to ERROR_MOD_NOT_FOUND (126).

If we run same text.exe in same conditions on Windows 10, LoadLibrary() sets LastError to ERROR_MOD_NOT_FOUND only, no dialog box appears.

In both cases ErrorMode is 0. So is there any possibility to catch a name of missing dependency in LoadLibrary() calling process, or, at least, how to make LoadLibrary() show error dialog on Windows 10?

Here is a sample code (using MinGW):

foo.c

int foo(int a, int b)
{
    return a + b;
}

Compile with: gcc foo.c -o libfoo.dll -fPIC -shared

bar.c

int foo(int a, int b);

int bar(int a, int b)
{
    return foo(a, b);
}

Compile with: gcc bar.c -o libbar.dll -fPIC -shared -L. -lfoo

test.c

#include <windows.h>
#include <stdio.h>

typedef int (*pfn)(int a, int b);

int main()
{
    SetErrorMode(0);

    HMODULE hmod = LoadLibrary("libbar.dll");

    if(!hmod)
    {
        fprintf(stderr, "error loading library %d\n", GetLastError());
        return 1;
    }

    pfn bar = (pfn)GetProcAddress(hmod, "bar");
    if(bar)
    {
        fprintf(stdout, "bar(3, 1) = %d\n", bar(3, 1));
    }
    else
    {
        fprintf(stderr, "can't load bar foonction\n");
    }

    FreeLibrary(hmod);
    return 0;
}

Compile with: gcc test.c -o test

like image 355
Henadzi Matuts Avatar asked Nov 08 '22 14:11

Henadzi Matuts


1 Answers

At the moment it seems like there is no elegant solution to the question posed.

As @DavidHeffernan noted in the comments to the original post, the problem should be solved on a fundamentally different level. As LoadLibrary() behaves just like it should behave, the key is the proper installation and error handling.

However, if the one needs to explicitly catch missing dependencies of the dynamically loaded libraries, the techniques provided by @IInspectable and @eryksun could be applied:

  • enabling Delay-Loded DLLs for the libraries that are going to be dynamically loaded. Such an approach provides helper callbacks for each dependent module, so missing dependencies could be handled in place. The main disadvantage of this approach is that the target library should be recompiled with proper linker flags;
  • the helper utility that dumps debug strings from the application could be written (see @eryksun comment to the original post for details). Disadvantages: besides the need of writing an additional module it also includes some registry manipulations.
like image 71
Henadzi Matuts Avatar answered Nov 15 '22 07:11

Henadzi Matuts