|
阅读:24455回复: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
看看
|
|
上一页
下一页