/*
例程是在运行在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 = ; 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,); //每隔三秒,计数器一个循环,输出以下log
if (previousCount==)
{
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,
, 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 = ; // 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 = ; 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;
}
代码