1. 程式人生 > >I/O定時器_3秒執行一次_1秒執行一次

I/O定時器_3秒執行一次_1秒執行一次

#include <windows.h>
#include <stdio.h>
//使用CTL_CODE必須加入winioctl.h
#include <winioctl.h>
#include "..\IO定時器\Ioctls.h"
int main()
{
	HANDLE hDevice = 
		CreateFile(L"\\\\.\\HelloDDK",
					GENERIC_READ | GENERIC_WRITE,
					0,		// share mode none
					NULL,	// no security
					OPEN_EXISTING,
					FILE_ATTRIBUTE_NORMAL,
					NULL );		// no template
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("Failed to obtain file handle to device: "
			"%s with Win32 error code: %d\n",
			"MyWDMDevice", GetLastError() );
		return 1;
	}
	DWORD dwOutput;
	DeviceIoControl(hDevice, IOCTL_START_TIMER, NULL, 0, NULL, 0, &dwOutput, NULL);//將控制程式碼直接傳送給指定的裝置驅動程式,使相應的裝置執行相應的操作。
	system("pause");
 	DeviceIoControl(hDevice, IOCTL_STOP, NULL, 0, NULL, 0, &dwOutput, NULL);
	CloseHandle(hDevice);
	system("pause");
	return 0;
}
// IOCTLS.H -- IOCTL code definitions for fileio driver
// Copyright (C) 1999 by Walter Oney
// All rights reserved
#ifndef IOCTLS_H
#define IOCTLS_H
#ifndef CTL_CODE
	#pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h")
#endif
#define IOCTL_START_TIMER CTL_CODE(\
			FILE_DEVICE_UNKNOWN, \
			0x800, \
			METHOD_BUFFERED, \
			FILE_ANY_ACCESS)

#define IOCTL_STOP CTL_CODE(\
			FILE_DEVICE_UNKNOWN, \
			0x801, \
			METHOD_IN_DIRECT, \
			FILE_ANY_ACCESS)
#endif
/************************************************************************
* 檔名稱:Driver.h                                                 
* 作    者:張帆
* 完成日期:2007-11-1
*************************************************************************/
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif 
#include "ioctls.h"
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
//設定3秒間隔時間
#define TIMER_OUT	4
typedef struct _DEVICE_EXTENSION {
	PDEVICE_OBJECT pDevice;
	UNICODE_STRING ustrDeviceName;	//裝置名稱
	UNICODE_STRING ustrSymLinkName;	//符號連結名
	LONG lTimerCount;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
// 函式宣告
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp);
NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp);

