123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- """Event Log Utilities - helper for win32evtlog.pyd
- """
- import win32api, win32con, winerror, win32evtlog
- error = win32api.error # The error the evtlog module raises.
- langid = win32api.MAKELANGID(win32con.LANG_NEUTRAL, win32con.SUBLANG_NEUTRAL)
- def AddSourceToRegistry(appName, msgDLL = None, eventLogType = "Application", eventLogFlags = None):
- """Add a source of messages to the event log.
- Allows Python program to register a custom source of messages in the
- registry. You must also provide the DLL name that has the message table, so the
- full message text appears in the event log.
- Note that the win32evtlog.pyd file has a number of string entries with just "%1"
- built in, so many Python programs can simply use this DLL. Disadvantages are that
- you do not get language translation, and the full text is stored in the event log,
- blowing the size of the log up.
- """
- # When an application uses the RegisterEventSource or OpenEventLog
- # function to get a handle of an event log, the event loggging service
- # searches for the specified source name in the registry. You can add a
- # new source name to the registry by opening a new registry subkey
- # under the Application key and adding registry values to the new
- # subkey.
- if msgDLL is None:
- msgDLL = win32evtlog.__file__
- # Create a new key for our application
- hkey = win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE, \
- "SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s" % (eventLogType, appName))
- # Add the Event-ID message-file name to the subkey.
- win32api.RegSetValueEx(hkey,
- "EventMessageFile", # value name \
- 0, # reserved \
- win32con.REG_EXPAND_SZ,# value type \
- msgDLL)
- # Set the supported types flags and add it to the subkey.
- if eventLogFlags is None:
- eventLogFlags = win32evtlog.EVENTLOG_ERROR_TYPE | win32evtlog.EVENTLOG_WARNING_TYPE | win32evtlog.EVENTLOG_INFORMATION_TYPE
- win32api.RegSetValueEx(hkey, # subkey handle \
- "TypesSupported", # value name \
- 0, # reserved \
- win32con.REG_DWORD, # value type \
- eventLogFlags)
- win32api.RegCloseKey(hkey)
- def RemoveSourceFromRegistry(appName, eventLogType = "Application"):
- """Removes a source of messages from the event log.
- """
- # Delete our key
- try:
- win32api.RegDeleteKey(win32con.HKEY_LOCAL_MACHINE, \
- "SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s" % (eventLogType, appName))
- except win32api.error as exc:
- if exc.winerror != winerror.ERROR_FILE_NOT_FOUND:
- raise
- def ReportEvent(appName, eventID, eventCategory = 0, eventType=win32evtlog.EVENTLOG_ERROR_TYPE, strings = None, data = None, sid=None):
- """Report an event for a previously added event source.
- """
- # Get a handle to the Application event log
- hAppLog = win32evtlog.RegisterEventSource(None, appName)
- # Now report the event, which will add this event to the event log */
- win32evtlog.ReportEvent(hAppLog, # event-log handle \
- eventType,
- eventCategory,
- eventID,
- sid,
- strings,
- data)
- win32evtlog.DeregisterEventSource(hAppLog);
- def FormatMessage( eventLogRecord, logType="Application" ):
- """Given a tuple from ReadEventLog, and optionally where the event
- record came from, load the message, and process message inserts.
- Note that this function may raise win32api.error. See also the
- function SafeFormatMessage which will return None if the message can
- not be processed.
- """
- # From the event log source name, we know the name of the registry
- # key to look under for the name of the message DLL that contains
- # the messages we need to extract with FormatMessage. So first get
- # the event log source name...
- keyName = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s" % (logType, eventLogRecord.SourceName)
- # Now open this key and get the EventMessageFile value, which is
- # the name of the message DLL.
- handle = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, keyName)
- try:
- dllNames = win32api.RegQueryValueEx(handle, "EventMessageFile")[0].split(";")
- # Win2k etc appear to allow multiple DLL names
- data = None
- for dllName in dllNames:
- try:
- # Expand environment variable strings in the message DLL path name,
- # in case any are there.
- dllName = win32api.ExpandEnvironmentStrings(dllName)
- dllHandle = win32api.LoadLibraryEx(dllName, 0, win32con.LOAD_LIBRARY_AS_DATAFILE)
- try:
- data = win32api.FormatMessageW(win32con.FORMAT_MESSAGE_FROM_HMODULE,
- dllHandle, eventLogRecord.EventID, langid, eventLogRecord.StringInserts)
- finally:
- win32api.FreeLibrary(dllHandle)
- except win32api.error:
- pass # Not in this DLL - try the next
- if data is not None:
- break
- finally:
- win32api.RegCloseKey(handle)
- return data or '' # Don't want "None" ever being returned.
- def SafeFormatMessage( eventLogRecord, logType=None ):
- """As for FormatMessage, except returns an error message if
- the message can not be processed.
- """
- if logType is None: logType = "Application"
- try:
- return FormatMessage(eventLogRecord, logType)
- except win32api.error:
- if eventLogRecord.StringInserts is None:
- desc = ""
- else:
- desc = ", ".join(eventLogRecord.StringInserts)
- return "<The description for Event ID ( %d ) in Source ( %r ) could not be found. It contains the following insertion string(s):%r.>" % (winerror.HRESULT_CODE(eventLogRecord.EventID), eventLogRecord.SourceName, desc)
- def FeedEventLogRecords(feeder, machineName = None, logName = "Application", readFlags = None):
- if readFlags is None:
- readFlags = win32evtlog.EVENTLOG_BACKWARDS_READ|win32evtlog.EVENTLOG_SEQUENTIAL_READ
- h=win32evtlog.OpenEventLog(machineName, logName)
- try:
- while 1:
- objects = win32evtlog.ReadEventLog(h, readFlags, 0)
- if not objects:
- break
- map(lambda item, feeder = feeder: feeder(*(item,)), objects)
- finally:
- win32evtlog.CloseEventLog(h)
|