xjcxc
驱动牛犊
驱动牛犊
  • 注册日期2002-03-27
  • 最后登录2006-08-28
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:2750回复:24

驱动程序和应用程序的通讯问题。。。。。

楼主#
更多 发布于:2002-06-22 08:13
在应用程序分配的数据空间到驱动程序不能使用,已用就死机。
use....
*p= new char[1024];
将p传到sys中
在sys中使用p死机

请指点,谢谢。。。。

给分。。。。!!!!!
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-07-05 12:50
如果你需要在应用程序和驱动程序中共享内存,根本不是用DeviceIoControl的上面的机制,我上面给你的一篇文档详细地阐述了如何实现,仔细看看吧。
祝你好运。
-----------------------------------------------------------------------------
本来这就是为了说明一个原理,有关2000系统的内存映射机制,只是告诉他知道一个有效用户地址驱动在什么条件下可以直接访问(而非驱动不可访问用户空间)。用DeviceIoControl只是为了最简单地告诉驱动该去直接访问的用户地址,与缓冲策略毫无关系,任何方法让驱动知道用户4字节地址而已,hehe




我这儿运行死机
------------------------------------------------------------------------------
你明白我所说的条件是什么就绝不会死机,有些很特殊情况还不得不使用这种方法。言尽于此
Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-07-05 11:05
用DeviceIoControl将p传到驱动程序
sys中用s_p=p;

    DeviceIoControl可以传入一个应用程序分配的内存以传入数据给驱动程序或让驱动程序返回数据,但是,驱动程序如何操作这块内存要看你声明命令码(即IOCTL_XXX)使用的I/O方式(是BUFFERED_IO,还是DIRECT_IN, DIRECT_OUT),I/O方式不同,解析内存的方式不同,而且这个方式不受创建设备对象时初始化的I/O方式影响。
当为BUFFERED_IO时,应用程序传入的内存被I/O Manager拷贝到pIrp->AssociatedIrp.SystemBuffer中,而当使用DIRECT_IO时,驱动程序就需要一个MDL来描述应用程序的内存。这里我不知道你声明IOCTL命令码时使用的是什么内存方式,解析方式又是否一至,请查明。

最上层驱动分派例程中:
addr=((PULONG)Irp->AssociatedIrp.SystemBuffer);

如果你声明内存I/O方式为METHOD_BUFFERED,则这一句是正确的,如果不是,则是错误的。


-----
for(b=0;b<1024;b++)
a+=*addr;
---------
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&a,4);
BytesTxd=OutputLength;

DeviceIoControl函数中可以同时指定输入缓冲和输出缓冲,但建议你不要同时使用,I/O 管理器对两种缓冲的处理方法可能存在不同。


应用中:
ULONG *addr=new ULONG[1024];
for(int i=0;i<1024;i++)
addr=1;
......

DeviceIoControl(hDevice,IOCTL_WDM1_GET_BUFFER,&addr,4,&res,4,&Bytes,0);


我不知道你在这里为什么要在输入缓冲参数中传入addr的地址(你的意思应该是一个指针),但应用程序和驱动程序不用一个内存空间,这样绝对是不合理的。你可以这样:
DeviceIoControl( hDevice, IOCTL_WDM1_GET_BUFFER, addr, 1024*sizeof(ULONG), .....);
这个函数中的输入/输出缓冲区的大小都是以字节为单位的。
这样,你就可以在驱动程序中正确无误地使用addr中的内容。



DeviceIoControl(hDevice,IOCTL_WDM1_GET_BUFFER,&addr,4,&res,4,&Bytes,0);

运行?????
我这儿运行死机

不死机才奇怪。
如果你需要在应用程序和驱动程序中共享内存,根本不是用DeviceIoControl的上面的机制,我上面给你的一篇文档详细地阐述了如何实现,仔细看看吧。
祝你好运。
Tom_lyd
xjcxc
驱动牛犊
驱动牛犊
  • 注册日期2002-03-27
  • 最后登录2006-08-28
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-07-05 10:08
引用:
--------------------------------------------------------------------------------

整个过程就是应用把分配的内存的地址的值传给驱动(我这儿是0x8744F8),驱动依次访问每个单元
---------------------------------------------------------------------------------
我用的是  KernelDriver ,还是死机。
char puser[1024];
char *psys
psys=Irp.SystemBuffer()[0];
i=*psys  死机;
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-07-05 07:16
最上层驱动分派例程中:
addr=((PULONG)Irp->AssociatedIrp.SystemBuffer)[0](*这有中括号里面是0*);
Irp->AssociatedIrp.SystemBuffer 是 PVOID
驱动的addr=*addr应用层。。。?


整个过程就是应用把分配的内存的地址的值传给驱动(我这儿是0x8744F8),驱动依次访问每个单元。
xjcxc
驱动牛犊
驱动牛犊
  • 注册日期2002-03-27
  • 最后登录2006-08-28
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-07-04 23:46
最上层驱动分派例程中:
addr=((PULONG)Irp->AssociatedIrp.SystemBuffer)[0](*这有中括号里面是0*);
Irp->AssociatedIrp.SystemBuffer 是 PVOID
驱动的addr=*addr应用层。。。?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-07-04 11:31

