久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

驅(qū)動(dòng)讀寫超時(shí)處理

 夢(mèng)醉千秋 2019-05-30

關(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ù)聲明:

首先是打開操作

NTSTATUS ZwCreateFile(
  _Out_    PHANDLE            FileHandle,
  _In_     ACCESS_MASK        DesiredAccess,
  _In_     POBJECT_ATTRIBUTES ObjectAttributes,
  _Out_    PIO_STATUS_BLOCK   IoStatusBlock,
  _In_opt_ PLARGE_INTEGER     AllocationSize,
  _In_     ULONG              FileAttributes,
  _In_     ULONG              ShareAccess,
  _In_     ULONG              CreateDisposition,
  _In_     ULONG              CreateOptions,
  _In_opt_ PVOID              EaBuffer,
  _In_     ULONG              EaLength
);

根據(jù)應(yīng)用層的經(jīng)驗(yàn),,如果要實(shí)現(xiàn)超時(shí)讀寫,,我們需要以異步的方式打開文件,而驅(qū)動(dòng)默認(rèn)即是異步打開操作,,如果你需要同步打開,,需要設(shè)置下面的值(兩個(gè)需要同時(shí)設(shè)置)
DesiredAccess:SYNCHRONIZE
CreateOptions:FILE_SYNCHRONOUS_IO_NONALERT

然后是讀寫函數(shù),兩個(gè)類似

NTSTATUS ZwReadFile(
  _In_     HANDLE           FileHandle,
  _In_opt_ HANDLE           Event,
  _In_opt_ PIO_APC_ROUTINE  ApcRoutine,
  _In_opt_ PVOID            ApcContext,
  _Out_    PIO_STATUS_BLOCK IoStatusBlock,
  _Out_    PVOID            Buffer,
  _In_     ULONG            Length,
  _In_opt_ PLARGE_INTEGER   ByteOffset,
  _In_opt_ PULONG           Key
);NTSTATUS ZwWriteFile(
  _In_     HANDLE           FileHandle,
  _In_opt_ HANDLE           Event,
  _In_opt_ PIO_APC_ROUTINE  ApcRoutine,
  _In_opt_ PVOID            ApcContext,
  _Out_    PIO_STATUS_BLOCK IoStatusBlock,
  _In_     PVOID            Buffer,
  _In_     ULONG            Length,
  _In_opt_ PLARGE_INTEGER   ByteOffset,
  _In_opt_ PULONG           Key
);

這里根據(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)建:

ZwCreateEvent(&g_hEvent, GENERIC_ALL, NULL, SynchronizationEvent, FALSE);

然后我們自然想到以Zw開頭來搜索相關(guān)的等待函數(shù)

status = ZwWaitForSingleObject(g_hEvent, FALSE, &time);

這個(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ù)聲明如下:

typedefNTSTATUS(NTAPI *MyZwCancelIoFile)(
    IN HANDLE               FileHandle,
    OUT PIO_STATUS_BLOCK    IoStatusBlock);

這個(gè)函數(shù)即可用來取消文件IO,,當(dāng)我們讀寫超時(shí)后,,我們先要取消文件后臺(tái)IO操作,,然后再關(guān)閉相關(guān)句柄。我們可以這樣獲得該函數(shù)地址:

UNICODE_STRING funcname = RTL_CONSTANT_STRING(L"ZwCancelIoFile");
ZwCancelIoFile = (MyZwCancelIoFile)MmGetSystemRoutineAddress(&funcname);if (ZwCancelIoFile == NULL)
{    return FALSE;
}

~完畢~

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多