获取开机时间并不像应用层简单的调用一个 API 就搞定了,在内核需要 GetTickCount
获取一个滴答数,然后把这个滴答数转为毫秒,再进行运算即可得出开的时间。以下是获取开机多少分钟和当前系统时间的结果,代码在下方:
tick count = 2 minutes.
time = 2016-04-01 00:39:26
实现代码
代码语言:javascript复制#include <ntddk.h>
#include <ntstrsafe.h>
// 获取系统开机一共经历过的时间(毫秒)
void MyGetTickCount(PULONG msec)
{
LARGE_INTEGER tick_count;
ULONG myinc = KeQueryTimeIncrement();
KeQueryTickCount(&tick_count);
tick_count.QuadPart *= myinc;
tick_count.QuadPart /= 10000;
*msec = tick_count.LowPart;
}
PWCHAR MyCurTimeStr()
{
LARGE_INTEGER snow, now;
TIME_FIELDS now_fields;
static WCHAR time_str[32] = { 0 };
// 获取格林威治时间
KeQuerySystemTime(&snow);
// 转为本地时间
ExSystemTimeToLocalTime(&snow, &now);
// 转为时间的结构体
RtlTimeToTimeFields(&now, &now_fields);
// 将结构体信息拼接起来
RtlStringCchPrintfW(
time_str,
32,
L"M-d-d d:d:d",
now_fields.Year, now_fields.Month, now_fields.Day,
now_fields.Hour, now_fields.Minute, now_fields.Second);
return time_str;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
ULONG msec;
UNICODE_STRING uTime;
PWCHAR time_str;
MyGetTickCount(&msec);
KdPrint(("tick count = %ld minutes.rn", msec / 1000 / 60));
time_str = MyCurTimeStr();
RtlInitEmptyUnicodeString(&uTime, time_str, wcslen(time_str) * sizeof(WCHAR));
uTime.Length = wcslen(time_str) * sizeof(WCHAR);
KdPrint(("time = %wZrn", &uTime));
return STATUS_UNSUCCESSFUL;
}