Windows驱动编程基础教程-谭文-代码整理

Windows驱动编程基础教程-谭文-代码整理

Windows驱动编程基础教程-谭文-代码整理
基本上是教程上原代码照抄,只给代码做了个排列组合,改了一些作者的小笔误
代码全部测试通过,测试环境:WinDDK 7600.16385.0 chk x86 WXP
教程上有很详细非常详细的讲解,偶就偷懒不写注释了
代码中有些应该考虑应该实现的东西偶不会,就省了。。。不会完善,能跑就行。。。

1 字符串使用
2 内存的分配与释放
3 LIST_ENTRY
4 LARGE_INTEGER
5 KSPIN_LOCK
6 文件操作
7 注册表读写
8 时间与定时

未完待续。。。

makefile
#
# DO NOT EDIT THIS FILE
!!!   Edit .\sources.  if  you want to add a  new  source
# file to 
this  component.  This file merely indirects to the real make file
# that 
is  shared by all the driver components of the Windows NT DDK
#

! INCLUDE $(NTMAKEENV)\makefile.def

sources
TARGETNAME = study
TARGETPATH
= OBJ
TARGETTYPE
= DRIVER
SOURCES
=     study.c

1 字符串使用
/*
 *《Windows驱动编程基础教程-谭文》-字符串使用
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

#include
< ntddk.h >
#include
< ntdef.h >

DRIVER_UNLOAD StudyUnload;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();
    
    DriverObject
-> DriverUnload  =  StudyUnload;
    
    
return  STATUS_SUCCESS;
}

VOID StudyUnload(PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING str1;
    UNICODE_STRING dst;
    WCHAR dst_buf[
256 ];
    UNICODE_STRING src 
=  RTL_CONSTANT_STRING(L " source string " );  // Init a UNICODE_STRING
    NTSTATUS status;
    PAGED_CODE();

    DbgPrint(
" Study:Our driver is unloading\r\n " );
    
// Init a UNICODE_STRING
    RtlInitUnicodeString( & str1,L " Init the string str1 " );
    KdPrint((
" Init a UNICODE_STRING:%wZ\r\n " , & str1));

    
// 把dst初始化成拥有缓冲区长度为256的UNICODE_STRING空串
    
// !!! copy 之前一定要先给dst分配空间!!!
    RtlInitEmptyUnicodeString( & dst,dst_buf, 256 * sizeof (WCHAR));
    
// copy a UNICODE_STRING
    RtlCopyUnicodeString( & dst, & src);
    KdPrint((
" Copy a UNICODE_STRING:%wZ\r\n " , & dst));

    
// append a UNICODE_STRING
    status  =  RtlAppendUnicodeToString( & dst,L " |append string. " );
    KdPrint((
" Append a UNICODE_STRING:%wZ\r\n " , & dst));

    
return ;
}

2 内存的分配与释放
/*
 *《Windows驱动编程基础教程-谭文》-内存的分配与释放
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

#include
< ntddk.h >
#include
< ntdef.h >

// 定义一个内存分配标记
#define  MEM_TAG "CG"

DRIVER_UNLOAD StudyUnload;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();
    
    DriverObject
-> DriverUnload  =  StudyUnload;
    
    
return  STATUS_SUCCESS;
}

VOID StudyUnload(PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING dst 
=  { 0 };
    UNICODE_STRING src 
=  RTL_CONSTANT_STRING(L " source string " );
    NTSTATUS status;

    PAGED_CODE();

    
// 根据src的长度,分配空间给dst
    dst.Buffer  =  (PWCHAR)ExAllocatePoolWithTag(NonPagedPool,  // PoolTape
        src.Length,  // NumberOfBytes 
        MEM_TAG);     // Tag
     if (dst.Buffer  ==  NULL){
        status 
=  STATUS_INSUFFICIENT_RESOURCES;
        KdPrint((
" FAIL with ExAllocatePoolWithTag " ));
        
return ;
    }
    dst.Length 
=  dst.MaximumLength  =  src.Length;
    RtlCopyUnicodeString(
& dst, & src);  // return void
    KdPrint(( " Copy a UNICODE_STRING:%wZ\r\n " , & dst));

    ExFreePool(dst.Buffer);
    dst.Buffer 
=  NULL;
    dst.Length 
=  dst.MaximumLength  =   0 ;

    
return ;
}


3 LIST_ENTRY
/*
 *《Windows驱动编程基础教程-谭文》- LIST_ENTRY
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

#include
< ntddk.h >
#include
< ntdef.h >

#define  MEM_TAG "CG"

DRIVER_UNLOAD StudyUnload;

// our list head
LIST_ENTRY my_list_head;

// our list node
typedef  struct  {
    LIST_ENTRY list_entry; 
// simple to put it at the head of the struct
    PFILE_OBJECT file_object;
    UNICODE_STRING file_name;
    
int  file_length;
}MY_FILE_INFOR,
* PMY_FILE_INFOR;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();

    
// Init our list head
    InitializeListHead( & my_list_head);
    
    DriverObject
-> DriverUnload  =  StudyUnload;
    
    
return  STATUS_SUCCESS;
}


// Append a node to list, note that file_name is allocated outside
NTSTATUS StudyAppendNode(
    PFILE_OBJECT file_object,
    UNICODE_STRING file_name,
    
int  file_length)
{
    PMY_FILE_INFOR my_file_infor 
=  (PMY_FILE_INFOR)ExAllocatePoolWithTag(PagedPool, sizeof (MY_FILE_INFOR),MEM_TAG);
    
if (my_file_infor  ==  NULL){
        
return  STATUS_INSUFFICIENT_RESOURCES;
        }

    my_file_infor
-> file_object  =  file_object;
    my_file_infor
-> file_name  =  file_name;
    my_file_infor
-> file_length  =  file_length;

    InsertHeadList(
& my_list_head,     // PLIST_ENTRY  ListHead,
        (PLIST_ENTRY)my_file_infor);     // PLIST_ENTRY  Entry ==my_file_info->list_entry
                                    
// we put the LIST_ENTRY at the head of the struct,so my_file_info==my_file_info->list_entry here

    
return  STATUS_SUCCESS;
}


VOID StudyUnload(PDRIVER_OBJECT DriverObject)
{
    PFILE_OBJECT file_object 
=  NULL;
    UNICODE_STRING file_name 
=  RTL_CONSTANT_STRING(L " c:\\study.txt " );
    UNICODE_STRING file_name2 
=  RTL_CONSTANT_STRING(L " c:\\study2.txt " );
    
int  file_length  =   0x123 ;
    PLIST_ENTRY p;

    StudyAppendNode(file_object,file_name,file_length);
    StudyAppendNode(file_object,file_name2,file_length);

    
for (p  =  my_list_head.Flink; p  !=   & my_list_head.Flink; p  =  p -> Flink){ 
        PMY_FILE_INFOR elem 
=  CONTAINING_RECORD(p,     // Address
            MY_FILE_INFOR,     // Type
            list_entry);     // Field
        KdPrint(( " node of MY_FILE_INFOR list, name: %wZ\n " , & elem -> file_name));
        }
    
    
return ;
}


4 LARGE_INTEGER
/*
 *《Windows驱动编程基础教程-谭文》- LARGE_INTEGER
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

#include
< ntddk.h >
#include
< ntdef.h >

#define  MEM_TAG "CG"

DRIVER_UNLOAD StudyUnload;

// our list head
LIST_ENTRY my_list_head;

// our list node
typedef  struct  {
    LIST_ENTRY list_entry; 
// simple to put it at the head of the struct
    PFILE_OBJECT file_object;
    UNICODE_STRING file_name;
    LARGE_INTEGER file_length;
}MY_FILE_INFOR,
* PMY_FILE_INFOR;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();

    
// Init our list head
    InitializeListHead( & my_list_head);
    
    DriverObject
-> DriverUnload  =  StudyUnload;
    
    
return  STATUS_SUCCESS;
}


// Append a node to list, note that file_name is allocated outside
NTSTATUS StudyAppendNode(
    PFILE_OBJECT file_object,
    UNICODE_STRING file_name,
    LARGE_INTEGER file_length)
{
    PMY_FILE_INFOR my_file_infor 
=  (PMY_FILE_INFOR)ExAllocatePoolWithTag(PagedPool, sizeof (MY_FILE_INFOR),MEM_TAG);
    
if (my_file_infor  ==  NULL){
        
return  STATUS_INSUFFICIENT_RESOURCES;
        }

    my_file_infor
-> file_object  =  file_object;
    my_file_infor
-> file_name  =  file_name;
    my_file_infor
-> file_length  =  file_length;

    InsertHeadList(
& my_list_head,     // PLIST_ENTRY  ListHead,
        (PLIST_ENTRY)my_file_infor);     // PLIST_ENTRY  Entry ==my_file_info->list_entry
                                    
// we put the LIST_ENTRY at the head of the struct,so my_file_info==my_file_info->list_entry here

    
return  STATUS_SUCCESS;
}


VOID StudyUnload(PDRIVER_OBJECT DriverObject)
{
    PFILE_OBJECT file_object 
=  NULL;
    UNICODE_STRING file_name 
=  RTL_CONSTANT_STRING(L " c:\\study.txt " );
    UNICODE_STRING file_name2 
=  RTL_CONSTANT_STRING(L " c:\\study2.txt " );
    LARGE_INTEGER file_length1,file_length2;
    PLIST_ENTRY p;

    file_length1.QuadPart 
=   100 ;
    file_length2.QuadPart 
=  file_length1.QuadPart  *   100 ;

    StudyAppendNode(file_object,file_name,file_length1);
    StudyAppendNode(file_object,file_name2,file_length2);

    
for (p  =  my_list_head.Flink; p  !=   & my_list_head.Flink; p  =  p -> Flink){ 
        PMY_FILE_INFOR elem 
=  CONTAINING_RECORD(p,     // Address
            MY_FILE_INFOR,     // Type
            list_entry);     // Field
        KdPrint(( " node of MY_FILE_INFOR list, name: %wZ, length:%d\n " , & elem -> file_name,elem -> file_length.QuadPart));
        
if (elem -> file_length.QuadPart  >   1000 ){
            KdPrint((
" file length > 1000,LowPart = %d, HighPart = %d\n " ,elem -> file_length.LowPart,elem -> file_length.HighPart));
            }
        }
    
    
return ;
}


5 KSPIN_LOCK
/*
 *《Windows驱动编程基础教程-谭文》- kSPIN_LOCK
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

#include
< ntddk.h >
#include
< ntdef.h >

#define  MEM_TAG "CG"

DRIVER_UNLOAD StudyUnload;

// our list head
LIST_ENTRY my_list_head;

// our list node
typedef  struct  {
    LIST_ENTRY list_entry; 
// simple to put it at the head of the struct
    PFILE_OBJECT file_object;
    UNICODE_STRING file_name;
    LARGE_INTEGER file_length;
}MY_FILE_INFOR,
* PMY_FILE_INFOR;

// our spin lock, CANNOT be local
KSPIN_LOCK my_spin_lock;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();

    
// Init our list head
    InitializeListHead( & my_list_head);
    
// Init our spin lock
    KeInitializeSpinLock( & my_spin_lock);
    
    DriverObject
-> DriverUnload  =  StudyUnload;
    
    
return  STATUS_SUCCESS;
}


// Append a node to list, note that file_name is allocated outside
NTSTATUS StudyAppendNode(
    PFILE_OBJECT file_object,
    UNICODE_STRING file_name,
    LARGE_INTEGER file_length)
{
    PMY_FILE_INFOR my_file_infor 
=  (PMY_FILE_INFOR)ExAllocatePoolWithTag(PagedPool, sizeof (MY_FILE_INFOR),MEM_TAG);
    
if (my_file_infor  ==  NULL){
        
return  STATUS_INSUFFICIENT_RESOURCES;
        }

    my_file_infor
-> file_object  =  file_object;
    my_file_infor
-> file_name  =  file_name;
    my_file_infor
-> file_length  =  file_length;

    ExInterlockedInsertHeadList(
& my_list_head,     // PLIST_ENTRY  ListHead,
        (PLIST_ENTRY)my_file_infor,
        
& my_spin_lock);    
                                    

    
return  STATUS_SUCCESS;
}


VOID StudyUnload(PDRIVER_OBJECT DriverObject)
{
    PFILE_OBJECT file_object 
=  NULL;
    UNICODE_STRING file_name 
=  RTL_CONSTANT_STRING(L " c:\\study.txt " );
    UNICODE_STRING file_name2 
=  RTL_CONSTANT_STRING(L " c:\\study2.txt " );
    LARGE_INTEGER file_length1,file_length2;
    PLIST_ENTRY p;

    file_length1.QuadPart 
=   100 ;
    file_length2.QuadPart 
=  file_length1.QuadPart  *   100 ;

    StudyAppendNode(file_object,file_name,file_length1);
    StudyAppendNode(file_object,file_name2,file_length2);

    
for (p  =  my_list_head.Flink; p  !=   & my_list_head.Flink; p  =  p -> Flink){ 
        PMY_FILE_INFOR elem 
=  CONTAINING_RECORD(p,     // Address
            MY_FILE_INFOR,     // Type
            list_entry);     // Field
        KdPrint(( " node of MY_FILE_INFOR list, name: %wZ, length:%d\n " , & elem -> file_name,elem -> file_length.QuadPart));
        
if (elem -> file_length.QuadPart  >   1000 ){
            KdPrint((
" file length > 1000,LowPart = %d, HighPart = %d\n " ,elem -> file_length.LowPart,elem -> file_length.HighPart));
            }
        }
    
    
return ;
}


6 文件操作
/*
 *《Windows驱动编程基础教程-谭文》- 文件操作
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

/*
 *需要在C盘根目录下放一个study.txt文件,写入任意内容,当作拷贝的原文件
*/