最上层驱动分派例程中:
addr=((PULONG)Irp->AssociatedIrp.SystemBuffer)[0](*这有中括号里面是0*);
for(b=0;b<1024;b++)
a+=((PULONG)addr)(*这有中括号里面是b*);
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&a,4);
BytesTxd=OutputLength;
应用中:
ULONG *addr=new ULONG[1024];//奇怪这给括号能显示
for(int i=0;i<1024;i++)
addr(*这有种括号里面是i*)=1;
......
DeviceIoControl(hDevice,IOCTL_WDM1_GET_BUFFER,&addr,4,&res,4,&Bytes,0);

运行后得到从驱动传回的累加结果:1024。
我这儿运行正常
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-07-04 09:51
[quote][quote]
运行?????
我这儿运行死机
 


for(int i=0;i<1024;i++)
addr=1; [/quote]
站长,这是什么bug?
我写的“addr”只显示出addr????

两次都是这样????? [/quote]

又是这样??!!
写汉字好了:
是addr加中括号、加i、加中括号。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-07-04 09:49
[quote]
运行?????
我这儿运行死机
 


for(int i=0;i<1024;i++)
addr=1; [/quote]
站长,这是什么bug?
我写的“addr”只显示出addr????

两次都是这样?????
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-07-04 09:46

运行?????
我这儿运行死机
 


for(int i=0;i<1024;i++)
addr=1;
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
10楼#
发布于:2002-07-04 09:26
ULONG *addr=new ULONG[1024];
       ----
for(int i=0;i<1024;i++)
addr=1;???????
......
DeviceIoControl(hDevice,IOCTL_WDM1_GET_BUFFER,&addr,4,&res,4,&Bytes,0);
                               -----
传递指针的指针到驱动吗?

估计是笔误。
*addr = 1;
xjcxc
驱动牛犊
驱动牛犊
  • 注册日期2002-03-27
  • 最后登录2006-08-28
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-07-03 22:26
ULONG *addr=new ULONG[1024];
       ----
for(int i=0;i<1024;i++)
addr=1;???????
......
DeviceIoControl(hDevice,IOCTL_WDM1_GET_BUFFER,&addr,4,&res,4,&Bytes,0);
                               -----
传递指针的指针到驱动吗?
xjcxc
驱动牛犊
驱动牛犊
  • 注册日期2002-03-27
  • 最后登录2006-08-28
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-07-03 22:19
最上层驱动分派例程中:
addr=((PULONG)Irp->AssociatedIrp.SystemBuffer);
-----
for(b=0;b<1024;b++)
a+=*addr;
---------
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&a,4);
BytesTxd=OutputLength;
应用中:
ULONG *addr=new ULONG[1024];
for(int i=0;i<1024;i++)
addr=1;
......
DeviceIoControl(hDevice,IOCTL_WDM1_GET_BUFFER,&addr,4,&res,4,&Bytes,0);

运行?????
我这儿运行死机
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-07-02 19:25
谢谢各位。
我是想直接使用用户空间,不知道怎样处理。
 

唉,上面就是在直接访问用户空间
xjcxc
驱动牛犊
驱动牛犊
  • 注册日期2002-03-27
  • 最后登录2006-08-28
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-07-02 19:13
谢谢各位。
我是想直接使用用户空间,不知道怎样处理。
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-07-02 18:30
用DeviceIoControl将p传到驱动程序
----------------------------------------------------------------------------
copy this
xjcxc
驱动牛犊
驱动牛犊
  • 注册日期2002-03-27
  • 最后登录2006-08-28
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-07-02 18:05
用DeviceIoControl将p传到驱动程序
sys中用s_p=p;
char mchar=*s_p;(出错)
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-07-02 17:17
用DeviceIoControl将p传到驱动程序
----------------------------------
这样肯定不行
 

也不是那么绝对,驱动可以访问用户空间,但要有较强的条件:确保驱动运行在所要访问的进程环境中;若IRQL等于或高于DSPATCH_LEVEL,则要确保页存在。
以前VXD与应用共享内存的一种常见方法就是应用分配一块空间,将地址传给驱动,让驱动lock所需pages,lock的目的在于确保符合以上二条件。
2000驱动也可用此方法,只是大家都用更常见的共享做法:驱动分配,映射给应用。
其实最上层驱动的分派例程工作于PASSIVE_LEVEL,且运行在发出请求的进程环境中,可以说符合要求(应用LOCK一下比较好)。我写个例子:
最上层驱动分派例程中:
addr=((PULONG)Irp->AssociatedIrp.SystemBuffer)[0];
for(b=0;b<1024;b++)
a+=((PULONG)addr);
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&a,4);
BytesTxd=OutputLength;
应用中:
ULONG *addr=new ULONG[1024];
for(int i=0;i<1024;i++)
addr=1;
......
DeviceIoControl(hDevice,IOCTL_WDM1_GET_BUFFER,&addr,4,&res,4,&Bytes,0);

运行后得到从驱动传回的累加结果:1024。
我这儿运行正常
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-07-02 16:14
用DeviceIoControl将p传到驱动程序
sys中用s_p=p;


faint
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
19楼#
发布于:2002-07-02 15:49
用DeviceIoControl将p传到驱动程序
sys中用s_p=p;
----------------------------------
Tom_lyd兄说得对,这样肯定不行,其实这个问题在论坛已经讨论过多次了。

可以参考MSDN中的文章:
HOWTO: Share Memory Between User Mode and Kernel Mode
Q191840

SAMPLE: Section.exe on Sharing Memory Between Kernel & User Mode
Q194945

八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
上一页
游客

返回顶部