使用这种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);
}
让后就是打开和关闭定时器了...