#include
< ntddk.h >
#include
< ntdef.h >

#define  MEM_TAG "CG"

DRIVER_UNLOAD StudyUnload;

VOID StudyBakFileThread(VOID);


NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();
    
    DriverObject
-> DriverUnload  =  StudyUnload;

    StudyBakFileThread();
    
    
return  STATUS_SUCCESS;
}




VOID
StudyBakFileThread()
{
    UNICODE_STRING src_name 
=  RTL_CONSTANT_STRING(L " \\DosDevices\\c:\\study.txt " ); 
    UNICODE_STRING dst_name 
=  RTL_CONSTANT_STRING(L " \\DosDevices\\c:\\study.bak " ); 
    HANDLE src 
=  NULL, dst  =  NULL;  // the handles of the files to be copyed and copyed to 
    PVOID buffer  =  NULL;
    OBJECT_ATTRIBUTES object_attributes_src,object_attributes_dst;
    LARGE_INTEGER offset 
=  { 0 };
    IO_STATUS_BLOCK io_status 
=  { 0 };
    NTSTATUS status;
    
int  length;

    
do {
        InitializeObjectAttributes(
        
& object_attributes_src,
        
& src_name,
        OBJ_CASE_INSENSITIVE 
|  OBJ_KERNEL_HANDLE,
        NULL,
        NULL);

        status 
=  ZwCreateFile(
        
& src,
        SYNCHRONIZE 
|  FILE_READ_DATA  |  FILE_WRITE_DATA,
        
& object_attributes_src,
        
& io_status,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ,
        FILE_OPEN_IF,
        FILE_NON_DIRECTORY_FILE 
|  FILE_RANDOM_ACCESS  |  FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        
0 );

        InitializeObjectAttributes(
        
& object_attributes_dst,
        
& dst_name,
        OBJ_CASE_INSENSITIVE 
|  OBJ_KERNEL_HANDLE,
        NULL,
        NULL);

        status 
=  ZwCreateFile(
        
& dst,
        SYNCHRONIZE 
|  FILE_READ_DATA  |  FILE_WRITE_DATA,
        
& object_attributes_dst,
        
& io_status,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        
0 ,
        FILE_OPEN_IF,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        
0 );

        buffer 
=  ExAllocatePoolWithTag(PagedPool, 4096 ,MEM_TAG);
        
if (NULL  ==  buffer){
            KdPrint((
" FAIL ExAllocatePoolWithTag " ));
            
return ;
            }

        
while ( 1 ){
            length 
=   4 * 1024 ;

            status 
=  ZwReadFile(
                src,NULL,NULL,NULL,
                
& io_status,
                buffer,
                length,
                
& offset,
                NULL);
            
if ( ! NT_SUCCESS(status)){
                
if (STATUS_END_OF_FILE)
                    status 
=  STATUS_SUCCESS;
                
break ;
                }

            length 
=  io_status.Information;

            status 
=  ZwWriteFile(
                dst,NULL,NULL,NULL,
                
& io_status,
                buffer,
                length,
                
& offset,
                NULL);
            
if ( ! NT_SUCCESS(status))
                
break ;

            offset.QuadPart 
+=  length;
            }
        
        }
while ( 0 );

    
if (NULL  !=  src)
        ZwClose(src);
    
if (NULL  !=  dst)
        ZwClose(dst);
    
if (NULL  !=  buffer)
        ExFreePool(buffer);

}


