Modify

Opened 10 years ago

Closed 8 years ago

Last modified 8 years ago

#3237 closed Bug (Fixed)

_EventLog__Read has an error in the __EventLog_DecodeDesc Function, Insertions replace unintended variables after %1- %9

Reported by: BILGUS Owned by: Jon
Milestone: 3.3.14.3 Component: Standard UDFs
Version: 3.3.14.0 Severity: None
Keywords: Cc:

Description

EventLog_DecodeDesc uses string replace on Insertion place holders returned from _WinAPI_FormatMessage
ex. %1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12
However every instance is replaced therefore The data in %1 is also replaced in %10, %11, %12, %13 etc
the data in %2 is replaced in %20 %21 etc.

For instance if %1 contains Foo
%10 becomes Foo0
%11 becomes Foo1
%12 becomes Foo2

The fix is to change
$sDesc = StringReplace($sDesc, "%" & $iI, $aStrings[$iI])
to
$sDesc = StringReplace($sDesc, "%" & $iI, $aStrings[$iI],1)

Func EventLog_DecodeDesc($tEventLog)

Local $aStrings = EventLog_DecodeStrings($tEventLog)
Local $sSource =
EventLog_DecodeSource($tEventLog)
Local $iEventID = DllStructGetData($tEventLog, "EventID")
Local $sKey = "HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\" & $g_sSourceName_Event & "\" & $sSource

Local $aMsgDLL = StringSplit(_WinAPI_ExpandEnvironmentStrings(RegRead($sKey, "EventMessageFile")), ";")

Local $iFlags = BitOR($EVENTLOG_FORMAT_MESSAGE_FROM_HMODULE, $EVENTLOG_FORMAT_MESSAGE_IGNORE_INSERTS)
Local $sDesc = ""
For $iI = 1 To $aMsgDLL[0]

Local $hDLL = _WinAPI_LoadLibraryEx($aMsgDLL[$iI], $EVENTLOG_LOAD_LIBRARY_AS_DATAFILE)
If $hDLL = 0 Then ContinueLoop
Local $tBuffer = DllStructCreate("wchar Text[4096]")
_WinAPI_FormatMessage($iFlags, $hDLL, $iEventID, 0, $tBuffer, 4096, 0)
_WinAPI_FreeLibrary($hDLL)
$sDesc &= DllStructGetData($tBuffer, "Text")

Next

If $sDesc = "" Then

For $iI = 1 To $aStrings[0]

$sDesc &= $aStrings[$iI]

Next

Else

For $iI = 1 To $aStrings[0]

$sDesc = StringReplace($sDesc, "%" & $iI, $aStrings[$iI],1);<<<<<<<<<HERE Added as 1st occurrence Bilgus 5-20-2016

Next

EndIf

Return StringStripWS($sDesc, $STR_STRIPLEADING + $STR_STRIPTRAILING)

EndFunc ;==>EventLog_DecodeDesc

Attachments (0)

Change History (8)

comment:1 by Melba23, 10 years ago

I think it might be better to use StringRegExpReplace to limit the replacements to a single place.

Can you please post (or send me via PM) a sample of $sDesc that causes the problem. Then I can look into how we might distinguish the separate elements within the RegEx pattern.

M23

comment:2 by anonymous, 10 years ago

#RequireAdmin

;++++++++++++++++++++++++++++++++++START OF INCLUDE
;;#include <EventLog.au3>
;#include-once

#include "Date.au3"
#include "Security.au3"
#include "StructureConstants.au3"
#include "WinAPI.au3"

; #INDEX# =======================================================================================================================
; Title .........: Event_Log
; AutoIt Version : 3.3.14.2
; Language ......: English
; Description ...: Functions that assist Windows System logs.
; Description ...: When an error occurs, the system administrator or support technicians must determine what caused the error,
; attempt to recover any lost data, and prevent the error from recurring. It is helpful if applications, the
; operating system, and other system services record important events such as low-memory conditions or excessive
; attempts to access a disk. Then the system administrator can use the event log to help determine what
; conditions caused the error and the context in which it occurred. By periodically viewing the event log, the
; system administrator may be able to identify problems (such as a failing hard drive) before they cause damage.
; Author(s) .....: Paul Campbell (PaulIA), Gary Frost
; Dll ...........: advapi32.dll
; ===============================================================================================================================

; #VARIABLES# ===================================================================================================================
Global $g_sSourceName_Event
; ===============================================================================================================================

