The version of Apache log4j used by SoundHelix.

[[ 🗃 ^aEp6o apache-log4j ]] :: [📥 Inbox] [📤 Outbox] [🐤 Followers] [🤝 Collaborators] [🛠 Commits]

Clone

HTTPS: git clone https://vervis.peers.community/repos/aEp6o

SSH: git clone USERNAME@vervis.peers.community:aEp6o

Branches

Tags

v_1_1b2 :: src / java / org / apache / log4j / nt /

nteventlog.cpp

#ifndef NtEventLogAppender_h
#define NtEventLogAppender_h
#include "org_apache_log4j_Priority.h"
#include "org_apache_log4j_nt_NTEventLogAppender.h"
#include <windows.h>

// Borrowed unabashedly from the JNI Programmer's Guide
void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg) {

  jclass classForName = env->FindClass(name);
  // If cls is null, an exception has already been thrown.
  if (classForName != (jclass)0) {
    env->ThrowNew(classForName, msg);
  }
  // cleanup
  env->DeleteLocalRef(classForName);
  return;
}

// Borrowed unabashedly from the JNI Programmer's Guide
char *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr) {
  static jmethodID midStringGetBytes = 0;
  jbyteArray bytes = 0;
  jthrowable exc;
  char *nstr = 0;
  
  //if (env->EnsureLocalCapacity(2) < 0) {
  // out of memory
  //return 0;
  //}

  if (midStringGetBytes == 0) {
    // Lookup and cache the String.getBytes() method id.
    jclass stringClass = env->FindClass("java/lang/String");
    if (stringClass == 0) {
      // An exception will have been thrown.
      return 0;
    }
    midStringGetBytes = env->GetMethodID(stringClass, "getBytes", "()[B");
    env->DeleteLocalRef(stringClass);
    if (midStringGetBytes == 0) {
      // An exception will have been thrown.
      return 0;
    }
  }

  bytes = (jbyteArray)env->CallObjectMethod(jstr, midStringGetBytes);
  exc = env->ExceptionOccurred();
  if (exc == 0) {
    // Attempt to malloc enough room for the length of the Java
    // string plus one byte for the 0-terminator.
    jint len = env->GetArrayLength(bytes);
    nstr = (char *)malloc(len + 1);
    if (nstr == 0) {
      // malloc failed -- throw an OutOfMemoryError
      JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);
      env->DeleteLocalRef(bytes);
      return 0;
    }
    // copy to the malloc'd array and 0-terminate
    env->GetByteArrayRegion(bytes, 0, len, (jbyte *)nstr);
    nstr[len] = 0;
  } else {
    // cleanup
    env->DeleteLocalRef(exc);
  }
  // cleanup
  env->DeleteLocalRef(bytes);
  return nstr;
}

/*
 * Convert log4j Priority to an EventLog category. Each category is
 * backed by a message resource so that proper category names will
 * be displayed in the NT Event Viewer.
 */
WORD getCategory(jint priority) {
  // Priority values map directly to EventLog category values
  return (WORD)(priority + 1);
}

/*
 * Convert log4j Priority to an EventLog type. The log4j package
 * supports 8 defined priorites, but the NT EventLog only knows
 * 3 event types of interest to us: ERROR, WARNING, and INFO.
 */
WORD getType(jint priority) {
  WORD ret_val;
  
  switch (priority) {
  case org_apache_log4j_Priority_FATAL_INT:
  case org_apache_log4j_Priority_ERROR_INT:
    ret_val = EVENTLOG_ERROR_TYPE;
    break;
  case org_apache_log4j_Priority_WARN_INT:
    ret_val = EVENTLOG_WARNING_TYPE;
    break;
  case org_apache_log4j_Priority_INFO_INT:
  case org_apache_log4j_Priority_DEBUG_INT:
  default:
    ret_val = EVENTLOG_INFORMATION_TYPE;
    break;
  }
  return ret_val;
}