VOID
StudyUnload(PDRIVER_OBJECT DriverObject)
{

    
return ;
}


7 注册表读写
/*
 *《Windows驱动编程基础教程-谭文》- 注册表读写
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

#include
< ntddk.h >
#include
< ntdef.h >

#define  MEM_TAG "CG"

DRIVER_UNLOAD StudyUnload;

VOID StudyRegistry(VOID);


NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();
    
    DriverObject
-> DriverUnload  =  StudyUnload;

    StudyRegistry();
    
    
return  STATUS_SUCCESS;
}


VOID
StudyRegistry()
{
    HANDLE my_key 
=  NULL;
    NTSTATUS status;
    
// read
    UNICODE_STRING my_key_path  =  RTL_CONSTANT_STRING(L " \\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion " );
    UNICODE_STRING my_key_name 
=  RTL_CONSTANT_STRING(L " SystemRoot " );
    UNICODE_STRING my_key_value;
    
// write
    UNICODE_STRING wr_name  =  RTL_CONSTANT_STRING(L " Test " );
    PCHAR wr_value 
=  {L " Test Value " };
    OBJECT_ATTRIBUTES my_obj_attr 
=  { 0 };
    KEY_VALUE_PARTIAL_INFORMATION key_infor; 
// tmp key_infor to test the length
    PKEY_VALUE_PARTIAL_INFORMATION ac_key_infor;  // actual key infor we use.buffer in dui
    ULONG ac_length;

    InitializeObjectAttributes(
        
& my_obj_attr,
        
& my_key_path,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    status 
=  ZwOpenKey(
        
& my_key,
        KEY_READ,
        
& my_obj_attr);
    
if ( ! NT_SUCCESS(status)){
        KdPrint((
" ERROR - ZwOpenKey " ));
        
return ;
        }

    
// get the real length of the key
    status  =  ZwQueryValueKey(
        my_key,    
// HANDLE  KeyHandle,
         & my_key_name,    
        KeyValuePartialInformation,
        
& key_infor,
        
sizeof (KEY_VALUE_PARTIAL_INFORMATION),
        
& ac_length);
    
if ( ! NT_SUCCESS(status)  &&
        STATUS_BUFFER_OVERFLOW 
!=  status  &&
        STATUS_BUFFER_TOO_SMALL 
!=  status){
        KdPrint((
" ERROR - ZwQueryValueKey " ));
        
return ;
        }

    
// Allocate enough space
    ac_key_infor  =  (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool,ac_length,MEM_TAG);
    
if (ac_key_infor  ==  NULL){
        KdPrint((
" ERROR - Allocate space for ac_key_infor " ));
        
return ;
        }

    status 
=  ZwQueryValueKey(
        my_key,    
// HANDLE  KeyHandle,
         & my_key_name,    
        KeyValuePartialInformation,
        ac_key_infor,
        ac_length,
        
& ac_length);
    
if (NT_SUCCESS(status)){
        KdPrint((
" SystemRoot is:%ws\n " ,ac_key_infor -> Data));
        }

    status 
=  ZwSetValueKey(
        my_key,        
// IN HANDLE  KeyHandle,
         & wr_name,     // IN PUNICODE_STRING  ValueName
         0 ,             // IN ULONG  TitleIndex  OPTIONAL,
        REG_SZ,         // IN ULONG  Type,
        wr_value,     // IN PVOID  Data,
        (wcslen(wr_value) + 1 ) * sizeof (WCHAR));     // IN ULONG  DataSize
     if ( ! NT_SUCCESS(status)){
        KdPrint((
" ERROR! - ZwSetValueKey " ));
        
return ;
        }


}

VOID
StudyUnload(PDRIVER_OBJECT DriverObject)
{

    
return ;
}


8 时间与定时
/*
 *《Windows驱动编程基础教程-谭文》- 时间与定时
 *测试环境:WinDDK 7600.16385.0 chk x86 WXP
 *小默 整理
*/