; #CONSTANTS# ===================================================================================================================
Global Const $EVENTLOG_SUCCESS = 0x00000000
Global Const $EVENTLOG_ERROR_TYPE = 0x00000001
Global Const $EVENTLOG_WARNING_TYPE = 0x00000002
Global Const $EVENTLOG_INFORMATION_TYPE = 0x00000004
Global Const $EVENTLOG_AUDIT_SUCCESS = 0x00000008
Global Const $EVENTLOG_AUDIT_FAILURE = 0x00000010
Global Const $EVENTLOG_SEQUENTIAL_READ = 0x00000001
Global Const $EVENTLOG_SEEK_READ = 0x00000002
Global Const $EVENTLOG_FORWARDS_READ = 0x00000004
Global Const $EVENTLOG_BACKWARDS_READ = 0x00000008

Global Const $EVENTLOG_LOAD_LIBRARY_AS_DATAFILE = 0x00000002
Global Const $
EVENTLOG_FORMAT_MESSAGE_FROM_HMODULE = 0x00000800
Global Const $EVENTLOG_FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
; ===============================================================================================================================

; #CURRENT# =====================================================================================================================
; _EventLogBackup
; _EventLog
Clear
; _EventLogClose
; _EventLog
Count
; _EventLogDeregisterSource
; _EventLog
Full
; _EventLogNotify
; _EventLog
Oldest
; _EventLogOpen
; _EventLog
OpenBackup
; _EventLogRead
; _EventLog
RegisterSource
; _EventLogReport
; ===============================================================================================================================

; #INTERNAL_USE_ONLY# ===========================================================================================================
; EventLog_DecodeCategory
;
EventLog_DecodeComputer
; EventLog_DecodeData
;
EventLog_DecodeDate
; EventLog_DecodeDesc
;
EventLog_DecodeEventID
; EventLog_DecodeSource
;
EventLog_DecodeStrings
; EventLog_DecodeTime
;
EventLog_DecodeTypeStr
; EventLog_DecodeUserName
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogBackup($hEventLog, $sFileName)

Local $aResult = DllCall("advapi32.dll", "bool", "BackupEventLogW", "handle", $hEventLog, "wstr", $sFileName)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0] <> 0

EndFunc ;==>_EventLogBackup

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogClear($hEventLog, $sFileName)

Local $bTemp = False
If StringLen($sFileName) = 0 Then

$sFileName = @TempDir & "\_EventLog_tempbackup.bak"
$bTemp = True

EndIf
Local $aResult = DllCall("advapi32.dll", "bool", "ClearEventLogW", "handle", $hEventLog, "wstr", $sFileName)
If @error Then Return SetError(@error, @extended, False)
If $bTemp Then FileDelete($sFileName)
Return $aResult[0] <> 0

EndFunc ;==>_EventLogClear

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogClose($hEventLog)

Local $aResult = DllCall("advapi32.dll", "bool", "CloseEventLog", "handle", $hEventLog)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0] <> 0

EndFunc ;==>_EventLogClose

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......:
; ===============================================================================================================================
Func _EventLogCount($hEventLog)

Local $aResult = DllCall("advapi32.dll", "bool", "GetNumberOfEventLogRecords", "handle", $hEventLog, "dword*", 0)
If @error Then Return SetError(@error, @extended, -1)
If $aResult[0] = 0 Then Return -1
Return $aResult[2]

EndFunc ;==>_EventLogCount

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeCategory
; Description ...: Decodes an event category for an event record
; Syntax.........:
EventLog_DecodeCategory ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - Event category
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeCategory($tEventLog)

Return DllStructGetData($tEventLog, "EventCategory")

EndFunc ;==>EventLog_DecodeCategory

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeComputer
; Description ...: Decodes the computer name from an event log record
; Syntax.........:
EventLog_DecodeComputer ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - Computer name
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeComputer($tEventLog)

Local $pEventLog = DllStructGetPtr($tEventLog)
; The buffer length doesn't need to extend past UserSidOffset since
; the string appears before that.
Local $iLength = DllStructGetData($tEventLog, "UserSidOffset") - 1
; This points to the start of the variable length data.
Local $iOffset = DllStructGetSize($tEventLog)
; Offset the buffer with the Source string length which appears right
; before the Computer name.
$iOffset += 2 * (StringLen(EventLog_DecodeSource($tEventLog)) + 1)
; Adjust the length to be a difference instead of absolute address.
$iLength -= $iOffset
; Adjust the buffer to point to the start of the Computer string.
Local $tBuffer = DllStructCreate("wchar Text& $iLength &", $pEventLog + $iOffset)
Return DllStructGetData($tBuffer, "Text")

