Search code examples
jna

Reading Windows event log using JNA provides me only part of the description available in Event Veiwer


This is my code Provide me details where am going wrong so that am getting only the part of the description available

======================================================================== http://code.dblock.org/jna-reading-windows-event-log-entries-in-java

@SuppressWarnings("unused")
public void testReadEventLogEntries() throws CharacterCodingException {
    final Charset charset = Charset.forName("UTF-8");
    Charset iso88591charset = Charset.forName("ISO-8859-1");
    final CharsetEncoder encoder = charset.newEncoder();
    final CharsetDecoder decoder = charset.newDecoder();
    int i = 0;// loop contro variable
    String type = null; // Type of the event
    String user = null;
    String str[] = { "System", "Application" };
    while (i < 2) {
        System.out.println("\n\n" + str[i]);
        HANDLE h = Advapi32.INSTANCE.OpenEventLog(null, str[i]); 
        IntByReference pnBytesRead = new IntByReference();
        IntByReference pnMinNumberOfBytesNeeded = new IntByReference();
        Memory buffer = new Memory(1024 * 64);
        IntByReference pOldestRecord = new IntByReference();
        int dwRecord = pOldestRecord.getValue();
        int rc = 0;
        while (true) { // Travesing the read log records
            if (!Advapi32.INSTANCE.ReadEventLog(h,
                    WinNT.EVENTLOG_SEQUENTIAL_READ
                            | WinNT.EVENTLOG_FORWARDS_READ, 0, buffer,
                    (int) buffer.size(), pnBytesRead,
                    pnMinNumberOfBytesNeeded)) {
                rc = Kernel32.INSTANCE.GetLastError();
                if (rc == W32Errors.ERROR_INSUFFICIENT_BUFFER) {
                    buffer = new Memory(pnMinNumberOfBytesNeeded.getValue());
                    continue;
                }
                break;
            }
            int dwRead = pnBytesRead.getValue();
            Pointer pevlr = buffer;
            while (dwRead > 0) {
                EVENTLOGRECORD record = new EVENTLOGRECORD(pevlr);
                EventLogRecord event = new EventLogRecord(pevlr);
                org.hyperic.sigar.win32.EventLogRecord sigar;
                EventLog log = new EventLog();
                if (record.EventType.intValue() == 1)
                    type = "Error";
                else if (record.EventType.intValue() == 10)
                    type = "Failure Audit";
                else if (record.EventType.intValue() == 8)
                    type = "Sucess Audit";
                else if (record.EventType.intValue() == 4)
                    type = "Information";
                else
                    type = "Warning";
                ByteBuffer names = pevlr
                        .getByteBuffer(
                                record.size(),
                                (record.UserSidLength.intValue() != 0 ? record.UserSidOffset
                                        .intValue() : record.StringOffset
                                        .intValue())
                                        - record.size());
                names.position(0);
                CharBuffer namesBuf = names.asCharBuffer();
                String[] splits = namesBuf.toString().split("\0");
                if (record.UserSidLength.intValue() != 0) {
                    ByteBuffer usersid = pevlr.getByteBuffer(
                            record.UserSidOffset.intValue(),
                            record.UserSidLength.intValue());
                    usersid.position(0);
                    CharBuffer sidBuf = usersid.asCharBuffer();
                    String[] sp = sidBuf.toString().split("\0");
                    // System.out.println(sp[0] + sp[1] + sp[2]);
                    /*
                     * dst.get user= new String(dst);
                     */
                } else {
                    user = "N/A";
                }

                System.out.println(type + "\t" + toDate(record) + "\t"
                        + event.getSource() + "\t" + record.EventCategory
                        + "\t" + record.EventID.shortValue() + "\t" + user
                        + "\t" + splits[1]);

                ByteBuffer strings = pevlr.getByteBuffer(
                        record.StringOffset.longValue(),
                        record.DataOffset.intValue()
                                - record.StringOffset.intValue());
                CharBuffer stringsBuf = strings.asCharBuffer();

                System.out.println("Desc: " + stringsBuf.toString());

                dwRecord++;
                dwRead -= record.Length.intValue();
                pevlr = pevlr.share(record.Length.intValue());

            }

        }

        i++;
    }

}

// Method to convert the timestamp to formated date
public Date toDate(EVENTLOGRECORD record) {
    Timestamp stamp = new Timestamp(record.TimeWritten.longValue() * 1000);
    Date date = new Date(stamp.getTime());
    return date;

}

}


Solution

  • Finally I figured out the solution....The description returned by the above code is just the insertion strings needed to build the message. Instead of using jna I used WMI which is simple to use and more handy

    /**
     * @param args
     */
    public static void main(String[] args) throws COMException {
        String computerName = ".";
        String userName = "";
        String password = "";
        String namespace = "root/cimv2";
        String Message = "";
        String queryProcessor = "Select * from Win32_NTLogEvent where Logfile='System'or Logfile='Application'";
        DispatchPtr dispatcher = null;
    
        try {
    
            ISWbemLocator locator = new ISWbemLocator(
                    "WbemScripting.SWbemLocator");
            ISWbemServices wbemServices = locator.ConnectServer(computerName,
                    namespace, userName, password, "", "", 0, dispatcher);
    
            ISWbemObjectSet wbemObjectSet = wbemServices.ExecQuery(
                    queryProcessor, "WQL", 0, null);
    
            DispatchPtr[] results = new DispatchPtr[wbemObjectSet.getCount()];
            IUnknown unknown = wbemObjectSet.get_NewEnum();
            IEnumVariant enumVariant = (IEnumVariant) unknown
                    .queryInterface(IEnumVariant.class);
    
            enumVariant.Next(wbemObjectSet.getCount(), results);
    
            for (int i = 0; i < results.length; i++) {
                ISWbemObject wbemObject = (ISWbemObject) results[i]
                        .queryInterface(ISWbemObject.class);
                if (wbemObject.get("Message") != null) {
                    Message = (String) wbemObject.get("Message");
                } else {
                    Message = "The description for Event ID ("
                            + wbemObject.get("EventCode")
                            + " ) in Source ( "
                            + wbemObject.get("SourceName")
                            + ") cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details.";
                }
                System.out.println(wbemObject.get("Logfile") + "\t"
                        + wbemObject.get("Type") + "\t"
                        + toDate(wbemObject.get("TimeGenerated").toString())
                        + "\t"
                        + toTime(wbemObject.get("TimeGenerated").toString())
                        + "\t" + wbemObject.get("EventCode") + "\t"
                        + wbemObject.get("ComputerName") + "\t" + Message);
                // System.out.println(wbemObject.GetObjectText_(0));
    
            }
    
        } catch (COMException e) {
            e.printStackTrace();
        }
    }
    
    public static String toDate(String time) throws COMException {
    
        String date = time.substring(6, 8) + "-" + time.substring(4, 6) + "-"
                + time.substring(0, 4);
        return date;
    
    }
    
    public static String toTime(String time) throws COMException {
    
        String Generatedtime = time.substring(8, 10) + ":"
                + time.substring(10, 12) + ":" + time.substring(12, 14) + ":"
                + time.substring(16, 21) + "-" + "GMT" + time.substring(21, 25);
        return Generatedtime;
    }