#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("DriverB:Enter B HelloDDKRead\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING DeviceName;
RtlInitUnicodeString( &DeviceName, L"\\Device\\MyDDKDeviceA" );
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
//得到设备对象指针
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);
KdPrint(("DriverB:FileObject:%x\n",FileObject));
KdPrint(("DriverB:DeviceObject:%x\n",DeviceObject));
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));
ntStatus = STATUS_UNSUCCESSFUL;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKRead\n"));
return ntStatus;
}
KEVENT event;
KeInitializeEvent(&event,NotificationEvent,FALSE);
PIRP pNewIrp = IoAllocateIrp(DeviceObject->StackSize,FALSE);
KdPrint(("pNewIrp->UserEvent :%x\n",pNewIrp->UserEvent));
pNewIrp->UserEvent = &event;
IO_STATUS_BLOCK status_block;
pNewIrp->UserIosb = &status_block;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
//因为DriverA是BUFFER IO设备
pNewIrp->AssociatedIrp.SystemBuffer = NULL;
KdPrint(("DriverB:pNewIrp:%x\n",pNewIrp));
PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(pNewIrp);
stack->MajorFunction = IRP_MJ_READ;
stack->MinorFunction=IRP_MN_NORMAL;//0
stack->FileObject = FileObject;
//调用DriverA驱动
NTSTATUS status = IoCallDriver(DeviceObject,pNewIrp);
if (status == STATUS_PENDING) {
status = KeWaitForSingleObject(
&event,
Executive,
KernelMode,
FALSE, // Not alertable
NULL);
KdPrint(("STATUS_PENDING\n"));
}
ObDereferenceObject( FileObject );
IoFreeIrp(pNewIrp);
ntStatus = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = ntStatus;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("DriverB:Leave B HelloDDKRead\n"));
return ntStatus;
}
《windows驱动开发详解》中有一个例子,使用DriverB创建一个DriverA的IRP并使用IoCallDriver发送IRP请求,我不明白为什么在设置DriverA堆栈时使用IoGetNextIrpStackLocation 获取下层堆栈并设置