EndFunc ;==>EventLog_DecodeComputer

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeData
; Description ...: Decodes the event specific binary data from an event log record
; Syntax.........:
EventLog_DecodeData ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - Array with the following format:
; |[0] - Number of bytes in array
; |[1] - Byte 1
; |[2] - Byte 2
; |[n] - Byte n
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeData($tEventLog)

Local $pEventLog = DllStructGetPtr($tEventLog)
Local $iOffset = DllStructGetData($tEventLog, "DataOffset")
Local $iLength = DllStructGetData($tEventLog, "DataLength")
Local $tBuffer = DllStructCreate("byte& $iLength &", $pEventLog + $iOffset)
Local $aData[$iLength + 1]
$aData[0] = $iLength
For $iI = 1 To $iLength

$aData[$iI] = DllStructGetData($tBuffer, 1, $iI)

Next
Return $aData

EndFunc ;==>EventLog_DecodeData

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeDate
; Description ...: Converts an event log time to a date string
; Syntax.........:
EventLog_DecodeDate ( $iEventTime )
; Parameters ....: $iEventTime - Event log time to be converted
; Return values .: Success - Date string in the format of mm/dd/yyyy
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeDate($iEventTime)

Local $tInt64 = DllStructCreate("int64")
Local $pInt64 = DllStructGetPtr($tInt64)
Local $tFileTime = DllStructCreate($tagFILETIME, $pInt64)
DllStructSetData($tInt64, 1, ($iEventTime * 10000000) + 116444736000000000)
Local $tLocalTime = _Date_Time_FileTimeToLocalFileTime($tFileTime)
Local $tSystTime = _Date_Time_FileTimeToSystemTime($tLocalTime)
Local $iMonth = DllStructGetData($tSystTime, "Month")
Local $iDay = DllStructGetData($tSystTime, "Day")
Local $iYear = DllStructGetData($tSystTime, "Year")
Return StringFormat("%02d/%02d/%04d", $iMonth, $iDay, $iYear)

EndFunc ;==>EventLog_DecodeDate

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeDesc
; Description ...: Decodes the description strings for an event record
; Syntax.........:
EventLog_DecodeDesc ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - Description
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeDesc($tEventLog)

Local $aStrings = EventLog_DecodeStrings($tEventLog)
Local $sSource =
EventLog_DecodeSource($tEventLog)
Local $iEventID = DllStructGetData($tEventLog, "EventID")
Local $sKey = "HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\" & $g_sSourceName_Event & "\" & $sSource
Local $aMsgDLL = StringSplit(_WinAPI_ExpandEnvironmentStrings(RegRead($sKey, "EventMessageFile")), ";")

Local $iFlags = BitOR($EVENTLOG_FORMAT_MESSAGE_FROM_HMODULE, $EVENTLOG_FORMAT_MESSAGE_IGNORE_INSERTS)
Local $sDesc = ""
For $iI = 1 To $aMsgDLL[0]

Local $hDLL = _WinAPI_LoadLibraryEx($aMsgDLL[$iI], $EVENTLOG_LOAD_LIBRARY_AS_DATAFILE)
If $hDLL = 0 Then ContinueLoop
Local $tBuffer = DllStructCreate("wchar Text[4096]")
_WinAPI_FormatMessage($iFlags, $hDLL, $iEventID, 0, $tBuffer, 4096, 0)
_WinAPI_FreeLibrary($hDLL)
$sDesc &= DllStructGetData($tBuffer, "Text")

Next

If $sDesc = "" Then

For $iI = 1 To $aStrings[0]

$sDesc &= $aStrings[$iI]

Next

Else

Local $sDescTEST=$sDesc
if $aStrings[0] > 9 Then msgbox(0,"INSERTION TEMPLATE BROKEN",$sDesc);ADDED TO SHOW PROBLEM
For $iI = 1 To $aStrings[0]

$sDesc = StringReplace($sDesc, "%" & $iI, $aStrings[$iI]);CHANGE TO $sDesc = StringReplace($sDesc, "%" & $iI, $aStrings[$iI],1) to fix

if $aStrings[0] > 9 and $iI <2 or $iI = $aStrings[0] Then msgbox(0,"INSERTION TEMPLATE BROKEN",$sDesc);ADDED TO SHOW PROBLEM
Next

