阅读:2674回复:30
在设备扩展开多大的区域比较合适
我修改了CHRIS CANT的例子程序作为一个PCI板卡的驱动,每往端口发送一个数据需要调用一次DeviceIoControl。现在用户的要求有变,希望能在60ms时间内发送64K个数据,我应该怎么办?在例子程序中有个分支可以发送多个字,但是如果希望60ms不停的发送,难道要在设备扩展中准备64K的空间来存放发送数,这样是不是太夸张?
老板催的很紧,各位大虾帮帮俺了,谢谢。 |
|
最新喜欢:![]() |
沙发#
发布于:2003-04-05 14:41
[quote] 我不记得怎么从驱动程序的向调用者返回数据了,你可以试试用输入缓冲区的数据返回,也许可行,毕竟都是buffer方式嘛 呵呵,至于追加分数我看就不用咯,要把好钢用在刀刃上啊,继续努力吧,呵呵 |
|
|
板凳#
发布于:2003-04-05 14:12
当然,我获取mdl大小的方式不好,你应该采用mdl指定的例程。我是因为我的驱动用的还可以,也就懒得改了,呵呵 太谢谢你了,果然是这样的。 但是我看到书上都是说METHOD_IN_DIRECT方式下,输入缓冲区的MDL放在IRP首部的MDLADDRESS域中,或者说来自调用者的IOCTL数据使用直接I/O传递,从驱动程序回到调用者的数据通过一个中间系统空间缓冲区传递。这里意思应该是第三第四个参数对应到MDL呀,难道我理解有误,能说说是怎么回事吗? 真的很感谢你。 BTW,我要追加分数怎么加?谢谢! |
|
地板#
发布于:2003-04-05 13:50
当然,我获取mdl大小的方式不好,你应该采用mdl指定的例程。我是因为我的驱动用的还可以,也就懒得改了,呵呵
[编辑 - 4/5/03 by mailme] |
|
|
地下室#
发布于:2003-04-05 13:47
给你贴一下我的用户态方式:
// 声明 #define IOCTL_WRITE_DATABUFFER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_IN_DIRECT, FILE_ANY_ACCESS) // 注意,是METHOD_IN_DIRECT ///////////////////////////////////////////////////////////////////////////// //写数据 //返回值->如果例程执行成功就返回true,否则为false bool WriteDataBuffer( ULONG Reg, PVOID pData, ULONG ulSize ) { DWORD code; if( (Reg < 0x10000) && ( pData != NULL ) && ( hCard != NULL ) ) code = IOCTL_WRITE_DATABUFFER; else return false; // 构造传输的数据变量 const ULONG ulNum = 2; ULONG InData[ulNum]; InData[0] = Reg; InData[1] = ulSize; //写数据 DWORD ReturnBytes; if( DeviceIoControl( hCard, code, InData, 4 * ulNum, pData, ulSize, &ReturnBytes, NULL) ) return true; else return false; } |
|
|
5楼#
发布于:2003-04-05 13:44
整理了一下,我的要求和现在的情况如下。 知道你问题出在哪里了,呵呵 问题出在你的用户态程序上,direct方式往下传数据时,DeviceIoControl的输出缓冲区(第5、6个参数!)才是你真正的往下传数据的缓冲区,也就是说你的文件中的数据应该放在第5、6个参数中!!! mdl获取的是deviceiocontrol中输出缓冲区参数,他的输入缓冲区仍采用buffer方式,你可以在里面放一些无关紧要的参数 |
|
|
6楼#
发布于:2003-04-05 13:33
在SOFTICE中看不到正确数据,dx->MdlAddress下面有个MappedSystemVa,调用MmGetSystemAddressForMdlSafe得到的值与它相同,然后点开它旁边的加号,下面只有一个数,是0,而我给的是一个1024元素的数组首地址。
|
|
7楼#
发布于:2003-04-05 13:22
[quote]bbs上的代码不好排版,费心看了,呵呵 非常感谢! 能否再说详细一点,“将文件中的数据保存在缓冲区中”是什么意思?我试过将一个数组的首地址传下去,好象还是不行。 [编辑 - 4/5/03 by kittylh] [/quote] 就是将文件中的数据读到缓冲区(堆或者栈),再将这个缓冲区首地址传给ioctol 数组应该没问题,我的驱动也用的数组,懒得开堆给他了 如果不行,你看看你传给ioctl的参数,注意两点:缓冲区的大小,以及缓冲区指针是否放在正确的参数位置 你在softice中能看到正确的数据吗? |
|
|
8楼#
发布于:2003-04-05 13:15
大侠,我说你好歹也放几分先嘛,也好让我们安安心先啊,呵呵,不情之请 :D SORRY :D 一急竟然忘了,明天是最后期限。 :( 我的代码和你的差不多啊,可是缓冲区里的始终是0 |
|
9楼#
发布于:2003-04-05 13:07
大侠,我说你好歹也放几分先嘛,也好让我们安安心先啊,呵呵,不情之请 :D
|
|
|
10楼#
发布于:2003-04-05 12:59
bbs上的代码不好排版,费心看了,呵呵 非常感谢! 能否再说详细一点,“将文件中的数据保存在缓冲区中”是什么意思?我试过将一个数组的首地址传下去,好象还是不行。 [编辑 - 4/5/03 by kittylh] |
|
11楼#
发布于:2003-04-05 12:48
bbs上的代码不好排版,费心看了,呵呵
另外,觉得你不应该传文件指针,而应该在用户态将文件中的数据保存在缓冲区中,然后直接将缓冲区指针传给ioctl |
|
|
12楼#
发布于:2003-04-05 12:46
case IOCTL_WRITE_DATABUFFER:
{ // IOCTL_WRITE_DATABUFFER if (cbin < 8 || cbout < sz || (MemOffset > ( pdx->memsize-16 )) ) { status = STATUS_INVALID_BUFFER_SIZE; break; } // WIN2000下用户数据缓冲区首地址 PULONG pulInBuffer = (PULONG) MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); for(int i = 0; ulTempSize < sz; i += 4) { if(i > 12) i=0; WRITE_REGISTER_ULONG( (PULONG)(pdx->membase + MemOffset + i), *pulInBuffer++ ); ulTempSize += 4; } info = sz; break; } // IOCTL_WRITE_DATABUFFER |
|
|
13楼#
发布于:2003-04-05 12:44
整理了一下,我的要求和现在的情况如下。 首先回答你的问题: 1、对 2、MmProbeAndLockPages不需要也不能要,MmGetSystemAddressForMdlSafe是访问mdl的正确方式 3、没用过,代码后面跟贴 |
|
|
14楼#
发布于:2003-04-05 12:40
[quote]ft,mdl不是这样用的。 是我错了! 先MmProbeAndLockPages,再MmGetSystemAddressForMdlSafe,对吗? 我从未用过MDL,大虾不要取笑。 [/quote] ddk中明确指出,上层的过滤器驱动已经调用了MmProbeAndLockPages,所以用户的功能驱动程序不需要(也不能)再调用MmProbeAndLockPages。 我的实际经历也证明情况确实如此,一开始我的驱动也和你的流程一样,但是如果这个ioctl调用很频繁的话(连续调用2000~2500次),系统就会自动重起,后来在ddk中找到了上述说明,把MmProbeAndLockPages一去掉,驱动就很稳定的工作了:) 呵呵,大家都有第一次用mdl的时候,没人取笑你,是帮你指正错误嘛,呵呵 [编辑 - 4/5/03 by mailme] |
|
|
15楼#
发布于:2003-04-05 05:56
整理了一下,我的要求和现在的情况如下。
我的要求:一个PCI板卡,每60ms传输64K的数据,大约要连续传输十多分钟 目前情况:我创建了一个使用DIRECT I/O的IOCTL(在初始化时设备被初始化为BUFFERED I/O),利用DeviceIoControl的第三和第四个参数带下来源文件的指针和大小。 现在IRP的流程好象是对的,主要问题是DIRECT I/O方式下,一直没有得到正确的指针,所以发送的数据不对。 我想问: 1、当IOCTL的指定DIRECT方式,是否不管以前驱动怎么指定,I/O管理器对此IOCTL都按DIRECT方式 2、如果I/O管理器按DIRECT方式,那么是否在STARTIO例程中读出Irp->MdlAddress是否已经由I/O管理器将输入缓冲的地址放入了,是否还需要我调用MmProbeAndLockPages,在真正读写时,是否还需要调用MmGetSystemAddressForMdlSafe 3、CHRIS CANT的例子程序中(WdmIo)的PHD_IO_CMDS中有个PHDIO_WRITES,有谁用过吗?能贴段代码吗? 谢谢! |
|
16楼#
发布于:2003-04-05 01:06
ft,mdl不是这样用的。 是我错了! 先MmProbeAndLockPages,再MmGetSystemAddressForMdlSafe,对吗? 我从未用过MDL,大虾不要取笑。 |
|
17楼#
发布于:2003-04-05 00:56
ft,mdl不是这样用的。
|
|
18楼#
发布于:2003-04-04 23:47
http://www.driverdevelop.com/dlit.php?id=70 下完了,谢谢。 我现在的做法是这样的: 1、创建一个IOCTL,它的TRANSFER TYPE是METHOD_IN_DIRECT 2、用DeviceIoControl调用时把一个文件指针作为第3个参数,需要一次性写的数据个数作为第4个参数,比如说1024个 用SOFTICE跟踪时也正确的从DISPATCH到STARTIO,再到真正的设备读写处,整个工作流程没有问题,但是我发现每次写的数据却是错误的,好象是从缓冲区中读出来的随机数,反正不是我给定的文件中的数据(我的文件中数据全部是0x4C)。 我想可能是直接I/O的使用方法有误,我是直接读出缓冲区地址的: Buffer = (PULONG)Irp->MdlAddress; 然后, ULONG temp = *Buffer; 向设备写temp; Buffer++ 这样的用法有什么不对吗?为什么每次temp的值都不对啊?谢谢。 |
|
19楼#
发布于:2003-04-04 19:06
http://www.driverdevelop.com/dlit.php?id=70
改为 http://www.driverdevelop.com:90/dlit.php?id=70 都是黑客(不知道算不算,呵呵)倒的鬼啦,你没看驱动的主页上都加了断口90的限制吗,呵呵 |
|
|
上一页
下一页