liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1521回复:18

基于ISA卡的VxD驱动捕获中断的问题

楼主#
更多 发布于:2003-03-08 09:28
我前两天在microsoft.public.development.device.drivers发了帖子询问,但是估计老外们看了我写的英文没有几个活下来的。有一个坚强的还回了帖,真令人敬佩!下面是我发的帖,估计咱中国人都看得懂,
Hello all:
I made a VxD to handle a interrupt from an ISA card. I made it by
VToolsD. In interrupt handle, a page faule occured. Here it is:

VOID XMyIRQ::OnHardwareInt(VMHANDLE hVM)
{
assert(hVM);
Out_Debug_String(\"assert(hVM) OK!\\n\");

MyGlobalEvent* pEvent = new MyGlobalEvent();
Out_Debug_String(\"Create new event OK!\\n\");

if (pEvent)
pEvent->schedule(); // <<--debug message:Break due to page fault(0Eh)

//interrupt over

pIRQ->sendPhysicalEOI(); // tell VPICD to clear the interrupt
Out_Debug_String(\"VPICD_Phys_EOI(hIRQ) OK!\\n\");

}

In SoftIce, I press continue, it will continue.
And go in MyGlobalEvent::handler.
Here it is:

VOID MyGlobalEvent::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, PVOID
refData)
{
// whatever your handler does
// (now safe to use any VMM service)
Out_Debug_String(\"In Event handler,read CN1!\\n\");
UCHAR i;
i=_inp(CN1);

Out_Debug_Chr(i);
// pIRQ->sendPhysicalEOI(); // tell VPICD to clear the interrupt
// Out_Debug_String(\"VPICD_Phys_EOI(hIRQ) OK!\\n\");

Out_Debug_String(\"\\nInvoke the callback!\\n\");
_VWIN32_QueueUserApc(ring3func, (DWORD)i, TheThread); //<<--here ,a lot of
page faults were shown, at last, it\'s hang.
}

I\'m a greenhand in this part. Please help me!

这个是老外的回帖:
I\'m not quite sure if you can allocate memory (call new) in the interrupt
handler.

我的疑问是:我完全按照VToolsD所提供的方法写的,这是VTooolsD提供的例程:

VOID XEOC_IRQ::OnHardwareInt(VMHANDLE hVM)
{

//dprintf(\"DATAACQ: IRQ index %d\",dataindex);

*pdatacursor = _inp(data_ac_base+0);
pdatacursor++;
dataindex++;


// schedule a global event
if (dataindex==buffersize)
{
EOC_GlobalEvent* pEvent = new EOC_GlobalEvent();
if (pEvent)
{
pEvent->schedule();
dataindex=0;
pdatacursor=(PCHAR)pdatabase;
}
else
{
dataindex--;
pdatacursor--;
}
}
pEOC_IRQ->sendPhysicalEOI();
}

我的VxD运行时,能捕获第一个中断,但以后就是Page Fault了,现在更惨:一有中断,机子就重启。
我不明白为什么我用的就是错的,它提供的例程是关于数据采集的,我没办法试。我写的程式是按照它的说明文档写的,并且例程也与我写的相符,为什么一运行就会出错?说明文档中介绍得很清楚,应该在GlobalEvent中调用服务,不能在中断服务中调用。

我几乎是把说明文档中的例程临摹下来的,可还是PageFault,请大虾指点!!

另外请问:在VxD处理中断的环境中,能否用APC的方式与Win32 App通讯?我在两个资料中看到两种答案,不知道该相信哪一种。请高手指点!分不是问题,只要能帮我搞通,我可以蹲在这里给大家泡分!

附件是VxD和应用程式主要的源文件
附件名称/大小 下载次数 最后更新
2003-03-08_vxd.rar (6KB)  1
X_ray
驱动中牛
驱动中牛
  • 注册日期2003-02-03
  • 最后登录2004-07-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-03-08 10:28
怎么有new没有delete?
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2003-03-08 16:57
非要用apc吗?
liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-03-08 23:44
当然不一定用APC,只不过比Event简单,只要能通过,什么都行!
求楼上大哥指点指点,我是个新手,都是自己摸索的,好困难哪。
帮帮忙吧! :D :D :D
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2003-03-09 12:03
你的ring3 function要干什么呢?
liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-03-10 12:59
情况是这样的:
    一个ISA卡,每秒钟有200次中断,程序要对中断计数,并且有中断来驱动整个程序运作。我的设想是这样的:VXD捕获中断后,对中断计数,然后发送消息(以计数值为参数)驱动主程序,请问这样是否可行,我写的程序是否有漏洞,所以才会有页面错误?请指教!
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2003-03-10 16:50
我都是用event的,apc还真是没有用过。 :D
vxd向app发消息也可以的。
liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-03-10 17:32
我是个新手,只对VxD了解一些皮毛,书上讲Event 比APC复杂,但比APC效率高。既然大侠擅长Event,那就请帮我看看这段代码,为什么会有页面错误呢?我是照着VToolsD的例子写的,怎么还有错?

VOID XMyIRQ::OnHardwareInt(VMHANDLE hVM)
{
assert(hVM);

MyGlobalEvent* pEvent = new MyGlobalEvent();

if (pEvent)
pEvent->schedule(); // <<--debug message:Break due to page fault(0Eh)

//interrupt over
......
}
详细的程序在最上面的附件里有,请大侠一定帮帮忙,我已经困在这里有好几个月了! :( :( :(
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
8楼#
发布于:2003-03-10 22:37
你用si看看pEvent
vtoolsd说可以在interrupt level用new,但是还是看看吧。
liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-03-11 10:52
您说的si是softICE 吧,
您的意思是vtoolsd说可以在interrupt level用new
这个结论并不正确是吗?
我又看了两天书,看出我的程序是个四不象,APC 和Event两种方法都有,我决定用Event的方法,但是VToolsD生成的代码里缺少了很多东西,比如说一些参数。我该怎么用呢?请指教!
xiaostorm
驱动牛犊
驱动牛犊
  • 注册日期2003-01-31
  • 最后登录2003-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-03-12 16:03
我和那个老外的想法一样。我曾经在中断中分配M,也死机,就是在GlobalEvent中也一样。所以要另想办法。我目前还没有好办法。
liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-03-12 17:52
我也有过这样的想法,不过VToolsD附带的例子中就有在中断中new Event的,我把它编译出来,用DriverMonitor载入了一下,一切正常,但是由于我没有中断,SoftICE的Genint也不大会用,所以没有在试。我的程序也是一样的,能够new Event,但是在中断处理过程中出现页面错误,机器down掉。我现在正在努力改写自己的程序,向例子靠拢,我就不信搞不定!
下面是例子代码中的部分代码:
VOID XEOC_IRQ::OnHardwareInt(VMHANDLE hVM)
{
    //dprintf(\"DATAACQ: IRQ index %d\",dataindex);

    *pdatacursor = _inp(data_ac_base+0);
    pdatacursor++;
    dataindex++;

    // schedule a global event
    if (dataindex==buffersize)
    {
EOC_GlobalEvent* pEvent = new EOC_GlobalEvent();
if (pEvent)
{
   pEvent->schedule();
   dataindex=0;
   pdatacursor=(PCHAR)pdatabase;
}
else
{
   dataindex--;
   pdatacursor--;
}
    }
    pEOC_IRQ->sendPhysicalEOI();
}
liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-03-14 14:09
这是个VxD编程中的问题,各种资料上都说在事件处理函数中可以安全的调用各种服
务,我调用_SHELL_PostMessage向主程序窗口发送消息,可是会有页面错误,请问怎样
解决。


VOID MyGlobalEvent::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, PVOID
refData)
{
 Out_Debug_String(\"In Event handler\\n\");

... ...

 if(_SHELL_PostMessage(msg->hWinhandle,msg->MessageID, (WORD)pos, (DWORD)0,
0, 0))
            //这里产生页面错误,
 { Out_Debug_String(\"PostMessage OK!\\n\"); }
 else
 { Out_Debug_String(\"PostMessage Error!\\n\"); }
}

msg:
struct msgbuf {
 HANDLE hWinhandle; //windows handle 存储从主程序传过来的窗口句柄
 UINT MessageID;  //Message ID
} *msg;


liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-03-14 15:54
用DriverMonitor载入VxD后,启动,捕获中断一切正常,也能够发送消息(当然,此时的msg->hWinhandle,msg->MessageID的值都是没有意义的)
但是用主程序运行,载入VxD,启动正常,中断来了之后,在Event handle中 _SHELL_PostMessage出现页面错误,估计可能是msg->hWinhandle的值导致的,请问哪位知道正确的方法,怎样避免这个页面错误?

msg->hWinhandle的值是主程序窗口的handle,我看到_SHELL_PostMessage的第一个参数是handle of a window,于是从主程序的this->hWnd将窗口handle传过来。
lrx666
驱动太牛
驱动太牛
  • 注册日期2001-08-17
  • 最后登录2010-10-25
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望47点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-03-14 21:14
这种方式频率不能做很高,我以前也碰到过,后来频率降低就好了,晕
liuguangzhou
驱动牛犊
驱动牛犊
  • 注册日期2002-07-26
  • 最后登录2006-03-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-03-14 22:34
我现在做的VxD要相应的中断是200Hz的,请问这个频率是否很高?
据我想应该不会吧?
我现在只要能顺利运行就可以,无论什么方法。请帮忙看看到底是什么地方错了。多谢!
zengshenbo
驱动牛犊
驱动牛犊
  • 注册日期2002-03-15
  • 最后登录2009-07-07
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-03-24 22:23
受益匪浅!!
HJZ
HJZ
驱动牛犊
驱动牛犊
  • 注册日期2002-01-14
  • 最后登录2005-01-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-08-04 11:01
很受用,谢谢!!!
qdyangjing
驱动小牛
驱动小牛
  • 注册日期2003-02-26
  • 最后登录2005-11-16
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望3点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-08-19 20:11
我以前也怀疑过ISA的中断频率问题,
但是我的卡要求2100Hz的中断.
在我经过无数次的思考,修改,测试后,做到了2100Hz,而且系统很稳定.
***************************** *********向军旗敬礼!******** ********向给分者微笑!******* *****************************
游客

返回顶部