#ifdef __cplusplus
extern "C"
{
#endif
#include "F://WINDDK//3790//inc//ddk//w2k//ntddk.h"
#ifdef __cplusplus
}
#endif
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT fdo;
PDEVICE_OBJECT NextStackDevice;
UNICODE_STRING ifSymLinkName;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
#define NT_DEVICE_NAME L"//Device//HHH"
#define DOS_DEVICE_NAME L"//DosDevices//HHH"
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject);
NTSTATUS Pnp(IN PDEVICE_OBJECT fdo,
IN PIRP Irp);
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT device,IN PIRP Irp);
void DrvUnload(IN PDRIVER_OBJECT DriverObject);
#define USER_CONTROL_CODE 1000
#include "main.h"
//-------------------------------------------------------------------------
// Function Name :DriverEntry
// Parameter(s) :PDRIVER_OBJECT DriverObject 指向驱动程序对象的指针
// :PUNICODE_STRING RegistryPath 驱动程序的服务主键
// Return :NTSTATUS
// Memo :驱动程序入口
//-------------------------------------------------------------------------
extern "C"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
DbgPrint( "DriverEntry/n" );
NTSTATUS status = STATUS_SUCCESS;
// 创建设备
PDEVICE_OBJECT lpDeviceObject = 0;
UNICODE_STRING DevNameString;
RtlInitUnicodeString( &DevNameString, NT_DEVICE_NAME);
status = IoCreateDevice( DriverObject //驱动程序对象
, 0 //扩展设备的大小,由于不需要,所以置0
, &DevNameString //设备名称
, FILE_DEVICE_UNKNOWN //设备类型
, 0 //指示设备允许的操作
, FALSE //如果为TRUE,表示只能有一个线程使用该设备,为FALSE,则没有限制
, &lpDeviceObject //返回的设备对象
);
if( !NT_SUCCESS(status) )
return status;
// 创建符号连接
UNICODE_STRING DevLinkString;
RtlInitUnicodeString( &DevLinkString, DOS_DEVICE_NAME);
status = IoCreateSymbolicLink( &DevLinkString, &DevNameString);
if( NT_SUCCESS(status) )
{
// 设置函数指针
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = Pnp;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DrvDispatch;
DriverObject->DriverUnload = DrvUnload;
}
return status;
}
//-------------------------------------------------------------------------
// Function Name :DrvUnload
// Parameter(s) :PDRIVER_OBJECT DriverObject 指向驱动程序对象的指针
// Return :void
// Memo :删除设备
//-------------------------------------------------------------------------
void DrvUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING DeviceLinkString;
RtlInitUnicodeString( &DeviceLinkString, DOS_DEVICE_NAME);
IoDeleteSymbolicLink( &DeviceLinkString); //删除符号连接
PDEVICE_OBJECT DeviceObjectTemp1=NULL;
PDEVICE_OBJECT DeviceObjectTemp2=NULL;
if( DriverObject != NULL )
{
DeviceObjectTemp1 = DriverObject->DeviceObject;
//删除设备
while( DeviceObjectTemp1 != NULL )
{
DeviceObjectTemp2 = DeviceObjectTemp1;
DeviceObjectTemp1 = DeviceObjectTemp1->NextDevice;
IoDeleteDevice(DeviceObjectTemp2);
}
}
}
//-------------------------------------------------------------------------
// Function Name :DrvDispatch
// Parameter(s) :
// :
// Return :
// Memo :驱动消息分发
//-------------------------------------------------------------------------
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG IoControlCodes = 0; //I/O控制代码
//得到当前调用者的IRP
PIO_STACK_LOCATION IrpStack = NULL;
IrpStack = IoGetCurrentIrpStackLocation(pIrp);
//设置IRP状态
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:
break;
case IRP_MJ_CLOSE:
break;
case IRP_MJ_DEVICE_CONTROL:
{
//取得I/O控制代码
IoControlCodes = IrpStack->Parameters.DeviceIoControl.IoControlCode;
switch(IoControlCodes)
{
// 自定义控制码
case USER_CONTROL_CODE:
DbgPrint("Starting /"Hello World/"/n");
break;
default:
pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
}
break;
}// case IRP_MJ_DEVICE_CONTROL
default:
break;
}
status = pIrp->IoStatus.Status;
IoCompleteRequest( pIrp, IO_NO_INCREMENT);
return status;
}
//-------------------------------------------------------------------------
// Function Name :WDMAddDevice
// Parameter(s) :
// :
// Return :
// Memo :添加设备
//-------------------------------------------------------------------------
NTSTATUS AddDevice(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;
}
//-------------------------------------------------------------------------
// Function Name :WDMPnp
// Parameter(s) :
// :
// Return :
// Memo :处理“即插即用”消息
//-------------------------------------------------------------------------
NTSTATUS Pnp(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;
}