if $aStrings[0] > 9 Then msgbox(0,"INSERTION TEMPLATE FIXED",$sDescTEST);ADDED TO SHOW PROBLEM

For $iI = 1 To $aStrings[0]

$sDescTEST = StringReplace($sDescTEST, "%" & $iI, $aStrings[$iI],1);CHANGED FROM $sDesc = StringReplace($sDesc, "%" & $iI, $aStrings[$iI])

if $aStrings[0] > 9 and $iI <2 or $iI = $aStrings[0] Then msgbox(0,"INSERTION TEMPLATE FIXED",$sDescTEST);ADDED TO SHOW PROBLEM
Next

EndIf
Return StringStripWS($sDesc, $STR_STRIPLEADING + $STR_STRIPTRAILING)

EndFunc ;==>EventLog_DecodeDesc

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeEventID
; Description ...: Decodes an event ID for an event record
; Syntax.........:
EventLog_DecodeEventID ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - Event ID
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeEventID($tEventLog)

Return BitAND(DllStructGetData($tEventLog, "EventID"), 0x7FFF)

EndFunc ;==>EventLog_DecodeEventID

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeSource
; Description ...: Decodes the event source from an event log record
; Syntax.........:
EventLog_DecodeSource ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - Source name
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeSource($tEventLog)

Local $pEventLog = DllStructGetPtr($tEventLog)
; The buffer length doesn't need to extend past UserSidOffset since
; the string appears before that.
Local $iLength = DllStructGetData($tEventLog, "UserSidOffset") - 1
; This points to the start of the variable length data.
Local $iOffset = DllStructGetSize($tEventLog)
; Adjust the length to be a difference instead of absolute address.
$iLength -= $iOffset
; Initialize the buffer to the start of the variable length data
Local $tBuffer = DllStructCreate("wchar Text& $iLength &", $pEventLog + $iOffset)
Return DllStructGetData($tBuffer, "Text")

EndFunc ;==>EventLog_DecodeSource

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeStrings
; Description ...: Decodes the insertion strings from an event log record
; Syntax.........:
EventLog_DecodeStrings ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - Array with the following format:
; |[0] - Number of strings in array
; |[1] - String 1
; |[2] - String 2
; |[n] - String n
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeStrings($tEventLog)

Local $pEventLog = DllStructGetPtr($tEventLog)
Local $iNumStrs = DllStructGetData($tEventLog, "NumStrings")
Local $iOffset = DllStructGetData($tEventLog, "StringOffset")
; The data offset is used to calculate buffer sizes.
Local $iDataOffset = DllStructGetData($tEventLog, "DataOffset")
Local $tBuffer = DllStructCreate("wchar Text& $iDataOffset - $iOffset &", $pEventLog + $iOffset)

Local $aStrings[$iNumStrs + 1]
$aStrings[0] = $iNumStrs
For $iI = 1 To $iNumStrs

$aStrings[$iI] = DllStructGetData($tBuffer, "Text")
$iOffset += 2 * (StringLen($aStrings[$iI]) + 1)
$tBuffer = DllStructCreate("wchar Text& $iDataOffset - $iOffset &", $pEventLog + $iOffset)

Next
Return $aStrings

EndFunc ;==>EventLog_DecodeStrings

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeTime
; Description ...: Converts an event log time to a date time
; Syntax.........:
EventLog_DecodeTime ( $iEventTime )
; Parameters ....: $iEventTime - Event log time to be converted
; Return values .: Success - Time string in the format of hh:mm:ss am/pm
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeTime($iEventTime)

Local $tInt64 = DllStructCreate("int64")
Local $pInt64 = DllStructGetPtr($tInt64)
Local $tFileTime = DllStructCreate($tagFILETIME, $pInt64)
DllStructSetData($tInt64, 1, ($iEventTime * 10000000) + 116444736000000000)
Local $tLocalTime = _Date_Time_FileTimeToLocalFileTime($tFileTime)
Local $tSystTime = _Date_Time_FileTimeToSystemTime($tLocalTime)
Local $iHours = DllStructGetData($tSystTime, "Hour")
Local $iMinutes = DllStructGetData($tSystTime, "Minute")
Local $iSeconds = DllStructGetData($tSystTime, "Second")
Local $sAMPM = "AM"
If $iHours < 12 Then

If $iHours = 0 Then

$iHours = 12

EndIf

