阅读:3210回复:1
为什么我拦截U盘的SCSIOP_WRITE会出现问题 主要是USBSCSIPassThrough()函数的代码
#include "filter.h"
ULONG InstanceCount = 0; int flag=1; //这个是应用层控制的 #ifdef ALLOC_PRAGMA #pragma alloc_text (INIT, DriverEntry) #pragma alloc_text (PAGE, FilterAddDevice) #pragma alloc_text (PAGE, FilterDispatchPnp) #pragma alloc_text (PAGE, FilterUnload) #endif #ifdef IOCTL_INTERFACE #ifdef ALLOC_PRAGMA #pragma alloc_text (PAGE, FilterCreateControlObject) #pragma alloc_text (PAGE, FilterDeleteControlObject) #pragma alloc_text (PAGE, FilterDispatchIo) #endif FAST_NUTEX ControlMutex; //ULONG InstanceCount = 0; //PDEVICE_OBJECT ControlDeviceObject; #endif PDEVICE_OBJECT ControlDeviceObject; NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS; ULONG ulIndex; PDRIVER_DISPATCH * dispatch; DbgPrint("test:1111111111111111\n"); DbgPrint("观察:Entry DriverEntry\n"); UNREFERENCED_PARAMETER (RegistryPath); for (ulIndex=0,dispatch=DriverObject->MajorFunction; ulIndex<=IRP_MJ_MAXIMUM_FUNCTION; ulIndex++,dispatch++) { *dispatch = FilterPass; } DriverObject->MajorFunction[IRP_MJ_SCSI]=USBSCSIPassThrough; // DriverObject->MajorFunction[IRP_MJ_SCSI]=FilterPass; DriverObject->MajorFunction[IRP_MJ_PNP] = FilterDispatchPnp; DriverObject->DriverUnload = FilterUnload; DriverObject->DriverExtension->AddDevice = FilterAddDevice; #ifdef IOCTL_INTERFACE // DriverObject->MajorFunction[IRP_MJ_CREATE] = // DriverObject->MajorFunction[IRP_MJ_CLOSE] = // DriverObject->MajorFunction[IRP_MJ_CLEANUP] = // DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] // = FilterDispatchIo; // DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSCSIPassThrough; ExInitializeFastMutex(&ControlMutex); #endif return status; } VOID FilterUnload( IN PDRIVER_OBJECT DriverObject ) { PAGED_CODE(); ASSERT(DriverObject->DeviceObject == NULL); DbgPrint("观察:Entry FilterUnload\n"); return; } NTSTATUS FilterAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject=NULL; PDEVICE_EXTENSION deviceExtension; ULONG deviceType=FILE_DEVICE_DISK; UNICODE_STRING ntName; UNICODE_STRING win32Name; RtlInitUnicodeString(&ntName, L"\\Device\\dnmm"); RtlInitUnicodeString(&win32Name, L"\\DosDevices\\dnmm"); DbgPrint("观察:Entry FilterAddDevice\n"); PAGED_CODE(); if (!IoIsWdmVersionAvailable(1,0x20)) { deviceObject=IoGetAttachedDeviceReference(PhysicalDeviceObject); deviceType=deviceObject->DeviceType; ObDereferenceObject(deviceObject); } status=IoCreateDevice( DriverObject, sizeof (DEVICE_EXTENSION), &ntName, FILE_DEVICE_DISK, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject ); if (!NT_SUCCESS(status)) { return status; } deviceExtension=(PDEVICE_EXTENSION)deviceObject->DeviceExtension; deviceExtension->NextLowerDriver=IoAttachDeviceToDeviceStack( deviceObject, PhysicalDeviceObject); if (NULL==deviceExtension->NextLowerDriver) { DbgPrint("注意了:FilterAddDevice:NULL==deviceExtension->NextLowerDriver\n"); IoDeleteDevice(deviceObject); return STATUS_UNSUCCESSFUL; } status = IoCreateSymbolicLink( &win32Name, &ntName); if (!NT_SUCCESS(status)) { DbgPrint("重点啊:IoCreateSymbolicLink(&win32Name, &ntName) 错了的\n"); } deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags& (DO_BUFFERED_IO|DO_DIRECT_IO|DO_POWER_PAGABLE); // deviceObject->DeviceType=deviceExtension->NextLowerDriver->DeviceType; deviceObject->DeviceType=FILE_DEVICE_DISK; deviceObject->Characteristics=deviceExtension->NextLowerDriver->Characteristics; deviceExtension->Self=deviceObject; IoInitializeRemoveLock(&deviceExtension->RemoveLock, POOL_TAG,1,100); INITIALIZE_PNP_STATE(deviceExtension); deviceObject->Flags&=~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; } NTSTATUS FilterDispatchIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION irpStack; NTSTATUS status; PCONTROL_DEVICE_EXTENSION deviceExtension; DbgPrint("观察:Entry FilterDispatchIo\n"); PAGED_CODE(); if (DeviceObject!=ControlDeviceObject) { return FilterPass(DeviceObject,Irp); } deviceExtension=ControlDeviceObject->DeviceExtension; if (!deviceExtension->Deleted) { status=STATUS_SUCCESS; Irp->IoStatus.Information=0; irpStack=IoGetCurrentIrpStackLocation(Irp); switch(irpStack->MajorFunction) { case IRP_MJ_CREATE: DbgPrint("I am IRP_MJ_CREATE\n"); break; case IRP_MJ_CLOSE: DbgPrint("I am IRP_MJ_CLOSE\n"); break; case IRP_MJ_CLEANUP: DbgPrint("I am IRP_MJ_CLEANUP\n"); break; case IRP_MJ_DEVICE_CONTROL: DbgPrint("I am IRP_MJ_DEVICE_CONTROL\n"); break; default: break; } } else { ASSERTMSG(FALSE, "Requests being sent to a dead device\n"); status = STATUS_DEVICE_REMOVED; } Irp->IoStatus.Status=status; IoCompleteRequest(Irp,IO_NO_INCREMENT); DbgPrint("观察:Entry FilterDispatchIo is over!!!\n"); return status; } NTSTATUS FilterPass( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PIO_STACK_LOCATION irpStack; PVOID inputBuffer; CHAR n; DbgPrint("观察:Entry FilterPass!\n"); irpStack = IoGetCurrentIrpStackLocation(Irp); DbgPrint("关键:irpStack->MajorFunction=%d\n",irpStack->MajorFunction); if (irpStack->MajorFunction==IRP_MJ_DEVICE_CONTROL) { if (irpStack->Parameters.DeviceIoControl.IoControlCode==IOCTL_800) { inputBuffer = Irp->AssociatedIrp.SystemBuffer; DbgPrint("我得到了IOCTL_800并且inputBuffer=%s\n",inputBuffer); n=*(CHAR*)inputBuffer; n=n-'0'; if (n==0) { DbgPrint("flag=0\n"); flag=0; } if (n==1) { DbgPrint("flag=1\n"); flag=1; } } } deviceExtension=(PDEVICE_EXTENSION) DeviceObject->DeviceExtension; status=IoAcquireRemoveLock(&deviceExtension->RemoveLock,Irp); if (!NT_SUCCESS(status)) { Irp->IoStatus.Status=status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return status; } IoSkipCurrentIrpStackLocation(Irp); status=IoCallDriver(deviceExtension->NextLowerDriver,Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp); return status; } NTSTATUS FilterDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; NTSTATUS status; KEVENT event; DbgPrint("观察:Entry FilterDispatchPnp.\n"); PAGED_CODE(); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); status = IoAcquireRemoveLock(&deviceExtension->RemoveLock,Irp); if (!NT_SUCCESS(status)) { Irp->IoStatus.Status = status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return status; } switch(irpStack->MinorFunction) { case IRP_MN_START_DEVICE: DbgPrint("观察:IRP_MN_START_DEVICE:\n"); KeInitializeEvent(&event,NotificationEvent,FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) FilterStartCompletionRoutine, &event, TRUE, TRUE, TRUE); status = IoCallDriver(deviceExtension->NextLowerDriver,Irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); status = Irp->IoStatus.Status; } if (NT_SUCCESS(status)) { SET_NEW_PNP_STATE(deviceExtension,Started); if (deviceExtension->NextLowerDriver->Characteristics & FILE_REMOVABLE_MEDIA) { DeviceObject->Characteristics|=FILE_REMOVABLE_MEDIA; } #ifdef IOCTL_INTERFACE if (Stop != deviceExtension->PreviousPnPState) { FilterCreateControlObject(DeviceObject); } #endif } Irp->IoStatus.Status = status; IoCompleteRequest(Irp,IO_NO_INCREMENT); IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp); return status; case IRP_MN_REMOVE_DEVICE: DbgPrint("观察:IRP_MN_REMOV_DEVICE:\n"); IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock,Irp); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver,Irp); SET_NEW_PNP_STATE(deviceExtension,Deleted); #ifdef IOCTL_INTERFACE FilterDeleteControlObject(); #endif IoDetachDevice(deviceExtension->NextLowerDriver); IoDeleteDevice(DeviceObject); return status; case IRP_MN_QUERY_STOP_DEVICE: DbgPrint("观察:IRP_MN_QUERY_STOP_DEVICE:\n"); SET_NEW_PNP_STATE(deviceExtension,StopPending); status = STATUS_SUCCESS; break; case IRP_MN_CANCEL_STOP_DEVICE: DbgPrint("观察:IRP_MN_CANCEL_STOP_DEVICE:\n"); if (StopPending == deviceExtension->DevicePnPState) { RESTORE_PREVIOUS_PNP_STATE(deviceExtension); } status = STATUS_SUCCESS; break; case IRP_MN_STOP_DEVICE: SET_NEW_PNP_STATE(deviceExtension, Stopped); status = STATUS_SUCCESS; break; case IRP_MN_QUERY_REMOVE_DEVICE: DbgPrint("观察:IRP_MN_QUERY_REMOVE_DEVICE:\n"); SET_NEW_PNP_STATE(deviceExtension, RemovePending); status = STATUS_SUCCESS; break; case IRP_MN_SURPRISE_REMOVAL: DbgPrint("观察:IRP_MN_SURPRISE_REMOVAL:\n"); SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending); status = STATUS_SUCCESS; break; case IRP_MN_CANCEL_REMOVE_DEVICE: DbgPrint("观察:IRP_MN_CANCEL_REMOVE_DEVICE:\n"); if(RemovePending == deviceExtension->DevicePnPState) { RESTORE_PREVIOUS_PNP_STATE(deviceExtension); } status = STATUS_SUCCESS; // We must not fail this IRP. break; case IRP_MN_DEVICE_USAGE_NOTIFICATION: DbgPrint("观察:IRP_MN_DEVICE_USAGE_NOTIFICATION:\n"); if ((DeviceObject->AttachedDevice == NULL) || (DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) { DeviceObject->Flags |= DO_POWER_PAGABLE; } IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, FilterDeviceUsageNotificationCompletionRoutine, NULL, TRUE, TRUE, TRUE ); return IoCallDriver(deviceExtension->NextLowerDriver, Irp); default: DbgPrint("观察:default:\n"); status = Irp->IoStatus.Status; break; } Irp->IoStatus.Status = status; IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver,Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp); return status; } NTSTATUS FilterStartCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PKEVENT event = (PKEVENT)Context; DbgPrint("观察:Entry FilterStartCompletionRoutine!\n"); UNREFERENCED_PARAMETER(DeviceObject); if (Irp->PendingReturned == TRUE) { KeSetEvent(event,IO_NO_INCREMENT,FALSE); } return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS FilterCreateControlObject( //这个一般不会出现 IN PDEVICE_OBJECT DeviceObject ) { UNICODE_STRING ntDeviceName; UNICODE_STRING symbolicLinkName; PCONTROL_DEVICE_EXTENSION deviceExtension; NTSTATUS status = STATUS_UNSUCCESSFUL; UNICODE_STRING sddlString; DbgPrint("观察:Entry FilterCreateControlObject!\n"); PAGED_CODE(); // ExAcquireFastMutexUnsafe(&ControlMutex); if (1 == ++InstanceCount) { RtlInitUnicodeString(&ntDeviceName, NTDEVICE_NAME_STRING); RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING); RtlInitUnicodeString( &sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"); /* status = IoCreateDeviceSecure( DeviceObject->DriverObject, sizeof(CONTROL_DEVICE_EXTENSION), &ntDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &sddlString, (LPCGUID)&GUID_SD_FILTER_CONTROL_OBJECT, &ControlDeviceObject ); */ if (NT_SUCCESS(status)) { ControlDeviceObject->Flags |= DO_BUFFERED_IO; status = IoCreateSymbolicLink(&symbolicLinkName,&ntDeviceName); if ( !NT_SUCCESS( status )) { IoDeleteDevice(ControlDeviceObject); DbgPrint("IoCreateSymbolicLink failed %x\n", status); goto End; } deviceExtension = ControlDeviceObject->DeviceExtension; deviceExtension->ControlData = NULL; deviceExtension->Deleted = FALSE; ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; } else { DbgPrint("IoCreateDevice failed %x\n", status); } } End: // ExReleaseFastMutexUnsafe(&ControlMutex); return status; } VOID FilterDeleteControlObject( ) { UNICODE_STRING symbolicLinkName; PCONTROL_DEVICE_EXTENSION deviceExtension; PAGED_CODE(); DbgPrint("观察:Entry FilterDeleteControlObject!\n"); // ExAcquireFastMutexUnsafe (&ControlMutex); if(!(--InstanceCount) && ControlDeviceObject) { RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING); deviceExtension = ControlDeviceObject->DeviceExtension; deviceExtension->Deleted = TRUE; IoDeleteSymbolicLink(&symbolicLinkName); IoDeleteDevice(ControlDeviceObject); ControlDeviceObject = NULL; } // ExReleaseFastMutexUnsafe (&ControlMutex); } NTSTATUS FilterDeviceUsageNotificationCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PDEVICE_EXTENSION deviceExtension; DbgPrint("观察:Entry FilterDeviceUsageNotificationCompletionRoutine!\n"); UNREFERENCED_PARAMETER(Context); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) { DeviceObject->Flags &= ~DO_POWER_PAGABLE; } IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return STATUS_CONTINUE_COMPLETION; } NTSTATUS USBSCSIPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; PIO_STACK_LOCATION irpStack; PSCSI_REQUEST_BLOCK CurSrb; PMODE_PARAMETER_HEADER modeData; PDEVICE_OBJECT pDeviceObject; PCDB cdb ; UCHAR opCode; KIRQL IrqLevel; PDEVICE_EXTENSION StorExtension = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension; IoAcquireRemoveLock(&StorExtension->RemoveLock,Irp); DbgPrint("观察:USBSCSICompletion\n"); irpStack = IoGetCurrentIrpStackLocation( Irp ); CurSrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK), DISK_TAG_SRB); if (CurSrb == NULL) { DbgPrint("观察:CurSrb==NULL\n"); } else { DbgPrint("观察:CurSrb!=NULL\n"); } RtlZeroMemory(CurSrb, SCSI_REQUEST_BLOCK_SIZE); if (irpStack->MajorFunction==IRP_MJ_INTERNAL_DEVICE_CONTROL) { DbgPrint("注意:我终于得到了IRP_MJ_INTERNAL_DEVICE_CONTROL\n"); CurSrb=irpStack->Parameters.Scsi.Srb; cdb = (PCDB)CurSrb->Cdb; opCode=cdb->CDB6GENERIC.OperationCode; if (opCode==SCSIOP_WRITE) { IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp); DbgPrint("关键:opCode==SCSIOP_WRITE\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; Irp->Iostatus.Information=.........; //这里的操作字符有点忘记了 Irp->Irpcomplete(IRP,...); //这里的操作字符有点忘记了 return Irp->IoStatus.Status; } } IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp); IoAcquireRemoveLock(&StorExtension->RemoveLock,Irp); IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp); IoSkip...Location(Irp); return IoCall...(...); } wei |
|
沙发#
发布于:2009-09-19 14:06
首先
一个irp被complete了以后就不能再引用了 if (opCode==SCSIOP_WRITE) { IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp); DbgPrint("关键:opCode==SCSIOP_WRITE\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; Irp->Iostatus.Information=.........; //这里的操作字符有点忘记了 Irp->Irpcomplete(IRP,...); //这里的操作字符有点忘记了 return Irp->IoStatus.Status; } 这个地方的return是不能引用这个已经complete了的irp的 然后 scsi的complete不是irp的complete.这样设置一个status设置一个info就行的 中间涉及到srb的数个field的设置 SrbStatus,ScsiStatus,还可能需要做auto sense 建议先读一读scsi的规范 |
|