我的第一个Winxp sp2驱动程序(hello world)

        经过半个多月的煎熬终于推出了我的第一个驱动程序,虽然不能真正的驱动什么设备,但是我还是很激动,贴出来恭大家批评指正.

         我的驱动程序是从网上一位前辈的写的,功能再简单不过了,就是在设备管理器中看到它的身影,其他的没有任何作用,但是程序是在2002年写的,那时还没有WINXP sp2,所以环境有些不一样,在加上我一开始什么都不懂,走了不少弯路.不过现在还是有很多不明白的.

        开发驱动程序少不了要安装DDK,我一开始安装的是winxpsp1的,后来换成了IFSKIT(也是别人建议我安装的,不太清楚跟DDK有什么关系,好象里多了Win2003的DDK),例子程序如下:

//HelloWDM.h

#ifdef __cplusplus

extern "C"
{
#endif
#include <wdm.h>

//本来是包含的ntddk.h,但是它编译通不过,可能是比较的老是头文件吧。后来换成了wdm.h才通过

//#include "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);

_____________________________________________________________________________

//HelloWDM.cpp

#include "HelloWDM.h"

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;
}


NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
  //定义一个NTSTATUS类型的返回值:
  NTSTATUS status;
  //定义一个功能设备对象(Functional Device Object):
  PDEVICE_OBJECT fdo;

  //创建我们的功能设备对象,并储存到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的指针:
  PDEVICE_EXTENSION 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;
}


NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
  //创建一个设备扩展对象dx,用于存储指向fdo的指针:
  PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

  //首先要通过函数IoGetCurrentIrpStackLocation()得到当前的IRP,并由此得到Minor Function:
  PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
  ULONG MinorFunction = IrpStack->MinorFunction;

  //然后把这个Minor Function传递给下一个设备栈:
  IoSkipCurrentIrpStackLocation(Irp);
  NTSTATUS 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;
}

_____________________________________________________________________________

#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 

SOURCES=HelloWDM.cpp/

_____________________________________________________________________________


然后在开始菜单中点击Windows XP Checked Build Environment,在弹出的DOS窗口中切换到程序所在的目录(包含上面的四个文件的文件夹),输入build,如果没有错误的话会在当前目录下生成objchk_wxp_x86目录,下面有个i386目录,其中就包含了驱动程序文件HelloWDM.sys了.

然后就是安装了,其实安装比编译更加的麻烦,主要原因就是安装用的inf文件要自己编写,这里还算顺利.我在NT环境下开发的驱动,所以就要在Mfg0中选择YouMark_DDI.NT,在后面的ID里随便写了个编号(hehe),然后建立目录objfre/i386,将HelloWDM拷过来.下面的就是我的INF

; Copyright (C) 2002 SworderAndy
; All rights reserved

;--------- Version Section ---------------------------------------------------

[Version]
Signature="$CHICAGO$"
Provider=LC_Device
DriverVer=8/21/2002,3.0.0.3

; If device fits one of the standard classes, use the name and GUID here,
; otherwise create your own device class and GUID as this example shows.

Class=MyMissiles
ClassGUID={40EDD7EF-EAD8-4693-9256-5F70D920B2F3}

;--------- SourceDiskNames and SourceDiskFiles Section -----------------------

; These sections identify source disks and files for installation. They are
; shown here as an example, but commented out.

[SourceDisksNames]
1 = "HelloWDM",Disk1,,

[SourceDisksFiles]
HelloWDM.sys = 1,objfre/i386,

;--------- ClassInstall/ClassInstall32 Section -------------------------------

; Not necessary if using a standard class

; 9X Style
[ClassInstall]
Addreg=Class_AddReg

; NT Style
[ClassInstall32]
Addreg=Class_AddReg

