加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

windows驱动开发教程及例子

(2011-07-20 23:24:52)
标签:

windows

驱动开发

实例

it

分类: 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 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 字符串使用


#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 stringhttp://www.cppblog.com/Images/dot.gif"); //Init UNICODE_STRING
    NTSTATUS status;
    PAGED_CODE();

    DbgPrint(
"Study:Our driver is unloadinghttp://www.cppblog.com/Images/dot.gif\r\n");
    
//Init UNICODE_STRING
    RtlInitUnicodeString(&str1,L"Init the string str1http://www.cppblog.com/Images/dot.gif");
    KdPrint((
"Init UNICODE_STRING:%wZ\r\n",&str1));

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

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

    
return;
}

2 内存的分配与释放


#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 stringhttp://www.cppblog.com/Images/dot.gif");
    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 UNICODE_STRING:%wZ\r\n",&dst));

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

    
return;
}


3 LIST_ENTRY


#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 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; != &my_list_head.Flink; = 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


#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 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; != &my_list_head.Flink; = 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


#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 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; != &my_list_head.Flink; = 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 文件操作




#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 注册表读写


#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 时间与定时


#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
"M---- -----",
        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;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有