關(guān)于驅(qū)動(dòng)讀寫異步超時(shí)的處理,網(wǎng)絡(luò)上的資料相對(duì)稀少,正好最近在工作上遇到了這個(gè)問題,,所以就研究了一下,,發(fā)現(xiàn)還是有些門道的,。如果完全按照應(yīng)用層讀寫超時(shí)的處理邏輯來處理驅(qū)動(dòng)層的話就會(huì)出現(xiàn)藍(lán)屏等問題 只要涉及到讀寫超時(shí),,那么我們第一印象肯定會(huì)想到事件和事件等待相關(guān)操作與函數(shù)的調(diào)用,,那么我們來看一下驅(qū)動(dòng)的幾個(gè)文件操作函數(shù)聲明: 首先是打開操作
根據(jù)應(yīng)用層的經(jīng)驗(yàn),,如果要實(shí)現(xiàn)超時(shí)讀寫,,我們需要以異步的方式打開文件,而驅(qū)動(dòng)默認(rèn)即是異步打開操作,,如果你需要同步打開,,需要設(shè)置下面的值(兩個(gè)需要同時(shí)設(shè)置) 然后是讀寫函數(shù),兩個(gè)類似
這里根據(jù)應(yīng)用層的經(jīng)驗(yàn),,我們會(huì)找關(guān)于事件(Event)的參數(shù),,根據(jù)文檔聲明,正好第二個(gè)參數(shù)涉及到了事件,,查閱文檔后確定該參數(shù)可以用于異步超時(shí)等待,。這個(gè)時(shí)候我們需要?jiǎng)?chuàng)建一個(gè)事件,關(guān)于驅(qū)動(dòng)中創(chuàng)建事件的函數(shù)我們首先會(huì)想到 KeInitializeEvent ,但是此處需要的是 HANDLE 類型,,所以我們需要使用下面的方法來創(chuàng)建:
然后我們自然想到以Zw開頭來搜索相關(guān)的等待函數(shù)
這個(gè)時(shí)候如果status返回的是 STATUS_TIMEOUT ,,那么就代表文件讀寫超時(shí),這時(shí)候我們就關(guān)閉事件句柄和文件句柄然后返回。如果你真的這么做了,,那么等數(shù)據(jù)真正的返回的時(shí)候,,就會(huì)出現(xiàn)藍(lán)屏問題。 經(jīng)過分析發(fā)現(xiàn)是因?yàn)槲覀冊(cè)谑褂?nbsp;ZwClose 函數(shù)關(guān)閉句柄后,,windows并沒有停止對(duì)文件的操作,,由于是是異步的,所以后臺(tái)仍然在等待數(shù)據(jù)的返回,,如果這時(shí)候我們銷毀了資源,,但是數(shù)據(jù)在超時(shí)后返回,那么就會(huì)出現(xiàn) 0xc0000005 這種內(nèi)存訪問錯(cuò)誤藍(lán)屏,。那么我們理所當(dāng)然想到是否有一個(gè)函數(shù)用來取消文件IO操作,,答案是有的,但是是未文檔化函數(shù),,函數(shù)聲明如下:
這個(gè)函數(shù)即可用來取消文件IO,,當(dāng)我們讀寫超時(shí)后,,我們先要取消文件后臺(tái)IO操作,,然后再關(guān)閉相關(guān)句柄。我們可以這樣獲得該函數(shù)地址:
~完畢~ |
|