Else

$sAMPM = "PM"
If $iHours > 12 Then

$iHours -= 12

EndIf

EndIf
Return StringFormat("%02d:%02d:%02d %s", $iHours, $iMinutes, $iSeconds, $sAMPM)

EndFunc ;==>EventLog_DecodeTime

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeTypeStr
; Description ...: Decodes an event type to an event string
; Syntax.........:
EventLog_DecodeTypeStr ( $iEventType )
; Parameters ....: $iEventType - Event type
; Return values .: Success - String indicating the event type
; Failure - Unknown event type ID
; Author ........: Paul Campbell (PaulIA)
; Modified.......:
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeTypeStr($iEventType)

Select

Case $iEventType = $EVENTLOG_SUCCESS

Return "Success"

Case $iEventType = $EVENTLOG_ERROR_TYPE

Return "Error"

Case $iEventType = $EVENTLOG_WARNING_TYPE

Return "Warning"

Case $iEventType = $EVENTLOG_INFORMATION_TYPE

Return "Information"

Case $iEventType = $EVENTLOG_AUDIT_SUCCESS

Return "Success audit"

Case $iEventType = $EVENTLOG_AUDIT_FAILURE

Return "Failure audit"

Case Else

Return $iEventType

EndSelect

EndFunc ;==>EventLog_DecodeTypeStr

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: EventLog_DecodeUserName
; Description ...: Decodes the user name from an event log record
; Syntax.........:
EventLog_DecodeUserName ( $tEventLog )
; Parameters ....: $tEventLog - tagEVENTLOGRECORD structure
; Return values .: Success - User name
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; Remarks .......: This function is used internally
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func EventLog_DecodeUserName($tEventLog)

Local $pEventLog = DllStructGetPtr($tEventLog)
If DllStructGetData($tEventLog, "UserSidLength") = 0 Then Return ""
Local $pAcctSID = $pEventLog + DllStructGetData($tEventLog, "UserSidOffset")
Local $aAcctInfo = _SecurityLookupAccountSid($pAcctSID)
If IsArray($aAcctInfo) Then Return $aAcctInfo[1]
Return

EndFunc ;==>EventLog_DecodeUserName

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogDeregisterSource($hEventLog)

Local $aResult = DllCall("advapi32.dll", "bool", "DeregisterEventSource", "handle", $hEventLog)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0] <> 0

EndFunc ;==>_EventLogDeregisterSource

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogFull($hEventLog)

Local $aResult = DllCall("advapi32.dll", "bool", "GetEventLogInformation", "handle", $hEventLog, "dword", 0, "dword*", 0, "dword", 4, "dword*", 0)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[3] <> 0

EndFunc ;==>_EventLogFull

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogNotify($hEventLog, $hEvent)

Local $aResult = DllCall("advapi32.dll", "bool", "NotifyChangeEventLog", "handle", $hEventLog, "handle", $hEvent)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0] <> 0

EndFunc ;==>_EventLogNotify

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogOldest($hEventLog)

Local $aResult = DllCall("advapi32.dll", "bool", "GetOldestEventLogRecord", "handle", $hEventLog, "dword*", 0)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[2]

EndFunc ;==>_EventLogOldest

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogOpen($sServerName, $sSourceName)

$g_sSourceName_Event = $sSourceName
Local $aResult = DllCall("advapi32.dll", "handle", "OpenEventLogW", "wstr", $sServerName, "wstr", $sSourceName)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]

EndFunc ;==>_EventLogOpen

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogOpenBackup($sServerName, $sFileName)

Local $aResult = DllCall("advapi32.dll", "handle", "OpenBackupEventLogW", "wstr", $sServerName, "wstr", $sFileName)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]

EndFunc ;==>_EventLogOpenBackup

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogRead($hEventLog, $bRead = True, $bForward = True, $iOffset = 0)

Local $iReadFlags, $aEvent[15]
$aEvent[0] = False; in cas of error

If $bRead Then

$iReadFlags = $EVENTLOG_SEQUENTIAL_READ

Else

$iReadFlags = $EVENTLOG_SEEK_READ

EndIf
If $bForward Then

$iReadFlags = BitOR($iReadFlags, $EVENTLOG_FORWARDS_READ)

Else

$iReadFlags = BitOR($iReadFlags, $EVENTLOG_BACKWARDS_READ)

EndIf

