Windows驱动编程基础教程 第八部分
本文作者是楚狂人,有问题请联系QQ16191935,msn walled_river@hotmail.com
Windows驱动编程基础教程(5.1-5.2)
5.1 获得当前滴答数
在编程中,获得当前的系统日期和时间,或者是获得一个从启动开始的毫秒数,是很常见的需求。获得系统日期和时间往往是为了写日志。获得启动毫秒数很适合用来做一个随机数的种子。有时也使用时间相关的函数来寻找程序的性能瓶颈。
熟悉Win32应用程序开发的读者会知道有一个函数GetTickCount(),这个函数返回系统自启动之后经历的毫秒数。在驱动开发中有一个对应的函数KeQueryTickCount(),这个函数的原型如下:
- VOID KeQueryTickCount(
- OUT PLARGE_INTEGER TickCount
- );
遗憾的是,被返回到TickCount中的并不是一个简单的毫秒数。这是一个“滴答”数。但是一个“滴答”到底为多长的时间,在不同的硬件环境下可能有所不同。为此,必须结合另一个函数使用。下面这个函数获得一个“滴答”的具体的100纳秒数。
- ULONG KeQueryTimeIncrement();
得知以上的关系之后,下面的代码可以求得实际的毫秒数:
- 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;
- }
这不是一个简单的过程。不过所幸的是,现在有代码可以拷贝了。
5.2 获得当前系统时间
接下来的一个需求是得到当前的可以供人类理解的时间。包括年、月、日、时、分、秒这些要素。在驱动中不能使用诸如CTime之类的MFC类。不过与之对应的有TIME_FIELDS,这个结构中含有对应的时间要素。
KeQuerySystemTime()得到当前时间。但是得到的并不是当地时间,而是一个格林威治时间。之后请使用ExSystemTimeToLocalTime()转换可以当地时间。这两个函数的原型如下:
- VOID KeQuerySystemTime(
- OUT PLARGE_INTEGER CurrentTime
- );
- VOID ExSystemTimeToLocalTime(
- IN PLARGE_INTEGER SystemTime,
- OUT PLARGE_INTEGER LocalTime
- );
这两个函数使用的“时间”都是长长整型数据结构。这不是人类可以阅读的。必须通过函数RtlTimeToTimeFields转换为TIME_FIELDS。这个函数原型如下:
- VOID RtlTimeToTimeFields(
- IN PLARGE_INTEGER Time,
- IN PTIME_FIELDS TimeFields
- );
读者需要实际应用一下来加深印象。下面写出一个函数:这个函数返回一个字符串。这个字符串写出当前的年、月、日、时、分、秒,这些数字之间用“-”号隔开。这是一个很有用的函数。而且同时用到上面三个函数,此外,请读者回忆前面关于字符串的打印的相关章节。
- 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*2,
- L“%4d-%2d-%2d %2d-%2d-%2d”,
- now_fields.Year,now_fields.Month,now_fields.Day,
- now_fields.Hour,now_fields.Minute,now_fields.Second);
- return time_str;
- }
请注意time_str是静态变量。这使得这个函数不具备多线程安全性。请读者考虑一下,如何保证多个线程同时调用这个函数的时候,不出现冲突?