You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ca...@apache.org on 2008/09/06 01:35:09 UTC

svn commit: r692580 - in /logging/log4j/trunk/src: assembly/bin.xml main/java/org/apache/log4j/nt/NTEventLogAppender.java ntdll/nteventlog.cpp ntdll/resources/ ntdll/resources/NTEventLogAppender.amd64.dll

Author: carnold
Date: Fri Sep  5 16:35:09 2008
New Revision: 692580

URL: http://svn.apache.org/viewvc?rev=692580&view=rev
Log:
Bug 44386: Handle mapping approach for Win64, prebuilt amd64 dll

Added:
    logging/log4j/trunk/src/ntdll/resources/
    logging/log4j/trunk/src/ntdll/resources/NTEventLogAppender.amd64.dll   (with props)
Modified:
    logging/log4j/trunk/src/assembly/bin.xml
    logging/log4j/trunk/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java
    logging/log4j/trunk/src/ntdll/nteventlog.cpp

Modified: logging/log4j/trunk/src/assembly/bin.xml
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/assembly/bin.xml?rev=692580&r1=692579&r2=692580&view=diff
==============================================================================
--- logging/log4j/trunk/src/assembly/bin.xml (original)
+++ logging/log4j/trunk/src/assembly/bin.xml Fri Sep  5 16:35:09 2008
@@ -33,18 +33,18 @@
 				<include>KEYS</include>
 				<include>LICENSE</include>
 				<include>NOTICE</include>
