Windows日志服务
修改注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog此项下是事件查看器里面所有的事件日志,XP系统默认有三个,Application,System,Security。可以添加一个项作为新的事件日志,也可以直接建在系统默认的Application下。事件日志的子项叫事件源。
假设新建一个123456事件日志,在该事件源下创建一个SampleEventSource事件源。
至于怎么操作注册表此处就不讨论了
事件源的项下需要添加几个值:
CategoryCount | 自定义分类个数 | REG_DWORD | 0x00000003 |
CategoryMessageFile | 类型消息文件 | REG_SZ | |
EventMessageFile | 事件消息文件 | REG_SZ | |
ParameterMessageFile | 参数消息文件 | REG_SZ | |
TypesSupported | 支持事件类型 | REG_DWORD | 0x00000007 |
事件类型包括
#define EVENTLOG_SUCCESS 0x0000
#define EVENTLOG_ERROR_TYPE 0x0001
#define EVENTLOG_WARNING_TYPE 0x0002
#define EVENTLOG_INFORMATION_TYPE 0x0004
#define EVENTLOG_AUDIT_SUCCESS 0x0008
#define EVENTLOG_AUDIT_FAILURE 0x0010
TypesSupported的值等于所需支持的每个值的和,0x001f全部包括
中间三项需要有消息文件(MessageFile)提供,下面介绍如何生成MessageFile。
生成MessageFile
VS有一个工具,叫MessageCompiler(MC.exe),是用来生成MessageFile的,一般MessageFile都是dll,我们这里也生成dll。
首先编写MC文件,用txt编写,然后将结尾改成.mc即可。
注释
MC文件的注释前需要加一个分号‘;’,然后再加‘//’或者‘/*’。多行注释需要每行前面都加分号。
例如:
;//Thisisasingle-linecomment.
;/*Thisisablockcomment.
;Itspansmultiplelines.
;*/
头部声明部分
头部定义了一些类型名,语言和ID号类型的信息。
MessageIdTypedef=type
定义ID号的类型,如WORD,DWORD等。
在MC生成的.h文件中会看到类似#define name ((type)0xnnnnnnnn)的定义。
SeverityNames=(name=number[:name])
定义消息级别,默认的消息级别是
SeverityNames=(Success=0x0 Informational=0x1 Warning=0x2 Error=0x3)
FacilityNames=(name=number[:name])
定义设备名称,默认的设备名称是
FacilityNames=(System=0x0FF Application=0xFFF)
LanguageNames=(name=number:filename)
定义语言名称,即消息使用的语言,MC会生成一个Bin文件。
OutputBase=number
消息ID号的进制,只能选10或者16进制。
消息定义部分
顾名思义,定义消息的地方。
MessageId=[number|+number]
消息的ID号,必须为16进制,例如MessageId=0x100
Severity= name
消息级别,声明中定义的,例如Severity=Success
Facility= name
设备名称,声明中定义的,例如Facility=Application
SymbolicName= name
.h文件中的宏定义名称,例如SymbolicName=MSG_ERROR
OutputBase={number}
同头部定义
Language= name
语言选择,例如Language=English
messagetext
消息文本信息,非英语需要<>括起来
.
结束符号
Messagetext中会用到一些格式符号:
%n 输入的占位符,可以从1到99
%0 结束符
%n %r 换行
%b 空格
%%messageid 引入参数
编译连接
编辑一个MessageFile.mc放在VS根目录下的VC文件夹,也可放在外边操作的时候加目录。
在VS命令提示中执行如下三部完成编译连接全过程:
mcMessageFile.mc 生成.h.rc.bin文件
rcMessageFile.rc 生成.res文件
link–dll–noentryMessageFile.res 生成.dll文件
生成的dll文件路径就可以添加到前面提到的注册表值,可以把类型消息和参数放在一个dll中也可以分别放在三个dll中。
生成的.h文件可以用于使用消息文件的工程包含,使用其中的宏定义。
事件操作
提交一个事件
简单的操作涉及三个API函数:
RegisterEventSource 注册事件源,获取事件日志的句柄
函数原型:
HANDLERegisterEventSource(
LPCTSTRlpUNCServerName,
LPCTSTRlpSourceName
);
LPCTSTRlpUNCServerName, 机器名称,如果是本机则为NULL
LPCTSTRlpSourceName 事件源名称
ReportEvent 提交一个事件
函数原型:
BOOLReportEvent(
HANDLEhEventLog,
WORDwType,
WORDwCategory,
DWORDdwEventID,
PSIDlpUserSid,
WORDwNumStrings,
DWORDdwDataSize,
LPCTSTR*lpStrings,
LPVOIDlpRawData
);
HANDLEhEventLog, 上个函数获得的句柄
WORDwType, 事件类型
可选的事件类型如下:
EVENTLOG_SUCCESS 信息
EVENTLOG_ERROR_TYPE 错误
EVENTLOG_WARNING_TYPE 警告
EVENTLOG_INFORMATION_TYPE 信息
EVENTLOG_AUDIT_SUCCESS 审核成果
EVENTLOG_AUDIT_FAILURE 审核失败
WORDwCategory, 消息文件中定义的分类
DWORDdwEventID, 消息文件中定义的信息
PSIDlpUserSid, 用户SID
WORDwNumStrings, 输入的字符串个数
DWORDdwDataSize, 输入的数据大小
LPCTSTR*lpStrings, 输入的字符串
LPVOIDlpRawData 输入的数据
DeregisterEventSource 注销事件源
函数原型:
BOOLDeregisterEventSource(
HANDLEhEventLog
);
HANDLEhEventLog 事件日志的句柄
获取SID
此处不深究给大家一段代码:
HANDLEhProcess=GetCurrentProcess();
HANDLEhToken;
OpenProcessToken(hProcess,TOKEN_QUERY,&hToken);
DWORDdwTemp=0;
chartagTokenInfoBuf[256]={0};
PTOKEN_USERtagTokenInfo=(PTOKEN_USER)tagTokenInfoBuf;
GetTokenInformation(hToken,TokenUser,tagTokenInfoBuf,sizeof(tagTokenInfoBuf),
&dwTemp));
CloseHandle(hToken);
CloseHandle(hProcess);
tagTokenInfo里面有当前进程的令牌信息,包括PSID。
代码示例
.mc文件
; /*--------------------------------------------------------
; HEADER SECTION
;*/
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
)
;
;
OutputBase=16
;
;/* ------------------------------------------------------------------
; MESSAGE DEFINITION SECTION
;*/
MessageIdTypedef=WORD
MessageId=0x1
SymbolicName=CAT_1
Language=English
Category 1
.
MessageId=0x2
SymbolicName=CAT_2
Language=English
Category 2
.
MessageId=0x3
SymbolicName=CAT_3
Language=English
Category 3
.
MessageIdTypedef=DWORD
MessageId=+0x001
Severity=Error
Facility=System
SymbolicName=MSG_COMMAND_ERR
Language=English
The command is incorrect.
.
MessageId=0x101
Severity=Success
Facility=System
SymbolicName=MSG_STRIKE_ANY_KEY
Language=English
Press any key to continue . . . %0
.
MessageId=0x102
Severity=Error
Facility=System
SymbolicName=MSG_FILE_BAD_CONTENTS
Language=English
File %1 contains %2, which is in error
.
MessageId=0x103
Severity=Warning
Facility=System
SymbolicName=MSG_RETRYS
Language=English
There have been %1 retrys with %2 success!Disconnect from
the server and retry later.
.
MessageId=0x104
Severity=Informational
Facility=System
SymbolicName=MSG_INSERT_DISK
Language=English
Insert %%1000 in %%1001 and hit any key whenready...
.
;/* Insert string parameters */
;
MessageId=1000
Severity=Success
Facility=System
SymbolicName=DISK
Language=English
disk%0
.
MessageId=1001
Severity=Success
Facility=System
SymbolicName=DRIVE
Language=English
drive%0
.
.mc生成的.h文件
/*--------------------------------------------------------
HEADERSECTION
*/
/*------------------------------------------------------------------
MESSAGEDEFINITION SECTION
*/
//
// Valuesare 32 bit values laid out as follows:
//
// 3 3 2 22 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 87 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+-+-+-----------------------+-------------------------------+
// |Sev|C|R| Facility | Code |
// +---+-+-+-----------------------+-------------------------------+
//
// where
//
// Sev -is the severity code
//
// 00 - Success
// 01 - Informational
// 10 - Warning
// 11 - Error
//
// C -is the Customer code flag
//
// R -is a reserved bit
//
// Facility - is the facility code
//
// Code- is the facility's status code
//
//
// 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: CAT_1
//
// MessageText:
//
// Category 1
//
#define CAT_1 ((WORD)0x00000001L)
//
// MessageId: CAT_2
//
// MessageText:
//
// Category 2
//
#define CAT_2 ((WORD)0x00000002L)
//
// MessageId: CAT_3
//
// MessageText:
//
// Category 3
//
#define CAT_3 ((WORD)0x00000003L)
//
// MessageId: MSG_COMMAND_ERR
//
// MessageText:
//
// The command is incorrect.
//
#define MSG_COMMAND_ERR ((DWORD)0xC0000001L)
//
// MessageId: MSG_STRIKE_ANY_KEY
//
// MessageText:
//
// Press any key to continue . . . %0
//
#define MSG_STRIKE_ANY_KEY ((DWORD)0x00000101L)
//
// MessageId: MSG_FILE_BAD_CONTENTS
//
// MessageText:
//
// File %1 contains %2, which is in error
//
#define MSG_FILE_BAD_CONTENTS ((DWORD)0xC0000102L)
//
// MessageId: MSG_RETRYS
//
// MessageText:
//
// There have been %1 retrys with %2 success!Disconnect from
// the server and retry later.
//
#define MSG_RETRYS ((DWORD)0x80000103L)
//
// MessageId: MSG_INSERT_DISK
//
// MessageText:
//
// Insert %%1000 in %%1001 and hit any key whenready...
//
#define MSG_INSERT_DISK ((DWORD)0x40000104L)
/* Insert string parameters */
//
// MessageId: DISK
//
// MessageText:
//
// disk%0
//
#define DISK ((DWORD)0x000003E8L)
//
// MessageId: DRIVE
//
// MessageText:
//
// drive%0
//
#define DRIVE ((DWORD)0x000003E9L)
事件提交代码段
一个写事件的函数
bool WriteEventLog(LPCTSTR szSourceName =_T(""), WORD wEventType = NULL, LPCTSTR szEventMsg)
{
HANDLEhEventLog;
boolbSuccesful;
boolbReturn = true;
//-------------------------------------------------------------------------
if(_T("")== szSourceName)
{
szSourceName= AfxGetApp()->m_pszExeName;
}
LPWSTRpBadCommand = L"1234567890";
DWORDdwEventDataSize = (wcslen(pBadCommand) + 1) * sizeof(WCHAR);
hEventLog= RegisterEventSource(NULL,szSourceName);
if(NULL== hEventLog)
{
AfxMessageBox(_T("RegisterEventSourceFailed"));
returnfalse;
}
LPWSTRlps[2];
lps[0]= L"123";
lps[1]= L"321";
HANDLEhProcess = GetCurrentProcess();
if(!hProcess)
{
returnfalse;
}
HANDLEhToken;
if(!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken) || !hToken ){
CloseHandle(hProcess);
returnfalse;
}
DWORDdwTemp = 0;
chartagTokenInfoBuf[256] = {0};
PTOKEN_USERtagTokenInfo = (PTOKEN_USER)tagTokenInfoBuf;
if(!GetTokenInformation( hToken, TokenUser, tagTokenInfoBuf,
sizeof(tagTokenInfoBuf), &dwTemp ) )
{
CloseHandle(hToken);
CloseHandle(hProcess);
}
bSuccesful= ReportEvent(hEventLog,
wEventType,
0x00000002L,
0xC0000001L,
tagTokenInfo->User.Sid,
2,
dwEventDataSize,
(LPCWSTR*)lps,
pBadCommand);
if(false==bSuccesful)
{
AfxMessageBox(_T("ReportEventFailed"));
bReturn=false;
}
DeregisterEventSource(hEventLog);
returnbReturn;
};
转载请注明出处点击打开链接