驅動與應用程序的通信是非常有必要的,內核中執行代碼后需要將其動態顯示給應用層,但驅動程序與應用層畢竟不在一個地址空間內,為了實現內核與應用層數據交互則必須有通信的方法,微軟為我們提供了三種通信方式,如下先來介紹通過ReadFile系列函數實現的通信模式 。
長話短說,不說沒用的概念,首先系統中支持的通信模式可以總結為三種 。
- 緩沖區方式讀寫(DO_BUFFERED_IO)
- 直接方式讀寫(DO_DIRECT_IO)
- 其他方式讀寫
首先需要實現初始化各類派遣函數這么一個案例,如下代碼則是通用的一種初始化派遣函數的基本框架,分別處理了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;}
經驗總結擴展閱讀
- 用golang開發系統軟件的一些細節
- 抖音團購套餐傭金抽成是多少
- 全國計算機等級考試通過率
- 狗狗靠什么辨認主人?
- 三十六 Java開發學習----SpringBoot三種配置文件解析
- aardio + Python 可視化快速開發桌面程序,一鍵生成獨立 EXE
- 驅動精靈重裝了驅動后無法開機
- 微粒貸在哪
- Windows esp-idf 安裝
- 口袋妖怪火紅版中如何走精靈塔
