`
阿尔萨斯
  • 浏览: 4170324 次
社区版块
存档分类
最新评论

[WDM]驱动程序框架 我还没写完 好忙 没时间玩

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

#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_NAMEL"//Device//HHH"
#define DOS_DEVICE_NAMEL"//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_CODE1000

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




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics