驅動開發之 設備讀寫方式:緩沖區方式

1.

設備對象一共同擁有三種讀寫方式:緩沖區方式讀寫(Buffered方式);直接方式讀寫(Direct方式)。Neither方式。這三種方式的Flags分別相應DO_BUFFERED_IO,DO_DIRECT_IO,0

在buffered方式中。I/O管理器先創建一個與用戶模式數據緩沖區大小相等的系統緩沖區。而你的驅動程序將使用這個系統緩沖區工作。I/O管理器負責在系統緩沖區和用戶模式緩沖區之間復制數據。

?
在direct方式中,I/O管理器鎖定了包括用戶模式緩沖區的物理內存頁。并創建一個稱為MDL(內存描寫敘述符表)的輔助數據結構來描寫敘述鎖定頁。因此你的驅動程序將使用MDL工作。?
在neither方式中。I/O管理器僅簡單地把用戶模式的虛擬地址傳遞給你。

而使用用戶模式地址的驅動程序應十分小心。


2.

以下介紹緩沖區方式讀寫。其長處是比較簡單的攻克了將用戶地址傳入驅動的問題,缺點是須要用戶模式和內核模式之間數據復制。可想而知。執行效率會受到影響。

適合少量內存操作時使用的一種方法。

創建好設備IoCreateDevice后。須要設置DO_BUFFERED_IO, ?pDevObj->Flags |= DO_BUFFERED_IO.

如今以readfile為例,首先應用程序中須要提供一段緩沖區并把緩沖區大小作為參數傳入,比如

UCHAR OutputBuffer[10];
DWORD RetLen = 0;
readfile(hDevice,OutputBuffer,sizeof(OutputBuffer),&RetLen,NULL);

OutputBuffer是提供的輸出緩沖區。是用戶模式的內存地址,操作系統將此緩沖區的數據拷貝到內核模式下的地址中,sizeof(OutputBuffer)是緩沖區的大小,而RetLen是真正的輸出的字節數。


那么內核模式怎么得到此內核模式地址呢?怎么得到writefile或readfile的字節數呢?答案在以下。

此內核模式下的地址能夠通過此readfile創建的IRP的AssociatedIrp.SystemBuffer得到。

假如請求的IRP為PIRP pIrp(通常是派遣函數的參數),那么UCHAR* OutputBuffer= (UCHAR*)pIrp->AssociatedIrp.SystemBuffer;

而readfile請求的字節數為IO_STACK_LOCATION中的Parameters.Read.Length,writefilew為IO_STACK_LOCATION中的Parameters.Write.Length

//得到當前堆棧
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
//得到readfile緩沖區大小
ULONG cbread = stack->Parameters..Read.Length;
//得到writefile緩沖區大小
ULONG cbwrite = stack->Parameters.Write.Length;


得到了內核模式下的緩沖區地址了就能夠對此緩沖區操作了。比方:

UCHAR*?OutputBuffer= (UCHAR*)pIrp->AssociatedIrp.SystemBuffer;

ULONG cbread = stack->Parameters..Read.Length;

memcpy(OutputBuffer,0xBB,cbread);

這樣用戶模式下的緩沖區內得到的數據是0xBB。


另外還要設置實際操作的字節數,pIrp->IoStatus.Information = cbread;(實際操作的字節數不一定要設置為緩沖區的大小。但也不應該大于緩沖區的大小)

那么用戶模式下readfile的RetLen被設置為cbread。


以下是IRP_MJ_READ的派遣函數:

NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) 
{KdPrint(("Enter DispatchRead\n"));//對一般IRP的簡單操作。后面會介紹對IRP更復雜的操作NTSTATUS status = STATUS_SUCCESS;PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);ULONG ulReadLength = stack->Parameters.Read.Length;// 完畢IRP//設置IRP完畢狀態pIrp->IoStatus.Status = status;//設置IRP操作了多少字節pIrp->IoStatus.Information = ulReadLength;	memset(pIrp->AssociatedIrp.SystemBuffer,0xAA,ulReadLength);//處理IRPIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave DispatchRead\n"));return status;
}

設備讀寫方式:直接讀取方式:http://blog.csdn.net/liyun123gx/article/details/38043849

Neither方式:http://blog.csdn.net/liyun123gx/article/details/38046865



轉載于:https://www.cnblogs.com/gavanwanggw/p/6908009.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/456400.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/456400.shtml
英文地址,請注明出處:http://en.pswp.cn/news/456400.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

flask開啟調試的四種模式

在app.run()中加一個參數, debugTrue就可以開啟debug模式 from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return Hello World!if __name__ __main__:app.run(debugTrue) 將app的debug屬性賦值為True 1 from flask import Flask2 3 app Flas…

Python基礎常見面試題總結

文章目錄基礎知識題看程序寫結果題編程題以下是總結的一些常見的Python基礎面試題,幫助大家回顧基礎知識,了解面試套路。會一直保持更新狀態。PS:加粗為需要注意的點。基礎知識題 1、深拷貝和淺拷貝的區別是什么? 深拷貝是將對象…

2、nginx配置文件

2、nginx配置文件user [user] [group];//運行nginx的用戶(組)(只能在全局設置)worker process number|auto;//允許生成的worker process數(只能在全局設置,通常設置成和cpu的數量相等 )pid file;//nginx進程的Pid存放路…

watir6.0 -selenium3新時代的watir-webdriver

很久沒寫博客了- - 記得幾年前使用watir的時候還是1.x系列,個人感覺還是非常好用的,不過缺點也很明顯,只支持ie,對于彈出框下載框等支持不是很好,經常需要結合autoit 一起使用。 中間有一段時間沒有使用過watir&#x…

Flask-Script擴展命令行manager = Manager(app)

通過使用Flask-Script擴展,我們可以在Flask服務器啟動的時候,通過命令行的方式傳入參數。而不僅僅通過app.run()方法中傳參,比如我們可以通過python hello.py runserver --host ip地址,告訴服務器在哪個網絡接口監聽來自客戶端的連…

Python基礎總結之常用內置方法總結

文章目錄前言1、str1.1、內置方法:1.2、常用的內置方法1.3、String模塊的一些方法2、list2.1、內置方法2.2、常用內置方法3、tupple3.1、內置方法3.2、常用內置方法4、dict4.1、內置方法4.2、常用內置方法5、其他5.1、幾個sort的使用5.2、enumerate(&…

線程的條件變量實例

情景1:Jack開著一輛出租車來到一個網站停車。看見沒人就走了。過段時間。Susan來到網站準備乘車。可是沒有來,于是就等著。過了一會Mike開著車來到了這個網站,Sunsan就上了Mike的車走了。如圖所看到的:程序實現該情景:…

Flask 模板 之 變量和過濾器

1.模板 在前面的示例中,視圖函數的主要作用是生成請求的響應,這是最簡單的請求。實際上,視圖函數有兩個作用:處理業務邏輯和返回響應內容。在大型應用中,把業務邏輯和表現內容放在一起,會增加代碼的復雜度…

架設證書服務器 及 讓IIS啟用HTTPS服務

http://blog.csdn.net/dier4836/article/details/7719532轉載于:https://www.cnblogs.com/kunlunmountain/p/6428838.html

淺談互聯網寒冬與經濟形勢

文章目錄前言:閑扯總結:前言: 作為剛進入職場一年多的小白來說,剛準備“猥瑣發育漲經驗”,卻碰到這股互聯網寒冬,也感到鴨梨山大。也許有人認為我在販賣焦慮,但是現實真的很嚴峻。接下說下過去…

jenkins 配置

build periodically 周期進行項目構建poll scm 定時檢查遠嗎變更,如果有更新就checkout最新code下來,然后執行構建動作日程表:H 9 *** : 每天9點固定構建一次H/30 8-17 *** : 每天的8-17點每隔三十分鐘檢查一次轉載于:https://…

Java集合---LinkedList源碼解析

一、源碼解析1、 LinkedList類定義2、LinkedList數據結構原理3、私有屬性4、構造方法5、元素添加add()及原理6、刪除數據remove()7、數據獲取get()8、數據復制clone()與toArray()9、遍歷數據:Iterator()二、ListItr 一、源碼解析 1、 LinkedList類定義。 public cla…

Mysql面試熱身題集總結

文章目錄前言1、熱身題實踐其他前言 一直有個想法:把面試需要的知識點全都總結一下,包括數據庫,語言,算法,數據結構等知識,形成一個面試總結筆記,這樣以后面試的時候只看這些文章回顧下就行了。…

Flask中的 url_for() 函數

最近在學Python Flask框架,并且學會做一些簡單的項目,如做一個網站的登錄頁面等,其中學到了一個路由反向解析的函數 url_for(),這里做一個小結,供日后復習。 1.URL反轉:根據視圖函數…

Oracle執行計劃解釋

為什么80%的碼農都做不了架構師?>>> 一.相關的概念 Rowid的概念:rowid是一個偽列,既然是偽列,那么這個列就不是用戶定義,而是系統自己給加上的。 對每個表都有一個rowid的偽列,但是表…

鄧迎春繪畫201702作品10

轉載于:https://www.cnblogs.com/hanxiangmin/p/6439376.html

解決:FLASK中Warning: (1366, Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...'

Flask項目中使用mysql數據庫啟動項目是發出警告: Warning: (1366, “Incorrect string value: ‘\xD6\xD0\xB9\xFA\xB1\xEA…’ for column ‘VARIABLE_VALUE’ at row 479/480/481”) 但是項目可以正常啟動使用 如果想將次警告去掉需要導入一個模塊 解決方法&…

Pandas常用操作總結

文章目錄前言1、DF常用的兩種創建方式方式一:通過np來生成方式二:通過字典來生成2、pandas常用的屬性及方法3、Pandas Select(數據選擇)4、Pandas Set_values設置值5、Pandas Nan處理缺失值方法一:剔除缺失值所在的行或列方法二:填…

jmeter跨線程組傳值

在測試過程中,有時候需要jmeter跨線程組傳值,jmeter本身又不具備此功能,那么,又該如何實現呢? 其實,我們可以通過BeanShell去實現。 實現過程如下: 1.線程組A中,使用正則表達式提取器…

BZOJ 3093: [Fdu校賽2012] A Famous Game

3093: [Fdu校賽2012] A Famous Game Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 248 Solved: 133[Submit][Status][Discuss]Description Mr. B and Mr. M like to play with balls. They have many balls colored in blue and red. Firstly, Mr. B randomly picks up N …