使用这种I/O定时器,系统会每隔1秒调用定时例程...
可以用一个变量存储计数值,当大于某值做一些什么并重设初始值,,那么可以实现N秒定时器...
如果要实现ms级别的间隔可以用DPC定时器,,,我会在下一篇博文写出..
驱动部分:
typedef struct _DEVICE_EXTENSION{ UNICODE_STRING ustrDeviceName; UNICODE_STRING ustrDeviceSymlink; LONG lTimerCount; }DEVICE_EXTENSION;
定义设备扩展用来储存那个定时器的计数值
#define IOCOL_START CTL_CODE(FILE_DEVICE_UNKNOWN ,5001,METHOD_BUFFERED ,FILE_ANY_ACCESS) #define IOCOL_STOP CTL_CODE(FILE_DEVICE_UNKNOWN ,5002,METHOD_BUFFERED ,FILE_ANY_ACCESS)
#ifdef __cplusplus extern "C" { #endif NTSTATUS DriverEntry( IN OUT PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { PDEVICE_OBJECT pdoDeviceObj = 0; NTSTATUS status = STATUS_UNSUCCESSFUL; pdoGlobalDrvObj = DriverObject; // Create the device object. if(!NT_SUCCESS(status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), &usDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pdoDeviceObj ))) { // Bail out (implicitly forces the driver to unload). return status; }; DEVICE_EXTENSION *pDex=(DEVICE_EXTENSION *)pdoDeviceObj->DeviceExtension; pDex->ustrDeviceName=usDeviceName; pDex->ustrDeviceSymlink=usSymlinkName; pDex->lTimerCount=3; // Now create the respective symbolic link object if(!NT_SUCCESS(status = IoCreateSymbolicLink( &usSymlinkName, &usDeviceName ))) { IoDeleteDevice(pdoDeviceObj); return status; } // NOTE: You need not provide your own implementation for any major function that // you do not want to handle. I have seen code using DDKWizard that left the // *empty* dispatch routines intact. This is not necessary at all! DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DRIVER4_DispatchCreateClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DRIVER4_DispatchDeviceControl; DriverObject->DriverUnload = DRIVER4_DriverUnload; KdPrint(("初始化时钟...哈哈哈....ternsoft.com")); IoInitializeTimer(pdoDeviceObj,MyIoTimerRoutine,NULL); return STATUS_SUCCESS; } #ifdef __cplusplus }; // extern "C" #endif
NTSTATUS DRIVER4_DispatchDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); switch(irpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_DRIVER4_OPERATION: // status = SomeHandlerFunction(irpSp); break; case IOCOL_START: KdPrint(("case IOCOL_START")); IoStartTimer(DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; break; case IOCOL_STOP: KdPrint(("case IOCOL_STOP")); IoStopTimer(DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; break; default: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; break; } status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
VOID MyIoTimerRoutine( IN DEVICE_OBJECT *DeviceObject, IN PVOID Context ){ DEVICE_EXTENSION *pDex=(DEVICE_EXTENSION *)DeviceObject->DeviceExtension; InterlockedIncrement(&pDex->lTimerCount); KdPrint(("时钟:%d",pDex->lTimerCount)); }下面是应用程序部分:
HANDLE m_hIoContorl;声明一只类成员,,用来保存打开设备的句柄
~CDeviceIoControlDlg(){ CloseHandle(m_hIoContorl); };在对象销毁前释放句柄
m_hIoContorl=CreateFile("\\\\.\\DRIVER4_DeviceName",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(m_hIoContorl==NULL){ MessageBox("打开设备失败"); }在BOOL CDeviceIoControlDlg::OnInitDialog()打开设备哈
void CDeviceIoControlDlg::OnButton1() { // TODO: Add your control notification handler code here DWORD dwRes; DeviceIoControl(m_hIoContorl,IOCOL_START,NULL,NULL,NULL,NULL,&dwRes,NULL); } void CDeviceIoControlDlg::OnButton2() { // TODO: Add your control notification handler code here DWORD dwRes; DeviceIoControl(m_hIoContorl,IOCOL_STOP,NULL,NULL,NULL,NULL,&dwRes,NULL); }让后就是打开和关闭定时器了...