Reporting an Event(用于在系统事件日志中登记自定义日志信息)

Before you can log an event in an event log, you must first complete Steps from 1 through 5, as explained in the Using Event Logging topic:

1.Create a message file (.mc) that defines the events and their messages. For more information about message files, see Message Text Files. For this example, the message file, Sample.mc, contains the following text.
// ***** sample.mc ***** 
// This is the header.
MessageIdTypedef=DWORD
SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
    Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
    Warning=0x2:STATUS_SEVERITY_WARNING
    Error=0x3:STATUS_SEVERITY_ERROR
    )

FacilityNames=(System=0x0:FACILITY_SYSTEM
    Runtime=0x2:FACILITY_RUNTIME
    Stubs=0x3:FACILITY_STUBS
    Io=0x4:FACILITY_IO_ERROR_CODE
)
LanguageNames=(English=0x409:MSG00409)

// The following are message definitions.
MessageId=0x1
Severity=Error
Facility=Runtime
SymbolicName=MSG_BAD_COMMAND
Language=English
You have chosen an incorrect command: %1.
// ********************
The %1 is an insertion string placeholder. The %1 is replaced by the string in the szMsg variable passed to ReportEvent function.
2.Compile the message file with the Message Compiler tool. The following command can be used to compile the Sample.mc file: mc -U sample.mc
The message compiler generates the following files: Sample.h, Sample.rc, MSG00001.bin, and MSG00002.bin. Sample.h contains the message definitions. Sample.rc defines MSG00001.bin and MSG00002.bin as resources that contain messages in the two languages. The generated header file contains the following text.

//*********Sample.h************
// Define the facility codes.
//
#define FACILITY_SYSTEM                  0x0
#define FACILITY_STUBS                   0x3
#define FACILITY_RUNTIME                 0x2
#define FACILITY_IO_ERROR_CODE           0x4

//
// Define the severity codes.
//
#define STATUS_SEVERITY_WARNING          0x2
#define STATUS_SEVERITY_SUCCESS          0x0
#define STATUS_SEVERITY_INFORMATIONAL    0x1
#define STATUS_SEVERITY_ERROR            0x3

//
// MessageId: MSG_BAD_COMMAND
//
// MessageText:
//
//  You have chosen an incorrect command: %1.
//
#define MSG_BAD_COMMAND                  ((DWORD)0xC0020001L)
//******************************

3.Build the resource files with the Resource Compiler tool. The following command builds the resource strings: rc -r sample.rc

4.Link the resource file to a DLL. The DLL file will contain the event messages. The following command line links the sample.res file to the      eventSource.dll file: link -dll -noentry -out:%SYSTEMROOT%\System32\eventSource.dll sample.res
Note  The link command can be run from a Visual Studio Command Prompt tool.

5.Add an event source name to the registry. For more information, see Adding a Source to the Registry. When you add the event source to the        registry, specify the location of the DLL file created in Step 4.
************AddEventToReg.cpp***************
#include <stdafx.h>
#include <windows.h>
#include <iostream>
#include <strsafe.h>
int __cdecl wmain(int argc, LPWSTR *argv)
{
    // Name of the event log.
    wchar_t *logName = L"Application";
    // Event Source name.
    wchar_t *sourceName = L"SampleEventSourceName";
    // DLL that contains the event messages (descriptions).
    wchar_t *dllName = L"C:\\WINDOWS\\SYSTEM32\\eventSource.dll";
    // This number of categories for the event source.
    DWORD dwCategoryNum = 1;
  
   HKEY hk;
   DWORD dwData, dwDisp;
   TCHAR szBuf[MAX_PATH];
   size_t cchSize = MAX_PATH;
   // Create the event source as a subkey of the log.
   HRESULT hr = StringCchPrintf(szBuf, cchSize,
      L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s",
      logName, sourceName);

   if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szBuf,
          0, NULL, REG_OPTION_NON_VOLATILE,
          KEY_WRITE, NULL, &hk, &dwDisp))
   {
      printf("Could not create the registry key.");
      return 0;
   }

   // Set the name of the message file.

   if (RegSetValueEx(hk,             // subkey handle
          L"EventMessageFile",        // value name
          0,                         // must be zero
          REG_EXPAND_SZ,             // value type
          (LPBYTE) dllName,          // pointer to value data
          (DWORD) (lstrlen(dllName)+1)*sizeof(TCHAR))) // data size
   {
      printf("Could not set the event message file.");
      RegCloseKey(hk);
      return 0;
   }

   // Set the supported event types.

   dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
        EVENTLOG_INFORMATION_TYPE;

   if (RegSetValueEx(hk,      // subkey handle
           L"TypesSupported",  // value name
           0,                 // must be zero
           REG_DWORD,         // value type
           (LPBYTE) &dwData,  // pointer to value data
           sizeof(DWORD)))    // length of value data
   {
      printf("Could not set the supported types.");
      RegCloseKey(hk);
      return 0;
   }

   // Set the category message file and number of categories.
   if (RegSetValueEx(hk,              // subkey handle
           L"CategoryMessageFile",     // value name
           0,                         // must be zero
           REG_EXPAND_SZ,             // value type
           (LPBYTE) dllName,          // pointer to value data
           (DWORD) (lstrlen(dllName)+1)*sizeof(TCHAR))) // data size
   {
      printf("Could not set the category message file.");
      RegCloseKey(hk);
      return 0;
   }

   if (RegSetValueEx(hk,            // subkey handle
           L"CategoryCount",         // value name
           0,                       // must be zero
           REG_DWORD,               // value type
           (LPBYTE) &dwCategoryNum, // pointer to value data
           sizeof(DWORD)))          // length of value data
   {
      printf("Could not set the category count.");
      RegCloseKey(hk);
      return 0;
   }
   RegCloseKey(hk);
   return 1;
}
******************************
After you have added a source name to the registry, use the RegisterEventSource function to get a handle to the Application event log. The following code example obtains the handle and then adds an error event to the log using the ReportEvent function.
*************ReportAnEvent.cpp*************
#include <stdafx.h>
#include <windows.h>
#include "sample.h"
void __cdecl wmain(int argc, LPWSTR *argv)
{
    wchar_t *sourceName = L"SampleEventSourceName";  // The event source name.
    DWORD dwEventID = MSG_BAD_COMMAND;               // The event identifier.
    WORD cInserts = 1;                               // The count of insert strings.
    LPCWSTR szMsg = L"insertString";                 // The insert strings.
    HANDLE h;
    // Get a handle to the event log.
    h = RegisterEventSource(NULL,  // Use local computer.
            sourceName);           // Event source name.
    if (h == NULL)
    {
        printf("Cannot register the event source.");
        return;
    }
    // Report the event.

    if (!ReportEvent(h,           // Event log handle.
            EVENTLOG_ERROR_TYPE,  // Event type.
            0,                    // Event category.  
            dwEventID,            // Event identifier.
            NULL,                 // No user security identifier.
            cInserts,             // Number of substitution strings.
            0,                    // No data.
            &szMsg,               // Pointer to strings.
            NULL))                // No data.
    {
        printf("Cannot report the event.");
    }

    DeregisterEventSource(h);
    return;
}

**********ReportEvent Function***********
BOOL ReportEvent(
  __in  HANDLE hEventLog,
  __in  WORD wType,
  __in  WORD wCategory,
  __in  DWORD dwEventID,
  __in  PSID lpUserSid,
  __in  WORD wNumStrings,
  __in  DWORD dwDataSize,
  __in  LPCTSTR *lpStrings,
  __in  LPVOID lpRawData
);
Parameters
hEventLog [in]
A handle to the event log. This handle is returned by the RegisterEventSource function.
As of Windows XP with SP2, this parameter cannot be a handle to the Security log. To write an event to the Security log, use the AuthzReportSecurityEvent function.
wType [in]
The type of event to be logged. This parameter can be one of the following values.
Value Meaning
EVENTLOG_SUCCESS
0x0000
Information event

EVENTLOG_AUDIT_FAILURE
0x0010
Failure Audit event

EVENTLOG_AUDIT_SUCCESS
0x0008
Success Audit event

EVENTLOG_ERROR_TYPE
0x0001
Error event

EVENTLOG_INFORMATION_TYPE
0x0004
Information event

EVENTLOG_WARNING_TYPE
0x0002
Warning event

For more information about event types, see Event Types.
wCategory [in]
The event category. This is source-specific information; the category can have any value. For more information, see Event Categories.
dwEventID [in]
The event identifier. The event identifier specifies the entry in the message file associated with the event source. For more information, see Event Identifiers.
lpUserSid [in]
A pointer to the current user's security identifier. This parameter can be NULL if the security identifier is not required.
wNumStrings [in]
The number of insert strings in the array pointed to by the lpStrings parameter. A value of zero indicates that no strings are present.
dwDataSize [in]
The number of bytes of event-specific raw (binary) data to write to the log. If this parameter is zero, no event-specific data is present.
lpStrings [in]
A pointer to a buffer containing an array of null-terminated strings that are merged into the message before Event Viewer displays the string to the user. This parameter must be a valid pointer (or NULL), even if wNumStrings is zero. Each string has a limit of 32K characters.
lpRawData [in]
A pointer to the buffer containing the binary data. This parameter must be a valid pointer (or NULL), even if the dwDataSize parameter is zero.
Return Value
If the function succeeds, the return value is nonzero, indicating that the entry was written to the log.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Remarks
This function is used to log an event. The entry is written to the end of the configured log for the source identified by the hEventLog parameter. The ReportEvent function adds the time, the entry's length, and the offsets before storing the entry in the log. To enable the function to add the username, you must supply the user's SID in the lpUserSid parameter.
Note that there is no way to log a string that contains %n, where n is an integer value. This syntax is used in IPv6 addresses, so it is a problem to log an event message that contains an IPv6 address. For example, if the message text contains %1, the event viewer treats it as an insertion string.
posted @ 2010-01-18 17:05  Blue`  阅读(722)  评论(0编辑  收藏  举报