阅读:1705回复:7
StartIO的问题
我最近正在研究StartIO,这方面资料少,手头的资料写的横含糊,请各位高手能解释一下StartIO如何工作,以及IRP如何排队。
|
|
最新喜欢:![]() |
沙发#
发布于:2002-06-18 12:40
举个例子简单的说:
win32api:readfile--io管理器构造irp--你的驱动中的xxxreadfile--调用IoStartPacket--调用startio例程--启动设备--产生中断,调用中断服务例程--dpc例程--完成这个irp |
|
|
板凳#
发布于:2002-06-18 13:29
是不是这样理解:
所有的 IRP_MJ_XXXX 通过IoStartPacket来使得Irp排队,StartIO例程处理排队的Irp,有没有写的简单的例子。 |
|
地板#
发布于: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 ); } |
|
|
地下室#
发布于:2002-06-18 14:36
所有的 IRP_MJ_XXXX 通过IoStartPacket来使得Irp排队 这句话不对, startio排队的只是对于硬件访问的irp,如读或写,这是为了保证在一个时刻只有一个irp在访问硬件 写和读是一样的。 |
|
|
5楼#
发布于:2002-06-18 15:03
真的要感谢各位高手的帮助。
如果不是对硬件作Irp排队可以么,比如完成某一个特定的功能处理。 |
|
6楼#
发布于:2002-06-18 15:17
还有一个比较愚蠢的问题。我来到这个论坛不久,不知道怎么给分,还有分数起什么作用呀
|
|
7楼#
发布于:2002-06-18 15:22
这个问题我会回答,在你的问题下,有给分按钮,
分数多当然好,可以多提问嘛! |
|