• 64位内核第十四讲,获取系统滴答数与日期时间


    一丶简介

    在ring3层中.我们会使用 ** GetTickCount** 这个函数,返回系统自启动到现在所经历的毫秒数.在驱动中也有一个对应的函数 ** KeQueryTickCount**

    二丶 获取系统滴答数,并进行转换.

    2.1 获取滴答数与毫秒数

    上面说了有对应函数获取. 但是 这个函数返回的 TickCount 并不是简单的毫秒数,所以必须结合 ** KeQueryTimeinCrement **函数来求得具体的纳秒数.

    如下代码.求得实际的毫秒数. 两个函数结合使用.

    代码如下;

    
    void MyGetTickCount(PULONG  msec) //进行传出
    {
    	LARGE_INTEGER la;
    	ULONG MyInc;
    	MyInc = KeQueryTimeIncrement(); //返回滴答数
    
    	//下方 KeQueryTickCount 的宏的原型.
    
    	KeQueryTickCount(&la);
    	
    	la.QuadPart *= MyInc;
    	la.QuadPart /= 10000;
    	
    	*msec = la.LowPart;
    
    }
    

    获得毫秒等是远远不够的.还要获取当前系统的时间

    2.2 获取年月日

    上面的获取是远远不够的. 如果向进一步获取详细信息. 那么驱动中提供了一个结构

    ** TIME_FIELDS ** 这个结构里面提供了相信的信息.

    结构如下:

    
    typedef struct _TIME_FIELDS {
        CSHORT Year;        // range [1601...]
        CSHORT Month;       // range [1..12]
        CSHORT Day;         // range [1..31]
        CSHORT Hour;        // range [0..23]
        CSHORT Minute;      // range [0..59]
        CSHORT Second;      // range [0..59]
        CSHORT Milliseconds;// range [0..999]
        CSHORT Weekday;     // range [0..6] == [Sunday..Saturday]
    } TIME_FIELDS;
    

    想要进行获取.需要三个API函数

    1. ** KeQuerySystemTime ** 得到当前的格林威治时间
    2. ** ExSystemTimeToLocalTime** 将格林威治事件转化为本地时间
    3. ** RtlTimerToTimeFields ** 转化为人们可以阅读的 Time_File类型的事件.

    函数原型:

    Ps 64为下跟32位的函数是一样的.但是64位下会替换为宏.但是不影响你使用.

    VOID
    KeQuerySystemTime (
        _Out_ PLARGE_INTEGER CurrentTime
        );                                   //64位下会替换为宏,没有此函数类型.
    
    
    NTKERNELAPI
    VOID
    ExSystemTimeToLocalTime (
        _In_ PLARGE_INTEGER SystemTime,
        _Out_ PLARGE_INTEGER LocalTime
        );
    
    
    NTSYSAPI
    VOID
    NTAPI
    RtlTimeToTimeFields (
        _In_ PLARGE_INTEGER Time,
        _Out_ PTIME_FIELDS TimeFields
        );
    

    前两个函数的转化得到的都是 PLARGE_INTEGER 类型.并不是人们所能直观看到的.所以利用最后一个函数进行转化即可.

    
    PTCHAR GetTimeYMS()
    {
    	//获取年月日.
    	LARGE_INTEGER SystemTime;
    	LARGE_INTEGER LocalTime;
    	TIME_FIELDS TimeFiled;
    	TCHAR *time_str = ExAllocatePoolWithTag(PagedPool, 32, 0);
    
    	KeQuerySystemTime(&SystemTime);
    	ExSystemTimeToLocalTime(&SystemTime,&LocalTime);
    	RtlTimeToTimeFields(&LocalTime,&TimeFiled);
    #ifdef UNICODE
    #define RtlStringCchPrintf RtlStringCchPrintfW
    #else
    #define RtlStringCchPrintf RtlStringCchPrintfA
    #endif // UNICODE
    
    	RtlStringCchPrintf(
    		time_str,
    		32,
    		TEXT("%4d-%2d-%2d %2d-%2d-%2d"),
    		TimeFiled.Year,
    		TimeFiled.Month,
    		TimeFiled.Day,				//年月日时分秒
    		TimeFiled.Hour,
    		TimeFiled.Minute,
    		TimeFiled.Second);
    	return time_str;
    }
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
    {
    
    
    	
    	
    
    	PTCHAR pTime = NULL;
    	pDriverObj->DriverUnload = DriverUnLoad;
    	
    	pTime = GetTimeYMS();
    
    	
    	DbgPrint("%Ls 
    ", pTime);
    	return STATUS_SUCCESS;
    }
    
    
    
    
  • 相关阅读:
    HttpClient使用
    十九、springboot使用@ControllerAdvice(二)之深入理解
    如何同步删除svn管理的package包目录
    在使用FastJson开发遇到的的坑
    解决tomcat端口被占用:Port 8005 required by Tomcat v7.0 Server at localhost is already in use
    SpringBoot使用Mybatis-Generator
    SpringCloud Gateway入门
    使用Nginx部署静态网站
    SpringBoot使用Jsp
    SpringBoot应用War包形式部署到外部Tomcat
  • 原文地址:https://www.cnblogs.com/iBinary/p/11372686.html
Copyright © 2020-2023  润新知