#include
< ntddk.h >
#include
< ntdef.h >
#include
< ntstrsafe.h >

#define  MEM_TAG "CG"

DRIVER_UNLOAD StudyUnload;

typedef 
struct  MY_TIMER_
{
    KDPC dpc;
    KTIMER timer;
    PKDEFERRED_ROUTINE func;
    
int  private_context;
}MY_TIMER,
* PMY_TIMER;

VOID StudyGetTickCount(VOID);
VOID StudyCurTimeStr();
VOID StudySetTimer();
VOID StudyDcpRoutine(
    PRKDPC dpc,
    PVOID DeferredContext,
    PVOID SystemArgument1,
    PVOID SystemArgument2);


NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    PAGED_CODE();
    
    DriverObject
-> DriverUnload  =  StudyUnload;

    StudyGetTickCount();
    StudyCurTimeStr();
    StudySetTimer();
    
    
return  STATUS_SUCCESS;
}

VOID
StudyGetTickCount()
{
    LARGE_INTEGER tick_count;
    ULONG time_inc 
=  KeQueryTimeIncrement();  // the number of 100-nanosecond units between two interval clock interrupts
    KeQueryTickCount( & tick_count);  // count of the interval clock interrupts that have occurred since the system was booted
    tick_count.QuadPart  *=  time_inc;
    tick_count.QuadPart 
/=   10000 ;
    KdPrint((
" the system has been booted %d ms\n " ,tick_count.LowPart));

    
return ;
}

