zhiji
驱动牛犊
驱动牛犊
  • 注册日期2002-03-10
  • 最后登录2009-07-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1393回复:1

为什么IoCopyCurrentIrpStackLocationToNext(Irp)与完成例程IoSetCompletionRoutine不能一起工作? 详见(键盘过滤)...

楼主#
更多 发布于:2004-10-09 13:06

我为《驱动程序模型设计》中第九章-过滤器驱动程序 添加一个“IRP_MJ_READ的完成例程”
目录 .\Chap9\FILTER

//=========================
NTSTATUS ReadComplete( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PDEVICE_EXTENSION pdx)
{
DebugPrintMsg("ReadComplete");
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return  Irp->IoStatus.Status;
}
////////////
NTSTATUS DispatchRead(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchRead
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
NTSTATUS status;

status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
return CompleteRequest(Irp, status, 0);
}

DebugPrintMsg("DispatchRead");

IoSkipCurrentIrpStackLocation(Irp); //正常工作
// IoCopyCurrentIrpStackLocationToNext(Irp); // 不正常工作
IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)ReadComplete,
(PVOID)pdx, TRUE, TRUE, TRUE);

status = IoCallDriver(pdx->LowerDeviceObject, Irp);

//  不需要--在ReadComplete释放
// IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

return status;
}
//=====================
可使用
IoCopyCurrentIrpStackLocationToNext(Irp); // 不正常工作
完成例程调用一次后,键盘驱动就好像死了,不管怎么按键都没反映
而 IoSkipCurrentIrpStackLocation(Irp); //可以正常工作--为什么 (可不能在完成例程中读数据)


以下全部DriverEntry.cpp的代码 --我使用了《WDM设备驱动程序开发指南》中的调试工具“DebugPrint”


#pragma INITCODE
extern "C" NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
#if DBG
DebugPrintInit("KbdFiter");
#else
DebugPrintInit("KbdFiter");
#endif
// Initialize function pointers

DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;

for (int i = 0; i < arraysize(DriverObject->MajorFunction); ++i)
DriverObject->MajorFunction = DispatchAny;

DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;

return STATUS_SUCCESS;
}

////////////////////

#pragma PAGEDCODE

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
PAGED_CODE();
DebugPrintClose();
}

////////////////////

NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{ // AddDevice
PAGED_CODE();

NTSTATUS status;

// Create a functional device object to represent the hardware we're managing.

PDEVICE_OBJECT fdo;
#define xsize sizeof(DEVICE_EXTENSION)
status = IoCreateDevice(DriverObject,
xsize, NULL,
FILE_DEVICE_KEYBOARD, 0,
FALSE, &fdo);

if (!NT_SUCCESS(status))
{ // can't create device object
return status;
} // can't create device object

PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

////

IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);

PDEVICE_OBJECT ldo = IoAttachDeviceToDeviceStack(fdo, pdo);
if (ldo==NULL)
{
status = STATUS_DEVICE_REMOVED;
}

pdx->LowerDeviceObject = ldo;
fdo->Flags |= ldo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE | DO_POWER_INRUSH);

fdo->Characteristics = ldo->Characteristics;

fdo->Flags &= ~DO_DEVICE_INITIALIZING;

return status;
}

////////////////////

#pragma LOCKEDCODE

NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
{ // CompleteRequest
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest

NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status)
{ // CompleteRequest
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest

////////////////////

#pragma LOCKEDCODE // make no assumptions about pageability of dispatch fcns
//
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchAny
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

// Pass request down without additional processing
KIRQL irql;
NTSTATUS status;

status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
return CompleteRequest(Irp, status, 0);
}

IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

return status;
} // DispatchAny
////////////
NTSTATUS ReadComplete( IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PDEVICE_EXTENSION pdx)
{
DebugPrintMsg("ReadComplete");
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return  Irp->IoStatus.Status;
}
////////////
NTSTATUS DispatchRead(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchRead
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
NTSTATUS status;

status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
return CompleteRequest(Irp, status, 0);
}

DebugPrintMsg("DispatchRead");

IoSkipCurrentIrpStackLocation(Irp); //正常工作
// IoCopyCurrentIrpStackLocationToNext(Irp); // 不正常工作
IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)ReadComplete,
(PVOID)pdx, TRUE, TRUE, TRUE);

status = IoCallDriver(pdx->LowerDeviceObject, Irp);

//  不需要--在ReadComplete释放
// IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

return status;
} // DispatchRead

////////////////////
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchPower

PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
PoStartNextPowerIrp(Irp); // must be done while we own the IRP

NTSTATUS status;
KIRQL irql;

status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);

if (!NT_SUCCESS(status))
{
return CompleteRequest(Irp, status, 0);
}

IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

return status;
} // DispatchPower

////////////////////

NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchPnp
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG fcn = stack->MinorFunction;

KIRQL irql;
NTSTATUS status;

PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
{
return CompleteRequest(Irp, status, 0);
}

IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);

if (fcn == IRP_MN_REMOVE_DEVICE)
{
IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
RemoveDevice(fido);
}
else
{
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
}

return status;
} // DispatchPnp
////////////////////

#pragma PAGEDCODE

VOID RemoveDevice(IN PDEVICE_OBJECT fdo)
{ // RemoveDevice
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS status;


if (pdx->LowerDeviceObject!=NULL)
IoDetachDevice(pdx->LowerDeviceObject);

IoDeleteDevice(fdo);
} // RemoveDevice



acidfish
驱动小牛
驱动小牛
  • 注册日期2002-05-20
  • 最后登录2009-11-11
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-10-11 11:35
你先试试取消
IoAcquireRemoveLock
IoReleaseRemoveLock
这两个函数的调用,会不会出现上述的现象。
游客

返回顶部