; First call gets the size for the buffer. A fake buffer is passed because
; the function demands the buffer be non-NULL even when requesting the size.
Local $tBuffer = DllStructCreate("wchar[1]")
Local $aResult = DllCall("advapi32.dll", "bool", "ReadEventLogW", "handle", $hEventLog, "dword", $iReadFlags, "dword", $iOffset, _

"struct*", $tBuffer, "dword", 0, "dword*", 0, "dword*", 0)

If @error Then Return SetError(@error, @extended, $aEvent)

; Allocate the buffer and repeat the call obtaining the information.
Local $iBytesMin = $aResult[7]
$tBuffer = DllStructCreate("wchar& $iBytesMin + 1 &")
$aResult = DllCall("advapi32.dll", "bool", "ReadEventLogW", "handle", $hEventLog, "dword", $iReadFlags, "dword", $iOffset, _

"struct*", $tBuffer, "dword", $iBytesMin, "dword*", 0, "dword*", 0)

If @error Or Not $aResult[0] Then Return SetError(@error, @extended, $aEvent)

Local $tEventLog = DllStructCreate($tagEVENTLOGRECORD, DllStructGetPtr($tBuffer))
$aEvent[0] = True
$aEvent[1] = DllStructGetData($tEventLog, "RecordNumber")
$aEvent[2] = EventLog_DecodeDate(DllStructGetData($tEventLog, "TimeGenerated"))
$aEvent[3] =
EventLog_DecodeTime(DllStructGetData($tEventLog, "TimeGenerated"))
$aEvent[4] = EventLog_DecodeDate(DllStructGetData($tEventLog, "TimeWritten"))
$aEvent[5] =
EventLog_DecodeTime(DllStructGetData($tEventLog, "TimeWritten"))
$aEvent[6] = EventLog_DecodeEventID($tEventLog)
$aEvent[7] = DllStructGetData($tEventLog, "EventType")
$aEvent[8] =
EventLog_DecodeTypeStr(DllStructGetData($tEventLog, "EventType"))
$aEvent[9] = EventLog_DecodeCategory($tEventLog)
$aEvent[10] =
EventLog_DecodeSource($tEventLog)
$aEvent[11] = EventLog_DecodeComputer($tEventLog)
$aEvent[12] =
EventLog_DecodeUserName($tEventLog)
$aEvent[13] = EventLog_DecodeDesc($tEventLog)
$aEvent[14] =
EventLog_DecodeData($tEventLog)
Return $aEvent

EndFunc ;==>_EventLogRead

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogRegisterSource($sServerName, $sSourceName)

$g_sSourceName_Event = $sSourceName
Local $aResult = DllCall("advapi32.dll", "handle", "RegisterEventSourceW", "wstr", $sServerName, "wstr", $sSourceName)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]

EndFunc ;==>_EventLogRegisterSource

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost (gafrost)
; ===============================================================================================================================
Func _EventLogReport($hEventLog, $iType, $iCategory, $iEventID, $sUserName, $sDesc, $aData)

Local $tSID = 0

If $sUserName <> "" Then

$tSID = _SecurityGetAccountSid($sUserName)

EndIf

Local $iData = $aData[0]
Local $tData = DllStructCreate("byte& $iData &")
Local $iDesc = StringLen($sDesc) + 1
Local $tDesc = DllStructCreate("wchar& $iDesc &")
Local $tPtr = DllStructCreate("ptr")
DllStructSetData($tPtr, 1, DllStructGetPtr($tDesc))
DllStructSetData($tDesc, 1, $sDesc)
For $iI = 1 To $iData

DllStructSetData($tData, 1, $aData[$iI], $iI)

Next
Local $aResult = DllCall("advapi32.dll", "bool", "ReportEventW", "handle", $hEventLog, "word", $iType, "word", $iCategory, _

"dword", $iEventID, "struct*", $tSID, "word", 1, "dword", $iData, "struct*", $tPtr, "struct*", $tData)

If @error Then Return SetError(@error, @extended, False)
Return $aResult[0] <> 0

EndFunc ;==>_EventLogReport

;++++++++++++++++++++++++END OF INCLUDE

Example()

Func Example()

Local Const $GUI_EVENT_CLOSE = -3

Local Const $WS_VSCROLL = 0x00200000

Local $hEventLog, $aEvent

; Create GUI
GUICreate("EventLog", 400, 300)

Local $idMemo = GUICtrlCreateEdit("", 2, 2, 396, 300,$WS_VSCROLL)

