Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1332506
  • 博文数量: 92
  • 博客积分: 10389
  • 博客等级: 上将
  • 技术积分: 1918
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-10 16:13
文章存档

2014年(1)

2012年(15)

2009年(6)

2008年(37)

2007年(72)

2006年(54)

我的朋友

分类: WINDOWS

2006-12-12 16:45:33

如果你和我一样没有天才的智慧那么漫漫来看看这个ddk_hello..
 
###########首先感谢这位高手以前的杰作####################
 
首先这个过程让你体会到了如何编译一个简单的ddk程序,同时在解决了几个简单而致命的错误之后,你会更有信心深入了解DDK!
 
C语言是这里的神,所以你的程序中必须要按照C语言的规范:
如:
1/函数声明后在 具体化它;
2/函数体内的变量必须放在函数体靠前的地方声明;
 
首先这是个WDM的hello;
 
代码如下:
hello.c
 
 
/***************************************************************
程序名称:Hello World for WDM
文件名称:HelloWDM.c
作者:罗聪
日期:2002-8-16
***************************************************************/
//一定要的头文件,声明了函数模块和变量:
#include "helloWDM.h"
//#include
//#include
//#include
//#include
//#include

NTSTATUS DriverEntry(   IN PDRIVER_OBJECT DriverObject,
                        IN PUNICODE_STRING RegistryPath);
                       
                       
                       
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject); 
                                           
                                           
                                               
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                     IN PIRP Irp);
                    
                    
/***************************************************************
函数名称:DriverEntry()
功能描述:WDM程序入口
***************************************************************/
//extern "C"是必须的,表示“用C链接”。如果你的文件名是HelloWDM.c的话,这句可以省略。
//extern "C"
NTSTATUS DriverEntry(    IN PDRIVER_OBJECT DriverObject,
                        IN PUNICODE_STRING RegistryPath)
{
    //指定“添加设备”消息由函数“HelloWDMAddDevice()”来处理:
    DriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
    //指定“即插即用”消息由函数“HelloWDMPnp()”来处理:
    DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
    //返回一个NTSTATUS值STATUS_SUCCESS。几乎所有的驱动程序例程都必须返回一个NTSTATUS值,这些值在NTSTATUS.H DDK头文件中有详细的定义。
    return STATUS_SUCCESS;
}

/***************************************************************
函数名称:HelloWDMAddDevice()
功能描述:处理“添加设备”消息
***************************************************************/
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject)
{
    //定义一个NTSTATUS类型的返回值:
    NTSTATUS status;
    PDEVICE_OBJECT fdo;
    PDEVICE_EXTENSION dx ;
    //定义一个功能设备对象(Functional Device Object):
   
    //创建我们的功能设备对象,并储存到fdo中:
    status = IoCreateDevice(
        DriverObject,                //驱动程序对象
        sizeof(DEVICE_EXTENSION),    //要求的设备扩展的大小
        NULL,                        //设备名称,这里为NULL
        FILE_DEVICE_UNKNOWN,        //设备的类型,在标准头文件WDM.H或NTDDK.H中列出的FILE_DEVICE_xxx值之一
        0,                            //各种常量用OR组合在一起,指示可删除介质、只读等。
        FALSE,                        //如果一次只有一个线程可以访问该设备,为TRUE,否则为FALSE
        &fdo);                        //返回的设备对象
    //NT_SUCCESS宏用于测试IoCreateDevice内核是否成功完成。不要忘记检查对内核的所有调用是否成功。NT_ERROR宏不等同于!NT_SUCCESS,最好使用!NT_SUCCESS,因为除了错误外,它还截获警告信息。
    if( !NT_SUCCESS(status))
        return status;
    //创建一个设备扩展对象dx,用于存储指向fdo的指针:
   
    dx= (PDEVICE_EXTENSION)fdo->DeviceExtension;
    dx->fdo = fdo;
    //用IoAttachDeviceToDeviceStack函数把HelloWDM设备挂接到设备栈:
    dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
    //设置fdo的flags。有两个“位”是必须改变的,一个是必须清除DO_DEVICE_INITIALIZING标志,如果在DriverEntry例程中调用IoCreateDevice(),就不需要清除这个标志位。还有一个是必须设置DO_BUFFER_IO标志位:
    fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
    fdo->Flags &= ~DO_DEVICE_INITIALIZING;
    //返回值:
    return STATUS_SUCCESS;
}

/***************************************************************
函数名称:HelloWDMPnp()
功能描述:处理“即插即用”消息
***************************************************************/
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp)
{
    //创建一个设备扩展对象dx,用于存储指向fdo的指针:
    PDEVICE_EXTENSION dx;
    PIO_STACK_LOCATION IrpStack;
    ULONG MinorFunction;
    NTSTATUS status;
   
    dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
    //首先要通过函数IoGetCurrentIrpStackLocation()得到当前的IRP,并由此得到Minor Function:
   
    IrpStack = IoGetCurrentIrpStackLocation(Irp);
    MinorFunction = IrpStack->MinorFunction;
    //然后把这个Minor Function传递给下一个设备栈:
    IoSkipCurrentIrpStackLocation(Irp);
    status = IoCallDriver( dx->NextStackDevice, Irp);
    //处理“即插即用”次功能代码:
    //当Minor Function等于IRP_MN_REMOVE_DEVICE时,说明有设备被拔出或卸下,这时要取消资源分配并删除设备:
    if( MinorFunction==IRP_MN_REMOVE_DEVICE)
    {
        //取消设备接口:
        IoSetDeviceInterfaceState(&dx->ifSymLinkName, FALSE);
        RtlFreeUnicodeString(&dx->ifSymLinkName);
       
        //调用IoDetachDevice()把fdo从设备栈中脱开:
        if (dx->NextStackDevice)
            IoDetachDevice(dx->NextStackDevice);
        //删除fdo:
        IoDeleteDevice(fdo);
    }
    //返回值:
    return status;
}
####################################################################
/***************************************************************
程序名称:Hello World for WDM
文件名称:HelloWDM.h
作者:罗聪
日期:2002-8-16
***************************************************************/
//头文件,只是声明一些函数和变量,比较简单就不多说了,请读者自行研究:
 
#include
#ifdef __cplusplus
extern "C"
{
#endif
//#include "c:\winddk\2600\inc\ddk\wxp\ntddk.h"
#ifdef __cplusplus
}
#endif
typedef struct _DEVICE_EXTENSION
{
    PDEVICE_OBJECT    fdo;
    PDEVICE_OBJECT    NextStackDevice;
    UNICODE_STRING    ifSymLinkName;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject);
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp);
 
 
##############################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
 
##########################source####################################
TARGETNAME=HelloWDM
TARGETTYPE=DRIVER
DRIVERTYPE=WDM
TARGETPATH=OBJ
 
INCLUDES=$(BASEDIR)\inc;\
         $(BASEDIR)\inc\ddk\wxp;\
        
        
TARGETLIBS=
SOURCES=helloWDM.c\
 
这里要提醒你,如果你和我一样喜欢自定义环境变量,那么这里的basedir就自己定义好了
 
###########################未完成#######################################
阅读(2860) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~