[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-5"

;--------- DestinationDirs Section -------------------------------------------

[DestinationDirs]
YouMark_Files_Driver = 10,System32/Drivers

;--------- Manufacturer and Models Sections ----------------------------------

[Manufacturer]
%MfgName%=Mfg0

[Mfg0]

; PCI hardware Ids use the form
; PCI/VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd
;改成你自己的ID
%DeviceDesc%=YouMark_DDI.NT, PCI/VEN_1234&DEV_5678

;---------- DDInstall Sections -----------------------------------------------
; --------- Windows 9X -----------------

; Experimentation has shown that DDInstall root names greater than 19 characters
; cause problems in Windows 98

[YouMark_DDI]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_9X_AddReg

[YouMark_9X_AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,HelloWDM.sys
HKR, "Parameters", "BreakOnEntry", 0x00010001, 0

; --------- Windows NT -----------------

[YouMark_DDI.NT]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_NT_AddReg

[YouMark_DDI.NT.Services]
Addservice = HelloWDM, 0x00000002, YouMark_AddService

[YouMark_AddService]
DisplayName = %SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%/System32/Drivers/HelloWDM.sys

[YouMark_NT_AddReg]
HKLM, "System/CurrentControlSet/Services/HelloWDM/Parameters",/
"BreakOnEntry", 0x00010001, 0


; --------- Files (common) -------------

[YouMark_Files_Driver]
HelloWDM.sys

;--------- Strings Section ---------------------------------------------------

[Strings]
ProviderName="Flying L Co.,Ltd."
MfgName="LC Soft"
DeviceDesc="Hello World WDM!"
DeviceClassName="LC_Device"
SvcDesc="???"

 最后一步了,就是打开Windows的控制面板,选择添加新硬件,在弹出的对话框点下一步,选是,我已连接此硬件,点下一步,选择最下面的添加新的硬件设备,点下一步选安装我手动从列表选择的硬件,点下一步,选显示所有设备,点下一步,点从磁盘安装,在弹出的对话框中选择HelloWDM所在的目录,该目录应该有objfre/i386/文件夹和里面的HelloWDM.sys文件,好了,最激动的时刻到来了,当安装提示成功的时候,打开你的设备管理器看看吧.里面会多了一个叫LC_Device的设备类,点击旁边的加号,就会显示一个Hello World WDM!设备.

哈哈,是不是很cool,其实驱动开发是一个漫长的过程,所涉及的东西太多,但不管怎样我总算迈出了第一步.

 
Intel 946-G45/Q45系列集成显卡驱动14.37.1.5029版For Win2000/XP [13.63M] 2009年02月13日 是 Intel 946-G35/Q35系列集成显卡驱动15.12.75.4.1930版For Win7-32 [22.57M] 2009年10月29日 是 Intel B43/G41/G43/G45/Q43/Q45(包括移动版)系列芯片组集成显卡驱动14.42.11.5355版For WinXP-32/XP-64 [17.81M] 2011年05月21日 无 Intel B43/G41/G43/G45/Q43/Q45(包括移动版)系列芯片组集成显卡驱动15.17.17.2413版For Vista-32/Win7-32 [37.94M] 2011年07月04日 无 Intel B43/G41/G43/G45/Q43/Q45(包括移动版)系列芯片组集成显卡驱动15.17.17.2413版For Vista-64/Win7-64 [39.89M] 2011年07月04日 无 Intel英特尔Core i3/Core i5/Core i7系列核芯显卡驱动14.46.4.5337版For WinXP-32 [22.87M] 2011年04月21日 是 Intel英特尔Core i3/Core i5/Core i7系列核芯显卡驱动15.22.4.2418 WHQL版For Vista-32/Win7-32 [67.62M] 2011年06月24日 是 Intel英特尔Core i3/Core i5/Core i7系列核芯显卡驱动15.22.4.2418 WHQL版For Vista-64/Win7-64 [84.89M] 2011年06月24日 是 Intel英特尔GMA 3150显示驱动14.37.50.4.5260版For WinXP-32 [15.25M] 2010年05月31日 无 Intel英特尔GMA 500显示驱动3.3.0版For WinXP-32 [29.75M] 2009年1221日 是 Intel英特尔GMA 600显示驱动8.14.6.3067版For Win7-32 [25.56M] 2011年07月25日 是 S3 DeltaChrome/GammaChrome系列显卡驱动6.14.10.2021-15.16.14j版For Win2000/XP [8.55M] 2005年09月02日 无 S3 Chrome S20/GammaChrome系列显卡驱动6.14.10.2401版For Win2000/XP [10.44M] 2008年03月14日 无 S3 Chrome 400/500系列显卡驱动6.14.10.0517 WHQL版For WinXP [18.98M] 2010年11月16日 是 VIA威盛VIA Chrome9 HC IGP图形核心驱动20.07.01i版For Win2000/XP [9.84M] 2008年10月10日 是 VIA威盛UniChrome Pro图形核心驱动22.00.01e版For Win2000/XP/Vista-32 [6.67M] 2007年12月03日 是 SiS矽统Xabre 600/Xabre 400/Xabre 200/Xabre 80显卡驱动3.57.53官方正式版For Win9x/ME/2000/XP [9.47M] 2004年03月09日 是 SiS矽统SiSM771/771/M671MX/M671/671/671FX显示驱动UniVGA5 5.25版For Vista-32/Vista-64 [14.41M] 2009年12月15日 是 SiS矽统661/662/671/672/760/761芯片组显示驱动UniVGA3 3.93版For Win2000/XP/2003 [14.41M] 2010年12月15日 是 SiS矽统SiS671/671FX/672/672FX/M671/M671MX/M672/M672MX芯片组显示驱动UniVGA5 5.29版For Win7-32/Win7-64 [14.41M] 2011年01月07日 是 SiS矽统315/315E显卡驱动3.51 WHQL版For Win98/ME/2000/XP [10.60M] 2003年09月21日 是 XGI图诚Volari V3系列显卡驱动1.16.02 WHQL官方正式版For WinXP [6.41M] 2006年06月13日 无 XGI图诚Volari Z7/Z9/Z9s/Z11系列显卡驱动1.11.03 WHQL版For Win2000/XP-32/XP-64/Vista-32/Vista-64 [8.62M] 2008年11月09日 无 XGI图诚Volariz V8/V5/V3XT系列显卡驱动1.09.75官方正式版For Win2000/XP [17.49M] 2006年04月17日 是 Matrox Millennium G450/Millennium G550系列显卡驱动2.05.01.030 SE版For Win2000/XP-32/2003-32/Vista-32 [11.55M] 2007年11月10日 是 Matrox Parhelia/P650/P690/P750/M9120/M9125/M9140系列显卡驱动2.09.04.061 SE U W7版For WinXP/2003/2008/Vista/Win7 [51.60M] 2010年11月29日 无 3dfx Voodoo 3/4/5显卡SFFT驱动1.5版For Win2000/XP/XP-64 万能网卡驱动兼容win7 / xp 万能网卡驱动兼容win7 / xp 万能网卡驱动兼容win7 / xp万能网卡驱动兼容win7 / xp 万能网卡驱动兼容win7 / xp 万能网卡驱动兼容win7 / xp万能网卡驱动兼容win7 / xp万能网卡驱动兼容win7 / xp万能网卡驱动兼容win7 / xp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值