📄 hellowdm.cpp
字号:
#include "HelloWDM.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] = HelloWDMDispatchControlp;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloWDMCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloWDMClose;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloWDMRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMWrite;
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;
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\\COM7");
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;
}
#pragma PAGEDCODE
NTSTATUS HelloWDMCreate(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PAGED_CODE();
KdPrint(("HelloWDMCreate()\n"));
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// Init the device extension
pdx->BaudRate = 1200;
pdx->RTSstate = 0;
pdx->DTRstate = 0;
pdx->Timeouts.ReadIntervalTimeout = 0;
pdx->Timeouts.ReadTotalTimeoutMultiplier = 0;
pdx->Timeouts.ReadTotalTimeoutConstant = 0;
pdx->Timeouts.WriteTotalTimeoutMultiplier = 0;
pdx->Timeouts.WriteTotalTimeoutConstant = 0;
//pdx->Lc
pdx->IsOpen = TRUE;
KeInitializeSpinLock(&pdx->WriteSpinLock);
KeInitializeSpinLock(&pdx->IoctlSpinLock);
pdx->EventMask = 0;
pdx->HistoryEvents = 0;
pdx->pWaitIrp = NULL;
pdx->pReadIrp = NULL;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
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);
IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);
//调用IoDetachDevice()把fdo从设备栈中脱开:
if (pdx->NextStackDevice)
IoDetachDevice(pdx->NextStackDevice);
//删除fdo:
IoDeleteDevice(pdx->fdo);
KdPrint(("Leave HandleRemoveDevice\n"));
return status;
}
/************************************************************************
* 函数名称: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) =
{
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))
{ // 未知的子功能代码
status = DefaultPnpHandler(pdx, Irp); // some function we don't know about
return status;
}
#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;
}
/************************************************************************
* 函数名称:HelloWDMUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
DriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject)
{
PAGED_CODE();
KdPrint(("Enter HelloWDMUnload\n"));
KdPrint(("Leave HelloWDMUnload\n"));
}
void PrintIoControlCode(ULONG code)
{
switch(code)
{
case IOCTL_SERIAL_CLEAR_STATS:
KdPrint(("IOCTL code: IOCTL_SERIAL_CLEAR_STATS\n"));
break;
case IOCTL_SERIAL_CLR_DTR:
KdPrint(("IOCTL code: IOCTL_SERIAL_CLR_DTR\n"));
break;
case IOCTL_SERIAL_CLR_RTS:
KdPrint(("IOCTL code: IOCTL_SERIAL_CLR_RTS\n"));
break;
case IOCTL_SERIAL_CONFIG_SIZE:
KdPrint(("IOCTL code: IOCTL_SERIAL_CONFIG_SIZE\n"));
break;
case IOCTL_SERIAL_GET_BAUD_RATE:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_BAUD_RATE\n"));
break;
case IOCTL_SERIAL_GET_CHARS:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_CHARS\n"));
break;
case IOCTL_SERIAL_GET_COMMSTATUS:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_COMMSTATUS\n"));
break;
case IOCTL_SERIAL_GET_DTRRTS:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_DTRRTS\n"));
break;
case IOCTL_SERIAL_GET_HANDFLOW:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_HANDFLOW\n"));
break;
case IOCTL_SERIAL_GET_LINE_CONTROL:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_LINE_CONTROL\n"));
break;
case IOCTL_SERIAL_GET_MODEM_CONTROL:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_MODEM_CONTROL\n"));
break;
case IOCTL_SERIAL_GET_MODEMSTATUS:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_MODEMSTATUS\n"));
break;
case IOCTL_SERIAL_GET_PROPERTIES:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_PROPERTIES\n"));
break;
case IOCTL_SERIAL_GET_STATS:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_STATS\n"));
break;
case IOCTL_SERIAL_GET_TIMEOUTS:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_TIMEOUTS\n"));
break;
case IOCTL_SERIAL_GET_WAIT_MASK:
KdPrint(("IOCTL code: IOCTL_SERIAL_GET_WAIT_MASK\n"));
break;
case IOCTL_SERIAL_IMMEDIATE_CHAR:
KdPrint(("IOCTL code: IOCTL_SERIAL_IMMEDIATE_CHAR\n"));
break;
case IOCTL_SERIAL_LSRMST_INSERT:
KdPrint(("IOCTL code: IOCTL_SERIAL_LSRMST_INSERT\n"));
break;
case IOCTL_SERIAL_PURGE:
KdPrint(("IOCTL code: IOCTL_SERIAL_PURGE\n"));
break;
case IOCTL_SERIAL_RESET_DEVICE:
KdPrint(("IOCTL code: IOCTL_SERIAL_RESET_DEVICE\n"));
break;
case IOCTL_SERIAL_SET_BAUD_RATE:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_BAUD_RATE\n"));
break;
case IOCTL_SERIAL_SET_BREAK_OFF:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_BREAK_OFF\n"));
break;
case IOCTL_SERIAL_SET_BREAK_ON:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_BREAK_ON\n"));
break;
case IOCTL_SERIAL_SET_CHARS:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_CHARS\n"));
break;
case IOCTL_SERIAL_SET_DTR:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_DTR\n"));
break;
case IOCTL_SERIAL_SET_FIFO_CONTROL:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_FIFO_CONTROL\n"));
break;
case IOCTL_SERIAL_SET_HANDFLOW:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_HANDFLOW\n"));
break;
case IOCTL_SERIAL_SET_LINE_CONTROL:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_LINE_CONTROL\n"));
break;
case IOCTL_SERIAL_SET_MODEM_CONTROL:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_MODEM_CONTROL\n"));
break;
case IOCTL_SERIAL_SET_QUEUE_SIZE:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_QUEUE_SIZE\n"));
break;
case IOCTL_SERIAL_SET_RTS:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_RTS\n"));
break;
case IOCTL_SERIAL_SET_TIMEOUTS:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_TIMEOUTS\n"));
break;
case IOCTL_SERIAL_SET_WAIT_MASK:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_WAIT_MASK\n"));
break;
case IOCTL_SERIAL_SET_XOFF:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_XOFF\n"));
break;
case IOCTL_SERIAL_SET_XON:
KdPrint(("IOCTL code: IOCTL_SERIAL_SET_XON\n"));
break;
case IOCTL_SERIAL_WAIT_ON_MASK:
KdPrint(("IOCTL code: IOCTL_SERIAL_WAIT_ON_MASK\n"));
break;
case IOCTL_SERIAL_XOFF_COUNTER:
KdPrint(("IOCTL code: IOCTL_SERIAL_XOFF_COUNTER\n"));
break;
default:
KdPrint(("IOCTL code: unkown\n"));
}
}
VOID DriverCancelWaitIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
KdPrint(("DriverCancelWaitIrp\n"));
PDEVICE_EXTENSION pExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
KIRQL OldIrql;
IoReleaseCancelSpinLock(Irp->CancelIrql);
KeAcquireSpinLock(&pExtension->IoctlSpinLock, &OldIrql);
pExtension->pWaitIrp = NULL;
KeReleaseSpinLock(&pExtension->IoctlSpinLock, OldIrql);
Irp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
VOID DriverCheckEvent(IN PDEVICE_EXTENSION pExtension, IN ULONG events)
{
KdPrint(("DriverCheckEvent\n"));
PIRP pOldWaitIrp = NULL;
PDRIVER_CANCEL pOldCancelRoutine;
KIRQL OldIrql;
KeAcquireSpinLock(&pExtension->IoctlSpinLock, &OldIrql);
pExtension->HistoryEvents |= events;
events &= pExtension->EventMask;
//相当于设置触发事件
if ((pExtension->pWaitIrp != NULL) && (events != 0))
{
pOldWaitIrp = pExtension->pWaitIrp;
pOldCancelRoutine = IoSetCancelRoutine(pOldWaitIrp, NULL);
//是否已经被cancel掉?
if (pOldCancelRoutine != NULL)
{
// Nein, also Request beenden
pOldWaitIrp->IoStatus.Information = sizeof(ULONG);
*(PULONG)pOldWaitIrp->AssociatedIrp.SystemBuffer = events;
pOldWaitIrp->IoStatus.Status = STATUS_SUCCESS;
pExtension->pWaitIrp = NULL;
pExtension->HistoryEvents = 0;
}
else
{
//如果cancel掉,就不用IoCompleteRequest了
pOldWaitIrp = NULL;
}
}
KeReleaseSpinLock(&pExtension->IoctlSpinLock, OldIrql);
if (pOldWaitIrp != NULL)
{
KdPrint(("complete the wait irp\n"));
IoCompleteRequest(pOldWaitIrp, IO_NO_INCREMENT);
}
}
#pragma PAGEDCODE
NTSTATUS HelloWDMDispatchControlp(PDEVICE_OBJECT fdo,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -