JNA Event Log Reader

后端 未结 1 606
醉梦人生
醉梦人生 2020-12-17 05:01

I am using the below code to read through the Windows Application Event Log using JNA. I want to be able to specify which event to start at instead of always starting with t

相关标签:
1条回答
  • 2020-12-17 06:01

    Bondo, here is a possible solution. In my test, it reads all 570 event logs under Application event; each event log will display in detail its event log record data.

    Code solution:

    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.util.Arrays;
    
    import com.sun.jna.*;
    import com.sun.jna.platform.win32.*;
    import com.sun.jna.platform.win32.WinNT.*;
    import com.sun.jna.ptr.IntByReference;
    
    public class Test {
    
        public static void main(String[] args) throws NumberFormatException, IOException {
    
            HANDLE h = com.sun.jna.platform.win32.Advapi32.INSTANCE.OpenEventLog(null, "Application");
            IntByReference pnBytesRead = new IntByReference();
            IntByReference pnMinNumberOfBytesNeeded = new IntByReference();
    
            IntByReference pOldestRecord = new IntByReference();
            assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.GetOldestEventLogRecord(h, pOldestRecord));
            int dwRecord = pOldestRecord.getValue();
            System.out.println("OLD: " + dwRecord);
            IntByReference pRecordCount = new IntByReference();
            assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, pRecordCount));
            int dwRecordCnt = pRecordCount.getValue();
            System.out.println("CNT: " + dwRecordCnt);
    
            int bufSize = 0x7ffff; //(r.size()) * 2048;
            Memory buffer = new Memory(bufSize);
            int rc = 0;
            int cnt = 0;
            while(com.sun.jna.platform.win32.Advapi32.INSTANCE.ReadEventLog(h, 
                    WinNT.EVENTLOG_SEEK_READ  /*
                    | WinNT.EVENTLOG_SEQUENTIAL_READ */ 
                    | WinNT.EVENTLOG_FORWARDS_READ /*
                    | WinNT.EVENTLOG_BACKWARDS_READ*/
                    , 
                    dwRecord, buffer, 
                    bufSize, 
                    pnBytesRead, 
                    pnMinNumberOfBytesNeeded)) {
    
                rc = Kernel32.INSTANCE.GetLastError();
                if (rc == W32Errors.ERROR_INSUFFICIENT_BUFFER) {
                    break;
                }        
    
                int dwRead = pnBytesRead.getValue();
                Pointer pevlr = buffer;
    
                while (dwRead > 0) 
                {
                    cnt++;
                    EVENTLOGRECORD record = new EVENTLOGRECORD(pevlr);
                    System.out.println("------------------------------------------------------------");
                    System.out.println(cnt+". " + dwRecord + " Event ID: " + record.EventID.shortValue() + " SID: " + record.UserSidLength);
    
                    dwRecord++;
    
                    // WCHAR SourceName[]
                    // WCHAR Computername[]
                    {
                        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");
                        System.out.println("SOURCE NAME: \n" + splits[0]);
                        System.out.println("COMPUTER NAME: \n" + splits[1]);
                    }
                    // SID   UserSid
                    if (record.UserSidLength.intValue() != 0){
                        ByteBuffer sid = pevlr.getByteBuffer(record.UserSidOffset.intValue(), record.UserSidLength.intValue());
                        sid.position(0);
                        //CharBuffer sidBuf = sid.asCharBuffer();
                        byte[] dst = new byte[record.UserSidLength.intValue()];
                        sid.get(dst);
                        System.out.println("SID: \n" + Arrays.toString(dst));
                    }
                    else {
                        System.out.println("SID: \nN/A");
                    }
                    // WCHAR Strings[]
                    {
                        ByteBuffer strings = pevlr.getByteBuffer(record.StringOffset.intValue(), record.DataOffset.intValue() - record.StringOffset.intValue());
                        strings.position(0);
                        CharBuffer stringsBuf = strings.asCharBuffer();
                        System.out.println("STRINGS["+record.NumStrings.intValue()+"]: \n" + stringsBuf.toString());
                    }
                    // BYTE  Data[]
                    {
                        ByteBuffer data = pevlr.getByteBuffer(record.DataOffset.intValue(), record.DataLength.intValue());
                        data.position(0);
                        CharBuffer dataBuf = data.asCharBuffer();
                        System.out.println("DATA: \n" + dataBuf.toString());
                    }
                    // CHAR  Pad[]
                    // DWORD Length;
    
                    dwRead -= record.Length.intValue();
                    pevlr = pevlr.share(record.Length.intValue());
                }
            }
            assertTrue(rc == W32Errors.ERROR_HANDLE_EOF);
            assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.CloseEventLog(h));        
        }
    
    
        private static void assertTrue(boolean getOldestEventLogRecord) {
    
        }
    
    }
    

    Sample output (the last of the event logs):

    ------------------------------------------------------------
    570. 26957 Event ID: 107 SID: 0
    SOURCE NAME: 
    Report Server Windows Service (VOSTRO)
    COMPUTER NAME: 
    CVS
    SID: 
    N/A
    STRINGS[1]: 
    Report Server Windows Service (VOSTRO)
    DATA: 
    

    Notes:

    I've set the lpBuffer at its maximum size of 0x7FFFF bytes.

    It uses WinNT.EVENTLOG_SEEK_READ mode with the record number offset dwRecordOffset starts at the oldest record number.

    The while loop will break when ReadEventLog() method returns zero and its GetLastError() returns W32Errors.ERROR_INSUFFICIENT_BUFFER.

    The event id should be read in short for the correct value: record.EventID.shortValue()

    0 讨论(0)
提交回复
热议问题