luke_gem
驱动牛犊
驱动牛犊
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1705回复:7

StartIO的问题

楼主#
更多 发布于:2002-06-18 12:20
我最近正在研究StartIO,这方面资料少,手头的资料写的横含糊,请各位高手能解释一下StartIO如何工作,以及IRP如何排队。

最新喜欢:

jinghuirenjinghu...
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-18 12:40
举个例子简单的说:

win32api:readfile--io管理器构造irp--你的驱动中的xxxreadfile--调用IoStartPacket--调用startio例程--启动设备--产生中断,调用中断服务例程--dpc例程--完成这个irp
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
luke_gem
驱动牛犊
驱动牛犊
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-18 13:29
是不是这样理解:
所有的 IRP_MJ_XXXX 通过IoStartPacket来使得Irp排队,StartIO例程处理排队的Irp,有没有写的简单的例子。
Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-18 14:35
是的。
VOID StartIo(
     IN PDEVICE_OBJECT pDevObj,
     IN PIRP pIrp
     ) {
     PIO_STACK_LOCATION pIrpStack =
          IoGetCurrentIrpStackLocation( pIrp );

PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
     pDevObj->DeviceExtension;
PUCHAR userBuffer;
ULONG xferSize;

switch( pIrpStack->MajorFunction ) {

// Use a SynchCritSection routine to
      // start the write operation...
      case IRP_MJ_WRITE:
            // Set up counts and byte pointer
            pDevExt->maxXferCount =
                 pIrpStack->Parameters.Write.Length;
            pDevExt->xferCount = 0;

// Since we processing a new Write request,
// free up any old buffer
if (pDevExt->deviceBuffer != NULL) {
     ExFreePool(pDevExt->deviceBuffer);
     pDevExt->deviceBuffer = NULL;
     pDevExt->deviceBufferSize = 0;
}
// Determine the length of the request
xferSize =
     pIrpStack->Parameters.Write.Length;
// Obtain user buffer pointer
userBuffer = (PUCHAR)
     pIrp->AssociatedIrp.SystemBuffer;
    
// Allocate the new buffer
pDevExt->deviceBuffer = (PUCHAR)
     ExAllocatePool( PagedPool, xferSize );
if (pDevExt->deviceBuffer == NULL) {
     // buffer didn\'t allocate???
     // fail the IRP
     pIrp->IoStatus.Status =
          STATUS_INSUFFICIENT_RESOURCES;
     pIrp->IoStatus.Information = 0;
     IoCompleteRequest( pIrp,
                IO_NO_INCREMENT );
     IoStartNextPacket( pDevObj, FALSE );
}

pDevExt->deviceBufferSize = xferSize;
//
// Try to send the first byte of data.
//
TransmitByte( pDevExt );
break;



ISR
The interrupt service routine for this driver is quite simple. It relies on a DpcForIsr routine to mark a completed IRP when the last byte of the user\'s output buffer has been sent to the printer port.


BOOLEAN Isr (
                IN PKINTERRUPT pIntObj,
                IN PVOID pServiceContext ) {

PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
     pServiceContext;
PDEVICE_OBJECT pDevObj = pDevExt->pDevice;
PIRP pIrp = pDevObj->CurrentIrp;

UCHAR status = ReadStatus( pDevExt );
if (!(status & STS_NOT_IRQ))
     return FALSE;

// its our interrupt, deal with it
// transmit another character
if (!TransmitByte( pDevExt ))
     // if no more bytes, complete the request
     IoRequestDpc( pDevObj, pIrp, (PVOID)pDevExt );
return TRUE;
}


DPCFORISR
The final interesting routine for this driver completes an I/O request when so ordered by the ISR.


VOID
DpcForIsr(
     IN PKDPC pDpc,
     IN PDEVICE_OBJECT pDevObj,
     IN PIRP pIrp,
     IN PVOID pContext
     )
{
    
     PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
         pContext;
        
     pIrp->IoStatus.Information =
               pDevExt->xferCount;

// This loopback device always works
pIrp->IoStatus.Status =
          STATUS_SUCCESS;
          
//
// If we\'re being called directly
from Start I/O,
// don\'t give the user any priority boost.
//
if( pDpc == NULL )
     IoCompleteRequest( pIrp, IO_NO_INCREMENT );
else
     IoCompleteRequest( pIrp, IO_PARALLEL_INCREMENT );
    
//
// This one\'s done. Begin working on
the next
IoStartNextPacket( pDevObj, FALSE );
}

Tom_lyd
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-06-18 14:36
 
所有的 IRP_MJ_XXXX 通过IoStartPacket来使得Irp排队


这句话不对, startio排队的只是对于硬件访问的irp,如读或写,这是为了保证在一个时刻只有一个irp在访问硬件

写和读是一样的。

[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
luke_gem
驱动牛犊
驱动牛犊
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-06-18 15:03
真的要感谢各位高手的帮助。

如果不是对硬件作Irp排队可以么,比如完成某一个特定的功能处理。
luke_gem
驱动牛犊
驱动牛犊
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-06-18 15:17
还有一个比较愚蠢的问题。我来到这个论坛不久,不知道怎么给分,还有分数起什么作用呀
xying
驱动牛犊
驱动牛犊
  • 注册日期2002-04-28
  • 最后登录2002-07-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-06-18 15:22
这个问题我会回答,在你的问题下,有给分按钮,
分数多当然好,可以多提问嘛!
游客

返回顶部