为了设备栈平衡,需要 IoSkipCurrentIrpStackLocation 或 IoCopyCurrentIrpStackLocationToNext
这个事例仅仅向下转发,没有做任何处理..所以IoSkipCurrentIrpStackLocation就好了.
这里把driver8挂载到drivertest ..顶层是 driver8 ,所以即使是发给drivertest的irp也会先传给driver8
#define DEVICE_NAME "\\Device\\DRIVER8_DeviceName"
#define SYMLINK_NAME "\\DosDevices\\DRIVER8_DeviceName"
PRESET_UNICODE_STRING(usDeviceName, DEVICE_NAME);
PRESET_UNICODE_STRING(usSymlinkName, SYMLINK_NAME);
typedef struct{
DEVICE_OBJECT *pTargetDevObj;
}DEVICE_EXTENSION;
#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
KdPrint(("DriverEntry 挂载例子..."));
PDEVICE_OBJECT pdoDeviceObj = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
pdoGlobalDrvObj = DriverObject;
// Create the device object.
if(!NT_SUCCESS(status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pdoDeviceObj
)))
{
// Bail out (implicitly forces the driver to unload).
return status;
};
// Now create the respective symbolic link object
if(!NT_SUCCESS(status = IoCreateSymbolicLink(
&usSymlinkName,
&usDeviceName
)))
{
IoDeleteDevice(pdoDeviceObj);
return status;
}
// NOTE: You need not provide your own implementation for any major function that
// you do not want to handle. I have seen code using DDKWizard that left the
// *empty* dispatch routines intact. This is not necessary at all!
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DRIVER8_DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DRIVER8_DispatchDeviceControl;
DriverObject->DriverUnload = DRIVER8_DriverUnload;
DriverObject->MajorFunction[IRP_MJ_READ]=DRIVER8_DispatchRead;
UNICODE_STRING ustrDeviceTest;
RtlInitUnicodeString(&ustrDeviceTest,L"\\Device\\DRIVERTEST_DeviceName");
DEVICE_OBJECT *pDeviceObject;
FILE_OBJECT *pFileObject;
NTSTATUS status2=IoGetDeviceObjectPointer(&ustrDeviceTest,FILE_ALL_ACCESS,&pFileObject,&pDeviceObject);
if(!NT_SUCCESS(status2)){
KdPrint(("IoGetDeviceObjectPointer failed"));
ObDereferenceObject(pFileObject);
return STATUS_SUCCESS;
}
DEVICE_EXTENSION *pDex=(DEVICE_EXTENSION*)pdoDeviceObj->DeviceExtension;
DEVICE_OBJECT *pDeviceObjectAttD2S=IoAttachDeviceToDeviceStack(pdoDeviceObj,pDeviceObject);
pDex->pTargetDevObj=pDeviceObjectAttD2S;//返回TargetDevice下面的低一层设备桟
if (!pDeviceObjectAttD2S)
{
KdPrint(("fck !IoAttachDeviceToDeviceStack"));
ObDereferenceObject(pFileObject);
IoDeleteDevice(pDeviceObject);
return STATUS_SUCCESS;
}
pdoDeviceObj->DeviceType=pDeviceObjectAttD2S->DeviceType;
pdoDeviceObj->Characteristics=pDeviceObjectAttD2S->Characteristics;
pdoDeviceObj->Flags&=~DO_DEVICE_INITIALIZING;
pdoDeviceObj->Flags|=(pDeviceObjectAttD2S->Flags&(DO_DIRECT_IO | DO_BUFFERED_IO));
ObDereferenceObject(pFileObject);
KdPrint(("Attached finished "));
return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif
NTSTATUS DRIVER8_DispatchRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
KdPrint(("DRIVER8_DispatchRead"));
NTSTATUS status = STATUS_SUCCESS;
// Irp->IoStatus.Status = status;
// Irp->IoStatus.Information = 0;
// IoCompleteRequest(Irp, IO_NO_INCREMENT);
DEVICE_EXTENSION *pDex=(DEVICE_EXTENSION*)DeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
status=IoCallDriver(pDex->pTargetDevObj,Irp);
return status;
}