Tech Support > Microsoft Windows > Drivers > How to develop a upper filter to prevent the access to usb device?
How to develop a upper filter to prevent the access to usb device?
Posted by JoeySwen on November 24th, 2004


Hi,

The aim is to filter the IRPs which are passed to lower driver,I see the
filter example of DDK, but I don't know how to connet the upper filter to
the usb device driver.And I want to load the filter driver in App.
Some people say I can use IoGetRelatedDeviceObject,then intercept
IRP_MJ_CREATE、IRP_MJ_SET_INFORMATION、IRP_MJ_DEVICE _CONTROL,As
a newbie I don't know how to do it.
Does anybody around here can give me some advice or examples?

Thanks in advance..

Joey Swen

Posted by Mark Roddy on November 24th, 2004


JoeySwen wrote:
AddDevice routine is where you connect to the devnode device object
stack. IoGetRelatedDeviceObject is the wrong way to go.

--

=====================
Mark Roddy DDK MVP
Windows 2003/XP/2000 Consulting
Hollis Technology Solutions 603-321-1032

Posted by heinz baer on November 24th, 2004


To connect your filter, you need to put it in the UpperFilters
registry value for the class of device you are interested in. Without
extra special designs, getting your filter to dynamically attach
generally means the device stack will need to be torn down and rebuilt
if that's a concern. It might help you get the right answer if you can
describe WHY you want to do this. If you just want to be able to
freeze all traffic to an arbitrary USB device on demand like a
firewall, you can download this tool http://www.perisoft.net/bushound
and double click your device and press the lock button. That suspends
all access to the device until the lock is released. You can also
deadlock the system trying to do things like this.

Posted by JoeySwen on November 25th, 2004


Thanks,I just want to load the filter driver in App,I wrote a filter driver
to prevent the access to CdRom.
code:
#define TARGET_DEVICE_NAME L"\\Device\\CdRom0"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_object,IN PUNICODE_STRING
registry_path)
{
UNICODE_STRING target_device_name;
PDEVICE_OBJECT target_device_object;
PFILE_OBJECT target_file_object;
NTSTATUS status;

RtlInitUnicodeString(&target_device_name, TARGET_DEVICE_NAME);

status = IoGetDeviceObjectPointer(
&target_device_name,
0,
&target_file_object,
&target_device_object
);
if (!NT_SUCCESS(status))
{
KdPrint(("IoGetDeviceObjectPointer return %Xn", status));
return status;
}

g_p_target_driver_object = target_device_object->DriverObject;
if (!g_p_target_driver_object)
{
KdPrint(("target_device_object->DriverObject == NULLn"));
return STATUS_UNSUCCESSFUL;
}

g_p_real_dispatch_device_control =
g_p_target_driver_object->MajorFunction[IRP_MJ_DEVICE_CONTROL];
g_p_target_driver_object->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
CfCommonDispatch;

driver_object->DriverUnload = DriverUnload;

return STATUS_SUCCESS;
}

NTSTATUS CfCommonDispatch(IN PDEVICE_OBJECT device_object,IN PIRP irp)
{
irp->IoStatus.Status = STATUS_ACCESS_DENIED;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
// KdPrint((DRIVERNAME " - deny the request\n"));
return STATUS_ACCESS_DENIED;
}

But it doesn't work for USB. Can I do the same thing to USB this way? How
to modify?

Posted by JoeySwen on November 25th, 2004


The filter example in DDK is:
#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)
#endif

#ifdef IOCTL_INTERFACE

#ifdef ALLOC_PRAGMA
#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;

#endif

NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++

Routine Description:

Installable driver initialization entry point.
This entry point is called directly by the I/O system.

Arguments:

DriverObject - pointer to the driver object

RegistryPath - pointer to a unicode string representing the path,
to driver-specific key in the registry.

Return Value:

STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise.

--*/
{
NTSTATUS status = STATUS_SUCCESS;
ULONG ulIndex;
PDRIVER_DISPATCH * dispatch;

UNREFERENCED_PARAMETER (RegistryPath);

DebugPrint (("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->DriverUnload = FilterUnload;

#ifdef IOCTL_INTERFACE
//
// 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);

#endif

return status;
}


NTSTATUS
FilterAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
/*++

Routine Description:

The Plug & Play subsystem is handing us a brand new PDO, for which we
(by means of INF registration) have been asked to provide a driver.

We need to determine if we need to be in the driver stack for the
device.
Create a function device object to attach to the stack
Initialize that device object
Return status success.

Remember: We can NOT actually send ANY non pnp IRPS to the given
driver
stack, UNTIL we have received an IRP_MN_START_DEVICE.

Arguments:

DeviceObject - pointer to a device object.

PhysicalDeviceObject - pointer to a device object created by the
underlying bus driver.

Return Value:

NT status code.

--*/
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
PDEVICE_EXTENSION deviceExtension;
ULONG deviceType = FILE_DEVICE_UNKNOWN;

PAGED_CODE ();


//
// IoIsWdmVersionAvailable(1, 0x20) returns TRUE on os after Windows
2000.
//
if (!IoIsWdmVersionAvailable(1, 0x20)) {
//
// Win2K system bugchecks if the filter attached to a storage
device
// doesn't specify the same DeviceType as the device it's
attaching
// to. This bugcheck happens in the filesystem when you disable
// the devicestack whose top level deviceobject doesn't have a
VPB.
// To workaround we will get the toplevel object's DeviceType and
// specify that in IoCreateDevice.
//
deviceObject =
IoGetAttachedDeviceReference(PhysicalDeviceObject) ;
deviceType = deviceObject->DeviceType;
ObDereferenceObject(deviceObject);
}

//
// Create a filter device object.
//

status = IoCreateDevice (DriverObject,
sizeof (DEVICE_EXTENSION),
NULL, // No Name
deviceType,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&deviceObject);


if (!NT_SUCCESS (status)) {
//
// Returning failure here prevents the entire stack from
functioning,
// but most likely the rest of the stack will not be able to
create
// device objects either, so it is still OK.
//
return status;
}

DebugPrint (("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) {

IoDeleteDevice(deviceObject);
return STATUS_UNSUCCESSFUL;
}

deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags &
(DO_BUFFERED_IO | DO_DIRECT_IO |
DO_POWER_PAGABLE );


deviceObject->DeviceType =
deviceExtension->NextLowerDriver->DeviceType;

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);

DebugPrint(("AddDevice: %x to %x->%x \n", deviceObject,
deviceExtension->NextLowerDriver,
PhysicalDeviceObject));

deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

return STATUS_SUCCESS;

}


NTSTATUS
FilterPass (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
return status;
}

NTSTATUS
FilterDispatchPnp (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
return status;
}

NTSTATUS
FilterDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
return status;
}


VOID
FilterUnload(
IN PDRIVER_OBJECT DriverObject
)
{
return;
}

NTSTATUS
FilterDispatchIo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)

{
//here you can add your code
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}

#endif

I just don't know how to pass the parameter PhysicalDeviceObject to
FilterAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)




Posted by Calvin Guan on November 25th, 2004



You don't.
Pnp manager calls your AddDevice routine with all objects provided.

--
Calvin Guan Software Engineer/Radeon NT Drivers
ATI Technologies Inc. Markham ON, Canada www.ati.com
No matter how many fish in the sea it'd be so empty without me - Without Me,
Eminem




Similar Posts