<commit_before>/*
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 * This file is part of SIGAR.
 * 
 * SIGAR is free software; you can redistribute it and/or modify
 * it under the terms version 2 of the GNU General Public License as
 * published by the Free Software Foundation. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

#ifdef WIN32
#include "javasigar.h"
#include "win32bindings.h"

#define MAX_MSG_LENGTH   8192
#define MAX_ERROR_LENGTH 1024

#define REG_MSGFILE_ROOT "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"

static void win32_set_pointer(JNIEnv *env, jobject obj, const void *ptr)
{
    jfieldID pointer_field;
    int pointer_int;
    jclass cls;

    cls = JENV->GetObjectClass(env, obj);
    
    pointer_field = JENV->GetFieldID(env, cls, "eventLogHandle", "I");
    pointer_int = (int)ptr;

    JENV->SetIntField(env, obj, pointer_field, pointer_int);
}

static HANDLE win32_get_pointer(JNIEnv *env, jobject obj)
{
    jfieldID pointer_field;
    HANDLE h;
    jclass cls;

    cls = JENV->GetObjectClass(env, obj);

    pointer_field = JENV->GetFieldID(env, cls, "eventLogHandle", "I");
    h = (HANDLE)JENV->GetIntField(env, obj, pointer_field);

    if (!h) {
        win32_throw_exception(env, "Event log not opened");
    }

    return h;
}

static int get_messagefile_dll(const char *app, char *source, char *dllfile)
{
    HKEY hk;
    char buf[MAX_MSG_LENGTH];
    DWORD type, data = sizeof(buf);
    LONG rc;

    sprintf(buf, "%s%s\\%s", REG_MSGFILE_ROOT, app, source);
    rc = RegOpenKey(HKEY_LOCAL_MACHINE, buf, &hk); 
    if (rc) {
        return rc;
    }

    rc = RegQueryValueEx(hk, "EventMessageFile", NULL, &type,
                         (UCHAR *)buf, &data);
    if (rc) {
        RegCloseKey(hk);
        return rc;
    }

    strncpy(dllfile, buf, MAX_MSG_LENGTH);
    dllfile[MAX_MSG_LENGTH-1] = '\0';

    RegCloseKey(hk);

    return ERROR_SUCCESS;
}

static int get_formatted_message(EVENTLOGRECORD *pevlr, char *dllfile,
                                 char *msg)
{
    HINSTANCE hlib;
    LPVOID msgbuf;
    char msgdll[MAX_MSG_LENGTH];
    char *insert_strs[56], *ch;
    int i, max = sizeof(insert_strs) / sizeof(char *);
    DWORD result;

    if (!ExpandEnvironmentStrings(dllfile, msgdll, MAX_PATH))
        return GetLastError();

    if (!(hlib = LoadLibraryEx(msgdll, NULL,
                               LOAD_LIBRARY_AS_DATAFILE)))
        return GetLastError();

    memset(insert_strs, '\0', sizeof(insert_strs));
    ch = (char *)((LPBYTE)pevlr + pevlr->StringOffset);
    for (i = 0; i < pevlr->NumStrings && i < max; i++) {
        insert_strs[i] = ch;
        if (ch == NULL) {
            break;
        }
        ch += strlen(ch) + 1;
    }

    result =
        FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
                      FORMAT_MESSAGE_FROM_SYSTEM |
                      FORMAT_MESSAGE_ALLOCATE_BUFFER |
                      FORMAT_MESSAGE_ARGUMENT_ARRAY,
                      hlib,
                      pevlr->EventID,
                      MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US),
                      (LPTSTR) &msgbuf,
                      MAX_MSG_LENGTH,
                      insert_strs);

    if (result) {
        strncpy(msg, msgbuf, MAX_MSG_LENGTH);
        msg[MAX_MSG_LENGTH-1] = '\0';
        result = ERROR_SUCCESS;
        LocalFree(msgbuf);
    }
    else {
        result = GetLastError();
    }

    FreeLibrary(hlib);

    return result;
}

JNIEXPORT void SIGAR_JNI(win32_EventLog_openlog)
(JNIEnv *env, jobject obj, jstring lpSourceName)
{<commit_msg>[SIGAR-80] Fix EventLog.message to handle multiple EventMessageFiles<commit_after>/*
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 * This file is part of SIGAR.
 * 
 * SIGAR is free software; you can redistribute it and/or modify
 * it under the terms version 2 of the GNU General Public License as
 * published by the Free Software Foundation. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

#ifdef WIN32
#include "javasigar.h"
#include "win32bindings.h"

#define MAX_MSG_LENGTH   8192
#define MAX_ERROR_LENGTH 1024

#define REG_MSGFILE_ROOT "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"

static void win32_set_pointer(JNIEnv *env, jobject obj, const void *ptr)
{
    jfieldID pointer_field;
    int pointer_int;
    jclass cls;

    cls = JENV->GetObjectClass(env, obj);
    
    pointer_field = JENV->GetFieldID(env, cls, "eventLogHandle", "I");
    pointer_int = (int)ptr;

    JENV->SetIntField(env, obj, pointer_field, pointer_int);
}

static HANDLE win32_get_pointer(JNIEnv *env, jobject obj)
{
    jfieldID pointer_field;
    HANDLE h;
    jclass cls;

    cls = JENV->GetObjectClass(env, obj);

    pointer_field = JENV->GetFieldID(env, cls, "eventLogHandle", "I");
    h = (HANDLE)JENV->GetIntField(env, obj, pointer_field);

    if (!h) {
        win32_throw_exception(env, "Event log not opened");
    }

    return h;
}

static int get_messagefile_dll(const char *app, char *source, char *dllfile)
{
    HKEY hk;
    char buf[MAX_MSG_LENGTH];
    DWORD type, data = sizeof(buf);
    LONG rc;

    sprintf(buf, "%s%s\\%s", REG_MSGFILE_ROOT, app, source);
    rc = RegOpenKey(HKEY_LOCAL_MACHINE, buf, &hk); 
    if (rc) {
        return rc;
    }

    rc = RegQueryValueEx(hk, "EventMessageFile", NULL, &type,
                         (UCHAR *)buf, &data);
    if (rc) {
        RegCloseKey(hk);
        return rc;
    }

    strncpy(dllfile, buf, MAX_MSG_LENGTH);
    dllfile[MAX_MSG_LENGTH-1] = '\0';

    RegCloseKey(hk);

    return ERROR_SUCCESS;
}

static int get_formatted_message(EVENTLOGRECORD *pevlr, char *dllfile,
                                 char *msg)
{
    LPVOID msgbuf = NULL;
    char msgdll[MAX_MSG_LENGTH];
    char *insert_strs[56], *ptr;
    int i, max = sizeof(insert_strs) / sizeof(char *);
    const DWORD flags =
        FORMAT_MESSAGE_FROM_HMODULE |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_ARGUMENT_ARRAY |
        FORMAT_MESSAGE_MAX_WIDTH_MASK;

    if (!ExpandEnvironmentStrings(dllfile, msgdll, sizeof(msgdll))) {
        return GetLastError();
    }

    memset(insert_strs, '\0', sizeof(insert_strs));
    ptr = (char *)((LPBYTE)pevlr + pevlr->StringOffset);
    for (i = 0; i < pevlr->NumStrings && i < max; i++) {
        insert_strs[i] = ptr;
        ptr += strlen(ptr) + 1;
    }

    ptr = msgdll;
    while (ptr) {
        HINSTANCE hlib;
        char *delim = strchr(ptr, ';');

        if (delim) {
            *delim++ = '\0';
        }

        hlib = LoadLibraryEx(ptr, NULL,
                             LOAD_LIBRARY_AS_DATAFILE);
        if (hlib) {
            FormatMessage(flags,
                          hlib,
                          pevlr->EventID,
                          MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US),
                          (LPTSTR) &msgbuf,
                          sizeof(msgbuf),
                          insert_strs);
            FreeLibrary(hlib);

            if (msgbuf) {
                break;
            }
        }
        ptr = delim;
    }

    if (msgbuf) {
        strncpy(msg, msgbuf, MAX_MSG_LENGTH);
        msg[MAX_MSG_LENGTH-1] = '\0';
        LocalFree(msgbuf);
        return ERROR_SUCCESS;
    }
    else {
        return !ERROR_SUCCESS;
    }
}

JNIEXPORT void SIGAR_JNI(win32_EventLog_openlog)
(JNIEnv *env, jobject obj, jstring lpSourceName)
{
{'fraction_non_alphanumeric': 0.1056338028169014, 'fraction_numerical': 0.013963088878096164, 'mean_word_length': 2.4580184718723763, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '234821', 'n_tokens_mistral': 2819, 'n_tokens_neox': 2644, 'n_words': 706}