Load DLL at runtime - c++

I'm using the CUDA Driver API in a project. When I execute the project in a PC that doesn't have a NVIDIA GPU, it gives "nvcuda.dll was not found".
The problem is: this DLL is only distributed with the GPU driver, not like in the Runtime API where you can put the DLL needed with your executable. I need to load this DLL in runtime, and if it doesn't exist I will know that CUDA is not available. I'm using Visual Studio 2012 Professional.
Is there a way to do that?

Windows provides an API function (LoadLibrary) to load DLLs into memory at runtime. You provide a LPCTSTR (null terminated pointer to a const TCHAR) containing the name/path of the DLL you want to load. If you provide a relative path, Windows will scan PATH and the executable's current directory for the file. If you provide an absolute path, Windows will use that.
If LoadLibrary returns NULL, Windows couldn't find the file.

Create a small "Launcher" app that will check if system meets your requirements and will launch the main application or display an error depending on the check results.
To check if a DLL is available you can use LoadLibrary() as previously suggested.

Related

Q: Proper way to access data in a data only dll file

My application store some data in data only dll files. Those dll files are loaded with LoadLibrary() when needed at runtime and then discarded with FreeLibrary() after finish using them. The main application access the data stored in the dll files using GetProcAddress(). The program is written in C++ and uses WinAPI calls, no MFC or other libraries. It has two versions x64 and x86. It works fine on most systems. My dll files do not call other libraries or depend on anything else. Each is a stand alone file.
Recently, I discovered the program does not work on one machine. this specific one has Windows 10 x64 installed on it. After investigations I found the following:
LoadLibrary() fails with error message "Could not find module". The dll is in same directory with main program.
I replaced the call to LoadLibrary() with LoadLibraryEx() and tried the following falgs:
LOAD_IGNORE_CODE_AUTHZ_LEVEL did not work. The dll could not be loaded.
DONT_RESOLVE_DLL_REFERENCES ... works?? But, Microsoft strongly recommends not to use it.
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE ... loading the dll succeeds?? But, the call to GetProcessAddress later fails. the program could not access the data in the dll file. So this is not actually working.
I could not find anything wrong with this machine. All other programs are working fine.
I tried the x86 version on this machine and it worked fine using original LoadLibrary().
My installer is dual system and automatically installs x64 version when it finds x64 windows. Normal user can not simply switch to x86 when he gets such error.
My question is how can I eliminate this error and make my program works on any machine:
Should I call LoadLibraryEx() using DONT_RESOLVE_DLL_REFERENCES flag and ignore Microsoft warning?
Is there any way I can get my library loaded with simple call to LoadLibrary()?
If I call LoadLibraryEx() with LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE flag, as recommended by Microsoft, how can I access the data without calling GetProcessAddress()?
Thank you in advance.

How can I control search order for DLLs to avoid hijacking?

As a background: my application requires:
admin privileges
access to WinAPI DLLs
be able to run on all OSs: Win7-Win10
Normally, to use API, I can just link required *.lib files. However it uses default search order, that means (according to https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order) it firstly loads DLLs from "The directory from which the application loaded."
As a result, if the DLL exists in the same directory, running my app by double-click loads also that DLL.
I want to look for DLLs only in system directories (similarly to https://stackoverflow.com/a/46182665/9015013 ).
I know I can try to create some kind of proxy, like
BOOL WinAPIFunction(WinAPIType param) {
return reinterpret_cast<decltype(&WinAPIFunction)>(
reinterpret_cast<void*>(GetProcAddress(manually_loaded_module, "WinAPIFunction")))(param);
}
But it is hard to maintain all these functions. Is there any better method to force windows to look only in system32? I thought about manifest file but it requires version for each DLL that can break "capability" requirement (DLLs have different version for Win7 and Win10)
The solution is posted by #Eryk Sun in comment above.
It is sufficient to add all DLLs not listed in known dlls to delayed loaded libraries and call SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); at the beginning of the WinMain.
Thanks
You can try to use "Known DLLs" feature: If Windows "knows" that DLL, Windows doesn't search dll file. Known feature is described into link, you written in question.

Is it possible to add dll to resources, and load that dll from resources with LoadLibrary? C++

I'm working on a keylogger. Here I found an implementation that loads current keyboard in runtime. The problem is that no keyboard libraries from win8 or win7 are loaded correctly. But I managed to find one US keyboard library that works fine.
So, now, I would like to add that library to resources and to use it when I'm loading keyboard.
My question is, how do I navigate to that resource dll when calling LoadLibrary()?
If you really want an exe instead of installer, you can bundle a dll as resource. ReadResource and write it to file disk(some temp path, such as appdata\local\temp); and then runtime load it, here is the link about runtime load library; Finally you need to delete it.

Selecting a specific opengl32.dll file at load time

Depending on the graphics card in a computer, I want my application to either pick the existing opengl32.dll (located in C:\Windows\System32), or a Mesa\software fallback opengl32.dll. Is it possible to do this at load time, or is this out of my control?
If not, is it possible to execute my own code at all before .dll files are loaded in a windows application (my backup solutions is to simply rename the software .dll file contained in the same dirextory as my executable) ?
Yes. Use delay loading. This is a very simple compiler flag. Behind the scenes, it will generate the LoadLibrary and GetProcAddress calls for you.
Sinde the actual loading of opengl32.dll will now be delayed to the first call of an OpenGL funciton, you have time to call SetDllDirectory.
Check out LoadLibrary(Ex).

Plugin DLLs that depend on other DLLs

I am writing a DLL to plug into another (3rd party) application. The DLL will need to depend on another set of DLLs (for license reasons I cannot link statically).
I would like my DLL to be "xcopy-deployable" to any directory. I would also like not to require adding this directory to the path.
If I just build the DLL the usual way, Windows will refuse to load the DLL, since it cannot find the DLLs next to the current process.
Are there any good options for helping Windows locate the DLL?
To answer some questions:
The DLL is written in C++.
The extra DLLs are QT-dlls.
I would like to place the extra DLLs in the same folder as my plugin DLL. I can get the name of that folder from GetModuleFileName.
The application is Firefox, the DLL is a PKCS#11 security module.
The application loads the DLL using the full path to the DLL (the user supplies it when installing the plugin).
Requiring that the DLLs be placed in System32 or next to the application would work, but it is a bit messy and could cause problems with uninstallers.
LoadLibrary and GetProcAddress would of course work, but is not really feasible in my case. I am using hundreds, if not thousands, of methods in the other DLLs. I really need to use the import-libraries.
I had thought about using delay-loaded dlls combined with SetDllDirectory in DllMain. Have anyone tried anything like this?
I can think of 3 ways.
put the dlls in the same folder as your application (you cannot do this?)
Use runtime linking. LoadLibrary() and GetProcAddress()
Use a manifest http://msdn.microsoft.com/en-us/library/aa374182(VS.85).aspx
But if the dll isn't in the same folder as the .exe, how are you going to know where it is? forget Windows not knowing, how do you know?
you can specify the path of dll as the parameter of LoadLibrary().
Another option is to modify the PATH variable. Have a batch file for launching the main app, and set the PATH=%PATH%;%~dp0. This ensures a minimal footprint, with no additional traces left in the system after running.