-				<include>contribs/**</include>
+				<include>contribs/**</include>
 				<include>examples/**</include>
 				<include>src/assembly/**</include>
 				<include>src/changes/**</include>
 				<include>src/main/**</include>
-				<include>src/ntdll/**</include>
+				<include>src/ntdll/*</include>
 				<include>src/performance/**</include>
 				<include>src/site/**</include>
-				<include>tests/README</include>
-				<include>tests/*.xml</include>
-				<include>tests/*.sample</include>
-				<include>tests/*.bat</include>
+				<include>tests/README</include>
+				<include>tests/*.xml</include>
+				<include>tests/*.sample</include>
+				<include>tests/*.bat</include>
 				<include>tests/input/**</include>
 				<include>tests/resources/**</include>
 				<include>tests/src/**</include>
@@ -60,5 +60,9 @@
                    <source>target/NTEventLogAppender.dll</source>
                    <fileMode>0755</fileMode>
                 </file>
+                <file>
+                   <source>src/ntdll/resources/NTEventLogAppender.amd64.dll</source>
+                   <fileMode>0755</fileMode>
+                </file>
         </files>
 </assembly>

Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java?rev=692580&r1=692579&r2=692580&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java (original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/nt/NTEventLogAppender.java Fri Sep  5 16:35:09 2008
@@ -30,7 +30,9 @@
    <p><b>WARNING</b> This appender can only be installed and used on a
    Windows system.
 
-   <p>Do not forget to place the file NTEventLogAppender.dll in a
+   <p>Do not forget to place NTEventLogAppender.dll,
+   NTEventLogAppender.amd64.dll, NTEventLogAppender.ia64.dll
+   or NTEventLogAppender.x86.dll as appropriate in a
    directory that is on the PATH of the Windows system. Otherwise, you
    will get a java.lang.UnsatisfiedLinkError.
 
@@ -157,6 +159,31 @@
   native private void deregisterEventSource(int handle);
 
   static {
-    System.loadLibrary("NTEventLogAppender");
-  }
+    String[] archs;
+    try {
+        archs = new String[] { "." + System.getProperty("os.arch"), ""};
+    } catch(SecurityException e) {
+        archs = new String[] { ".amd64", ".ia64", ".x86", ""};
+    }
+    Throwable t = null;
+    for(int i = 0; i < archs.length; i++) {
+        try {
+            System.loadLibrary("NTEventLogAppender" + archs[i]);
+            t = null;
+            break;
+        } catch(java.lang.UnsatisfiedLinkError e) {
+            t = e;
+        }
+    }
+    if (t != null) {
+        StringBuffer buf = new StringBuffer("Unable to load");
+        for (int i = 0; i < archs.length - 1; i++) {
+            buf.append(" NTEventLogAppender");
+            buf.append(archs[i]);
+            buf.append(".dll");
+        }
+        buf.append(" or NTEventLogAppender.dll.");
+        LogLog.error(buf.toString(), t);
+    }
+}
 }

Modified: logging/log4j/trunk/src/ntdll/nteventlog.cpp
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/ntdll/nteventlog.cpp?rev=692580&r1=692579&r2=692580&view=diff
==============================================================================
--- logging/log4j/trunk/src/ntdll/nteventlog.cpp (original)
+++ logging/log4j/trunk/src/ntdll/nteventlog.cpp Fri Sep  5 16:35:09 2008
@@ -28,6 +28,67 @@
 #include <jni.h>
 
 
+HINSTANCE gModule = 0;
+
+class EventSourceMap {
+#if _WIN64
+    enum { MAX_SOURCES = 256 };
+    HANDLE* sources;
+public:
+    EventSourceMap() {
+        sources = (HANDLE*) calloc(MAX_SOURCES, sizeof(*sources));
+    }
+
+    ~EventSourceMap() {
+        free(sources);
+    }
+
+    jint createKey(HANDLE handle) {
+        if (handle != 0) {
+            //
+            //   find first available null entry (excluding sources[0])
+            //
+            for(int i = 1; i < MAX_SOURCES; i++) {
+                if (InterlockedCompareExchangePointer(sources + i, handle, 0) == 0) {
+                    return i;
+                }
+            }
+        }
+        return 0;
+    }
+
+    HANDLE getHandle(jint key) {
+        if (key >= 1 && key < MAX_SOURCES) {
+            return sources[key];
+        }
+        return 0;
+    }
+
+    HANDLE releaseHandle(jint key) {
+        if (key >= 1 && key < MAX_SOURCES) {
+            return InterlockedExchangePointer(sources + key, 0);
+        }
+        return 0;
+    }
+#else
+public:
+    EventSourceMap() {
+    }
+
+    jint createKey(HANDLE handle) {
+        return (jint) handle;
+    }
+
+    HANDLE getHandle(jint key) {
+        return (HANDLE) key;
+    }
+
+    HANDLE releaseHandle(jint key) {
+        return (HANDLE) key;
+    }
+#endif
+} gEventSources;
+
 /*
  * Convert log4j Priority to an EventLog category. Each category is
  * backed by a message resource so that proper category names will
@@ -102,7 +163,10 @@
   wcscat(subkey, source);
   hkey = regGetKey(subkey, &disposition);
   if (disposition == REG_CREATED_NEW_KEY) {
-    HMODULE hmodule = GetModuleHandleW(L"NTEventLogAppender.dll");
+    HMODULE hmodule = gModule;
+    if (hmodule == NULL) {
+        hmodule = GetModuleHandleW(L"NTEventLogAppender.dll");
+    }
     if (hmodule != NULL) {
         wchar_t modpath[_MAX_PATH];
         DWORD modlen = GetModuleFileNameW(hmodule, modpath, _MAX_PATH - 1);
@@ -126,7 +190,7 @@
  */
 JNIEXPORT jint JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_registerEventSource(
    JNIEnv *env, jobject java_this, jstring server, jstring source) {
-  
+
   jchar *nserver = 0;
   jchar *nsource = 0;
 
@@ -143,7 +207,8 @@
     nsource[sourceLen] = 0;
   }
   addRegistryInfo((wchar_t*) nsource);
-  jint handle = (jint)RegisterEventSourceW((const wchar_t*) nserver, (const wchar_t*) nsource);
+  jint handle = gEventSources.createKey(RegisterEventSourceW(
+         (const wchar_t*) nserver, (const wchar_t*) nsource));
   free(nserver);
   free(nsource);
   return handle;
