|laziness, impatience, and hubris|
a use for Win32::LoadLibrary()by bulk88 (Priest)
|on Oct 10, 2011 at 03:42 UTC||Need Help??|
Ever wondered what on earth can you do with Win32's LoadLibrary on Windows Perl? This isn't C of course.
Reading GetProcAddress's documentation is funnier, and the same applies for LoadLibrary right?
Returns the address of a function inside a loaded library. The information about what you can do with this address has been lost in the mist of time. Use the Win32::API module instead of this deprecated function.
What can you do with LoadLibrary in Perl? DLL redirection and versioning!!
Lets say I have an XS module that has psapi.dll in its PE Import Table, but XS module doesn't have a manifest file. I have a psapi.dll (a fictional example) from Windows 2000 or ReactOS/Wine that I want to test my XS module with, but I run XP. I am not going to replace the psapi.dll in System32. What to do? Let me put the custom psapi.dll in the perl bin dir and make the perl.exe.local file in perl bin dir. Using Dependency Walker or Visual Studio I see it loaded the system32's psapi.dll after Dynaloader's LoadLibrary of the XS DLL (with _boot*). What happened? SxS happened. Any modern Perl VC compiled has a manifest file in perl.exe to turn on XP themed (ver 6) Comctl32.dll, self compiled and ActivePerl. Not sure about Mingw Perls. .local dll redirection is disabled if the exe has a manifest file (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682600%28v=vs.85%29.aspx ). ActivePerl 5.12 has a manifest. ActivePerl 5.10 doesn't. SxS is a nightmare. I gave up trying to use SxS to load my old psapi.dll.
There is a solution.
MyPsapi.dll (XS dll) will now load and use the old psapi.dll even thought .local doesn't work. Since this works, I figured the design of Windows DLL loader is as follows, first check the already loaded DLL list, do name match based on filename minus extension, if matched, increase ref count on the DLL and returns existing HMODULE, else pass to SxS/Path search system. So there you go, a valid use for Win32::LoadLibrary in Perl, in 2011.
This solution worked perfectly for me to load old Microsoft dlls in XP for backwards compatibility test with a manifested perl that disallows .local overriding.