VOID
StudyCurTimeStr()
{
    LARGE_INTEGER snow,now;
    TIME_FIELDS now_fields;
    WCHAR time_str[
32 =  {  0  };

    KeQuerySystemTime(
& snow);     // get the current system time of the GMT time zone
    ExSystemTimeToLocalTime( & snow, & now);  // adjust this value for the local time zone
    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);

    KdPrint((
" The current time: %ws " , & time_str));
}

VOID 
StudySetTimer()
{
    PMY_TIMER my_timer 
=  (PMY_TIMER)ExAllocatePoolWithTag(PagedPool, sizeof (MY_TIMER),MEM_TAG);
    LARGE_INTEGER due;
    
int  msec  =   1000 ;

    due.QuadPart 
=   - 10000 * msec;

    my_timer
-> private_context  =   5 ;
    my_timer
-> func  =  StudyDcpRoutine;
    
    KeInitializeDpc(
        
& my_timer -> dpc,         // PRKDPC  Dpc
        StudyDcpRoutine,     // PKDEFERRED_ROUTINE  DeferredRoutine,
        my_timer);     // PVOID  DeferredContext

    KeInitializeTimer(
& my_timer -> timer);  // Init Timer

    KdPrint((
" before set timer " ));
    
    KeSetTimer(
& my_timer -> timer,due, & my_timer -> dpc);
}


VOID
StudyDcpRoutine(
    PRKDPC dpc,
    PVOID DeferredContext,
    PVOID SystemArgument1,
    PVOID SystemArgument2)
{
    PMY_TIMER my_timer 
=  (PMY_TIMER)DeferredContext;

    KdPrint((
" in dcp routine,context %d " ,my_timer -> private_context));
}




VOID
StudyUnload(PDRIVER_OBJECT DriverObject)
{

    
return ;
}

你可能感兴趣的:(Windows驱动编程基础教程-谭文-代码整理)