Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools


<< Previous Article | Next Article >>

In my previous article Working with NT EventLog - Part 3 (Implementing CEventLog Class, Writing to EventLog) you learned how to write to the EventLog. This article will show you how to read from EventLog. Many steps required to read full information from EventLog. You can use ReadEventLog API to read a single entry from EventLog. Here is the VB declaration for ReadEventLog.

Click here to copy the following block
Private Declare Function ReadEventLog Lib "advapi32.dll" Alias "ReadEventLogA" ( _
    ByVal hEventLog As Long, _
    ByVal dwReadFlags As Long, _
    ByVal dwRecordOffset As Long, _
    lpBuffer As Any, _
    ByVal nNumberOfBytesToRead As Long, _
    pnBytesRead As Long, _
    pnMinNumberOfBytesNeeded As Long) As Long

Parameters
  • hEventLog : [in] Handle to the event log to be read. This handle is returned by the OpenEventLog function.
  • dwReadFlags : [in] Options for how the read operation is to proceed. This parameter must include one of the following values.

    If the buffer is large enough, more than one record can be read at the specified seek position; you must specify one of the following flags to indicate the direction for successive read operations.

  • dwRecordOffset : [in] Log-entry record number at which the read operation should start. This parameter is ignored unless dwReadFlags includes the EVENTLOG_SEEK_READ flag.
  • lpBuffer : [out] Pointer to a buffer for the data read from the event log. This parameter cannot be NULL, even if the nNumberOfBytesToRead parameter is zero. The buffer will be filled with an EVENTLOGRECORD structure.
  • nNumberOfBytesToRead : [in] Size of the buffer, in bytes. This function will read as many whole log entries as will fit in the buffer; the function will not return partial entries, even if there is room in the buffer.
  • pnBytesRead : [out] Pointer to a variable that receives the number of bytes read by the function.
  • pnMinNumberOfBytesNeeded : [out] Pointer to a variable that receives the number of bytes required for the next log entry. This count is valid only if ReadEventLog returns zero and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

Return Values

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Here is the few steps to read from the NT EventLog.

Step 1: First of all you need to decide mode of navigation. In our case ReadFlags = EVENTLOG_FORWARDS_READ Or EVENTLOG_SEEK_READ. Which is exact seek by Event Record Number which is similar to Pramary Key in RDBMS. ReadEntry function in CEventLog class takes 2 parameters. First parameter is recordNumber which is absolute position of a single event record. Understand that Event Record Number can be different than Absolute position of that record in EventLog

Step 2: To read full event entry you must provide sufficient Buffer to hold event entry. There is no way to find exact size of event record before you execute ReadEventLog API. You can use the trick which I have used here.
Note: EventRecord is a variable type of EVENTLOGRECORD structure

Click here to copy the following block
ret = ReadEventLog(m_hEventLog, _
    ReadFlags, _
    Offset, _
    EventRecord, _
    NumBytesToRead, _
    NumBytesRead, _
    MinBytesNeeded)

When you call ReadEventLog first time then it will fail if you dont have enough buffer. You can check for ret = 0 And Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER condition. After first call it will set MinBytesNeeded to bytes required to hold the record.

Step 3: Once you know the actual size needed to hold the buffer you can resize your buffer array and call ReadEventLog again as shown below.

Click here to copy the following block
'//DWORD align MinBytesNeeded
MinBytesNeeded = ((MinBytesNeeded + 3) \ 4) * 4
ReDim RecordBuffer(MinBytesNeeded - 1) As Byte

ret = ReadEventLog(m_hEventLog, _
    ReadFlags, _
    Offset, _
    RecordBuffer(0), _
    MinBytesNeeded, _
    NumBytesRead, _
    MinBytesNeeded)

After successful call to ReadEventLog you can fill EventRecord variable which is

Click here to copy the following block
'//Move to the bytes into structure
MoveMem EventRecord, RecordBuffer(0), Len(EventRecord)

Step 4: Now you have event data in RecordBuffer and EventRecord. You can get few event properties directly from EventRecord but for some variable length properties i.e Message, Category Name, User Name ... you have to perform extra work. Let me explain you how event record is stored in Event RecordBuffer. First EVENTLOGRECORD is stored in the RecordBuffer then all variable length data is stored.

Click here to copy the following block
'// Structure that defines the header of the Eventlog record. This is the
'// fixed-sized portion before all the variable-length strings, binary
'// data and pad bytes.
'//
'// TimeGenerated is the time it was generated at the client.
'// TimeWritten is the time it was put into the log at the server end.

Private Type EVENTLOGRECORD
  length         As Long  ' Length of full record
  Reserved        As Long  ' Used by the service
  RecordNumber      As Long  ' Absolute record number
  TimeGenerated     As Long  ' Seconds since 1-1-1970
  TimeWritten      As Long  ' Seconds since 1-1-1970
  EventId        As Long
  EventType       As Integer
  NumStrings       As Integer
  EventCategory     As Integer
  ReservedFlags     As Integer  ' For use with paired events (auditing)
  ClosingRecordNumber  As Long  ' For use with paired events (auditing)
  StringOffset      As Long  ' Offset from beginning of record
  UserSidLength     As Long
  UserSidOffset     As Long
  DataLength       As Long
  DataOffset       As Long  ' Offset from beginning of record
  ' //
  ' // Then follow:
  ' //
  ' // WCHAR SourceName[]
  ' // WCHAR Computername[]
  ' // SID  UserSid
  ' // WCHAR Strings[]
  ' // BYTE Data[]
  ' // CHAR Pad[]
  ' // DWORD Length;
  ' //
End Type

Here is some guidelines about how to read some important properties from eventlog.
Event Createation/Written Time : EventLog stores time in UTC format so you have to convert TimeGenerated/TimeWritten both to Local date/time using the following code.

Click here to copy the following block
m_EventTimeWritten = UTCtoLocal(DateAdd("s", EventRecord.TimeWritten, #1/1/1970#))
m_EventTimeCreated = UTCtoLocal(DateAdd("s", EventRecord.TimeGenerated, #1/1/1970#))

Event Source Name : Source name is stored after all Fixed length data in other term after EVENTLOGRECORD. Use the following code to grab Source name

Click here to copy the following block
m_EventSourceName = GetStrFromPtrA(VarPtr(RecordBuffer(Len(EventRecord))))

Event Machine Name : Machine name is stored after source name so just add length of source name to the Source String pointer to get Machine name. Use the following code to grab Source name

Click here to copy the following block
m_EventComputerName = GetStrFromPtrA(VarPtr(RecordBuffer(Len(EventRecord))) _
    + Len(m_EventSourceName) + 1)

Event User Name : Event Log stores User SID instead of name. So your first task is to get SID from variable length data and then you can use LookupAccountSid function to get username from SID. You can find exact location in of SID in RecordBuffer using UserSidOffset. I have wrapped LookupAccountSid API in a easy to use function GetUserNameFromSID. Following line will show you how to get User name.

Click here to copy the following block
m_EventUserName = GetUserNameFromSID(VarPtr(RecordBuffer(EventRecord.UserSidOffset)))

Event Category Name : Event Log only stores CategoryId. For Category name you have to do lookup in Resource File for Category. You can use LoadLibraryEx, FormatMessage and FreeLibrary apis to get Categoryname from CategoryId.

Event Message : To get full description of event you have to perform several tasks. First of all you have to find EventId and all Insert strings for that event. Insert strings are stored as Null seperated strings. You can split all strings and build string array. I have created a function called GetFormattedString which takes actual Message stored in Message File and string Array of insert strings. GetFormattedString function will mearge insert strings into actual message. For example Actaul Message stored in message file : "Drive %1 has only %2 MB left" will be replace by something like "Drive C has only 20 MB left". MessageString will do everything for you.
- Find insert string (null seperated placeholder strings) from RecordBuffer
- Split into string array.
- Find actual message associated with an EventId
- Mearge Insert Strings with Actual Message String

Here is the example to get message of an event.

Click here to copy the following block
m_EventDescription = MessageString(m_EventSourceName, EventRecord.EventId, RecordBuffer)

Here is the full code for all steps described above

Click here to copy the following block
Private Sub ClearVariables()
  m_EventCategoryString = ""
  m_EventComputerName = ""
  m_EventDescription = ""
  m_EventSourceName = ""
  m_EventUserName = ""
End Sub


Public Function GetFirstEventLogRecord() As Long
  Dim FirstRecord As Long
  Call GetOldestEventLogRecord(m_hEventLog, FirstRecord)
  GetFirstEventLogRecord = FirstRecord
End Function

'//If No RecordNumber is passed then default action is taken which is Read Next
Public Function ReadEntry(Optional RecordNumber As Long = 0, Optional ReadMsgDesc As Boolean = False) As Boolean
  Dim Offset           As Long
  Dim RecordBuffer()       As Byte  ' Used to read the event log records
  Dim EventLogHwnd        As Long  ' Handle to the current open event log
  Dim ReadFlags         As Long  ' Flags used to read the event log
  Dim NumBytesToRead       As Long  ' Number of bytes TO read from event log
  Dim NumBytesRead        As Long  ' Number of bytes actually READ from event log
  Dim NumRecords         As Long  ' Total number of records in this event log
  Dim MinBytesNeeded       As Long  ' Used in ReadEventLog API call
  Dim ret            As Long  ' Return value from ReadEventLog API call
  Dim FirstRecord        As Long
  
  ReadFlags = EVENTLOG_FORWARDS_READ Or EVENTLOG_SEEK_READ
  
  '//Call GetOldestEventLogRecord(m_hEventLog, FirstRecord)
  FirstRecord = GetFirstEventLogRecord
    
  '//offset is a record number where seek operation should start
  '//this is only valid if you specify EVENTLOG_SEEK_READ flag otherwise it will be ignored
  Offset = RecordNumber
  
  ClearVariables
    
  ret = ReadEventLog(m_hEventLog, _
      ReadFlags, _
      Offset, _
      EventRecord, _
      NumBytesToRead, _
      NumBytesRead, _
      MinBytesNeeded)

  If ret = 0 And Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER Then
    'Debug.Print modMain.ReturnApiErrString(Err.LastDllError)
    Exit Function
  ElseIf ret = 0 And Err.LastDllError = ERROR_INSUFFICIENT_BUFFER Then

    '//DWORD align MinBytesNeeded
    MinBytesNeeded = ((MinBytesNeeded + 3) \ 4) * 4
    ReDim RecordBuffer(MinBytesNeeded - 1) As Byte

    ret = ReadEventLog(m_hEventLog, _
        ReadFlags, _
        Offset, _
        RecordBuffer(0), _
        MinBytesNeeded, _
        NumBytesRead, _
        MinBytesNeeded)
    If ret = 0 Then Exit Function
  End If

  '//Move to the bytes into structure
  MoveMem EventRecord, RecordBuffer(0), Len(EventRecord)
  
  m_EventTimeWritten = UTCtoLocal(DateAdd("s", EventRecord.TimeWritten, #1/1/1970#))
  m_EventTimeCreated = UTCtoLocal(DateAdd("s", EventRecord.TimeGenerated, #1/1/1970#))
  m_EventSourceName = GetStrFromPtrA(VarPtr(RecordBuffer(Len(EventRecord))))
  m_EventComputerName = GetStrFromPtrA(VarPtr(RecordBuffer(Len(EventRecord))) + Len(m_EventSourceName) + 1)
  
  If EventRecord.UserSidLength > 0 Then
   m_EventUserName = GetUserNameFromSID(VarPtr(RecordBuffer(EventRecord.UserSidOffset)))
  End If
  
  m_EventCategoryString = CategoryString(m_EventSourceName, EventRecord.EventCategory)
  '//By default dont load Message Description coz its lot of processing
  If ReadMsgDesc = True Then
    m_EventDescription = MessageString(m_EventSourceName, EventRecord.EventId, RecordBuffer)
  End If
End Function

'//////////////////////////////////////////////////////////////////////
'//Function to convert UTC date/time to Local date/time
'//////////////////////////////////////////////////////////////////////
Private Function GetUTCBias() As Single
  ' Returns hour offset with West positive, East negative taking
  ' daylight time into account

  Dim dl As Long, dt As Integer
  Dim myTZ As TIME_ZONE_INFORMATION

  dl = GetTimeZoneInformation(myTZ)
  If dl = 2 Then dt = 1 Else dt = 0  'Daylight Time or not
  GetUTCBias = (myTZ.Bias + (myTZ.DaylightBias) * dt) / 60
End Function

Private Function UTCtoLocal(ByVal UTCTime As Date) As Date
  Dim Bias As Single
  Bias = GetUTCBias
  If Bias \ 1 = Bias Then
    UTCtoLocal = DateAdd("h", -1 * Bias, UTCTime)
  Else
    UTCtoLocal = DateAdd("n", -1 * (IIf(Bias < 0, -30, 30)), _
        DateAdd("h", -1 * (Bias \ 1), UTCTime))
  End If
End Function

'//////////////////////////////////////////////////////////////////////
'//Category name is stored in Message Lib, So get category name from ID
'//////////////////////////////////////////////////////////////////////
Private Function CategoryString(SourceName As String, CategoryId As Integer) As String
  On Error Resume Next
  Dim strLib As String, strLibExpandedPath As String
  Dim lpEventStr As Long, ret As Long, hModule As Long, nChars As Long, Flags As Long

  If CategoryId <= 0 Then CategoryString = "<none>": Exit Function

  strLib = GetLib(SourceName, CategoryFileLib)

  If strLib = "" Then
    AddLib SourceName
    strLib = GetLib(SourceName, CategoryFileLib)
    If strLib = "" Then CategoryString = "<none>": Exit Function
  End If

  CategoryString = MessageStringFromLib(strLib, CLng(CategoryId))
End Function

'//////////////////////////////////////////////////////////////////////
'//Functions to keep track of pre loaded Message Lib information so we
'//dont have to read from registry everytime
'//////////////////////////////////////////////////////////////////////
Private Function GetLib(EventSource As String, LType As LibType) As String
  On Error GoTo errHandler
  If LType = CategoryFileLib Then
    GetLib = colCategoryFileLib(EventSource)
  ElseIf LType = MessgeFileLib Then
    GetLib = colMessageFileLib(EventSource)
  ElseIf LType = ParameterFileLib Then
    GetLib = colParaMessageFileLib(EventSource)
  End If
errHandler:
End Function

Private Sub AddLib(EventSource As String)
  On Error GoTo errHandler
  Dim CatLibPath As String, MsgLibPath As String, ParaLibPath As String
  CatLibPath = ReadFromRegistry(HKEY_LOCAL_MACHINE, BASE_KEY & "\" & _
      m_EventLogName & "\" & EventSource, "CategoryMessageFile")
  MsgLibPath = ReadFromRegistry(HKEY_LOCAL_MACHINE, BASE_KEY & "\" & _
      m_EventLogName & "\" & EventSource, "EventMessageFile")
  ParaLibPath = ReadFromRegistry(HKEY_LOCAL_MACHINE, BASE_KEY & "\" & _
      m_EventLogName & "\" & EventSource, "ParameterMessageFile")

  If CatLibPath <> "" Then colCategoryFileLib.Add GetExpandedPath(CatLibPath), EventSource
  If MsgLibPath <> "" Then colMessageFileLib.Add GetExpandedPath(MsgLibPath), EventSource
  If ParaLibPath <> "" Then colParaMessageFileLib.Add GetExpandedPath(ParaLibPath), EventSource
errHandler:
End Sub

'//////////////////////////////////////////////////////////////////////
'//Converts a SID (security identifier) into a
'//fully qualified UserID and domain name.
'//////////////////////////////////////////////////////////////////////
Private Function GetUserNameFromSID(ByVal lpSid As Long) As String
  Dim Success   As Boolean
  Dim peUse As Long, UserID As String, DomainName As String

  ' Initialize buffers large enough to hold user and domain names
  UserID = String(64, 0)
  DomainName = String(64, 0)

  ' Get the NT Domain and UserName
  Success = LookupAccountSid(vbNullString, _
      ByVal lpSid, _
      UserID, _
      Len(UserID), _
      DomainName, _
      Len(DomainName), _
      peUse)

  If Success Then
    ' Trim off nulls and return
    GetUserNameFromSID = TrimNulls(UserID)
  End If
End Function

Private Function TrimNulls(InString As String) As String
  Dim Pos As Long     ' location of null terminator
  Pos = InStr(InString, Chr$(0))  ' find null terminator
  If Pos > 0 Then     ' terminator located
    TrimNulls = Left$(InString, Pos - 1)  ' strip terminator
  Else           ' no terminator found
    TrimNulls = InString ' return the supplied input string
  End If
End Function

'//////////////////////////////////////////////////////////////////////
'//Get fully prepared Event Description, This function takes ByteBuffer of event record
'//and then it mearges insert strings with actual message stored in the message Lib
'//////////////////////////////////////////////////////////////////////
Private Function MessageString(SourceName As String, Event_Id As Long, _
  RecordBuffer() As Byte) As String

  On Error Resume Next
  Dim lpEventStr As Long, ret As Long, hModule As Long, nChars As Long, Flags As Long
  Dim InsertionStrings As String, Msg As String, strLib As String, lngStringLen As Long

  If Event_Id = 0 Then MessageString = "<none>": Exit Function

  strLib = GetLib(SourceName, MessgeFileLib)

  If strLib = "" Then
    AddLib SourceName
    strLib = GetLib(SourceName, MessgeFileLib)
    If strLib = "" Then MessageString = "<none>": Exit Function
  End If

  ' Strings follow -- need to get the length here, otherwise
  ' function will truncate at first null
  lngStringLen = (EventRecord.DataOffset - EventRecord.StringOffset)  '+ 1
  Dim strStrings() As String

  InsertionStrings = GetStrFromPtrA(VarPtr(RecordBuffer(EventRecord.StringOffset)), lngStringLen)

  strStrings = Split(InsertionStrings, Chr(0))
  '//Incase extra insert string in array then remove
  If EventRecord.NumStrings > 0 Then ReDim Preserve strStrings(EventRecord.NumStrings - 1)

  Msg = MessageStringFromLib(strLib, EventRecord.EventId)

  If EventRecord.NumStrings > 0 Then
    If Msg <> "" Then
      MessageString = GetFormattedString(Msg, strStrings)
    Else
      MessageString = strStrings(0)
    End If
  Else
    MessageString = Msg
  End If
End Function

'//////////////////////////////////////////////////////////////////////
'//Function to retrive formatted message string from Library
'//////////////////////////////////////////////////////////////////////
Private Function GetFormattedString(strSource As String, Inserts() As String) As String
  'Loads a resource string replacing %n sequences with strings
  'from the Inserts argument(s). (First insert is %1, next %2, etc.)
  Dim sSource As String, sBuf As String, sAnsiInserts() As String
  Dim i As Integer, iLB As Integer, iUB As Integer
  Dim lpInserts() As Long, lBufSize As Long, lRet As Long, lpInsertionStrings As Long

  'sSource = LoadResString(lResID)
  sSource = strSource

  iLB = LBound(Inserts): iUB = UBound(Inserts)
  ReDim lpInserts(iLB To iUB)
  ReDim sAnsiInserts(iLB To iUB)

  For i = iLB To iUB
    '//special handling for values coming from ParameteMessageFile
    sBuf = Inserts(i)
    If InStr(1, sBuf, "%%") > 0 Then
      Inserts(i) = MessageStringFromLib(GetLib(Me.EventSourceName, ParameterFileLib) _
          , Val(Right(sBuf, Len(sBuf) - 2)))

      lBufSize = Len(Inserts(i)) * 2  'Unicode len is twice than BSTR
    End If

    sAnsiInserts(i) = StrConv(Inserts(i), vbFromUnicode)
    lpInserts(i) = StrPtr(sAnsiInserts(i))
  Next

  'If EventRecord.RecordNumber = 1305 Then Stop

  Dim lpsBuf As Long, lpSource As Long
  ' Point to the first element in the array
  lpInsertionStrings = VarPtr(lpInserts(0))
  lBufSize = lBufSize + Len(strSource) + 2 + (EventRecord.DataOffset - EventRecord.StringOffset) * 2

  sSource = StrConv(sSource, vbFromUnicode)
  lpSource = StrPtr(sSource)

  lRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER Or _
      FORMAT_MESSAGE_FROM_STRING Or _
      FORMAT_MESSAGE_ARGUMENT_ARRAY, _
      ByVal lpSource, 0&, 0&, lpsBuf, lBufSize, ByVal lpInsertionStrings)

  sBuf = GetStrFromPtrA(lpsBuf, lBufSize)
  GetFormattedString = Left$(sBuf, lRet)
End Function

'//////////////////////////////////////////////////////////////////////
'//Get String from Library (*.Dll,*.Exe) By MessageId
'//////////////////////////////////////////////////////////////////////
Private Function MessageStringFromLib(strLib As String, MessageId As Long) As String
  Dim hModule As Long, lpEventStr As Long, nChars As Long, Flags As Long

  hModule = LoadLibraryEx(strLib, 0&, LOAD_LIBRARY_AS_DATAFILE)

  If hModule > 0 Then
    ' Convert the EventID into a string, which may have
    ' embedded insertion string variables.
    Flags = FORMAT_MESSAGE_FROM_HMODULE Or _
        FORMAT_MESSAGE_IGNORE_INSERTS Or _
        FORMAT_MESSAGE_ALLOCATE_BUFFER

    nChars = FormatMessage(Flags, ByVal hModule, MessageId, _
        0&, ByVal VarPtr(lpEventStr), 0&, ByVal 0&)

    ' Create a string from the buffer; strip off trailing line feeds.
    MessageStringFromLib = GetStrFromPtrA(lpEventStr)
    If Right$(MessageStringFromLib, 2) = vbCrLf Then
      MessageStringFromLib = Left$(MessageStringFromLib, Len(MessageStringFromLib) - 2)
    End If
  Else
    MessageStringFromLib = ""
  End If

  FreeLibrary hModule
End Function

'//////////////////////////////////////////////////////////////////////
'//Expand any environmental strings in the registry entry
'//(i.e. %SystemRoot%\System32\ulib.dll=> c:\windows\system32\ulib.dll)
'//////////////////////////////////////////////////////////////////////
Private Function GetExpandedPath(ByVal strPath As String) As String
  Dim strExpandedPath As String
  strPath = UCase$(strPath)
  If InStr(strPath, "%") > 0 Then
    strExpandedPath = Space$(256)
    ret = ExpandEnvironmentStrings(strPath, strExpandedPath, Len(strExpandedPath))
    If ret > 0 Then
      GetExpandedPath = Mid$(strExpandedPath, 1, ret - 1)  '//Grab path without trailing space
    End If
  Else
    GetExpandedPath = strPath  '//No need to expand
  End If
End Function

Private Function GetStrFromPtrA(ByVal lngPtrString As Long, Optional lngLen As Long = 0) As String
  Dim lngNumChars As Long
  If lngLen = 0 Then
    lngNumChars = lstrlenA(ByVal lngPtrString)
  Else
    lngNumChars = lngLen
  End If

  GetStrFromPtrA = Space$(lngNumChars)
  MultiByteToWideChar 0&, _
      0, _
      ByVal lngPtrString, _
      lngNumChars, _
      ByVal StrPtr(GetStrFromPtrA), _
      lngNumChars
End Function

'// FF=1 Byte so ANDing any number with FFFF will return lowest 2 Bytes (word)
Private Function LoWord(ByVal lngNumber As Long) As Long
  LoWord = lngNumber And &HFFFF&
End Function

'//////////////////////////////////////////////////////////////////////
'//Properties of current event record
'//////////////////////////////////////////////////////////////////////
Public Property Get EventTimeCreated() As Date
  EventTimeCreated = m_EventTimeCreated
End Property
Public Property Get EventSourceName() As String
  EventSourceName = m_EventSourceName
End Property
Public Property Get EventUserName() As String
  EventUserName = m_EventUserName
End Property
Public Property Get EventComputerName() As String
  EventComputerName = m_EventComputerName
End Property
Public Property Get EventType() As String
  Select Case EventRecord.EventType
  Case enumLogEntryTypes.EVENTLOG_INFORMATION_TYPE
    EventType = "Info"
  Case enumLogEntryTypes.EVENTLOG_ERROR_TYPE
    EventType = "Error"
  Case enumLogEntryTypes.EVENTLOG_SUCCESS
    EventType = "Success"
  Case enumLogEntryTypes.EVENTLOG_WARNING_TYPE
    EventType = "Warning"
  Case enumLogEntryTypes.EVENTLOG_AUDIT_FAILURE
    EventType = "Audit Failure"
  Case enumLogEntryTypes.EVENTLOG_AUDIT_SUCCESS
    EventType = "Audit Success"
  End Select
End Property
Public Property Get EventDescription() As String
  EventDescription = m_EventDescription
End Property
Public Property Get EventCategoryString() As String
  EventCategoryString = m_EventCategoryString
End Property
Public Property Get EventRecordNum() As Long
  EventRecordNum = EventRecord.RecordNumber
End Property
Public Property Get EventId() As Long
  EventId = LoWord(EventRecord.EventId)
End Property

<< Previous Article | Next Article >>


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.