EXE与SYS通信(直接访问模式)
CTL_CODE(DeviceType,Function,Method,Acess);
Method是指定數據傳遞的模式?有這幾個值:
METHOD_BUFFERED?//使用緩沖區方式操作?0
METHOD_IN_DIRECT?//直接寫方式?1
METHOD_OUT_DIRECT?//直接讀方式?2
METHOD_NEITHER?//其它方式?3
直接內存操作方式METHOD_IN_DIRECT和METHOD_OUT_DIRECT模式都以相同方式處理。僅有的不同是它們訪問用戶模式緩沖區時所需的訪問權限;METHOD_IN_DIRECT需要讀權限;METHOD_OUT_DIRECT既需要讀權限又需要寫權限。使用這兩種模式時,I/O管理器會為輸入數據提供一個內核模式拷貝緩沖區(AssociatedIrp.SystemBuffer),為輸出數據緩沖區提供一個MDL。?
MdlAddress(PMDL)域指向一個內存描述符表(MDL),該表描述了一個與該請求關聯的用戶模式緩沖區。
當IRP_MJ_DEVICE_CONTROL請求的控制代碼指定METHOD_IN_DIRECT或METHOD_OUT_DIRECT操作方式,則I/O管理器為該請求使用的輸出緩沖區創建一個MDL。MDL本身用于描述用戶模式虛擬緩沖區,但它同時也含有該緩沖區鎖定內存頁的物理地址。
EXE部分
head.h
[cpp]?view plaincopy
?
main.cpp
[cpp]?view plaincopy
?
SYS部分
head.h
[cpp]?view plaincopy
cpp
#include <ntdef.h> #include <ntddk.h> #include "head.h" #ifdef __cplusplus extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); #endif NTSTATUS ddk_DispatchRoutine_CONTROL(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp ); void TestDDK125096Unload(IN PDRIVER_OBJECT DriverObject); NTSTATUS CreateMyDevice (IN PDRIVER_OBJECT pDriverObject); NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { DbgPrint("Hello from TestDDK125096!\n"); DriverObject->DriverUnload = TestDDK125096Unload; DriverObject->MajorFunction[IRP_MJ_CREATE]=ddk_DispatchRoutine_CONTROL; //IRP_MJ_CREATE相關IRP處理函數 DriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine_CONTROL; //IRP_MJ_CREATE相關IRP處理函數 DriverObject->MajorFunction[IRP_MJ_READ]=ddk_DispatchRoutine_CONTROL; //IRP_MJ_CREATE相關IRP處理函數 DriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine_CONTROL; //IRP_MJ_CREATE相關IRP處理函數 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=ddk_DispatchRoutine_CONTROL; //IRP_MJ_CREATE相關IRP處理函數 CreateMyDevice(DriverObject);//創建相應的設備 return STATUS_SUCCESS; } void TestDDK125096Unload(IN PDRIVER_OBJECT DriverObject) { DbgPrint("Goodbye from TestDDK125096!\n"); PDEVICE_OBJECT pDev;//用來取得要刪除設備對象 UNICODE_STRING symLinkName; // pDev=DriverObject->DeviceObject; IoDeleteDevice(pDev); //刪除設備 //取符號鏈接名字 RtlInitUnicodeString(&symLinkName,L"\\??\\My_DriverLinkName"); //刪除符號鏈接 IoDeleteSymbolicLink(&symLinkName); KdPrint(("驅動成功被卸載...OK-----------")); //sprintf,printf //取得要刪除設備對象 //刪掉所有設備 DbgPrint("卸載成功"); } NTSTATUS ddk_DispatchRoutine_CONTROL(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp ) { // ULONG info; //得到當前棧指針 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); ULONG mf=stack->MajorFunction;//區分IRP switch (mf) { case IRP_MJ_DEVICE_CONTROL: { KdPrint(("Enter myDriver_DeviceIOControl\n")); NTSTATUS status = STATUS_SUCCESS; //得到輸入緩沖區大小 ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength; //得到輸出緩沖區大小 ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength; //得到IOCTL碼 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; switch (code) { case add_code: { int a,b; KdPrint(("add_code 1111111111111111111\n")); //緩沖區方式IOCTL //獲取緩沖區數據 a,b int * InputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer; _asm { mov eax,InputBuffer mov ebx,[eax] mov a,ebx mov ebx,[eax+4] mov b,ebx } KdPrint(("a=%d,b=%d \n", a,b)); a=a+b; //C、驅動層返回數據至用戶層 //操作輸出緩沖區 //int* OutputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer; int OutputBuffer =(int)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority); _asm { mov eax,a mov ebx,OutputBuffer mov [ebx],eax //bufferet=a+b } KdPrint(("a+b=%d \n",a)); //設置實際操作輸出緩沖區長度 info = 4; break; } case sub_code: { break; } }//end code switch break; } case IRP_MJ_CREATE: { break; } case IRP_MJ_CLOSE: { break; } case IRP_MJ_READ: { break; } } //對相應的IPR進行處理 pIrp->IoStatus.Information=info;//設置操作的字節數為0,這里無實際意義 pIrp->IoStatus.Status=STATUS_SUCCESS;//返回成功 IoCompleteRequest(pIrp,IO_NO_INCREMENT);//指示完成此IRP KdPrint(("離開派遣函數\n"));//調試信息 return STATUS_SUCCESS; //返回成功 } NTSTATUS CreateMyDevice (IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status; PDEVICE_OBJECT pDevObj;/*用來返回創建設備*/ //創建設備名稱 UNICODE_STRING devName; UNICODE_STRING symLinkName; // RtlInitUnicodeString(&devName,L"\\Device\\125DDK_Device");/*對devName初始化字串為 "\\Device\\125DDK_Device"*/ //創建設備 status = IoCreateDevice( pDriverObject,\0,\&devName,\FILE_DEVICE_UNKNOWN,\0, TRUE,\&pDevObj);if (!NT_SUCCESS(status)) { if (status==STATUS_INSUFFICIENT_RESOURCES) { KdPrint(("資源不足 STATUS_INSUFFICIENT_RESOURCES")); } if (status==STATUS_OBJECT_NAME_EXISTS ) { KdPrint(("指定對象名存在")); } if (status==STATUS_OBJECT_NAME_COLLISION) { KdPrint(("//對象名有沖突")); } KdPrint(("設備創建失敗...++++++++")); return status; } KdPrint(("設備創建成功...++++++++")); pDevObj->Flags |= DO_BUFFERED_IO; //創建符號鏈接 RtlInitUnicodeString(&symLinkName,L"\\??\\My_DriverLinkName"); status = IoCreateSymbolicLink( &symLinkName,&devName ); if (!NT_SUCCESS(status)) /*status等于0*/ { IoDeleteDevice( pDevObj ); return status; } return STATUS_SUCCESS; }
總結
以上是生活随笔為你收集整理的EXE与SYS通信(直接访问模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EXE与SYS通信(缓冲模式)
- 下一篇: EXE与SYS通信(其他模式)