Add tentative support for DllMain of high loaded DLLs.
authorMarcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
Tue, 5 Oct 2010 19:51:14 +0000 (21:51 +0200)
committerMarcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
Tue, 5 Oct 2010 19:51:14 +0000 (21:51 +0200)
loader/CMakeLists.txt
loader/himemce.h
loader/libhimemce.c [new file with mode: 0644]
loader/libhimemce.def [new file with mode: 0644]
loader/ntdll_loader.c

index b76fdf1..8c634d5 100644 (file)
@@ -6,14 +6,19 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 # For dlmalloc.h
 add_definitions(-DUSE_DL_PREFIX=1)
 
 # For dlmalloc.h
 add_definitions(-DUSE_DL_PREFIX=1)
 
+add_library(libhimemce SHARED libhimemce.c libhimemce.def)
+install(TARGETS libhimemce DESTINATION bin)
+
 add_executable(himemce himemce.c
   wine.h my_winternl.h compat.c
 #  dlmalloc.h dlmalloc.c
   kernel32_kernel_private.h kernel32_process.c kernel32_module.c
   ntdll_error.c ntdll_loader.c ntdll_virtual.c
   server_protocol.h server_mapping.c)
 add_executable(himemce himemce.c
   wine.h my_winternl.h compat.c
 #  dlmalloc.h dlmalloc.c
   kernel32_kernel_private.h kernel32_process.c kernel32_module.c
   ntdll_error.c ntdll_loader.c ntdll_virtual.c
   server_protocol.h server_mapping.c)
+target_link_libraries(himemce libhimemce)
 install(TARGETS himemce DESTINATION bin)
 
 install(TARGETS himemce DESTINATION bin)
 
+
 #Example rules how to build a library.
 #add_library(newtest SHARED newtest.cpp newtest.def)
 #add_executable(newtestex newtestex.cpp)
 #Example rules how to build a library.
 #add_library(newtest SHARED newtest.cpp newtest.def)
 #add_executable(newtestex newtestex.cpp)
@@ -38,6 +43,7 @@ add_executable(himemce-pre himemce-pre.c
   kernel32_kernel_private.h kernel32_process.c kernel32_module.c
   ntdll_error.c ntdll_loader.c ntdll_virtual.c
   server_protocol.h server_mapping.c)
   kernel32_kernel_private.h kernel32_process.c kernel32_module.c
   ntdll_error.c ntdll_loader.c ntdll_virtual.c
   server_protocol.h server_mapping.c)
+target_link_libraries(himemce-pre libhimemce)
 install(TARGETS himemce-pre DESTINATION bin)
 
 
 install(TARGETS himemce-pre DESTINATION bin)
 
 
index 6d8335a..12419d7 100644 (file)
@@ -37,4 +37,8 @@ extern int verbose;
 #include "wine.h"
 
 
 #include "wine.h"
 
 
+/* libhimemce.c */
+void himemce_set_dllmain_cb (void (*cb) (DWORD, LPVOID));
+
+
 #endif /* HIMEMCE_H */
 #endif /* HIMEMCE_H */
diff --git a/loader/libhimemce.c b/loader/libhimemce.c
new file mode 100644 (file)
index 0000000..27c11cd
--- /dev/null
@@ -0,0 +1,25 @@
+#include <windows.h>
+
+static void dllmain_cb (DWORD reason, LPVOID reserved);
+
+
+/* This library is necessary, because if DLLs are loaded high, they
+   need to be notified of new threads, and we can't do that without
+   a DLL that receives these notifications from the system.  */
+
+BOOL
+DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+  if (fdwReason != DLL_THREAD_ATTACH && fdwReason != DLL_THREAD_DETACH)
+    return TRUE;
+
+  if (dllmain_cb)
+    (*dllmain_cb) (fdwReason, lpvReserved);
+}
+
+
+void
+himemce_set_dllmain_cb (void (*cb) (DWORD, LPVOID))
+{
+  dllmain_cb = cb;
+}
diff --git a/loader/libhimemce.def b/loader/libhimemce.def
new file mode 100644 (file)
index 0000000..f674ced
--- /dev/null
@@ -0,0 +1,3 @@
+LIBRARY "libhimemce.dll"
+EXPORTS
+       himemce_set_dllmain_cb
index 8496801..56b9e1f 100644 (file)
@@ -50,6 +50,33 @@ static int himemce_map_initialized;
 static struct himemce_map *himemce_map;
 int himemce_mod_loaded[HIMEMCE_MAP_MAX_MODULES];
 
 static struct himemce_map *himemce_map;
 int himemce_mod_loaded[HIMEMCE_MAP_MAX_MODULES];
 
+void
+himemce_invoke_dll_mains (DWORD reason, LPVOID reserved)
+{
+  int i;
+
+  if (! himemce_map)
+    return NULL;
+
+  for (i = 0; i < himemce_map->nr_modules; i++)
+    if (himemce_mod_loaded[modidx])
+      {
+       char *ptr = himemce_map->module[i].base;
+       IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)ptr;
+       IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew);
+       BOOL WINAPI (*dllmain) (HINSTANCE, DWORD, LPVOID);
+       BOOL res;
+
+       dllmain = nt->OptionalHeader.AddressOfEntryPoint;
+       res = (*dllmain) (ptr, reason, reserved);
+       if (reason == DLL_PROCESS_ATTACH && !res)
+         {
+           ERR ("attaching %s failed (ignored)", himemce_map->module[i].name);
+         }
+      }
+}
+
+
 static void
 himemce_map_init ()
 {
 static void
 himemce_map_init ()
 {
@@ -75,6 +102,8 @@ himemce_map_init ()
       himemce_map = NULL;
       return;
     }
       himemce_map = NULL;
       return;
     }
+
+  himemce_set_dllmain_cb (himemce_invoke_dll_mains);
 }
 
 
 }
 
 
@@ -646,6 +675,11 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
     }
   current_modref = prev;
   //  if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
     }
   current_modref = prev;
   //  if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
+
+#ifdef USE_HIMEMCE_MAP
+  himemce_invoke_dll_mains (DLL_PROCESS_ATTACH, NULL);
+#endif
+
   return status;
 }
 
   return status;
 }