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

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

代碼運行效果如下:

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

文章插圖
通用框架有了,接下來就是讓該驅動支持使用ReadWrite的方式實現通信,首先我們需要在DriverEntry處增加兩個派遣處理函數的初始化 。
// 入口函數// By: LySharkNTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath){ DbgPrint("hello lyshark \n"); // 調用創建設備 CreateDriverObject(pDriver); // 初始化其他派遣 for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {DbgPrint("初始化派遣: %d \n", i);pDriver->MajorFunction[i] = DriverDefaultHandle; } pDriver->DriverUnload = UnDriver;                          // 卸載函數 pDriver->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;    // 創建派遣函數 pDriver->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;      // 關閉派遣函數 // 增加派遣處理 pDriver->MajorFunction[IRP_MJ_READ] = DispatchRead;        // 讀取派遣函數 pDriver->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;      // 寫入派遣函數 DbgPrint("驅動加載完成..."); return STATUS_SUCCESS;}接著,我們需要分別實現這兩個派遣處理函數,如下DispatchRead負責讀取時觸發,與之對應DispatchWrite負責寫入觸發 。
  • 引言:
  • 對于讀取請求I/O管理器分配一個與用戶模式的緩沖區大小相同的系統緩沖區SystemBuffer,當完成請求時I/O管理器將驅動程序已經提供的數據從系統緩沖區復制到用戶緩沖區 。
  • 對于寫入請求,會分配一個系統緩沖區并將SystemBuffer設置為地址,用戶緩沖區的內容會被復制到系統緩沖區,但是不設置UserBuffer緩沖 。
通過IoGetCurrentIrpStackLocation(pIrp)接收讀寫請求長度,偏移等基本參數,AssociatedIrp.SystemBuffer則是讀寫緩沖區,IoStatus.Information是輸出緩沖字節數,Parameters.Read.Length是讀取寫入的字節數 。
// 讀取回調函數NTSTATUS DispatchRead(PDEVICE_OBJECT pDevObj, PIRP pIrp){ NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(pIrp); ULONG ulReadLength = Stack->Parameters.Read.Length; char szBuf[128] = "hello lyshark"; pIrp->IoStatus.Status = Status; pIrp->IoStatus.Information = ulReadLength; DbgPrint("讀取長度:%d \n", ulReadLength); // 取出字符串前5個字節返回給R3層 memcpy(pIrp->AssociatedIrp.SystemBuffer, szBuf, ulReadLength); IoCompleteRequest(pIrp, IO_NO_INCREMENT); return Status;}// 接收傳入回調函數// By: LySharkNTSTATUS DispatchWrite(struct _DEVICE_OBJECT *DeviceObject, struct _IRP *Irp){ NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); ULONG ulWriteLength = Stack->Parameters.Write.Length; PVOID ulWriteData = Irp->AssociatedIrp.SystemBuffer; // 輸出傳入字符串 DbgPrint("傳入長度: %d 傳入數據: %s \n", ulWriteLength, ulWriteData); IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status;}【驅動開發:通過ReadFile與內核層通信】如上部分都是在講解驅動層面的讀寫派遣,應用層還沒有介紹,在應用層我們只需要調用ReadFile函數當調用該函數時驅動中會使用DispatchRead派遣例程來處理這個請求,同理調用WriteFile函數則觸發的是DispatchWrite派遣例程 。

經驗總結擴展閱讀