cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
阅读:2203回复:18

关于虚拟光驱

楼主#
更多 发布于:2004-06-29 10:59
各位老大,现在在做虚拟光驱,实在是不能入门,乞请大家帮我一吧。
 我看了Vaporcd的源码,它只是在浏览器的层次上虚出来了一各设备,接受OS的IOCTL_CDROM_READ_TOC ,IOCTL_CDROM_GET_CONTROL ,这样的消息欺骗0S,但是怎样在系统总线上虚出一个设备呢?我看了ddk的miniport例子,它做出了一各SCSI adapter,但是怎么在其上定义一个CDROM呢?就是一个具有HA,TA,LUN的设备。这方面实在是不清楚,哪位大哥告诉小弟应该看那些资料,现在看DDK帮助感觉离CDROM很远,能帮小弟间说一下流程愿把所有分奉上。
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
沙发#
发布于:2004-06-29 17:34
要虚拟出一个CD-ROM需要在系统发送 SCSIOP_INQUIRY 命令的时候,报告有一个设备(设备类型要设好)。然后系统会发送一些命令如:SCSIOP_READ_CAPACITY, 正确处理就可以了。

论坛有一个大牛Xinghai_Kang曾经写了一个(名字叫 VDISK),搜索一下吧。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
FredLiu
驱动牛犊
驱动牛犊
  • 注册日期2004-01-07
  • 最后登录2004-07-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-06-29 18:01
http://www.driverdevelop.com/forum/viewthread.php?tid=31076
里面就有楼上的大牛说的那个大牛的例子;P,不过那个例子是虚拟一个移动硬盘,不是cdrom。要改成cdrom,除了在SCSIOP_INQUIRY时报告是cdrom以外,你还要支持一些与cdrom相关的scsi command set,另外,那个例子实现worker thread的方法也不太好,有时候会蓝屏(起码在我的机器上是),除此之外,实现虚拟驱动大部分需要的东西都在这个例子里了。

vaporcd是用直接写一个相当于cdrom class driver的驱动来实现的,用service control manager实现动态加载和卸载光驱,实现比较简单,但是好像不太稳定
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-06-30 11:22
多谢两位回复,搜索了帖子找到了VDISK,不知 seaquester 兄还记得不,你曾经在帖子里讲过VDISK的机制,还有FredLiu兄你的问题我也注意到了,在VDISK里作者是用了两种方式处理SRB,一是用工作线程,一中是在函数里直接处理返回,用NOTHREAD_TEST宏进行区分,现在含有两个问题不明想请教:
1》工作线程中为什么要用TIMER来提交处理结果,线程处理完后直接返回不行吗?
2》在SubmitRequest中判断了IRQ级别, KeSetEvent can only be running at DISPATCH_LEVEL and less 当前IRQ级别太高时返回了NOT_READ,如此说来对处理SRB用那一种方法最好呢?
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
地下室#
发布于:2004-06-30 12:37
在系统线程里面调用ScsiPortNotification结束一个SRB是不管用的.只有在StartIo、ISR里面或者像VDISK中的做法一样用ScsiPortNotification(RequestTimerCall)才行。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-07-01 15:36
seaquester: 感谢回复。目前还有一点不明确:
在DriverEntry中的例程HwInitialize运行的IRQL是不固定的(从你以前的贴子得知),可是VDISK在这个例程中创建了工作线程,和EVENT对象,这两个东西DDK明确规定在PASSIVE_LEVE级别的。我的程序现在象FredLiu说的那样,一起动就蓝屏重启,因为我仅仅改了些无关紧要的代码,所以我看就是这个中断级别的问题。我也想过将其移动到DriverEntry中,但是这个入口函数中没有HwDeviceExtension,没有办法移动这里来,望请指点迷经,感谢万分!
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
6楼#
发布于:2004-07-01 16:37
我以前曾经试过,能运行,看来你的运气不太好。

