pengenwen
禁止发言
禁止发言
  • 注册日期2003-03-07
  • 最后登录2016-04-11
  • 粉丝0
  • 关注0
  • 积分1586分
  • 威望8380点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1816回复:14

IRP 的PENDING问题

楼主#
更多 发布于:2003-11-26 16:54
用户被禁言,该主题自动屏蔽!
grassland
驱动牛犊
驱动牛犊
  • 注册日期2003-10-12
  • 最后登录2005-06-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-11-30 21:57

“在返回return STATUS_SUCCESS前加个:
if ( Irp->PendingReturned )
IoMarkIrpPending( Irp );”

 qinxg说的好像有道理。
                                
qinxg
驱动小牛
驱动小牛
  • 注册日期2002-11-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望27点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-11-28 12:05
在返回return STATUS_SUCCESS前加个:
if ( Irp->PendingReturned )
    IoMarkIrpPending( Irp );
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-11-28 11:08
应该到哪查询系统错误的信息那?
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-11-28 08:37
还是不行。
郁闷到底。
pagefault fault=0000,这是什么意思???

[编辑 -  11/28/03 by  xiaorain]
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-11-27 16:18
多谢,我试一下先
qinxg
驱动小牛
驱动小牛
  • 注册日期2002-11-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望27点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-11-27 14:57
irpStack = IoGetNextIrpStackLocation( Irp );
改成IoGetCurrentIrpStackLocation()试试
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-11-27 12:02
太强了这是AGSGetcts()的代码能否帮忙看一下????
用softice执行到
IOcalldriver()就死机是page fault,帮帮我把....

NTSTATUS AGSGetCts(PDEVICE_OBJECT fdo,PIRP Irp, PVOID ScardExtension)
{
NTSTATUS status;
ULONG ulModemStatus ;
PIO_STACK_LOCATION irpStack;
KIRQL irql;
ULONG chbtemp;
PSMARTCARD_EXTENSION SmartcardExtension = (PSMARTCARD_EXTENSION)ScardExtension;

ulModemStatus = SmartcardExtension->ReaderExtension->ModemStatus;

if(SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask)
{
//
// Only inform the user of a card insertion/removal event
// if this function isn\'t called due to a power down - power up cycle
//
if (SmartcardExtension->ReaderExtension->PowerRequest == FALSE)// && SmartcardExtension->OsData->NotificationIrp)
{
// AGSCompleteCardTracking(SmartcardExtension);
}

if(SmartcardExtension->ReaderExtension->GetModemStatus)// && SmartcardExtension->ReaderExtension->Running)
//Variable used to receive the modem status
{
KeAcquireSpinLock(
&SmartcardExtension->OsData->SpinLock,
&irql
);
        
chbtemp=SmartcardExtension->ReaderExtension->ModemStatus & SERIAL_CTS_STATE;

if(chbtemp)
{
// Card is removed
SmartcardExtension->ReaderExtension->CardPresent = FALSE;
SmartcardExtension->CardCapabilities.ATR.Length = 0;
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
SmartcardExtension->ReaderExtension->AtrRetrieved = FALSE;
}
else
{
// Card is inserted
SmartcardExtension->ReaderExtension->CardPresent = TRUE;
SmartcardExtension->ReaderExtension->First = FALSE;
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
SmartcardExtension->CardCapabilities.Protocol.Selected =  SCARD_PROTOCOL_UNDEFINED;
}
KeReleaseSpinLock( &SmartcardExtension->OsData->SpinLock,irql );
// Setup call for device control to wait for a serial event
irpStack = IoGetNextIrpStackLocation( Irp );
irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
irpStack->MinorFunction = 0UL;
irpStack->Parameters.DeviceIoControl.OutputBufferLength =
sizeof(SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask);
irpStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_SERIAL_WAIT_ON_MASK;
SmartcardExtension->ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer =
&SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask;
SmartcardExtension->ReaderExtension->GetModemStatus = FALSE;
}
else
{
// AGSGetModemStatus(fdo,Irp,SmartcardExtension);
SmartcardExtension->ReaderExtension->GetModemStatus = TRUE;
}
//S: registers an IoCompletion routine to be called
//when the next-lower-level driver has completed the requested operation for the given IRP
IoSetCompletionRoutine(
Irp,
AGSGetCts,
SmartcardExtension,
TRUE,
TRUE,
TRUE
);
//S: sends an IRP to the next-lower-level driver after the caller has set up the I/O stack location
//in the IRP for that driver.
status = IoCallDriver(
((PDEVICE_EXTENSION)fdo->DeviceExtension)->pLowerDev,
Irp
);
return STATUS_MORE_PROCESSING_REQUIRED;
}
else
{
return STATUS_SUCCESS;
}
}
qinxg
驱动小牛
驱动小牛
  • 注册日期2002-11-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望27点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-11-27 09:51
那是AGSGetCts()函数有问题,此时IRQL的级别可能是DISPATCH_LEVEL,与下层驱动返回IRP时的级别一样.这个级别上有很多限制的,查里面每个函数的级别限制,或用Softice跟踪一下
qinxg
驱动小牛
驱动小牛
  • 注册日期2002-11-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望27点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-11-27 09:46
要看IRP的性质,对有的IRP上层驱动就不能等待下层驱动完成.如ReadFile(),下层驱动可能要读很长时间,这段时间内上层驱动将完全死锁,不传递任何IRP.
如果下层驱动能够立即完成IRP,则上层驱动可以等待它完成
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-11-27 09:41
要看IoCallDriver()的返回值,如果它返回PENDING,则应该先返回PENDING,之后在返回原IRP,否则驱动可能阻塞至死,我是有过教训的

qinxg,你说的驱动阻塞至死,是否意味着出现分页错误,系统重启呢(Win2000中)?
IoSetCompletionRoutine(
Irp,
AGSGetCts,
SmartcardExtension,
TRUE,
TRUE,
TRUE
);
//S: sends an IRP to the next-lower-level driver after the caller has set up the I/O stack location
//in the IRP for that driver.
status = IoCallDriver(
((PDEVICE_EXTENSION)fdo->DeviceExtension)->pLowerDev,
Irp
);
在执行完上边的代码后,就死机。是否setcompletionroutine()与
iocalldriver(),不能同时用啊?
因为如果没有iosetcompletionroutine(),直接用iocalldriver()就不会死机。
pengenwen
禁止发言
禁止发言
  • 注册日期2003-03-07
  • 最后登录2016-04-11
  • 粉丝0
  • 关注0
  • 积分1586分
  • 威望8380点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-11-27 09:04
用户被禁言,该主题自动屏蔽!
qinxg
驱动小牛
驱动小牛
  • 注册日期2002-11-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望27点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-11-27 08:39
要看IoCallDriver()的返回值,如果它返回PENDING,则应该先返回PENDING,之后在返回原IRP,否则驱动可能阻塞至死,我是有过教训的
icube
驱动牛犊
驱动牛犊
  • 注册日期2002-04-11
  • 最后登录2004-12-19
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-11-26 19:01
通过阻塞的方法等待下层驱动完成IRP不是一个好的方法,当然如果你是顶层的驱动你可以这样做,因为等待是在发起请求的线程上下文完成的,但是如果你的驱动不是顶层驱动的话,你的等待可能是在任意线程的上下文内进行的,在内核PASSIVE_LEVEL阻塞去等待IRP的完成不符合NT IO的异步特性,这可能会影响系统的吞吐量
escape
驱动老牛
驱动老牛
  • 注册日期2002-02-01
  • 最后登录2004-08-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-11-26 18:24
直接下传,多快好省。
游客

返回顶部