读取 Windows 事件日志 - 获取Windows 的最近的开机时间

最近踩过的一个坑,获取Windows 的最近的开机时间,不用说记代码吧:

#include "stdafx.h"
#include "Windows.h"
#include "tchar.h"
#include "atltime.h"
#include "time.h"

#define SystemTimeInformation 3

#define RECORDCOUNT    100

using namespace std;

typedef long(__stdcall *fnNtQuerySystemInformation)(
	IN  UINT SystemInformationClass,
	OUT PVOID SystemInformation,
	IN  ULONG SystemInformationLength,
	OUT PULONG ReturnLength OPTIONAL);

fnNtQuerySystemInformation NtQuerySystemInformation = NULL;

typedef struct {
	LARGE_INTEGER liKeBootTime;
	LARGE_INTEGER liKeSystemTime;
	LARGE_INTEGER liExpTimeZoneBias;
	ULONG uCurrentTimeZoneId;
	DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;



string GetBootTime()
{
	NtQuerySystemInformation = (fnNtQuerySystemInformation)GetProcAddress(LoadLibrary("ntdll.dll"),
		"NtQuerySystemInformation");
	if (NtQuerySystemInformation == NULL)
	{
		return "";
	}

	LONG status;
	SYSTEM_TIME_INFORMATION sti;
	status = NtQuerySystemInformation(SystemTimeInformation, &sti, sizeof(sti), 0);
	if (NO_ERROR != status)
	{
		return "";
	}

	FILETIME ft;
	SYSTEMTIME st;
	memcpy(&ft, &sti.liKeBootTime, sizeof(ft));
	FileTimeToLocalFileTime(&ft, &ft);
	FileTimeToSystemTime(&ft, &st);

	char timeBuf[MAX_PATH] = { 0 };
	sprintf(timeBuf, "%04d-%02d-%02d %02d:%02d:%02d\n", st.wYear, st.wMonth, st.wDay,
		st.wHour, st.wMinute, st.wSecond);

	printf("开机时间: %s", timeBuf );

	return timeBuf;
}

UINT64 GetBootRunTime()
{
	int s = GetTickCount() / 1000;

	int second = s % 60;
	int minute = s / 60 % 60;
	int hour = s / 60 / 60;

	UINT64 minutes = hour * 60 + minute;

	printf("距此时长: %d Minute\n", minutes);

	return minutes;
}

//读取 Windows 事件日志
void ReadWindowsEventLog()
{

	HANDLE h;
	EVENTLOGRECORD* pevlr;
	TCHAR bBuffer[4096] = { 0 };

	DWORD dwRead, dwNeeded, cRecords, dwThisRecord = 0;

	/*
	Windows 日志:
	应用程序 "Application"  安全 "Security"  设置 "setup"  系统 "System"
	*/
	h = OpenEventLog(NULL,"System");
	if (h == NULL)
	{
		printf("Could not open the System event log.");

		return;
	}

	pevlr = (EVENTLOGRECORD*)&bBuffer;

	int count = 0;


	printf("\n最近 %d 次开机记录:\n"  , RECORDCOUNT);

	while (ReadEventLog(h,
		EVENTLOG_SEQUENTIAL_READ |
		EVENTLOG_BACKWARDS_READ,
		0,
		pevlr,
		4096,
		&dwRead,
		&dwNeeded))
	{
		bool find = false;

		while (dwRead > 0)
		{
			int EventID = (short)pevlr->EventID;

			if ( EventID == 6005 )
			{
				CTime time(pevlr->TimeWritten);
				time_t tmt = time.GetTime();
				tm logtime;
				localtime_s(&logtime, &tmt);

				char datatime[25] = { 0 };
				sprintf(datatime, "%d-%02d-%02d %02d:%02d:%02d", logtime.tm_year + 1900, logtime.tm_mon + 1, logtime.tm_mday, logtime.tm_hour, logtime.tm_min, logtime.tm_sec);

				printf("%02d %s\n", dwThisRecord++,  datatime);
				//printf("%02d  Event ID: %d %s ", dwThisRecord++, (short)pevlr->EventID, datatime);
				//printf("EventType: %d Source: %s\n", pevlr->EventType, (LPCTSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD)));

				find = true;
				count++;

				break;
			}

			dwRead -= pevlr->Length;
			pevlr = (EVENTLOGRECORD*)((LPBYTE)pevlr + pevlr->Length);
		}

		pevlr = (EVENTLOGRECORD*)&bBuffer;

		if (count >= RECORDCOUNT)/*(find)*/
		{
			break;
		}
	}

	CloseEventLog(h);
}

int main()
{
	GetBootTime();
	GetBootRunTime();
	ReadWindowsEventLog();

	getchar();

    return 0;
}