编译第一个驱动程序笔记

(以下代码大部分摘抄自王艳平老师的《Windows程序设计》一书中的源代码,这里只是为了展示驱动的编译过程)

1:安装VC6
2:安装DDK(大概230M,最好完全安装)

3:写以下源代码(随便用一个编辑器来写):
CharConvert.h:

#define  CHAR_CONVERT    
    CTL_CODE(FILE_DEVICE_UNKNOWN, 
0x830 , METHOD_BUFFERED, FILE_ANY_ACCESS)

CharConvert.cpp:

extern   " C "
{
    #include 
< ntddk.h >
}

#include 
< devioctl.h >
#include 
" CharConvert.h "

//  自定义函数的声明
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
void  DriverUnload(PDRIVER_OBJECT pDriverObj);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);

//  驱动内部名称和符号连接名称
#define  DEVICE_NAME L"/Device/devCharConvert"
#define  LINK_NAME L"/DosDevices/slCharConvert"

//  驱动程序加载时调用DriverEntry例程
extern   " C "  NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
    NTSTATUS status 
=  STATUS_SUCCESS;

    
//  初始化各个派遣例程
    pDriverObj -> MajorFunction[IRP_MJ_CREATE]  =  DispatchCreateClose;
    pDriverObj
-> MajorFunction[IRP_MJ_CLOSE]  =  DispatchCreateClose;
    pDriverObj
-> MajorFunction[IRP_MJ_DEVICE_CONTROL]  =  DispatchIoctl;
    pDriverObj
-> DriverUnload  =  DriverUnload;

        
//  创建、初始化设备对象
    
//  设备名称
    UNICODE_STRING ustrDevName;
    RtlInitUnicodeString(
& ustrDevName, DEVICE_NAME);
    
//  创建设备对象
    PDEVICE_OBJECT pDevObj;
    status 
=  IoCreateDevice(pDriverObj, 
                
0 ,
                
& ustrDevName, 
                FILE_DEVICE_UNKNOWN,
                
0 ,
                FALSE,
                
& pDevObj);
    
if ( ! NT_SUCCESS(status))
    {
        
return  status;
    }

        
//  创建符号连接名称
    
//  符号连接名称
    UNICODE_STRING ustrLinkName;
    RtlInitUnicodeString(
& ustrLinkName, LINK_NAME);
    
//  创建关联
    status  =  IoCreateSymbolicLink( & ustrLinkName,  & ustrDevName);  
    
if ( ! NT_SUCCESS(status))
    {
        IoDeleteDevice(pDevObj);  
        
return  status;
    }
    
    
return  STATUS_SUCCESS;
}

void  DriverUnload(PDRIVER_OBJECT pDriverObj)
{    
    
//  删除符号连接名称
    UNICODE_STRING strLink;
    RtlInitUnicodeString(
& strLink, LINK_NAME);
    IoDeleteSymbolicLink(
& strLink);

    
//  删除设备对象
    IoDeleteDevice(pDriverObj -> DeviceObject);
}

//  处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    pIrp
-> IoStatus.Status  =  STATUS_SUCCESS;
    
//  完成此请求
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    
return  STATUS_SUCCESS;
}

//  I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    
//  假设失败
    NTSTATUS status  =  STATUS_INVALID_DEVICE_REQUEST;

    
//  取得此IRP(pIrp)的I/O堆栈指针
    PIO_STACK_LOCATION pIrpStack  =  IoGetCurrentIrpStackLocation(pIrp);

    
//  取得I/O控制代码
    ULONG uIoControlCode  =  pIrpStack -> Parameters.DeviceIoControl.IoControlCode;
    
//  取得I/O缓冲区指针和它的长度
    PVOID pIoBuffer  =  pIrp -> AssociatedIrp.SystemBuffer;
    ULONG uInSize 
=  pIrpStack -> Parameters.DeviceIoControl.InputBufferLength;
    ULONG uOutSize 
=  pIrpStack -> Parameters.DeviceIoControl.OutputBufferLength;

    
switch (uIoControlCode)
    {
    
case  CHAR_CONVERT:
        {
            
char  str[]  =   " 零一二三四五六七八九 " ;
            
if (uInSize  >=   1   &&  uOutSize  >= 2 )
            {
                
char  c  =  (( char * )pIoBuffer)[ 0 ];
                
if (c  >=   ' 0 '   &&  c  <=   ' 9 ' )
                {
                    
//  进行转换
                    c  -=   ' 0 ' ;
                    RtlCopyMemory(pIoBuffer, 
& str[c * 2 ],  2 );
                    status 
=  STATUS_SUCCESS;
                }
            }
        }
        
break ;
    }

    
if (status  ==  STATUS_SUCCESS)
        pIrp
-> IoStatus.Information  =  uOutSize;
    
else
        pIrp
-> IoStatus.Information  =   0 ;

    
//  完成请求
    pIrp -> IoStatus.Status  =  status;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    
return  status;
}

注意:当你的驱动源代码文件为.cpp时,驱动的入口点函数名DriverEntry前需要添加extern "C"修饰符。
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
#

! IF DEFINED(_NT_TARGET_VERSION)
!    IF $(_NT_TARGET_VERSION) >= 0x501
!        IFNDEF AMD64
!            INCLUDE $(NTMAKEENV)makefile.def
!        ELSE
!            message BUILDMSG: Warning : Perm2 sample  is  not supported on AMD64.
!        ENDIF
!    ELSE
!        message BUILDMSG: Warning : The sample  " $(MAKEDIR) "   is  not valid  for  the current OS target.
!    ENDIF
! ELSE
!    INCLUDE $(NTMAKEENV)makefile.def
! ENDIF

sources:

TARGETNAME=CharConvert
TARGETPATH=obj
TARGETTYPE=DRIVER

SOURCES=CharConvert.cpp

注意:TARGETNAME是驱动编译后的驱动文件名,TARGETTYPE是驱动类型,SOURCES是源代码文件名。

4:开始-程序-Development Kits-Windows DDK 3790.1830-Windows XP-Windows XP Checked Build Environment

从而打开了一个命令行窗口。

cd E:                     //进入源代码目录(我的是E:/CharConvert文件夹)
cd CharConvert (回车)
build                     //运行build命令

BUILD:Adding /Y to COPYCMD so xcopy ops won't hang.
BUILD:Object root set to: ==> objchk_wxp_x86
BUILD:Compile and Link for i386
BUILD:Loading D:/WINDDK/3790~1.183/build.dat...
BUILD:Computing Include file dependencies:
BUILD:Examining e:/CharConvert directory for files to compile.
    e:/CharConvert - 1 source files <138 lines>
BUILD:Compiling <NoSync> e:/CharConvert directory
Compiling - CharConvert.cpp for i386
BUILD:Linking e:/CharConvert directory
Linking Executable - objchk_wxp_x86/i386/CharConvert.sys for i386
BUILD:Done

    2 files compiled
    1 executable built

在E:/CharConvert/objchk_wxp_x86/i386目录下就生成了CharConvert.sys驱动程序文件。至此驱动编译成功!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值