为了设备栈平衡,需要 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; }