GUICtrlSetFont($idMemo, 9, 400, 0, "Courier New")
GUISetState(@SW_SHOW)

Local $i=0

; Read most current event record
$hEventLog = _EventLogOpen("", "Security")
Do

$aEvent = _EventLogRead($hEventLog, True, False)

$i+=1

; $hEventLog = _EventLogOpen("", "System")

; $aEvent = _EventLogRead($hEventLog)
; $aEvent = _EventLog
Read($hEventLog, True, False)

; MemoWrite($idMemo,"Result ............: " & $aEvent[0])
; MemoWrite($idMemo,"Record number .....: " & $aEvent[1])
; MemoWrite($idMemo,"Submitted .........: " & $aEvent[2] & " " & $aEvent[3])
; MemoWrite($idMemo,"Generated .........: " & $aEvent[4] & " " & $aEvent[5])
; MemoWrite($idMemo,"Event ID ..........: " & $aEvent[6])
; MemoWrite($idMemo,"Type ..............: " & $aEvent[8])
; MemoWrite($idMemo,"Category ..........: " & $aEvent[9])
; MemoWrite($idMemo,"Source ............: " & $aEvent[10])
; MemoWrite($idMemo,"Computer ..........: " & $aEvent[11])
; MemoWrite($idMemo,"Username ..........: " & $aEvent[12])
; MemoWrite($idMemo,"Description .......: " & $aEvent[13])
Until $i=_EventLogCount ( $hEventLog )-1
_EventLog
Close($hEventLog)

Do

; Loop until the user exits.

Until GUIGetMsg() = $GUI_EVENT_CLOSE or $i=10

EndFunc ;==>Example

; Write a line to the memo control
Func MemoWrite($idMemo,$sMessage)

GUICtrlSetData($idMemo, $sMessage & @CRLF, 1)

EndFunc ;==>MemoWrite

Version 0, edited 10 years ago by anonymous (next)

comment:3 by Melba23, 10 years ago

Like you I have access to the various functions involved, thanks, so there was no need to paste all that code.

What I wanted was a copy of a $sDesc variable from inside the EventLog_DecodeDesc function which gives you the problem. When I run the example code in the Help file on my machine $sDesc is an empty string, so I get no indication of how it might be delimited and therefore cannot work out a suitable RegEx pattern to replace the various elements.

So what I would like you to do is post an example of a $sDesc variable that includes some of these %1, %10, %11 etc.

M23

comment:4 by anonymous, 10 years ago

The code supplied was changed to illustrate the issue hence the reason I pasted it all, The example function was changed to only bring up the proper data source.

Here is a sample of the template string:


The Windows Filtering Platform has blocked a connection.

Application Information:

Process ID: %1
Application Name: %2

Network Information:

Direction: %3
Source Address: %4
Source Port: %5
Destination Address: %6
Destination Port: %7
Protocol: %8

Filter Information:

Filter Run-Time ID: %9
Layer Name: %10
Layer Run-Time ID: %11

<-----------------------------------------------------
After The first Replacement:


Application Information:

Process ID: 524
Application Name: %2

Network Information:

Direction: %3
Source Address: %4
Source Port: %5
Destination Address: %6
Destination Port: %7
Protocol: %8

Filter Information:

Filter Run-Time ID: %9
Layer Name: 5240
Layer Run-Time ID: 5241

<----------------------------------------------
Here is the $desc after replacement:


The Windows Filtering Platform has blocked a connection.

Application Information:

Process ID: 524
Application Name: \device\harddiskvolume11\windows\system32\svchost.exe

Network Information:

Direction: %%14592
Source Address: 255.255.255.255
Source Port: 67
Destination Address: 0.0.0.0
Destination Port: 68
Protocol: 0

Filter Information:

Filter Run-Time ID: 70589
Layer Name: 5240
Layer Run-Time ID: 5241

<-----------------------------------------------
Here is the Array of Strings: (0 holds count)


The Windows Filtering Platform has blocked a connection.

Application Information:

Process ID: 524
Application Name: \device\harddiskvolume11\windows\system32\svchost.exe

Network Information:

Direction: %%14592
Source Address: 255.255.255.255
Source Port: 67
Destination Address: 0.0.0.0
Destination Port: 68
Protocol: 0

Filter Information:

Filter Run-Time ID: 70589
Layer Name: 5240
Layer Run-Time ID: 5241

<-----------------------------------------------
AND. Finally after the fix this is the returned $Desc


The Windows Filtering Platform has blocked a connection.

