Commit f3da31d7a3e4b300f325624bf4e424c3bbcd521b

Pali Rohár 2019-05-06T21:47:33

Load Psapi.dll at runtime, this avoids linking caveat

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 07addbb..e44343d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,7 +17,6 @@ if (BUILD_SHARED_LIBS)
 endif (BUILD_SHARED_LIBS)
 
 add_library(dl ${sources})
-target_link_libraries(dl psapi)
 
 install (TARGETS dl EXPORT dlfcn-win32-targets
                     RUNTIME DESTINATION bin
diff --git a/Makefile b/Makefile
index efac5af..9f5985e 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,6 @@
 #
 include config.mak
 CFLAGS = -Wall -O3 -fomit-frame-pointer
-LIBS  += -lpsapi
 
 ifeq ($(BUILD_SHARED),yes)
 	TARGETS += libdl.dll
@@ -34,7 +33,7 @@ libdl.a: $(LIB_OBJS)
 	$(RANLIB) libdl.a
 
 libdl.dll: $(LIB_OBJS)
-	$(CC) $(SHFLAGS) -shared -o $@ $^ $(LIBS)
+	$(CC) $(SHFLAGS) -shared -o $@ $^
 
 libdl.lib: libdl.dll
 	$(LIBCMD) /machine:i386 /def:libdl.def
@@ -54,20 +53,20 @@ static-install: include-install
 	mkdir -p $(DESTDIR)$(libdir)
 	cp libdl.a $(DESTDIR)$(libdir)
 
-lib-install: $(LIBS)
+lib-install:
 	mkdir -p $(DESTDIR)$(libdir)
 	cp libdl.lib $(DESTDIR)$(libdir)
 
 install: $(INSTALL)
 
 test.exe: test.o $(TARGETS)
-	$(CC) -o $@ $< -L. -ldl $(LIBS)
+	$(CC) -o $@ $< -L. -ldl
 
 testdll.dll: testdll.c
 	$(CC) -shared -o $@ $^
 
 testdll2.dll: testdll2.c $(TARGETS)
-	$(CC) -shared -o $@ $< -L. -ldl $(LIBS)
+	$(CC) -shared -o $@ $< -L. -ldl
 
 testdll3.dll: testdll3.c
 	$(CC) -shared -o $@ $^
diff --git a/README.md b/README.md
index 6e8ec21..a5fdb02 100644
--- a/README.md
+++ b/README.md
@@ -43,12 +43,6 @@ target_link_libraries(<target> ${CMAKE_DL_LIBS})
 ...
 ~~~
 
-### Linking caveat  
-This library uses the Process Status API in Windows (`psapi.lib`). If you are
-linking to the static `dl.lib` or `libdl.a`, then you would need to explicitly
-add `psapi.lib` or `-lpsapi` to your linking command, depending on if MinGW is
-used.
-
 Author
 ------
 
diff --git a/dlfcn.c b/dlfcn.c
index 8687c51..69670d1 100644
--- a/dlfcn.c
+++ b/dlfcn.c
@@ -24,9 +24,7 @@
 #include <stdlib.h>
 #include <crtdbg.h>
 #endif
-#define PSAPI_VERSION 1
 #include <windows.h>
-#include <psapi.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -192,6 +190,24 @@ static void save_err_ptr_str( const void *ptr )
     save_err_str( ptr_buf );
 }
 
+/* Load Psapi.dll at runtime, this avoids linking caveat */
+static BOOL MyEnumProcessModules( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded )
+{
+    static BOOL (WINAPI *EnumProcessModulesPtr)(HANDLE, HMODULE *, DWORD, LPDWORD);
+    HMODULE psapi;
+
+    if( !EnumProcessModulesPtr )
+    {
+        psapi = LoadLibraryA( "Psapi.dll" );
+        if( psapi )
+            EnumProcessModulesPtr = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( psapi, "EnumProcessModules" );
+        if( !EnumProcessModulesPtr )
+            return 0;
+    }
+
+    return EnumProcessModulesPtr( hProcess, lphModule, cb, lpcbNeeded );
+}
+
 void *dlopen( const char *file, int mode )
 {
     HMODULE hModule;
@@ -240,7 +256,7 @@ void *dlopen( const char *file, int mode )
 
         hCurrentProc = GetCurrentProcess( );
 
-        if( EnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsBefore ) == 0 )
+        if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsBefore ) == 0 )
             dwProcModsBefore = 0;
 
         /* POSIX says the search path is implementation-defined.
@@ -251,7 +267,7 @@ void *dlopen( const char *file, int mode )
         hModule = LoadLibraryExA(lpFileName, NULL, 
                                 LOAD_WITH_ALTERED_SEARCH_PATH );
 
-        if( EnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 )
+        if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 )
             dwProcModsAfter = 0;
 
         /* If the object was loaded with RTLD_LOCAL, add it to list of local
@@ -366,12 +382,12 @@ void *dlsym( void *handle, const char *name )
          * if we want to get ALL loaded module including those in linked DLLs,
          * we have to use EnumProcessModules( ).
          */
-        if( EnumProcessModules( hCurrentProc, NULL, 0, &dwSize ) != 0 )
+        if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwSize ) != 0 )
         {
             modules = malloc( dwSize );
             if( modules )
             {
-                if( EnumProcessModules( hCurrentProc, modules, dwSize, &cbNeeded ) != 0 && dwSize == cbNeeded )
+                if( MyEnumProcessModules( hCurrentProc, modules, dwSize, &cbNeeded ) != 0 && dwSize == cbNeeded )
                 {
                     for( i = 0; i < dwSize / sizeof( HMODULE ); i++ )
                     {
diff --git a/visual-studio/12/dl/dl.vcxproj b/visual-studio/12/dl/dl.vcxproj
index 77c7cdb..baa22d1 100644
--- a/visual-studio/12/dl/dl.vcxproj
+++ b/visual-studio/12/dl/dl.vcxproj
@@ -129,7 +129,6 @@
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugStatic|Win32'">
@@ -151,7 +150,6 @@
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugStatic|x64'">
@@ -177,7 +175,6 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'">
@@ -207,7 +204,6 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'">
diff --git a/visual-studio/12/test/test.vcxproj b/visual-studio/12/test/test.vcxproj
index aabc464..7f5feff 100644
--- a/visual-studio/12/test/test.vcxproj
+++ b/visual-studio/12/test/test.vcxproj
@@ -128,7 +128,6 @@
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugStatic|Win32'">
@@ -139,7 +138,6 @@
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -150,7 +148,6 @@
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugStatic|x64'">
@@ -161,7 +158,6 @@
     </ClCompile>
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -176,7 +172,6 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'">
@@ -191,7 +186,6 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -206,7 +200,6 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'">
@@ -221,7 +214,6 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>