国产精品免费嫩草研究院|无遮羞动漫在线观看AV|国产麻豆精品传媒AV国产在线|村在线观看|寂寞情人1正版|韩国床震韩国床震古|精品系列专区久久

驅動開發:通過ReadFile與內核層通信

驅動與應用程序的通信是非常有必要的,內核中執行代碼后需要將其動態顯示給應用層,但驅動程序與應用層畢竟不在一個地址空間內,為了實現內核與應用層數據交互則必須有通信的方法,微軟為我們提供了三種通信方式,如下先來介紹通過ReadFile系列函數實現的通信模式 。
長話短說,不說沒用的概念,首先系統中支持的通信模式可以總結為三種 。

  • 緩沖區方式讀寫(DO_BUFFERED_IO)
  • 直接方式讀寫(DO_DIRECT_IO)
  • 其他方式讀寫
而通過ReadFile,WriteFile系列函數實現的通信機制則屬于緩沖區通信模式,在該模式下操作系統會將應用層中的數據復制到內核中,此時應用層調用ReadFile,WriteFile函數進行讀寫時,在驅動內會自動觸發 IRP_MJ_READ 與 IRP_MJ_WRITE這兩個派遣函數,在派遣函數內則可以對收到的數據進行各類處理 。
首先需要實現初始化各類派遣函數這么一個案例,如下代碼則是通用的一種初始化派遣函數的基本框架,分別處理了IRP_MJ_CREATE創建派遣,以及IRP_MJ_CLOSE關閉的派遣,此外函數DriverDefaultHandle的作用時初始化其他派遣用的,也就是將除去CREATE/CLOSE這兩個派遣之外,其他的全部賦值成初始值的意思,當然不增加此段代碼也是無妨,并不影響代碼的實際執行 。
#include <ntifs.h>// 卸載驅動執行VOID UnDriver(PDRIVER_OBJECT pDriver){ PDEVICE_OBJECT pDev;                                        // 用來取得要刪除設備對象 UNICODE_STRING SymLinkName;                                 // 局部變量symLinkName pDev = pDriver->DeviceObject; IoDeleteDevice(pDev);                                           // 調用IoDeleteDevice用于刪除設備 RtlInitUnicodeString(&SymLinkName, L"\\??\\LySharkDriver");     // 初始化字符串將symLinkName定義成需要刪除的符號鏈接名稱 IoDeleteSymbolicLink(&SymLinkName);                             // 調用IoDeleteSymbolicLink刪除符號鏈接 DbgPrint("驅動卸載完畢...");}// 創建設備連接// LyShark.comNTSTATUS CreateDriverObject(IN PDRIVER_OBJECT pDriver){ NTSTATUS Status; PDEVICE_OBJECT pDevObj; UNICODE_STRING DriverName; UNICODE_STRING SymLinkName; // 創建設備名稱字符串 RtlInitUnicodeString(&DriverName, L"\\Device\\LySharkDriver"); Status = IoCreateDevice(pDriver, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj); // 指定通信方式為緩沖區 pDevObj->Flags |= DO_BUFFERED_IO; // 創建符號鏈接 RtlInitUnicodeString(&SymLinkName, L"\\??\\LySharkDriver"); Status = IoCreateSymbolicLink(&SymLinkName, &DriverName); return STATUS_SUCCESS;}// 創建回調函數NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp){ pIrp->IoStatus.Status = STATUS_SUCCESS;          // 返回成功 DbgPrint("派遣函數 IRP_MJ_CREATE 執行 \n"); IoCompleteRequest(pIrp, IO_NO_INCREMENT);        // 指示完成此IRP return STATUS_SUCCESS;                           // 返回成功}// 關閉回調函數NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp){ pIrp->IoStatus.Status = STATUS_SUCCESS;          // 返回成功 DbgPrint("派遣函數 IRP_MJ_CLOSE 執行 \n"); IoCompleteRequest(pIrp, IO_NO_INCREMENT);        // 指示完成此IRP return STATUS_SUCCESS;                           // 返回成功}// 默認派遣函數NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp){ NTSTATUS status = STATUS_SUCCESS; pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status;}// 入口函數// By: LySharkNTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath){ DbgPrint("hello lyshark \n"); // 調用創建設備 CreateDriverObject(pDriver); pDriver->DriverUnload = UnDriver;                          // 卸載函數 pDriver->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;    // 創建派遣函數 pDriver->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;      // 關閉派遣函數 // 初始化其他派遣 for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {DbgPrint("初始化派遣: %d \n", i);pDriver->MajorFunction[i] = DriverDefaultHandle; } DbgPrint("驅動加載完成..."); return STATUS_SUCCESS;}

經驗總結擴展閱讀