@@ -155,12 +220,12 @@
  * Signature: (ILjava/lang/String;I)V
  */
 JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_reportEvent(
-   JNIEnv *env, jobject java_this, jint handle, jstring jstr, jint priority) {
-  
+   JNIEnv *env, jobject java_this, jint jhandle, jstring jstr, jint priority) {
   jboolean localHandle = JNI_FALSE;
+  HANDLE handle = gEventSources.getHandle(jhandle);
   if (handle == 0) {
     // Client didn't give us a handle so make a local one.
-    handle = (jint)RegisterEventSourceW(NULL, L"Log4j");
+    handle = RegisterEventSourceW(NULL, L"Log4j");
     localHandle = JNI_TRUE;
   }
   
@@ -174,14 +239,14 @@
   // a message resource which consists of just '%1' which is replaced
   // by the string we just created.
   const DWORD messageID = 0x1000;
-  ReportEventW((HANDLE)handle, getType(priority), 
+  ReportEventW(handle, getType(priority), 
 	      getCategory(priority), 
 	      messageID, NULL, 1, 0, (const wchar_t**) &msg, NULL);
   
   free((void *)msg);
   if (localHandle == JNI_TRUE) {
     // Created the handle here so free it here too.
-    DeregisterEventSource((HANDLE)handle);
+    DeregisterEventSource(handle);
   }
   return;
 }
@@ -196,7 +261,8 @@
 jobject java_this, 
 jint handle)
 {
-  DeregisterEventSource((HANDLE)handle);
+
+  DeregisterEventSource(gEventSources.releaseHandle(handle));
 }
 
 
@@ -205,9 +271,13 @@
 //     when invoked using regsvr32 tool.
 //
 //
-STDAPI __declspec(dllexport) DllRegisterServer(void) {
+extern "C" {
+__declspec(dllexport) HRESULT __stdcall DllRegisterServer(void) {
 	HRESULT hr = E_FAIL;
-    HMODULE hmodule = GetModuleHandleW(L"NTEventLogAppender.dll");
+    HMODULE hmodule = gModule;
+    if (hmodule == NULL) {
+        hmodule = GetModuleHandleW(L"NTEventLogAppender.dll");
+    }
     if (hmodule != NULL) {
         wchar_t modpath[_MAX_PATH];
         DWORD modlen = GetModuleFileNameW(hmodule, modpath, _MAX_PATH - 1);
@@ -229,11 +299,11 @@
 				}
 				if(stat == ERROR_SUCCESS) {
 					DWORD value = 7;
-					stat == RegSetValueExW(hkey, L"TypesSupported", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
+					stat = RegSetValueExW(hkey, L"TypesSupported", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
 				}
 				if(stat == ERROR_SUCCESS) {
 					DWORD value = 6;
-					stat == RegSetValueExW(hkey, L"CategoryCount", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
+					stat = RegSetValueExW(hkey, L"CategoryCount", 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
 				}
 				LONG closeStat = RegCloseKey(hkey);
 				if (stat == ERROR_SUCCESS && closeStat == ERROR_SUCCESS) {
@@ -251,9 +321,32 @@
 //     when invoked using regsvr32 tool with /u option.
 //
 //
-STDAPI __declspec(dllexport) DllUnregisterServer(void) {
+__declspec(dllexport) HRESULT __stdcall DllUnregisterServer(void) {
 	LONG stat = RegDeleteKeyW(HKEY_LOCAL_MACHINE, 
 		L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\Log4j");
 	return (stat == ERROR_SUCCESS || stat == ERROR_FILE_NOT_FOUND) ? S_OK : E_FAIL;
 }
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+					 )
+{
+	switch (ul_reason_for_call)
+	{
+	case DLL_PROCESS_ATTACH:
+	    gModule = hModule;
+	    break;
+	case DLL_PROCESS_DETACH:
+	    gModule = 0;
+	    break;
+	    
+	case DLL_THREAD_ATTACH:
+	case DLL_THREAD_DETACH:
+		break;
+	}
+	return TRUE;
+}
+
+}
 #endif

Added: logging/log4j/trunk/src/ntdll/resources/NTEventLogAppender.amd64.dll
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/ntdll/resources/NTEventLogAppender.amd64.dll?rev=692580&view=auto
==============================================================================
Binary file - no diff available.

Propchange: logging/log4j/trunk/src/ntdll/resources/NTEventLogAppender.amd64.dll
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org