?? hellowdm.cpp
字號:
/************************************************************************
* 文件名稱:HelloWDM.cpp
* 作 者:張帆
* 完成日期:2007-11-1
*************************************************************************/
#include "HelloWDM.h"
#include <initguid.h>
#include "guid.h"
/************************************************************************
* 函數名稱:DriverEntry
* 功能描述:初始化驅動程序,定位和申請硬件資源,創建內核對象
* 參數列表:
pDriverObject:從I/O管理器中傳進來的驅動對象
pRegistryPath:驅動程序在注冊表的中的路徑
* 返回 值:返回初始化驅動狀態
*************************************************************************/
#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_CLOSE] =
pDriverObject->MajorFunction[IRP_MJ_READ] =
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_POWER] = HelloWDMDispatchPower;
pDriverObject->DriverUnload = HelloWDMUnload;
KdPrint(("Leave DriverEntry\n"));
return STATUS_SUCCESS;
}
/************************************************************************
* 函數名稱:HelloWDMAddDevice
* 功能描述:添加新設備
* 參數列表:
DriverObject:從I/O管理器中傳進來的驅動對象
PhysicalDeviceObject:從I/O管理器中傳進來的物理設備對象
* 返回 值:返回添加新設備狀態
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
PAGED_CODE();
KdPrint(("Enter HelloWDMAddDevice\n"));
NTSTATUS status;
PDEVICE_OBJECT fdo;
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,//沒有指定設備名
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);
//創建設備接口
status = IoRegisterDeviceInterface(PhysicalDeviceObject, &MY_WDM_DEVICE, NULL, &pdx->interfaceName);
if( !NT_SUCCESS(status))
{
IoDeleteDevice(fdo);
return status;
}
KdPrint(("%wZ\n",&pdx->interfaceName));
IoSetDeviceInterfaceState(&pdx->interfaceName, TRUE);
if( !NT_SUCCESS(status))
{
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
* 功能描述:對PNP IRP進行缺省處理
* 參數列表:
pdx:設備對象的擴展
Irp:從IO請求包
* 返回 值:返回狀態
*************************************************************************/
#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
* 功能描述:對IRP_MN_REMOVE_DEVICE IRP進行處理
* 參數列表:
fdo:功能設備對象
Irp:從IO請求包
* 返回 值:返回狀態
*************************************************************************/
#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);
IoSetDeviceInterfaceState(&pdx->interfaceName, FALSE);
RtlFreeUnicodeString(&pdx->interfaceName);
//調用IoDetachDevice()把fdo從設備棧中脫開:
if (pdx->NextStackDevice)
IoDetachDevice(pdx->NextStackDevice);
//刪除fdo:
IoDeleteDevice(pdx->fdo);
KdPrint(("Leave HandleRemoveDevice\n"));
return status;
}
#pragma PAGEDCODE
NTSTATUS HandleStartDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter HandleStartDevice\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
NTSTATUS status = DefaultPnpHandler(pdx, Irp);
KdPrint(("Leave HandleStartDevice\n"));
return status;
}
NTSTATUS OnRequestComplete(PDEVICE_OBJECT junk, PIRP Irp, PKEVENT pev)
{ // OnRequestComplete
//在完成例程中設置等待事件
KeSetEvent(pev, 0, FALSE);
//標志本IRP還需要再次被完成
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
{ // ForwardAndWait
PAGED_CODE();
KEVENT event;
//初始化事件
KeInitializeEvent(&event, NotificationEvent, FALSE);
//將本層堆棧拷貝到下一層堆棧
IoCopyCurrentIrpStackLocationToNext(Irp);
//設置完成例程
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnRequestComplete,
(PVOID) &event, TRUE, TRUE, TRUE);
//調用底層驅動,即PDO
IoCallDriver(pdx->NextStackDevice, Irp);
//等待PDO完成
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
return Irp->IoStatus.Status;
} // ForwardAndWait
NTSTATUS CompleteIrp( IN PIRP Irp, IN NTSTATUS status, IN ULONG info)
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return status;
}
#define SetMostPoweredState( SystemState, OurDeviceState) \
dps = deviceCapabilities->DeviceState[SystemState]; \
if( dps==PowerDeviceUnspecified || dps>OurDeviceState) \
deviceCapabilities->DeviceState[SystemState] = OurDeviceState
NTSTATUS PnpQueryCapabilitiesHandler( IN PDEVICE_EXTENSION pdx, IN PIRP Irp)
{
NTSTATUS status = ForwardAndWait( pdx, Irp);
if( NT_SUCCESS(status))
{
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_CAPABILITIES deviceCapabilities;
deviceCapabilities = IrpStack->Parameters.DeviceCapabilities.Capabilities;
for(int ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++)
KdPrint(("Capabilities from bus: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds]));
DEVICE_POWER_STATE dps;
SetMostPoweredState( PowerSystemWorking, PowerDeviceD0);
SetMostPoweredState( PowerSystemSleeping1, PowerDeviceD3);
SetMostPoweredState( PowerSystemSleeping2, PowerDeviceD3);
SetMostPoweredState( PowerSystemSleeping3, PowerDeviceD3);
SetMostPoweredState( PowerSystemHibernate, PowerDeviceD3);
SetMostPoweredState( PowerSystemShutdown, PowerDeviceD3);
//重點就是這句話了
deviceCapabilities->Removable=TRUE;
for(ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++)
KdPrint(("Capabilities now: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds]));
}
return CompleteIrp( Irp, status, Irp->IoStatus.Information);
}
/************************************************************************
* 函數名稱:HelloWDMPnp
* 功能描述:對即插即用IRP進行處理
* 參數列表:
fdo:功能設備對象
Irp:從IO請求包
* 返回 值:返回狀態
*************************************************************************/
#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) =
{
HandleStartDevice, // 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
PnpQueryCapabilitiesHandler, // 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -