Is there a benefit to using LoadLibrary instead of linking? - windows

Using dependency walker I noticed some apps that definitely use Direct3D 11, but only link to Direct3D 9's library dll.
Do I gain something by linking? Would there be any benefit in using LoadLibrary?
Why might I choose one method over the other?

As I think, if you link DLL statically to your application you will not be able to even start the application if any DLL is missing. In case of manual LoadLibrary the application can start, check DLL availability and write message to log, show a good error description to user or even use another DLL set, e.g. another version of DLLs with different names instead of newest ones.

Related

workaround bug of LoadLibraryEx(..., LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR) loading wrong dll

The situation is following.
These dlls are loaded in a process:
c:\abc\foo.dll
c:\abc\bar.dll
c:\zxc\foo.dll
And the process is located in c:\abc\.
I'm loading c:\zxc\bar.dll. It implicitly links to foo.dll. And it should link to c:\zxc\foo.dll, which is in same folder.
I load it with
LoadLibraryExA("c:\\zxc\\bar.dll", NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)
If c:\abc\foo.dll is not loaded in process, then c:\zxc\foo.dll gets properly loaded and c:\zxc\bar.dll links to it.
But if c:\abc\foo.dll is loaded, then c:\\zxc\\bar.dll links to c:\abc\foo.dll instead of c:\zxc\foo.dll (even if c:\zxc\foo.dll is already loaded in the process). This was confirmed with help of "Show loader snaps" checkbox of Global Flags.
How do I work around it?
The bar.dll is third party so I cannot implement DELAYLOAD in it.
And I cannot prevent loading c:\abc\foo.dll to the process.
I'm thinking of hooking ntdll!LdrpFindOrMapDll, but it seems unreliable and I will have to test this thoroughly in all supported Windows versions, so I'm first searching for a simpler workaround.
I think you can try to make your foo.dll a side-by-side assembly, and reference it in your dll manifest.
This is how, for instance, Common Controls of 5 and 6 versions and Visual Studio different C runtime versions supposed to coexist in the same process.
If this works, don't necessarily need to install your foo.dll to WinSxS folder, maybe you can do with private assemblies.
If side-by-side assemblies won't work for you, then any hooking solution is complex and risky.
Think of it: number of calls like GetModuleHandleW(L"foo.dll") supposed to return proper one DLL handle in each context!
(and side-by-side assemblies do this trick if bar.dll code is compiled with ISOLATION_AWARE_ENABLED defined)

LoadLibraryExW() fails, last error is ERROR_MOD_NOT_FOUND, but no missing dependencies?

A customer is using our dll which is creating a child process which uses an open source library, which ultimately fails because of a call to LoadLibraryExW(), the last error returned is ERROR_MOD_NOT_FOUND. This occurs on WinXP 32-bit, but not on other machines. But we know the correct set of dependencies is installed and even in the same directory.
So we thought naturally, to use Dependency Walker to look for what dependency is missing on that particular machine. Unfortunately it doesn't show any missing, just some delay-load warnings that aren't direct dependencies of the library. In my experience using depends.exe has always revealed what the missing dependency is.
So at this point I've pulled my hair out trying to understand why I'm getting ERROR_MOD_NOT_FOUND if all of the library's dependencies are there? The only other thing that makes this machine unique is it's very secure because it's used by the government, but if we were having an access/permissions issue I'd expect a different type of error code.
I've built a small Win32 executable that does nothing but call LoadLibraryExW() on the said library, when it's run from the same directory as the library is located, it loads the library without issue, on the customer's problematic machine.
One thing is that our product is an ActiveX plugin which launches a child process, the child process calls into the 3rd party library, the 3rd party library has the problematic LoadLibraryExW() call. So maybe why it's failing is the context it's running (e.g. from the browser)?
Use the Profiling option of the Dependency Walker on your application. Possibly the library is trying to resolve some APIs dynamically (using LoadLibrary/GetProcAddress) and this won't show up in the static dependencies.
The best way is to use loader snaps. Basically you use gflags.exe (which is included with windbg) to enable loader snaps; then, run the process with the debugger attached. Loader snaps will enable the loader to print out dbg messages of the process and it will print the failures.
gflags.exe -i yourcode.exe +sls
windbg yourcode.exe
Your dependencies might be present on the system but they could be in a folder that is not part of the search order during LoadLibraryExW().
A SetDllDirectory() or AddDllDirectory() call would ensure that the folder containing the dependencies is searched during the LoadLibraryExW() call

LIB and DLL difference

What is the difference between a LIB and DLL? I have read plenty of posts on here about it and there are some good, clear answers however I am writing to ask for clarity on one matter.
Is it better to use a LIB (static link library) when there is only one user e.g. for a administration application client installed locally on the PC? and is it better to use a DLL (Dynamic link library) when there are multiple concurrent users accessing a classic asp application that uses vb6 classes?
A LIB file generally corresponds to a static library, which means that all of the library code that your application uses is compiled directly into your application.
A DLL file represents a dynamic library that your application links to, and then when you want to use code from the library, you call into it dynamically while your application is running.
Of course, you'll frequently see a LIB file for a dynamically-linked library as well. That file contains "stubs" that the linker uses to implicitly link to the DLL.
The obvious benefit of a DLL (dynamic linking) is that one DLL with common functionality can be shared with multiple applications that use that same functionality. Bug fixes can be made in a single place, and only one component has to be updated in order for all of the apps to take advantage of those fixes.
If you only have a single application that uses your code, there's little reason to put it into a DLL. Multiple users on multiple computers are going to have to have their own copy of the DLL anyway, so there will be no code sharing going on in that situation.
All of that said, I have no idea what this question has to do with VB 6. To my knowledge, you can only use it to create ActiveX DLLs (which have a different use case) and it can't create static libraries at all.

Implicit vs. Explicit linking to a DLL

When one should implicitly or explicitly link to a DLL and what are common practices or pitfalls?
It is fairly rare to explicitly link a DLL. Mostly because it is painful and error prone. You need to write a function pointer declaration for the exported function and get the LoadLibrary + GetProcAddress + FreeLibrary code right. You'd do so only if you need a runtime dependency on a plug-in style DLL or want to select from a set of DLLs based on configuration. Or to deal with versioning, an API function that's only available on later versions of Windows for example. Explicit linking is the default for COM and .NET DLLs.
More background info in this MSDN Library article.
I'm assuming you refer to linking using a .lib vs loading a DLL dynamically using LoadLibrary().
Loading a DLL statically by linking to its .lib is generally safer. The linking stage checks that all the entry points exist in compile time and there is no chance you'll load a DLL that doesn't have the function you're expecting. It is also easier not to have to use GetProcAddress().
So generally you should use dynamic loading only when it is absolutely required.
I agree with other who answered you already (Hans Passant and shoosh). I want add only two things:
1) One common scenario when you have to use LoadLibrary and GetProcAddress is the following: you want use some new API existing in new versions of Windows only, but the API are not critical in your application. So you test with LoadLibrary and GetProcAddress whether the function which you need exist, and use it in the case. What your program do if the functions not exist depend total from your implementation.
2) There are one important options which you not included in your question: delayed loading of DLLs. In this case the operating system will load the DLL when one of its functions is called and not at the application start. It allows to use import libraries (.lib files) in some scenarios where explicitly linking should be used at the first look. Moreover it improve the startup time of the applications and are wide used by Windows itself. So the way is also recommended.

Which headers should I not use if I don't want my program to be linked with any of msvc*.dll's?

Which headers should I not use if I don't want my program to be linked with any of msvc*.dll ?
At the moment my application uses:
kernel32
user32
shell32
msvcp90
msvcr90
I want to get rid of the bottom two files. I don't mind if I will have to rewrite certain aspects of the program.
Because I know if you code in C and then link it won't link any msvc's
I believe you have to change the way the CRT is linked into your program. I think for that you have to change the C++->Code Generation->Runtime-Library to the static version. This is for Visual Studio 2005, don't know about newer versions.
Those libraries contain the C++ runtime - heap management and other stuff hard to get rid from.
You could link the C++ statically instead - use "C++ -> Code Generation -> Runtime Library" setting. Then you will not need those .dll files. However this is not the recommended way - if a vulnerability is found in the C++ runtime you'll have to recompile and reship your program.
Static link is the right answer. A related bit of advice is to use depends.exe to see what functions your exe is actually hitting in the dependent dlls. Those dependencies might be due to explicit use on your part or due to CRT implementation that you don't explicitly invoke.

Resources