首先确认一下问题就出在PsCreateSystemThread, 在它前面添加:

   KIRQL byIrql = KeGetCurrentIrql();
   if( byIrql > PASSIVE_LEVEL )
   {
       KdPrint(("Wrong IRQL"));
   }
看它的IRQL是不是太高。

如果真的太高,那就没法子了,最好不要使用系统线程了 :P

如果非要用的话,用一个比较傻的方法:
在DriverEntry中创建系统线程, 在系统线程的开始作一个检测,如果HwDeviceExtension 没有传进来,就等待。
然后在HwInitialize中将 HwDeviceExtension 通过全局变量传进来,系统线程恢复运行。
 :(
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-07-02 15:50
谢谢您的帮助,现在调的加载数据ISO镜像出现容量为0的音频CD,不过还是有很大的进步了,看来是一些光驱命令模拟的不对,一点一点调吧,再次感谢您的帮助。
FredLiu
驱动牛犊
驱动牛犊
  • 注册日期2004-01-07
  • 最后登录2004-07-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-07-02 23:24
出现音频cd是因为READTOC的命令处理的不好,你用bushound看看真正的cd, 或者deamon tools对READTOC是如何处理的,比较一下应该就可以发现问题出在哪~
你最后irql的问题怎么解决的?
我解决irql太高的问题是通过从系统的workitem queue 中调一个thread出来来解决的。osronline 上面有一篇专门讲worker thread的文章,可以去看看~
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-07-05 10:01
FredLiu: 我实现的方法还是和VDISK的一样,不过侥幸成功了,不过这样的方式确实是不可取的,当我装载完镜像后重起时就出问题。现在ISO镜像能正确装入了,但是速度很慢,浏览时有时WINDOWS的手电筒在摇来摇去的等待。其实影响速度的关键应该是读取数据速度,可是基于这中线程和TIMER的工作机制你是怎么提高速度的。
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-07-05 10:26
这个方案没有你们说的那么多问题,好好检查自己的代码。

它唯一的缺点就是速度慢,但做虚拟光驱也够了,只要加上cache,可以轻松的跑到100速光驱!
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-07-05 10:42
用timer我不用cache速度也还过的去啊?你的速度多少啊?
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-07-05 11:16
具体速度还没查,我将TIMER的频率调为1000,现在浏览速度可以了,拷贝一个50M的文件浏览器显示要50秒钟。请问怎么实现CACHE,是不是将最近读取的内容放入内存,记录下LBA,检查请求是否在此翻围内,然后相应操作?刚才观察了一下实际光驱,拷贝一个40M的文件显示用55秒钟,但再次拷贝时不到10S钟。
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-07-05 13:05
用Nero的CDSpeed测试。
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-07-05 14:24
请问版主: 如果要虚拟出多个光驱是不是在inquiry命令时按相应的TAG值填充INQUIRYDATA结构,然后其他读写命令按Srb->TargetId值相应操作就行了? 另外动态增减光驱怎么通知系统来扫描总线?
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-07-06 13:10
什么TAG?
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-07-06 17:33
就是Srb->TargetId,我想用不同的TargetID来区分设备,返回相同的INQUIRYDATA,但是不能成功,即:

if(Srb->TargetID < 4 && Srb->Lun == 0)
{
 ....
填充INQUIRYDATA结构。
}

请问怎么才能出来4个光盘?
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-07-06 21:12
TargetID不过是个number而已,你到叫它tag了,呵呵
TargetID不过是从0开始+1而已。DDK里面定义了max target id,FindAdapter里面填充的struct也有一个对此有限制。
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
cxl7980
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2012-03-07
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望17点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-07-09 15:16
使用这种方法来做虚拟光驱问题确实太多了。
Irql的问题确实存在。
pnp的问题确实存在。
standby的问题确实存在。
每一个问题都是很头疼的,daemon是怎么实现的呢? 有人分析过吗?
游客

返回顶部