阅读:22525回复:95
禁用和只读U盘驱动的实现
我是把ddk中filter.c例子增加了IRP_MJ_SCSI例程,在 {36FC9E60-C465-11CF-8056-444553540000} 下增加了LowerFilters="usbstorfilter",然后在service下增加了usbstorfilter。
具体是在IRP_MJ_SCSI中实现禁用和主动添加对USBSTOR的过滤设备,具体实现见代码。经测试存在2个问题 (1)、本人基本功太差,程序中存在一些错误,比如好像存在分页和IRQLEVEL冲突造成系统蓝屏异常,所以将代码发上来请大家指点。 (2)、不能通过程序控制在不重启机器情况下控制U盘的使用。 USBFILTER.rar |
|
沙发#
发布于:2009-10-03 00:09
新手,学习一下
|
|
板凳#
发布于:2009-10-03 00:11
我已回复,为什么看不到?
|
|
地板#
发布于:2009-10-03 14:02
不太熟悉如何上传附件,我也没想设置附件隐藏,无线上网,传送附件不知道成不成功。
|
|
|
地下室#
发布于:2009-10-05 09:23
为了方便高手指点,现将代码直接贴出来,可能篇幅稍长,请版主原谅
头文件: #if !defined(_FILTER_H_) //注意这个位置不能乱放,我的认识是要放在加载的头文件的下面 #define _FILTER_H_ #include <ntddk.h> #include <scsi.h> #include <wdmsec.h> // for IoCreateDeviceSecure #include <initguid.h> // {8E7341F9-04AD-41da-AC0E-72099E39D7EE} DEFINE_GUID(GUID_SD_FILTER_CONTROL_OBJECT, 0x8e7341f9, 0x4ad, 0x41da, 0xac, 0xe, 0x72, 0x9, 0x9e, 0x39, 0xd7, 0xee); #define IOCTL_820 \ CTL_CODE(FILE_DEVICE_DISK, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS) #define DISK_TAG_SRB 'SDcS' // "ScDS" - srb allocation #define MAXLEN 256 #ifndef STATUS_CONTINUE_COMPLETION #define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS #endif #define POOL_TAG 'liFT' typedef enum _DEVICE_PNP_STATE{ NotStarted = 0, Started, StopPending, Stopped, RemovePending, SurpriseRemovePending, Deleted } DEVICE_PNP_STATE; #define INITIALIZE_PNP_STATE(_Data_) \ (_Data_)->DevicePnPState = NotStarted;\ (_Data_)->PreviousPnPState = NotStarted; #define SET_NEW_PNP_STATE(_Data_, _state_) \ (_Data_)->PreviousPnPState = (_Data_)->DevicePnPState;\ (_Data_)->DevicePnPState = (_state_); #define RESTORE_PREVIOUS_PNP_STATE(_Data_) \ (_Data_)->DevicePnPState = (_Data_)->PreviousPnPState;\ typedef struct _HUA_ATTACHED_DEVICE { LIST_ENTRY listEntry; PDEVICE_OBJECT FilterUsbStor; PDEVICE_OBJECT FilterUsbStorLowerDriver; }HUA_ATTACHED_DEVICE,*PHUA_ATTACHED_DEVICE; typedef struct _DEVICE_EXTENSION { // A back pointer to the device object. PDEVICE_OBJECT Self; //The top of the stack before this filter was added. PDEVICE_OBJECT NextLowerDriver; //Current PnP state of the device DEVICE_PNP_STATE DevicePnPState; //The previous pnp state DEVICE_PNP_STATE PreviousPnPState; //Removelock to track IRPs so that device can be //removed and the driver can be unloaded safely. IO_REMOVE_LOCK RemoveLock; //HUA ADD LIST_ENTRY pFilterUsbStorListHead; USHORT bUSBSTORFILTERDEVICE; } DEVICE_EXTENSION,*PDEVICE_EXTENSION; NTSTATUS FilterAddDeviceFun( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN USHORT bUSBSTORFILTERDEVICE, IN OUT PDEVICE_OBJECT *deviceObject ); NTSTATUS FilterAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ); NTSTATUS FilterDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS FilterDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID FilterUnload( IN PDRIVER_OBJECT DriverObject ); NTSTATUS FilterPass( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); NTSTATUS FilterStartCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS FilterDeviceUsageNotificationCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS FilterDispatchScsi( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS USBSCSICompletion2( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); NTSTATUS CreateFilterUsbstoreObject(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT UsbStorDeviceObject ); // 这个函数是事实存在的,只是文档中没有公开。声明一下 // 就可以直接使用了。 NTSTATUS ObReferenceObjectByName( PUNICODE_STRING ObjectName, ULONG Attributes, PACCESS_STATE AccessState, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, PVOID ParseContext, PVOID *Object ); extern POBJECT_TYPE IoDriverObjectType; #define USB_STOR_DRIVER_NAME L"\\Driver\\USBSTOR" #define NTDEVICE_NAME_STRING L"\\Device\\HUSBFilter" #define SYMBOLIC_NAME_STRING L"\\DosDevices\\HUSBFilter" typedef struct _CONTROL_DEVICE_EXTENSION { ULONG Deleted; // False if the deviceobject is valid, TRUE if it's deleted PVOID ControlData; // Store your control data here } CONTROL_DEVICE_EXTENSION, *PCONTROL_DEVICE_EXTENSION; NTSTATUS FilterCreateControlObject( IN PDEVICE_OBJECT DeviceObject ); VOID FilterDeleteControlObject( ); NTSTATUS FilterDispatchIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); #endif |
|
5楼#
发布于:2009-10-05 09:24
实现代码:
#include "filter.h" #ifdef ALLOC_PRAGMA #pragma alloc_text (INIT, DriverEntry) #pragma alloc_text (PAGE, FilterAddDevice) #pragma alloc_text (PAGE, FilterDispatchPnp) #pragma alloc_text (PAGE, FilterUnload) #pragma alloc_text (PAGE, FilterCreateControlObject) #pragma alloc_text (PAGE, FilterDeleteControlObject) #pragma alloc_text (PAGE, FilterDispatchIo) #endif FAST_MUTEX ControlMutex; ULONG InstanceCount = 0; PDEVICE_OBJECT ControlDeviceObject; int flag=2;//0:不控制;1:不可见;2:只读 PDEVICE_OBJECT firstUsbStorDeviceObject=NULL; #if DBG PCHAR PnPMinorFunctionString ( UCHAR MinorFunction ) { switch (MinorFunction) { case IRP_MN_START_DEVICE: return "IRP_MN_START_DEVICE"; case IRP_MN_QUERY_REMOVE_DEVICE: return "IRP_MN_QUERY_REMOVE_DEVICE"; case IRP_MN_REMOVE_DEVICE: return "IRP_MN_REMOVE_DEVICE"; case IRP_MN_CANCEL_REMOVE_DEVICE: return "IRP_MN_CANCEL_REMOVE_DEVICE"; case IRP_MN_STOP_DEVICE: return "IRP_MN_STOP_DEVICE"; case IRP_MN_QUERY_STOP_DEVICE: return "IRP_MN_QUERY_STOP_DEVICE"; case IRP_MN_CANCEL_STOP_DEVICE: return "IRP_MN_CANCEL_STOP_DEVICE"; case IRP_MN_QUERY_DEVICE_RELATIONS: return "IRP_MN_QUERY_DEVICE_RELATIONS"; case IRP_MN_QUERY_INTERFACE: return "IRP_MN_QUERY_INTERFACE"; case IRP_MN_QUERY_CAPABILITIES: return "IRP_MN_QUERY_CAPABILITIES"; case IRP_MN_QUERY_RESOURCES: return "IRP_MN_QUERY_RESOURCES"; case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS"; case IRP_MN_QUERY_DEVICE_TEXT: return "IRP_MN_QUERY_DEVICE_TEXT"; case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS"; case IRP_MN_READ_CONFIG: return "IRP_MN_READ_CONFIG"; case IRP_MN_WRITE_CONFIG: return "IRP_MN_WRITE_CONFIG"; case IRP_MN_EJECT: return "IRP_MN_EJECT"; case IRP_MN_SET_LOCK: return "IRP_MN_SET_LOCK"; case IRP_MN_QUERY_ID: return "IRP_MN_QUERY_ID"; case IRP_MN_QUERY_PNP_DEVICE_STATE: return "IRP_MN_QUERY_PNP_DEVICE_STATE"; case IRP_MN_QUERY_BUS_INFORMATION: return "IRP_MN_QUERY_BUS_INFORMATION"; case IRP_MN_DEVICE_USAGE_NOTIFICATION: return "IRP_MN_DEVICE_USAGE_NOTIFICATION"; case IRP_MN_SURPRISE_REMOVAL: return "IRP_MN_SURPRISE_REMOVAL"; default: return "unknown_pnp_irp"; } } #endif NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS; ULONG ulIndex; PDRIVER_DISPATCH * dispatch; UNREFERENCED_PARAMETER (RegistryPath); KdBreakPoint(); KdPrint (("观察:Entered the Driver Entry\n")); // // Create dispatch points // for (ulIndex = 0, dispatch = DriverObject->MajorFunction; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++, dispatch++) { *dispatch = FilterPass; } DriverObject->MajorFunction[IRP_MJ_PNP] = FilterDispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = FilterDispatchPower; DriverObject->DriverExtension->AddDevice = FilterAddDevice; DriverObject->MajorFunction[IRP_MJ_SCSI] = FilterDispatchScsi; DriverObject->DriverUnload = FilterUnload; // // Set the following dispatch points as we will be doing // something useful to these requests instead of just // passing them down. // DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FilterDispatchIo; // // Mutex is to synchronize multiple threads creating & deleting // control deviceobjects. // ExInitializeFastMutex(&ControlMutex); return status; } VOID FilterUnload( IN PDRIVER_OBJECT DriverObject ) { PAGED_CODE (); ASSERT(DriverObject->DeviceObject == NULL); KdPrint(("观察:Entry FilterUnload\n")); return; } NTSTATUS FilterAddDeviceFun( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN USHORT bUSBSTORFILTERDEVICE, IN OUT PDEVICE_OBJECT *deviceObject ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension; ULONG deviceType = FILE_DEVICE_DISK; status = IoCreateDevice (DriverObject, sizeof (DEVICE_EXTENSION), NULL, deviceType, FILE_DEVICE_SECURE_OPEN, FALSE, deviceObject); if (!NT_SUCCESS (status)) { KdPrint (("IoCreateDevice Error:(0x%x)\n",status)); return status; } KdPrint (("AddDevice PDO (0x%x) FDO (0x%x)\n", PhysicalDeviceObject, deviceObject)); deviceExtension = (PDEVICE_EXTENSION)(*deviceObject)->DeviceExtension; deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack ( *deviceObject, PhysicalDeviceObject); // // Failure for attachment is an indication of a broken plug & play system. // if(NULL == deviceExtension->NextLowerDriver) { KdPrint (("注意了:FilterAddDevice:NULL==deviceExtension->NextLowerDriver\n")); IoDeleteDevice(*deviceObject); return STATUS_UNSUCCESSFUL; } (*deviceObject)->Flags |= deviceExtension->NextLowerDriver->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE ); (*deviceObject)->DeviceType=FILE_DEVICE_DISK; (*deviceObject)->Characteristics = deviceExtension->NextLowerDriver->Characteristics; deviceExtension->Self = (*deviceObject); // // Let us use remove lock to keep count of IRPs so that we don't // deteach and delete our deviceobject until all pending I/Os in our // devstack are completed. Remlock is required to protect us from // various race conditions where our driver can get unloaded while we // are still running dispatch or completion code. // IoInitializeRemoveLock (&deviceExtension->RemoveLock , POOL_TAG, 1, // MaxLockedMinutes 100); // HighWatermark, this parameter is // used only on checked build. Specifies // the maximum number of outstanding // acquisitions allowed on the lock // // Set the initial state of the Filter DO // INITIALIZE_PNP_STATE(deviceExtension); InitializeListHead(&deviceExtension->pFilterUsbStorListHead); deviceExtension->bUSBSTORFILTERDEVICE=bUSBSTORFILTERDEVICE; KdPrint(("AddDevice: %x to %x->%x \n", *deviceObject, deviceExtension->NextLowerDriver, PhysicalDeviceObject)); (*deviceObject)->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; } NTSTATUS FilterAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) { PDEVICE_OBJECT deviceObject = NULL; PAGED_CODE (); return (FilterAddDeviceFun(DriverObject,PhysicalDeviceObject,0,&deviceObject)); } NTSTATUS FilterPass ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; 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 FilterDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp); if (!NT_SUCCESS (status)) { // may be device is being removed. Irp->IoStatus.Status = status; PoStartNextPowerIrp(Irp); IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(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; PHUA_ATTACHED_DEVICE pData=NULL; PLIST_ENTRY pEntry=NULL; PAGED_CODE(); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; if(deviceExtension->bUSBSTORFILTERDEVICE) { return FilterPass(DeviceObject,Irp); } irpStack = IoGetCurrentIrpStackLocation(Irp); KdPrint(("FilterDO %s IRP:0x%x \n", PnPMinorFunctionString(irpStack->MinorFunction), 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: // // The device is starting. // We cannot touch the device (send it any non pnp irps) until a // start device has been passed down to the lower drivers. // KeInitializeEvent(&event, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) FilterStartCompletionRoutine, &event, TRUE, TRUE, TRUE); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); // // Wait for lower drivers to be done with the Irp. Important thing to // note here is when you allocate memory for an event in the stack // you must do a KernelMode wait instead of UserMode to prevent // the stack from getting paged out. // if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = Irp->IoStatus.Status; } if (NT_SUCCESS (status)) { // // As we are successfully now back, we will // first set our state to Started. // SET_NEW_PNP_STATE(deviceExtension, Started); // // On the way up inherit FILE_REMOVABLE_MEDIA during Start. // This characteristic is available only after the driver stack is started!. // if (deviceExtension->NextLowerDriver->Characteristics & FILE_REMOVABLE_MEDIA) { DeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA; } // // If the PreviousPnPState is stopped then we are being stopped temporarily // and restarted for resource rebalance. // if(Stopped != deviceExtension->PreviousPnPState) { // // Device is started for the first time. // FilterCreateControlObject(DeviceObject); } } Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; case IRP_MN_REMOVE_DEVICE: // // Wait for all outstanding requests to complete // KdPrint(("Waiting for outstanding requests\n")); IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); SET_NEW_PNP_STATE(deviceExtension, Deleted); FilterDeleteControlObject(); while(!IsListEmpty(&deviceExtension->pFilterUsbStorListHead)) { pEntry=RemoveTailList(&deviceExtension->pFilterUsbStorListHead); pData=CONTAINING_RECORD(pEntry,HUA_ATTACHED_DEVICE,listEntry); IoDetachDevice(pData->FilterUsbStorLowerDriver); IoDeleteDevice(pData->FilterUsbStor); ExFreePool(pData); } IoDetachDevice(deviceExtension->NextLowerDriver); IoDeleteDevice(DeviceObject); return status; case IRP_MN_QUERY_STOP_DEVICE: SET_NEW_PNP_STATE(deviceExtension, StopPending); status = STATUS_SUCCESS; break; case IRP_MN_CANCEL_STOP_DEVICE: // // Check to see whether you have received cancel-stop // without first receiving a query-stop. This could happen if someone // above us fails a query-stop and passes down the subsequent // cancel-stop. // if(StopPending == deviceExtension->DevicePnPState) { // // We did receive a query-stop, so restore. // RESTORE_PREVIOUS_PNP_STATE(deviceExtension); } status = STATUS_SUCCESS; // We must not fail this IRP. break; case IRP_MN_STOP_DEVICE: SET_NEW_PNP_STATE(deviceExtension, Stopped); status = STATUS_SUCCESS; break; case IRP_MN_QUERY_REMOVE_DEVICE: SET_NEW_PNP_STATE(deviceExtension, RemovePending); status = STATUS_SUCCESS; break; case IRP_MN_SURPRISE_REMOVAL: SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending); status = STATUS_SUCCESS; break; case IRP_MN_CANCEL_REMOVE_DEVICE: // // Check to see whether you have received cancel-remove // without first receiving a query-remove. This could happen if // someone above us fails a query-remove and passes down the // subsequent cancel-remove. // if(RemovePending == deviceExtension->DevicePnPState) { // // We did receive a query-remove, so restore. // RESTORE_PREVIOUS_PNP_STATE(deviceExtension); } status = STATUS_SUCCESS; // We must not fail this IRP. break; case IRP_MN_DEVICE_USAGE_NOTIFICATION: // // On the way down, pagable might become set. Mimic the driver // above us. If no one is above us, just set pagable. // 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); case IRP_MN_QUERY_DEVICE_RELATIONS: status = Irp->IoStatus.Status; break; default: // // If you don't handle any IRP you must leave the // status as is. // status = Irp->IoStatus.Status; break; } // // Pass the IRP down and forget it. // 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; // UNREFERENCED_PARAMETER (DeviceObject); // // If the lower driver didn't return STATUS_PENDING, we don't need to // set the event because we won't be waiting on it. // This optimization avoids grabbing the dispatcher lock, and improves perf. // if (Irp->PendingReturned == TRUE) { KeSetEvent (event, IO_NO_INCREMENT, FALSE); } // // The dispatch routine will have to call IoCompleteRequest // return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS FilterDeviceUsageNotificationCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PDEVICE_EXTENSION deviceExtension; UNREFERENCED_PARAMETER(Context); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } // // On the way up, pagable might become clear. Mimic the driver below us. // if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) { DeviceObject->Flags &= ~DO_POWER_PAGABLE; } IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return STATUS_CONTINUE_COMPLETION; } NTSTATUS FilterDispatchScsi(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION pdx; PIO_STACK_LOCATION irpStack; NTSTATUS status; //KdPrint(("观察:进入FilterDispatchScsi\n")); pdx = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; if(pdx->bUSBSTORFILTERDEVICE) { status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } irpStack = IoGetCurrentIrpStackLocation(Irp); if (flag==2) { IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, USBSCSICompletion, NULL, TRUE, TRUE, TRUE ); status = IoCallDriver(pdx->NextLowerDriver, Irp); } else { IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (pdx->NextLowerDriver, Irp); } IoReleaseRemoveLock(&pdx->RemoveLock, Irp); } else if(DeviceObject->AttachedDevice!=NULL && _wcsnicmp(DeviceObject->AttachedDevice->DriverObject->DriverName.Buffer,L"[url=file://\\Driver\\USBSTOR]\\Driver\\USBSTOR",15)==0[/url]) { status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } irpStack = IoGetCurrentIrpStackLocation(Irp); // if (flag==1) { Irp->IoStatus.Status = STATUS_ACCESS_DENIED; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_ACCESS_DENIED; } else { IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, USBSCSICompletion2, DeviceObject->AttachedDevice, TRUE, TRUE, TRUE ); status = IoCallDriver(pdx->NextLowerDriver, Irp); } IoReleaseRemoveLock(&pdx->RemoveLock, Irp); } else { return FilterPass(DeviceObject, Irp); } return status; } NTSTATUS USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PDEVICE_EXTENSION pdx; PIO_STACK_LOCATION irpStack; PSCSI_REQUEST_BLOCK CurSrb; PCDB cdb; UCHAR opCode; PMODE_PARAMETER_HEADER modeData; pdx = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension; IoAcquireRemoveLock(&pdx->RemoveLock,Irp); irpStack = IoGetCurrentIrpStackLocation( Irp ); CurSrb=irpStack->Parameters.Scsi.Srb; cdb = (PCDB)CurSrb->Cdb; if(CurSrb && cdb) { opCode=cdb->CDB6GENERIC.OperationCode; //if(opCode) // DbgPrint("USBSCSICompletion: opCode=%d,CurSrb->DataBuffer=0x%x\n CurSrb->DataTransferLength=%d,%d\n", // opCode,CurSrb->DataBuffer,CurSrb->DataTransferLength,sizeof(MODE_PARAMETER_HEADER)); if(opCode==SCSIOP_MODE_SENSE && CurSrb->DataBuffer && CurSrb->DataTransferLength >= sizeof(MODE_PARAMETER_HEADER) ) { KdPrint(("SCSIOP_MODE_SENSE comming:0x%x!\n",DeviceObject)); modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer; modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; } else if(opCode==SCSIOP_WRITE) { KdPrint(("SCSIOP_WRITE comming:0x%x!\n",DeviceObject)); Irp->IoStatus.Status= STATUS_UNSUCCESSFUL;//难够拦截到,有出错提示,但是数据可以修改, } } if ( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } IoReleaseRemoveLock(&pdx->RemoveLock,Irp); return Irp->IoStatus.Status ; } NTSTATUS USBSCSICompletion2( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { NTSTATUS status; PDEVICE_EXTENSION pdx; pdx = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension; IoAcquireRemoveLock(&pdx->RemoveLock,Irp); // status=CreateFilterUsbstoreObject(DeviceObject,(PDEVICE_OBJECT)Context); // if ( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } // IoReleaseRemoveLock(&pdx->RemoveLock,Irp); return status; } |
|
6楼#
发布于:2009-10-05 09:33
NTSTATUS CreateFilterUsbstoreObject(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT UsbStorDeviceObject ) { PDRIVER_OBJECT usbStor; NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT pFilterDeviceObject = NULL; PDEVICE_OBJECT pTargetDeviceObject = NULL; PDEVICE_OBJECT pTempDeviceObject = NULL; PDEVICE_EXTENSION deviceExtension=NULL; PDEVICE_EXTENSION deviceExtension1=NULL; PHUA_ATTACHED_DEVICE pData=NULL; usbStor=((PDEVICE_OBJECT)UsbStorDeviceObject)->DriverObject; //这是设备链中的第一个设备 pTargetDeviceObject = usbStor->DeviceObject; if(firstUsbStorDeviceObject==pTargetDeviceObject)//减少不必要的遍历设备链,前提是新加入的设备在头部加入 { return( status ); } firstUsbStorDeviceObject=pTargetDeviceObject; // 现在开始遍历这个设备链 while(pTargetDeviceObject) { pTempDeviceObject=pTargetDeviceObject; while((pTempDeviceObject=pTempDeviceObject->AttachedDevice)!=NULL) { if(pTempDeviceObject->DriverObject==DeviceObject->DriverObject) break; } if(NULL==pTempDeviceObject) { status=FilterAddDeviceFun(DeviceObject->DriverObject,pTargetDeviceObject,1,&pFilterDeviceObject); if (NT_SUCCESS( status )) { deviceExtension=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension; deviceExtension1=(PDEVICE_EXTENSION)pFilterDeviceObject->DeviceExtension; pData=(PHUA_ATTACHED_DEVICE)ExAllocatePool(PagedPool,sizeof(HUA_ATTACHED_DEVICE)); pData->FilterUsbStor=deviceExtension1->Self; pData->FilterUsbStorLowerDriver=deviceExtension1->NextLowerDriver; InsertTailList(&deviceExtension->pFilterUsbStorListHead,&pData->listEntry); } } pTargetDeviceObject=pTargetDeviceObject->NextDevice; } return( status ); } // NTSTATUS FilterCreateControlObject( IN PDEVICE_OBJECT DeviceObject ) { UNICODE_STRING ntDeviceName; UNICODE_STRING symbolicLinkName; PCONTROL_DEVICE_EXTENSION deviceExtension; NTSTATUS status = STATUS_UNSUCCESSFUL; UNICODE_STRING sddlString; PAGED_CODE(); // // Using unsafe function so that the IRQL remains at PASSIVE_LEVEL. // IoCreateDeviceSecure & IoCreateSymbolicLink must be called at // PASSIVE_LEVEL. // ExAcquireFastMutexUnsafe(&ControlMutex); // // If this is a first instance of the device, then create a controlobject // and register dispatch points to handle ioctls. // if(1 == ++InstanceCount) { // // Initialize the unicode strings // RtlInitUnicodeString(&ntDeviceName, NTDEVICE_NAME_STRING); RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING); // // Initialize a security descriptor string. Refer to SDDL docs in the SDK // for more info. // RtlInitUnicodeString( &sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"); // // Create a named deviceobject so that applications or drivers // can directly talk to us without going throuhg the entire stack. // This call could fail if there are not enough resources or // another deviceobject of same name exists (name collision). // Let us use the new IoCreateDeviceSecure and specify a security // descriptor (SD) that allows only System and Admin groups to access the // control device. Let us also specify a unique guid to allow administrators // to change the SD if he desires to do so without changing the driver. // The SD will be stored in // HKLM\SYSTEM\CCSet\Control\Class\<GUID>\Properties\Security. // An admin can override the SD specified in the below call by modifying // the registry. // 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); KdPrint(("IoCreateSymbolicLink failed %x\n", status)); goto End; } deviceExtension = ControlDeviceObject->DeviceExtension; deviceExtension->ControlData = NULL; deviceExtension->Deleted = FALSE; ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; }else { KdPrint(("IoCreateDevice failed %x\n", status)); } } End: ExReleaseFastMutexUnsafe(&ControlMutex); return status; } VOID FilterDeleteControlObject( ) { UNICODE_STRING symbolicLinkName; PCONTROL_DEVICE_EXTENSION deviceExtension; PAGED_CODE(); ExAcquireFastMutexUnsafe (&ControlMutex); // // If this is the last instance of the device then delete the controlobject // and symbolic link to enable the pnp manager to unload the driver. // if(!(--InstanceCount) && ControlDeviceObject) { RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING); deviceExtension = ControlDeviceObject->DeviceExtension; deviceExtension->Deleted = TRUE; IoDeleteSymbolicLink(&symbolicLinkName); IoDeleteDevice(ControlDeviceObject); ControlDeviceObject = NULL; } ExReleaseFastMutexUnsafe (&ControlMutex); } // NTSTATUS ProcessControl(IN PIRP Irp , IN PIO_STACK_LOCATION irpStack) { PVOID inputBuffer; CHAR n; NTSTATUS status=STATUS_SUCCESS; KdPrint(("观察:Entry ProcessControl!\n")); if (irpStack->Parameters.DeviceIoControl.IoControlCode==IOCTL_820) { inputBuffer = Irp->AssociatedIrp.SystemBuffer; DbgPrint("我得到了IOCTL_800并且inputBuffer=%s\n",inputBuffer); n=*(CHAR*)inputBuffer; KdPrint(("n=%d;flag=%d\n",n,flag)); if(n>=0 && n<=2) flag=n; else status = STATUS_INVALID_PARAMETER; } else { status = STATUS_INVALID_PARAMETER; } return status; } // NTSTATUS FilterDispatchIo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION irpStack; NTSTATUS status; PCONTROL_DEVICE_EXTENSION deviceExtension; PAGED_CODE(); // // Please note that this is a common dispatch point for controlobject and // filter deviceobject attached to the pnp stack. // if(DeviceObject != ControlDeviceObject) { // // We will just the request down as we are not interested in handling // requests that come on the PnP stack. // return FilterPass(DeviceObject, Irp); } deviceExtension = ControlDeviceObject->DeviceExtension; // // Else this is targeted at our control deviceobject so let's handle it. // Here we will handle the IOCTl requests that come from the app. // We don't have to worry about acquiring remlocks for I/Os that come // on our control object because the I/O manager takes reference on our // deviceobject when it initiates a request to our device and that keeps // our driver from unloading when we have pending I/Os. But we still // have to watch out for a scenario where another driver can send // requests to our deviceobject directly without opening an handle. // if(!deviceExtension->Deleted) { //if not deleted status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; irpStack = IoGetCurrentIrpStackLocation (Irp); switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: KdPrint(("Create \n")); break; case IRP_MJ_CLOSE: KdPrint(("Close \n")); break; case IRP_MJ_CLEANUP: KdPrint(("Cleanup \n")); break; case IRP_MJ_DEVICE_CONTROL: KdPrint(("DeviceIoControl\n")); status =ProcessControl(Irp,irpStack); 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); return status; } |
|
7楼#
发布于:2009-10-08 22:43
我现在也在搞这个驱动,对单个U盘的控制怎么实现呀,比如插入两个U盘,一个为可控,一个为不可控,有兴趣的话我们共同讨论,QQ:329673470
|
|
8楼#
发布于:2009-10-10 10:14
look looka
|
|
9楼#
发布于:2009-10-10 10:14
woyaokanbkna
|
|
10楼#
发布于:2009-10-13 23:11
支持一下楼主辛苦工作
|
|
|
11楼#
发布于:2009-10-14 09:37
谢了.下回来看看
|
|
12楼#
发布于:2009-10-16 09:19
ding
|
|
13楼#
发布于:2009-10-16 09:20
dingdie
|
|
14楼#
发布于:2009-10-27 22:40
ok ok
|
|
|
15楼#
发布于:2009-10-28 17:28
还在学习中。。。
|
|
16楼#
发布于:2009-10-29 08:27
good
|
|
17楼#
发布于:2009-10-29 08:28
goood gooodd
|
|
18楼#
发布于:2009-10-31 11:04
goood gooodd
|
|
19楼#
发布于:2009-11-02 13:54
看看
|
|
上一页
下一页