您的位置:首页 > 大数据 > 物联网

时钟 IoTimer

2015-11-04 11:37 726 查看
/*
例程是在运行在DISPATCH_LEVEL的IRQL级别
例程中不能使用分页内存
另外在函数首部使用 #pragma LOCKEDCODE
*/

#include "Driver.h"

#define DeviceName L"\\Device\\MyDDKDevice"

#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath    )
{
NTSTATUS status;
KdPrint(("Enter DriverEntry\n"));

pDriverObject->DriverUnload = UnloadDriver;

//设置派遣函数

/*
ARRAY_SIZE 定义设备结构体的个数
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr))

*/

for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)    //ARRAY_SIZE 定义设备结构体的个数
pDriverObject->MajorFunction[i] = DispatchFunction;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControl;

//创建驱动设备对象
status = CreateDevice(pDriverObject);

KdPrint(("Leave DriverEntry\n"));
return status;
}

#pragma LOCKEDCODE
VOID OnTimer(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
DeviceObject->DeviceExtension;
KdPrint(("Enter OnTimer!\n"));

//将计数器自锁减一
InterlockedDecrement(&pDevExt->lTimerCount);

/*如果计数器减到0,重新编程TIMER_OUT,整个过程是互锁运算
LONG __cdecl InterlockedCompareExchange(

__inout  LONG volatile *Destination, //当前值

__in     LONG Exchange, //当比较值与当前值相同时 替换当前值

__in     LONG Comparand //比较值

PVOID __cdecl InterlockedCompareExchangePointer(

__inout  PVOID volatile *Destination,

__in     PVOID Exchange,

__in     PVOID Comparand

这两个函数以原子方式执行一个测试和设置操作。对32位应用程序来说,这两个函数都对32位值进行操作;
在64位应用程序中,InterlockedCompareExchange对32位值进行操作而InterlockedCompareExchangePointer对64位值进行操作。
函数会将当前值(Destination指向的)与参数Comparand进行比较,如果两个值相同,那么函数会将*Destination修改为Exchange参数指定的值。
若不等,则*Destination保持不变。函数会返回*Destination原来的值。所有这些操作都是一个原子执行单元来完成的。

*/
LONG previousCount = InterlockedCompareExchange(&pDevExt->lTimerCount,TIMER_OUT,0);

//每隔三秒,计数器一个循环,输出以下log
if (previousCount==0)
{
KdPrint(("%d seconds time out!\n",TIMER_OUT));
}

//证明该线程运行在任意线程上下文的
/*
PEPROCESS pEProcess = IoGetCurrentProcess();
PTSTR ProcessName = (PTSTR) ((ULONG)pEProcess + 0x174);
*/
PEPROCESS pEProcess = IoGetCurrentProcess();

PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);//即可得到用户进程

KdPrint(("The current process is %s\n",ProcessName));
}

/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (
IN PDRIVER_OBJECT    pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;

//创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,DeviceName);

//创建设备
status = IoCreateDevice( pDriverObject,
sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,
FILE_DEVICE_UNKNOWN,
0, TRUE,
&pDevObj );
if (!NT_SUCCESS(status))
return status;

pDevObj->Flags |= DO_DIRECT_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;

IoInitializeTimer(pDevObj,OnTimer,NULL);    // 初始化IoTimer

//创建符号链接
// 不进行Ring3层的交互  则不需要进行创建符号链接
NICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloDDKUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID UnloadDriver (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT    pNextObj;
KdPrint(("Enter DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
while (pNextObj != NULL)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pNextObj->DeviceExtension;
//删除符号链接
UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj = pNextObj->NextDevice;
IoDeleteDevice( pDevExt->pDevice );
}
}

/************************************************************************
* 函数名称:HelloDDKDispatchRoutin
* 功能描述:对读IRP进行处理
* 参数列表:
pDevObj:功能设备对象
pIrp:从IO请求包

默认派遣例程
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS DispatchFunction(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{

KdPrint(("Enter HelloDDKDispatchRoutin\n"));

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
//建立一个字符串数组与IRP类型对应起来
static char* irpname[] =
{
"IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE",
"IRP_MJ_READ",
"IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP",
};

UCHAR type = stack->MajorFunction;
if (type >= arraysize(irpname))
KdPrint((" - Unknown IRP, major type %X\n", type));
else
KdPrint(("\t%s\n", irpname[type]));

NTSTATUS status = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;    // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );

KdPrint(("Leave HelloDDKDispatchRoutin\n"));

return status;
}

#pragma PAGEDCODE
NTSTATUS DeviceIOControl(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
KdPrint(("Enter HelloDDKDeviceIOControl\n"));

//获得当前IRP堆栈
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
//得到输入缓冲区大小
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
//得到输出缓冲区大小
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
//得到IOCTL码
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;

PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDevObj->DeviceExtension;

ULONG info = 0;

switch (code)
{                        // process request
case IOCTL_START_TIMER:
{
KdPrint(("IOCTL_START_TIMER\n"));
pDevExt->lTimerCount = TIMER_OUT;
IoStartTimer(pDevObj);        //激活时钟
break;
}
case IOCTL_STOP:
{
KdPrint(("IOCTL_STOP\n"));
IoStopTimer(pDevObj);        // 停止时钟
break;
}
default:
status = STATUS_INVALID_VARIANT;
}

// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = info;    // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );

KdPrint(("Leave HelloDDKDeviceIOControl\n"));

return status;
}


代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: