/*
文本就命名为:IoAllocateErrorLogEntry.C吧!
made by correy
made at 2013.05.07
QQ:112426112
Email:kouleguan at hotmail dot com
Homepage:http://correy.webs.com
刚开始,我以为必须有mc文件才能生成时间日志呢?
其实不需要mc文件也可以生成日志。
不过需要mc文件生成时间日志也不难,很简单,source里面加入一行代码就可以编译了。
不过,还得编写mc文件。
不过编写mc文件也不难。
不过这很麻烦,所以我就不用mc文件了。
如果自己的驱动定义自己的错误码:可以修改:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\System\DriverName下面的值
EventMessageFile (REG_EXPAND_SZ) 和 TypesSupported (REG_DWORD)
刚开始我还以为是生成记录需要添加这呢!
参考资料:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff560866(v=vs.85).aspx
http://blog.csdn.net/peterwtu/article/details/8179674
http://driverentry.com.br/en/blog/?p=324
http://driverentry.com.br/en/blog/?p=348
http://www.osronline.com/showThread.cfm?link=28746
http://hi.baidu.com/wesley0312/item/a35737511c3e13dbd58bac51
*/
#include <ntddk.h>
#define _In_
#define _Inout_
#define _Inout_opt_
DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
}
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PVOID p = 0;
PIO_ERROR_LOG_PACKET pioelp;
KdBreakPoint();//#define KdBreakPoint() DbgBreakPoint()
DriverObject->DriverUnload = Unload;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//方法一:
p = IoAllocateErrorLogEntry(
DriverObject, //也可以:Pointer to a device object representing the device on which an I/O error occurred,
sizeof(IO_ERROR_LOG_PACKET) //sizeof(IO_ERROR_LOG_PACKET) + size of the DumpData member + combined size of any driver-supplied insertion strings.
);
//Drivers must not treat IoAllocateErrorLogEntry returning NULL as a fatal error.
//The driver must continue to function normally, whether or not it can log errors.
if (p == NULL) {
return status;
}
pioelp = p;
RtlZeroMemory(p, sizeof(IO_ERROR_LOG_PACKET));
pioelp->ErrorCode = 9;//查看日志的时候显示的是的:时间id == 9
//IoWriteErrorLogEntry frees the error log entry.
//Drivers must not call IoFreeErrorLogEntry on a log entry that they have already passed to IoWriteErrorLogEntry.
IoWriteErrorLogEntry(p);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//方法二:复杂一点。
p = IoAllocateErrorLogEntry(DriverObject, sizeof(IO_ERROR_LOG_PACKET) + sizeof(ULONG));
if (p == NULL) {
return status;
}
pioelp = p;
RtlZeroMemory(p, sizeof(IO_ERROR_LOG_PACKET));
pioelp->ErrorCode = 9;//查看日志的时候显示的是的:时间id == 9
pioelp->DumpData[0] = 0x12345678;//不过这个也能显示,要在数据里面查找。
pioelp->DumpDataSize = sizeof(ULONG);
IoWriteErrorLogEntry(p);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//方法三:再复杂一点,包含的信息也多一点。
{
UNICODE_STRING usNtStatus;
ANSI_STRING asNtStatus;
UCHAR ucFinalSize;
PWSTR pwzTarget;
PIO_ERROR_LOG_PACKET pLogPacket;
wchar_t ErroeMessage[] = L"made by correy"; //这个信息显示在前面。
RtlInitAnsiString(&asNtStatus, "QQ:112426112"); //这个信息显示在后面。
RtlAnsiStringToUnicodeString(&usNtStatus, &asNtStatus, TRUE);
ucFinalSize = sizeof(IO_ERROR_LOG_PACKET) + sizeof(ULONG) + usNtStatus.Length + sizeof(WCHAR) + (wcslen(ErroeMessage) + 1) * sizeof(WCHAR);
pLogPacket = IoAllocateErrorLogEntry(DriverObject, ucFinalSize);
RtlZeroMemory(pLogPacket, sizeof(IO_ERROR_LOG_PACKET));
//A variable-size array that can be used to store driver-specific binary data,
//Drivers must specify the size, in bytes, of the array in the DumpDataSize member of this structure.
pLogPacket->DumpData[0] = 0x12345678;//感觉这个显示的没啥用。
//Indicates the size, in bytes, of the variable-length DumpData member of this structure.
//The specified value must be a multiple of sizeof(ULONG).
pLogPacket->DumpDataSize = sizeof(ULONG);//估计是DumpData的个数 * sizeof(ULONG)
//Indicates the offset, in bytes, from the beginning of the structure, at which any driver-supplied insertion string data begins.
//Normally this will be sizeof(IO_ERROR_LOG_PACKET) plus the value of the DumpDataSize member.
//If there are no driver-supplied insertion strings, StringOffset can be zero.
pLogPacket->StringOffset = sizeof(IO_ERROR_LOG_PACKET) + pLogPacket->DumpDataSize;
//Indicates the number of insertion strings the driver will supply with this error log entry.
//Drivers set this value to zero for errors that need no insertion strings.
//The Event Viewer uses these strings to fill in the "%2" through "%n" entries in the string template for this error code.
//The null-terminated Unicode strings themselves follow the IO_ERROR_LOG_PACKET structure in memory.
pLogPacket->NumberOfStrings = 2;//有两个字符串。
//复制ErroeMessage信息
pwzTarget = (PWSTR) ((PCHAR)pLogPacket + pLogPacket->StringOffset);
wcscpy(pwzTarget, ErroeMessage);//追加数据。追加是最好的用词。 The strcpy function copies strSource, including the terminating null character
//复制usNtStatus信息
pwzTarget += wcslen(ErroeMessage) + 1;//这个空一个0.就是跳过一个0.
wcsncpy(pwzTarget, usNtStatus.Buffer, usNtStatus.Length / sizeof(WCHAR));//追加数据。感觉没有比较用字符串结构:UNICODE_STRING和ANSI_STRING
pwzTarget += usNtStatus.Length / sizeof(WCHAR);
*pwzTarget = 0;//结尾置零。
//Specifies the type of error. The Event Viewer uses the error code to determine which string to display as the Description value for the error.
//The Event Viewer takes the string template for the error supplied in the driver's message catalog,
//replaces "%1" in the template with the name of the driver's device object,
//and replaces "%2" through "%n" with the insertion strings supplied with the error log entry.
//ErrorCode is a system-defined or driver-defined constant;
pLogPacket->ErrorCode = 9;//如果赋值为0x12345678,得到的结果为: 22136 == 0x5678.注意这个结构的这个成员的大小。
//还有更多的参数没有填写。
IoWriteErrorLogEntry(pLogPacket);
RtlFreeUnicodeString(&usNtStatus);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return status;//STATUS_SUCCESS
}
没有评论:
发表评论