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
- #ifndef CTL_CODE
- #pragma message("\n \n-----------EXE . Include winioctl.h ")
- #include<winioctl.h> //CTL_CODE ntddk.h wdm.h
- #else
- #pragma message("\n \n----------SYS NO Include winioctl.h ")
- #endif
- #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_IN_DIRECT,FILE_ANY_ACCESS)
- #define sub_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_IN_DIRECT,FILE_ANY_ACCESS)
main.cpp
- #include <stdio.h>
- #include <tchar.h>
- #include <windows.h>
- #include "head.h"
- int add (HANDLE hDevice ,int a,int b)
- {
- int port[2]={a,b};
- int bufret=0;
- ULONG dwWrite=0;
- DeviceIoControl(hDevice,add_code,&port,sizeof(port),&bufret,sizeof(bufret),&dwWrite,NULL);
- return bufret;
- }
- int main (void)
- {
- getchar();
- getchar();
- HANDLE hDevice=CreateFile(TEXT("\\\\.\\My_DriverLinkName"),
- GENERIC_READ|GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hDevice==INVALID_HANDLE_VALUE)
- {
- printf("打开设备失败\n");
- getchar();
- getchar();
- return 0;
- }
- int k=add(hDevice,11,22);
- printf("%d\n",k);
- getchar();
- getchar();
- return 0;
- }
SYS部分
head.h
- #ifndef CTL_CODE
- #pragma message("\n \n-----------EXE . Include winioctl.h ")
- #include<winioctl.h> //CTL_CODE ntddk.h wdm.h
- #else
- #pragma message("\n \n----------SYS NO Include winioctl.h ")
- #endif
- #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_IN_DIRECT,FILE_ANY_ACCESS)
- #define sub_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_IN_DIRECT,FILE_ANY_ACCESS)
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部分 head.h [cpp] view plaincopy #ifndef CTL_CODE #pragma message("\n \n-----------EXE . Inc ...
- EXE与SYS通信(缓冲模式)
EXE部分 head.h [cpp] view plaincopy #include<winioctl.h> //CTL_CODE #define add_code CTL_CODE(FI ...
- EXE和SYS通信IOCTL方式
EXE部分 [cpp] view plaincopy #ifndef IOCTLS_H #define IOCTLS_H #ifndef CTL_CODE #pragma message(&qu ...
- EXE和SYS通信(ReadFile WriteFile) 其他方式
EXE部分 [cpp] view plaincopy #include <stdio.h> #include <Windows.h> int main (void) { cha ...
- EXE和SYS通信(ReadFile WriteFile DO_DIRECT_IO) 直接方式
EXE部分 [cpp] view plaincopy #include <stdio.h> #include <Windows.h> int main (void) { cha ...
- EXE和SYS通信(ReadFile WriteFile DO_BUFFERED_IO) 缓冲区方式
EXE部分 [cpp] view plaincopy #include <stdio.h> #include <Windows.h> int main (void) { cha ...
- 此项目的默认Web访问模式设置为文件共享, 但是无法从路径(此为转贴)
故障现象: 当你打开ASP.NET Web项目时,如果出现这样的错误提示: 提示窗口标题: Web访问失败 提示内容: 此项目的默认Web访问模式设置为文件共享, 但是无法从路径"...&q ...
- esp8266,esp32中的SPI FLASH 访问模式(QIO QOUT DIO DOUT)
本文 ESP8266 和 ESP32 支持四种不同的 SPI flash 访问模式:DIO.DOUT.QIO 和 QOUT. 这些可以通过 esptool.py write_flash 的 --fla ...
- 如何用 ndctl/ipmctl 管理工具 配置不同访问模式的pmem设备
文章目录 1 PMEM 底层架构 2 PMEM 逻辑架构 3 ipmctl 创建 不同模式的 region 3.1 安装 3.2 创建AppDirect mode的region 3.3 创建 Memo ...
最新文章
- Winform中添加客户信息
- dump java崩溃自动 不生成_一个宏命令,就可以程序崩溃时生成dump文件
- JS中调用本地exe程序
- [css] 用css画出一把刻度尺
- Linux的网络协议族是什么,Linux 网络协议的概述
- Try increasing heap size with java option '-Xmxlt;sizegt;’.
- (转)关于block使用的5点注意事项
- 如何在VM ware虚拟环境下建立纯软双机热备
- Web API 文档生成工具 apidoc
- 二分类模型评价指标-KS值
- 获取支付宝小程序链接
- Direct3D9初始化-------VB6编程学习DX9游戏编程DirectX9编程2D小游戏源码冷风引擎CoolWind2D游戏引擎(6)
- python控制灯开关_通过树莓派控制电灯开关
- 用u盘制作u启动重装系统的步骤实现
- 乐理基础知识-4.音程
- Android接入融云sdk流程(思路)
- 2022世界杯回忆录:我的青春我的歌
- 删除电脑属性制造商_win7系统怎么修改系统制造商信息?
- 本地ie打开html布局乱,网页设计:浏览器在兼容模式下布局全乱了 – 解决办法...
- 新南威尔士大学计算机排名,新南威尔士大学世界排名及专业排名汇总(QS世界大学排名版)...