Application Information:

Process ID: 524
Application Name: \device\harddiskvolume11\windows\system32\svchost.exe

Network Information:

Direction: %%14592
Source Address: 255.255.255.255
Source Port: 67
Destination Address: 0.0.0.0
Destination Port: 68
Protocol: 0

Filter Information:

Filter Run-Time ID: 70589
Layer Name: %%14610
Layer Run-Time ID: 44

<------------------------------------------------

Also note the Strings %%14592 and %%14610 I plan on fixing this in the next few days, as far as I can tell it needs to call FormatMessage with those ID's to fill these type of strings

comment:5 by anonymous, 10 years ago

Sorry here is the array of strings (0 Denotes Count):


13
524
\device\harddiskvolume11\windows\system32\svchost.exe
%%14592
255.255.255.255
67
0.0.0.0
68
0
70589
%%14610
44
S-1-0-0
S-1-0-0


comment:6 by anonymous, 10 years ago

Here is the fuction with code for insertion on %% placeholders


Func EventLog_DecodeDesc($tEventLog)

Local $aStrings = EventLog_DecodeStrings($tEventLog)
Local $sSource =
EventLog_DecodeSource($tEventLog)
Local $iEventID = DllStructGetData($tEventLog, "EventID")
Local $sKey = "HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\" & $g_sSourceName_Event & "\" & $sSource
Local $aMsgDLL = StringSplit(_WinAPI_ExpandEnvironmentStrings(RegRead($sKey, "EventMessageFile")), ";")

Local $iFlags = BitOR($EVENTLOG_FORMAT_MESSAGE_FROM_HMODULE, $EVENTLOG_FORMAT_MESSAGE_IGNORE_INSERTS)
Local $sDesc = ""
For $iI = 1 To $aMsgDLL[0]

Local $hDLL = _WinAPI_LoadLibraryEx($aMsgDLL[$iI], $EVENTLOG_LOAD_LIBRARY_AS_DATAFILE)
If $hDLL = 0 Then ContinueLoop
Local $tBuffer = DllStructCreate("wchar Text[4096]")
_WinAPI_FormatMessage($iFlags, $hDLL, $iEventID, 0, $tBuffer, 4096, 0)
_WinAPI_FreeLibrary($hDLL)
$sDesc &= DllStructGetData($tBuffer, "Text")

Next
;ADDED Source\Source\ParameterMessageFile for %% insertion place holders
$sKey = "HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\" & $g_sSourceName_Event & "\" & $g_sSourceName_Event
$aMsgDLL = StringSplit(_WinAPI_ExpandEnvironmentStrings(RegRead($sKey, "ParameterMessageFile")), ";")

For $iI = 1 To $aMsgDLL[0]

$hDLL = _WinAPI_LoadLibraryEx($aMsgDLL[$iI], $EVENTLOG_LOAD_LIBRARY_AS_DATAFILE)
If $hDLL <> 0 Then

For $iJ = 1 To $aStrings[0] ;Added to parse secondary replacements

Local $tBuffer = DllStructCreate("wchar Text[4096]")
If StringInStr($aStrings[$iJ], "%%") Then

_WinAPI_FormatMessage($iFlags, $hDLL, Int(StringTrimLeft($aStrings[$iJ], 2)), 0, $tBuffer, 4096, 0)
If @error = 0 Then $aStrings[$iJ] = DllStructGetData($tBuffer, "Text")

EndIf

Next
_WinAPI_FreeLibrary($hDLL)

EndIf

Next

If $sDesc = "" Then

For $iI = 1 To $aStrings[0]

$sDesc &= $aStrings[$iI]

Next

Else

For $iI = 1 To $aStrings[0]

$sDesc = StringReplace($sDesc, "%" & $iI, $aStrings[$iI], 1);Fixed

Next

EndIf
Return StringStripWS($sDesc, $STR_STRIPLEADING + $STR_STRIPTRAILING)

EndFunc ;==>EventLog_DecodeDesc

comment:7 by Jos, 8 years ago

Milestone: 3.3.15.1
Owner: set to Jos
Resolution: Fixed
Status: newclosed

Fixed by revision [11939] in version: 3.3.15.1

comment:8 by Jon, 8 years ago

Milestone: 3.3.15.13.3.14.3
Owner: changed from Jos to Jon

Fixed by revision [11942] in version: 3.3.14.3

Modify Ticket

Action
as closed The owner will remain Jon.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.