2

我正在修改现有的 Windows 内核设备驱动程序,我需要在其中捕获时间戳。我打算使用 time.h 库并调用 clock() 函数来获取它,但是在 Windows Visual Studio 下,链接失败。所以我把它当作我需要在驱动程序库中工作的一种手段。

我找到了以下函数,KeInitializeTimer 和 KeSetTimerEx,但如果我打算设置一个计时器并唤醒它,则使用这些函数。我真正需要的是能给我一个时间戳的东西。

有任何想法吗?

4

1 回答 1

7

我正在用答案更新我的问题,以便其他人从我的发现中受益。

要获取时间戳,您可以使用 KeQueryTickCount()。该例程将为您提供自系统启动以来发生的间隔中断的计数。但是,如果您需要找出自上次捕获的时间戳以来已经过去了 X 时间量,您还需要查询您的系统以确定每个间隔时钟中断所花费的时间。

ULONG KeQueryTimeIncrement() 为您提供 100 纳秒单位的数量。

例子:

PLARGE_INTEGER timeStamp;

KeQueryTickCount(&timeStamp);

请注意 PLARGE_INTEGER 的定义如下:

#if defined(MIDL_PASS)
typedef struct _LARGE_INTEGER {
#else // MIDL_PASS
typedef union _LARGE_INTEGER {
    struct {
        ULONG LowPart;
        LONG HighPart;
    } DUMMYSTRUCTNAME;
    struct {
        ULONG LowPart;
        LONG HighPart;
    } u;
#endif //MIDL_PASS
    LONGLONG QuadPart;
} LARGE_INTEGER;

因此,假设您想查看自上次获取时间戳后是否经过了 30 秒,您可以执行以下操作:

ULONG tickIncrement, ticks;
LARGE_INTEGER waitTillTimeStamp;
tickIncrement = KeQueryTimeIncrement();

// 1 秒是 1,000,000,000 纳秒,但是,因为 KeQueryTimeIncrement 以 // 100ns 为增量,除以它,你的常数就是 10,000,000

ticks = ((30 * 10,000,000) / tickIncrement);
KeQueryTickCount(&waitTillTimeStamp);
waitTillTimeStamp.QuadPart += ticks;

<.....Some code and time passage....>
KeQueryTickCount(&currTimeStamp);


if (waitTillTimeStamp.QuadPart < currTimeStamp.QuadPart) {
    <...Do whatever...>
}

另一个帮助你理解这一点的例子,如果你想把你得到的时间戳转换成一个时间值,比如毫秒。

LARGE_INTEGER mSec, currTimeStamp;
ULONG timeIncrement;

timeIncrement = KeQueryTimeIncrement();


KeQueryTickCount(&currTimeStamp);

// 1 millisecond is 1,000,000 nano seconds, but remember divide by 100 to account for 
// KeQueryTickCount granularity.
mSec.QuadPart = (currTimeStamp.QuadPart * timeIncrement) / 10000;

请记住,此示例是出于演示目的,mSec 不是当前时间(以毫秒为单位)。根据上面使用的 API,它只是系统启动后经过的毫秒数。

您也可以使用 GetTickCount(),但这会返回一个 DWORD,因此只能为您提供自系统启动最多 49.7 天以来的毫秒数。

于 2012-10-22T17:29:57.713 回答