sipu
驱动牛犊
驱动牛犊
  • 注册日期2002-05-13
  • 最后登录2005-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1169回复:3

请问应用态程序如何控制IRP的标志位

楼主#
更多 发布于:2002-12-02 18:10
在调用ReadFile时,IRP的标志位为0x00000900,即读、写、关闭标志。

而Cancel为1。

StartIO不能调用,导致该IRP一直处于pending状态,只有在应用程序退出时才调用Cancel程序。

使用的是Walt的程序进行的改进。相关代码如下:

应用态:

        if(!ReadFile(file, buf, sizeof(buf), &bytes, NULL))
        {
            printf(\"Error in ReadFile: %x\", GetLastError());
            free (deviceInterfaceDetailData);
        }
        printf(\"Read Successful\\n\");
        ch = _getche();

内核态:

NTSTATUS DispatchReadWrite(PDEVICE_OBJECT fdo, PIRP Irp)
{ // DispatchReadWrite
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

if(!pdx->bRun)
{
CompleteRequest(Irp,STATUS_CANCELLED,IO_NO_INCREMENT);
}

IoMarkIrpPending(Irp);
StartPacket(&pdx->dqReadWrite, fdo, Irp, OnCancelReadWrite);
return STATUS_PENDING;
} // DispatchReadWrite

#pragma LOCKEDCODE

VOID OnCancelReadWrite(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // OnCancelReadWrite
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
CancelRequest(&pdx->dqReadWrite, Irp);
} // OnCancelReadWrite

VOID StartIo(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // StartIo
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
CompleteRequest(Irp, status, 0);
return; }
}

最新喜欢:

sunmaculasunmac...
lonkiss
驱动牛犊
驱动牛犊
  • 注册日期2002-01-15
  • 最后登录2004-07-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-12-02 19:25
你的startIO()里为什么不对排队的IRP进行处理呢?至少你应该调用一次CompleteRequest()函数来结束这个IRP的请求。
比如下面这样:
VOID StartIo(IN PDEVICE_OBJECT fdo, IN PIRP Irp)//IRQL=2=DISPATCH_LEVEL
{ // StartIo
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// KdPrint((\"into StartIo\"));

PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
GenericMarkDeviceBusy(pdx->pgx);
NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
CompleteRequest(Irp, status, 0);
return;
}

switch(stack->MajorFunction)
{

case IOCTL_WRITE_BUFFER:
// KdPrint((\"startio write\"));
if(KeSynchronizeExecution( pdx->InterruptObject, (PKSYNCHRONIZE_ROUTINE)DoWriteSynch, (PVOID)fdo))
{
//uw 发完了启动定时器,等待给我回应
//uw KeSetTimer(&pdx->WriteDataTimer,pdx->WriteDataInterval,&pdx->WriteDataDPC);
NTSTATUS status = STATUS_SUCCESS;
ULONG info = 6;

*((PUCHAR)Irp->AssociatedIrp.SystemBuffer+4)=STATUS_SUCCESS;
*((PUCHAR)Irp->AssociatedIrp.SystemBuffer+5)=STATUS_SUCCESS;

StartNextPacket(&pdx->dqReadWrite, fdo);
CompleteRequest(Irp, status, info);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
}
else
{
// KdPrint((\"startio write error\"));
NTSTATUS status = STATUS_SUCCESS;
ULONG info = 0;
StartNextPacket(&pdx->dqReadWrite, fdo);
CompleteRequest(Irp, status, info);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
}
break;
default:
NTSTATUS status = STATUS_NOT_SUPPORTED;
ULONG info = 0;
StartNextPacket(&pdx->dqReadWrite, fdo);
CompleteRequest(Irp, status, info);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
break;

}

}
我的真名就叫-龙旗
sipu
驱动牛犊
驱动牛犊
  • 注册日期2002-05-13
  • 最后登录2005-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-12-02 21:35
谢谢关注。

可是我的应用中芯片使用一个RISC程序实现数据传输,由IOCTL来控制开始运行程序,执行完一场后重新跳转到程序起始位置开始执行。

这样的话我的CompleteRequest就在DPC中执行了。

现在的问题是程序就不进入StartIo中去,在里边无所谓处理了。

问你一下,IRP的Cancel位是1是否就表明该IRP只能被Cancel掉?
sipu
驱动牛犊
驱动牛犊
  • 注册日期2002-05-13
  • 最后登录2005-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-12-02 22:08
有没有这样的可能,由于ReadFile的异常情况,造成该IRP只能被Cancel掉。

所以其Cancel位是1。
游客

返回顶部