HKEY regGetKey(TCHAR *subkey, DWORD *disposition) {
  HKEY hkey = 0;
  RegCreateKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, NULL, 
		 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, 
		 &hkey, disposition);
  return hkey;
}

void regSetString(HKEY hkey, TCHAR *name, TCHAR *value) {
  RegSetValueEx(hkey, name, 0, REG_SZ, (LPBYTE)value, lstrlen(value));
}

void regSetDword(HKEY hkey, TCHAR *name, DWORD value) {
  RegSetValueEx(hkey, name, 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
}

/*
 * Add this source with appropriate configuration keys to the registry.
 */
void addRegistryInfo(char *source) {
  const TCHAR *prefix = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
  DWORD disposition;
  HKEY hkey = 0;
  TCHAR subkey[256];
  
  lstrcpy(subkey, prefix);
  lstrcat(subkey, source);
  hkey = regGetKey(subkey, &disposition);
  if (disposition == REG_CREATED_NEW_KEY) {
    regSetString(hkey, "EventMessageFile", "NTEventLogAppender.dll");
    regSetString(hkey, "CategoryMessageFile", "NTEventLogAppender.dll");
    regSetDword(hkey, "TypesSupported", (DWORD)7);
    regSetDword(hkey, "CategoryCount", (DWORD)8);
  }
	//RegSetValueEx(hkey, "EventMessageFile", 0, REG_SZ, (LPBYTE)dllname, lstrlen(dllname));
	//RegSetValueEx(hkey, "CategoryMessageFile", 0, REG_SZ, (LPBYTE)dllname, lstrlen(dllname));
	//RegSetValueEx(hkey, "TypesSupported", 0, REG_DWORD, (LPBYTE)&whichTypes, sizeof(DWORD));
	//RegSetValueEx(hkey, "CategoryCount", 0, REG_DWORD, (LPBYTE)&numCategories, sizeof(DWORD));
  RegCloseKey(hkey);
  return;
}

/*
 * Class:     org.apache.log4j.nt.NTEventLogAppender
 * Method:    registerEventSource
 * Signature: (Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_registerEventSource(
   JNIEnv *env, jobject java_this, jstring server, jstring source) {
  
  char *nserver = 0;
  char *nsource = 0;

  if (server != 0) {
    nserver = JNU_GetStringNativeChars(env, server);
  }
  if (source != 0) {
    nsource = JNU_GetStringNativeChars(env, source);
  }
  addRegistryInfo(nsource);
  jint handle = (jint)RegisterEventSource(nserver, nsource);
  free((void *)nserver);
  free((void *)nsource);
  return handle;
}

/*
 * Class:     org_apache_log4j_nt_NTEventLogAppender
 * Method:    reportEvent
 * 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) {
  
  jboolean localHandle = JNI_FALSE;
  if (handle == 0) {
    // Client didn't give us a handle so make a local one.
    handle = (jint)RegisterEventSource(NULL, "Log4j");
    localHandle = JNI_TRUE;
  }
  
  // convert Java String to character array
  const int numStrings = 1;
  LPCTSTR array[numStrings];
  char *nstr = JNU_GetStringNativeChars(env, jstr);
  array[0] = nstr;
  
  // This is the only message supported by the package. It is backed by
  // a message resource which consists of just '%1' which is replaced
  // by the string we just created.
  const DWORD messageID = 0x1000;
  ReportEvent((HANDLE)handle, getType(priority), 
	      getCategory(priority), 
	      messageID, NULL, 1, 0, array, NULL);
  
  free((void *)nstr);
  if (localHandle == JNI_TRUE) {
    // Created the handle here so free it here too.
    DeregisterEventSource((HANDLE)handle);
  }
  return;
}

/*
 * Class:     org_apache_log4j_nt_NTEventLogAppender
 * Method:    deregisterEventSource
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_org_apache_log4j_nt_NTEventLogAppender_deregisterEventSource(
JNIEnv *env, 
jobject java_this, 
jint handle)
{
  DeregisterEventSource((HANDLE)handle);
}


#endif

[See repo JSON]