HelloWDM驱动程序代码,HelloWDM.cpp

来源:互联网 发布:天津大学图片 知乎 编辑:程序博客网 时间:2024/05/16 19:12


#include "HelloWDM.h"

/************************************************************************
* 函数名称:DriverEntry
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
        IN PUNICODE_STRING pRegistryPath)
{
 KdPrint(("Enter DriverEntry/n"));

 pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
 pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
 pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
 pDriverObject->MajorFunction[IRP_MJ_CREATE] =
 pDriverObject->MajorFunction[IRP_MJ_READ] =
 pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
 pDriverObject->DriverUnload = HelloWDMUnload;

 KdPrint(("Leave DriverEntry/n"));
 return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloWDMAddDevice
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject)
{
 PAGED_CODE();
 KdPrint(("Enter HelloWDMAddDevice/n"));

 NTSTATUS status;
 PDEVICE_OBJECT fdo;
 UNICODE_STRING devName;
 RtlInitUnicodeString(&devName,L"//Device//MyWDMDevice");
 status = IoCreateDevice(
  DriverObject,
  sizeof(DEVICE_EXTENSION),
  &(UNICODE_STRING)devName,
  FILE_DEVICE_UNKNOWN,
  0,
  FALSE,
  &fdo);
 if( !NT_SUCCESS(status))
  return status;
 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
 pdx->fdo = fdo;
 pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
 UNICODE_STRING symLinkName;
 RtlInitUnicodeString(&symLinkName,L"//DosDevices//HelloWDM");

 pdx->ustrDeviceName = devName;
 pdx->ustrSymLinkName = symLinkName;
 status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,&(UNICODE_STRING)devName);

 if( !NT_SUCCESS(status))
 {
  IoDeleteSymbolicLink(&pdx->ustrSymLinkName);
  status = IoCreateSymbolicLink(&symLinkName,&devName);
  if( !NT_SUCCESS(status))
  {
   return status;
  }
 }

 fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
 fdo->Flags &= ~DO_DEVICE_INITIALIZING;

 KdPrint(("Leave HelloWDMAddDevice/n"));
 return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:DefaultPnpHandler
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
{
 PAGED_CODE();
 KdPrint(("Enter DefaultPnpHandler/n"));
 IoSkipCurrentIrpStackLocation(Irp);
 KdPrint(("Leave DefaultPnpHandler/n"));
 return IoCallDriver(pdx->NextStackDevice, Irp);
}

/************************************************************************
* 函数名称:HandleRemoveDevice
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
 PAGED_CODE();
 KdPrint(("Enter HandleRemoveDevice/n"));

 Irp->IoStatus.Status = STATUS_SUCCESS;
 NTSTATUS status = DefaultPnpHandler(pdx, Irp);
 IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);

    //调用IoDetachDevice()把fdo从设备栈中脱开:
    if (pdx->NextStackDevice)
        IoDetachDevice(pdx->NextStackDevice);
 
    //删除fdo:
    IoDeleteDevice(pdx->fdo);
 KdPrint(("Leave HandleRemoveDevice/n"));
 return status;
}

/************************************************************************
* 函数名称:HelloWDMPnp
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp)
{
 PAGED_CODE();

 KdPrint(("Enter HelloWDMPnp/n"));
 NTSTATUS status = STATUS_SUCCESS;
 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
 static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
 {
  DefaultPnpHandler,  // IRP_MN_START_DEVICE
  DefaultPnpHandler,  // IRP_MN_QUERY_REMOVE_DEVICE
  HandleRemoveDevice,  // IRP_MN_REMOVE_DEVICE
  DefaultPnpHandler,  // IRP_MN_CANCEL_REMOVE_DEVICE
  DefaultPnpHandler,  // IRP_MN_STOP_DEVICE
  DefaultPnpHandler,  // IRP_MN_QUERY_STOP_DEVICE
  DefaultPnpHandler,  // IRP_MN_CANCEL_STOP_DEVICE
  DefaultPnpHandler,  // IRP_MN_QUERY_DEVICE_RELATIONS
  DefaultPnpHandler,  // IRP_MN_QUERY_INTERFACE
  DefaultPnpHandler,  // IRP_MN_QUERY_CAPABILITIES
  DefaultPnpHandler,  // IRP_MN_QUERY_RESOURCES
  DefaultPnpHandler,  // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
  DefaultPnpHandler,  // IRP_MN_QUERY_DEVICE_TEXT
  DefaultPnpHandler,  // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
  DefaultPnpHandler,  //
  DefaultPnpHandler,  // IRP_MN_READ_CONFIG
  DefaultPnpHandler,  // IRP_MN_WRITE_CONFIG
  DefaultPnpHandler,  // IRP_MN_EJECT
  DefaultPnpHandler,  // IRP_MN_SET_LOCK
  DefaultPnpHandler,  // IRP_MN_QUERY_ID
  DefaultPnpHandler,  // IRP_MN_QUERY_PNP_DEVICE_STATE
  DefaultPnpHandler,  // IRP_MN_QUERY_BUS_INFORMATION
  DefaultPnpHandler,  // IRP_MN_DEVICE_USAGE_NOTIFICATION
  DefaultPnpHandler,  // IRP_MN_SURPRISE_REMOVAL
 };

 ULONG fcn = stack->MinorFunction;
 if (fcn >= arraysize(fcntab))
 {      // unknown function
  status = DefaultPnpHandler(pdx, Irp); // some function we don't know about
  return status;
 }      // unknown function

#if DBG
 static char* fcnname[] =
 {
  "IRP_MN_START_DEVICE",
  "IRP_MN_QUERY_REMOVE_DEVICE",
  "IRP_MN_REMOVE_DEVICE",
  "IRP_MN_CANCEL_REMOVE_DEVICE",
  "IRP_MN_STOP_DEVICE",
  "IRP_MN_QUERY_STOP_DEVICE",
  "IRP_MN_CANCEL_STOP_DEVICE",
  "IRP_MN_QUERY_DEVICE_RELATIONS",
  "IRP_MN_QUERY_INTERFACE",
  "IRP_MN_QUERY_CAPABILITIES",
  "IRP_MN_QUERY_RESOURCES",
  "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
  "IRP_MN_QUERY_DEVICE_TEXT",
  "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
  "",
  "IRP_MN_READ_CONFIG",
  "IRP_MN_WRITE_CONFIG",
  "IRP_MN_EJECT",
  "IRP_MN_SET_LOCK",
  "IRP_MN_QUERY_ID",
  "IRP_MN_QUERY_PNP_DEVICE_STATE",
  "IRP_MN_QUERY_BUS_INFORMATION",
  "IRP_MN_DEVICE_USAGE_NOTIFICATION",
  "IRP_MN_SURPRISE_REMOVAL",
 };

 KdPrint(("PNP Request (%s)/n", fcnname[fcn]));
#endif // DBG

 status = (*fcntab[fcn])(pdx, Irp);
 KdPrint(("Leave HelloWDMPnp/n"));
 return status;
}

/************************************************************************
* 函数名称:HelloWDMDispatchRoutine
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,
         IN PIRP Irp)
{
 PAGED_CODE();
 KdPrint(("Enter HelloWDMDispatchRoutine/n"));
 Irp->IoStatus.Status = STATUS_SUCCESS;
 Irp->IoStatus.Information = 0; // no bytes xfered
 IoCompleteRequest( Irp, IO_NO_INCREMENT );
 KdPrint(("Leave HelloWDMDispatchRoutine/n"));
 return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloWDMUnload
*************************************************************************/
#pragma PAGEDCODE
void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject)
{
 PAGED_CODE();
 KdPrint(("Enter HelloWDMUnload/n"));
 KdPrint(("Leave HelloWDMUnload/n"));
}

 

解释下:整个结构其实很简单,就是个DriverEntry函数,类似C中的main。在DriverEntry中调用了HelloWDMAddvice、HelloWDMPnp、HelloWDMDispatchRoutine和HelloWDMUnload四个函数。当然了,说是DriverEntry调用可能不合适,因为这些函数都是回调函数,其实都是在某个适合的时刻由系统调用的。而在HelloWDMPnp中又调用了DefaultPnpHandler和HandleRemoveDevice两个函数,因此,整个代码文件就是以上7个函数组成。

一、AddDevice回调函数只有在WDM驱动程序中出现,用于创建设备对象并由PNP管理器调用。

二、出现了设备栈的概念,这个日后书中会有解释

三、大部分的卸载任务,WDM已经放在了IRP_MN_REMOVE_DEVICED的处理函数HandleRemoveDevice中了