/************************************************************************
* 檔名稱:Driver.cpp                                                 
* 作    者:張帆
* 完成日期:2007-11-1
*************************************************************************/
#include "Driver.h"
/************************************************************************
* 函式名稱:DriverEntry
* 功能描述:初始化驅動程式,定位和申請硬體資源,建立核心物件
* 引數列表:
      pDriverObject:從I/O管理器中傳進來的驅動物件
      pRegistryPath:驅動程式在登錄檔的中的路徑
* 返回 值:返回初始化驅動狀態
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath	) 
{
	NTSTATUS status;
	KdPrint(("Enter DriverEntry\n"));
	//設定解除安裝函式
	pDriverObject->DriverUnload = HelloDDKUnload;
	//設定派遣函式
	for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)
		pDriverObject->MajorFunction[i] = HelloDDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDeviceIOControl;
	//建立驅動裝置物件
	status = CreateDevice(pDriverObject);
	//IoStartTimer(pDriverObject->DeviceObject);
	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);//3秒	計算機語言函式,該函式減小指定的變數,並檢查值,可以保證同一時刻只有一個執行緒訪問該變數,即保證增加操作的原子性。
	LONG previousCount = InterlockedCompareExchange(&pDevExt->lTimerCount,TIMER_OUT,0);//如果計數器減到0,重新程式設計TIMER_OUT,整個過程是互鎖運算  擴充套件減到0 再弄成3
	//是把目標運算元(第1引數所指向的記憶體中的數)與一個值(第3引數)比較,如果相等,則用另一個值(第2引數)與目標運算元(第1引數所指向的記憶體中的數)交換;InterlockedExchange是不比較直接交換。
	//每隔三秒,計數器一個迴圈,輸出以下log
	if (previousCount == 0)//返回值是 Destination(第一個引數) 指標的初始值
	{
		//KdPrint(("%d seconds time out!\n",TIMER_OUT));
		KdPrint(("這裡是3秒執行一次"));
	}
	//證明該執行緒執行在任意執行緒上下文的
    PEPROCESS pEProcess = IoGetCurrentProcess();
    PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);//即可得到使用者程序
    KdPrint(("當前程序名%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,L"\\Device\\MyDDKDevice");
	//建立裝置
	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);//io定時器初始化
	//建立符號連結
	UNICODE_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 HelloDDKUnload (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 );
	//}
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK");
	pNextObj = pDriverObject->DeviceObject;//我的第一個裝置          
	IoDeleteSymbolicLink(&symLinkName);//刪除符號連線          
	IoDeleteDevice(pDriverObject->DeviceObject);//刪除裝置  
}
/************************************************************************
* 函式名稱:HelloDDKDispatchRoutin
* 功能描述:對讀IRP進行處理
* 引數列表:
      pDevObj:功能裝置物件
      pIrp:從IO請求包
* 返回 值:返回狀態
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutin(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 HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;
	KdPrint(("Enter HelloDDKDeviceIOControl\n"));
	//得到當前堆疊
	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;//時間間隔3秒
			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;
}



相關推薦

I/O定時_3執行_1執行

#include <windows.h> #include <stdio.h> //使用CTL_CODE必須加入winioctl.h #include <winioctl.h> #include "..\IO定時器\Ioctls.h" i

CCS中使用DSP定時的計時程式,可以精確計算某段程式的執行時間

#include <csl_timer.h> TIMER_Handle hTimer0; TIMER_Config TimerConfig = { TIMER_CTL_RMK ( TIMER_CTL_SPND_EMUSTOP, TIMER_CTL_

啟動系統定時,每隔1分鐘/指定時間執行任務 學習筆記

啟動系統定時器每隔1分鐘/指定時間執行 import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class DemoTimer { //啟

PHP 定時實現 timer 每隔幾執行

PHP定時器實現每隔幾秒執行一次,下面寫個簡單例子來講解這個方法。 <?PHP  ignore_user_abort();//關閉瀏覽器仍然執行 set_time_limit(0);//讓程式一直執行下去 $interval=3;//每隔一定時間執行 do{   

linux 定時 PHP定時實現每隔幾執行

PHP定時器實現每隔幾秒執行一次,下面寫個簡單例子來講解這個方法。 <?php  ignore_user_abort();//關閉瀏覽器仍然執行 set_time_limit(0);//讓程式一直執行下去 $interval=3;//每隔一定時間執行 do{   

這是一個定時,定時執行,用在定時發送郵件

mail pri 創建 sendmail public sta 發送 mes times public static void main(String[] args) { //1. 創建計時器類 Timer timer = new Timer(); //2. 創建任

作業系統,核心定時:使用“訊號”建立種使用者空間機制來測量一個多執行緒程式的執行時間。

      核心是一個作業系統的核心。它負責管理系統的程序、記憶體、裝置驅動程式、檔案和網路系統,決定著系統的效能和穩定性。 定時器是Linux提供的一種定時服務的機制,它在某個特定的時間喚醒某個程序來進行工作。核心在時鐘中斷髮生後檢測各定時器是否到期,在li

.js高階(6)-閉包-定時-js中程式碼執行順序

閉包1:巢狀的兩個作用域中 內層作用域訪問外層作用域 區域性變數的 過程 閉包2 :  就是能夠訪問其他函式內部變數的函式;     由於js中只有函式內部的子函式才能訪問區域性變數,所以可以簡單的把閉包理解為"定義在哈拿書內部的函式";     本質上閉包就是連線函式內部和外部的一座橋樑;

步步動手實現高併發的Reactor模型 —— Kafka底層如何充分利用多執行緒優勢去處理網路I/O與業務分發

一、從《Apeche Kafka原始碼剖析》上搬來的概念和圖 Kafka網路採用的是Reactor模式,是一種基於事件驅動的模式。熟悉Java程式設計的讀者應該瞭解Java NIO提供了Reactor模式的API。常見的單執行緒Java NIO程式設計模式如圖所示。 熟悉NIO程式設計都應該知道這個Sele

spring定時定時執行的問題

今天在做一個專案的時候用到了Spring的定時計劃任務。這是Spring的特色功能,可以根據設定在特定的時間或間隔時間做特定的事。 下面給出一個例子: package net.csdn.blog.chaijunkukn;   import

Java 定時任務執行():定時 Timer 的使用.

https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/   閱讀目錄 一、概念 二、Timer類注意事項 三、scheduleAtFixedRate(TimerTask task,Date f

js定時(執行、重複執行)

1,只執行一次的定時器 <script> //定時器 非同步執行 function hello(){ alert("hello"); } //使用方法名字執行方法 var t1 = window.setTimeout(hello,1000); va

rxjava2定時請求資料

專案進行的過程中有個需求是在20秒內每秒請求一次資料,請求成功的json中有個欄位,如果有這個欄位代表請求成功,如果沒有則繼續請求,直到20秒結束,20秒結束則失敗 本來最開始採用countDownTimer來做,很簡單就搞定了,但是專案引進了rxjava,那

使用定時2後終止一個執行

使用最簡便的方法終止執行緒。 class Thread1 extends Thread{ private int count = 5; private String name; public Thread1(String name)

android 定時,每變換圖片!

在android中,要讓每秒進行一次ui更新,就需要利用到定時器和handler,message的結合,如果不使用handler就不能達到更新ui的效果,我的理解是handler中存在一個佇列問題,可以保證不產生阻塞。 程式碼如下: package com.my; im

種提高單片機i/o口驅動能力的方法

water clas aik eas 發現 strong img white .net 一、簡述問題 當你用單片驅動發光二極管的時,你還感覺不到P0、P1口的差別。(10-20mA之間,當中P0驅動能力最強,但對於驅動直流電機依舊非常弱。其結果就是電機不轉)。那麽

Python開發【筆記】:單線程下執行多個定時

自動 代碼 python 線程 timer ont -s 大量 過多 單線程多定時器   前言:公司業務需求,實例當中大量需要啟動定時器的操作;大家都知道python中的定時器用的是threading.Timer,每當啟動一個定時器時,程序內部起了一個線程,定時器觸發執行結

定時4+10控制js

on() 控制 int text tin fun 定時器 ext tex $(function() { window.setInterval(numJia, 4000);}) function numJia() { var str=$(".num").text(); var

WinForm中,每隔段時間(參數)調用函數(使用定時

pre tick break switch 時間 器) chan pri args 1      System.Windows.Forms.Timer setTimer; //定義一個定時器 2 int flg = 0;

Linux crontab定時設置(定期執行java程序)(轉)

在那 安裝 一次 tin 文件名 ani data 說明 ive Crontab 語法 Crontab語法一個crontab文件用五個段來定義:天,日期和時間,和一個要定期執行的命令代碼。 * * * * * command to be execut