I want to get file name when some files in my usb mass storage is reading or
writing
but I can not get IRP_MJ_CREATE why ??
need your help please…
there are my filter driver source code and INF file…
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
filter.c
Abstract: NULL filter driver – boilerplate code
Author:
ervinp
Environment:
Kernel mode
Revision History:
–*/
#include <wdm.h>
#include <stdio.h>
#include “filter.h”
//#include “filemon.h”
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, VA_AddDevice)
#pragma alloc_text(PAGE, VA_DriverUnload)
#endif
typedef enum {
STANDARD,
NPFS,
MSFS
} FILE_SYSTEM_TYPE, PFILE_SYSTEM_TYPE;
typedef struct {
FILE_SYSTEM_TYPE Type;
PDEVICE_OBJECT FileSystem;
unsigned LogicalDrive;
} HOOK_EXTENSION, PHOOK_EXTENSION;
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
–/
{
ULONG i;
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistryPath);
DBGOUT((“DriverEntry”));
DbgPrint(“DriverEntry==================”);
/
* Route all IRPs on device objects created by this driver
* to our IRP dispatch routine.
/
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++){
DriverObject->MajorFunction[i] = VA_Dispatch;
}
DriverObject->DriverExtension->AddDevice = VA_AddDevice;
DriverObject->DriverUnload = VA_DriverUnload;
return STATUS_SUCCESS;
}
NTSTATUS VA_AddDevice(
IN PDRIVER_OBJECT driverObj,
IN PDEVICE_OBJECT physicalDevObj
)
/++
Routine Description:
The PlugPlay subsystem is handing us a brand new
PDO (Physical Device Object), for which we
(by means of INF registration) have been asked to filter.
We need to determine if we should attach or not.
Create a filter 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:
driverObj - pointer to a device object.
physicalDevObj - pointer to a physical device object pointer
created by the underlying bus driver.
Return Value:
NT status code.
–/
{
NTSTATUS status;
PDEVICE_OBJECT filterDevObj = NULL;
PAGED_CODE();
DBGOUT((“VA_AddDevice: drvObj=%ph, pdo=%ph”, driverObj,
physicalDevObj));
DbgPrint(“—Add_Device—”);
status = IoCreateDevice( driverObj,
sizeof(struct DEVICE_EXTENSION),
NULL, // name for this device
//FILE_DEVICE_UNKNOWN,
// device
characteristics
FILE_DEVICE_FILE_SYSTEM,
FILE_REMOVABLE_MEDIA,
//FILE_AUTOGENERATED_DEVICE_NAME,
//FILE_DEVICE_SECURE_OPEN,
FALSE, // not exclusive
&filterDevObj); // our device object
//
// It is important that you choose correctly the file type for this
// device object. Here we use FILE_DEVICE_UNKNOWN because this is
// a generic filter, however as will all filters, the creator needs
// to understand to which stack this filter is attaching.
// E.G. if you are writing a CD filter driver you need to use
// FILE_DEVICE_CD_ROM. IoCreateDevice actually creates device object
// with different properties dependent on this field.
//
if (NT_SUCCESS(status)){
struct DEVICE_EXTENSION devExt;
ASSERT(filterDevObj);
/
* Initialize device extension for new device object
/
devExt = (struct DEVICE_EXTENSION )filterDevObj->DeviceExtension;
RtlZeroMemory(devExt, sizeof(struct DEVICE_EXTENSION));
devExt->signature = DEVICE_EXTENSION_SIGNATURE;
devExt->state = STATE_INITIALIZED;
devExt->filterDevObj = filterDevObj;
devExt->physicalDevObj = physicalDevObj;
devExt->pendingActionCount = 0;
KeInitializeEvent(&devExt->removeEvent, NotificationEvent, FALSE);
#ifdef HANDLE_DEVICE_USAGE
KeInitializeEvent(&devExt->deviceUsageNotificationEvent,
SynchronizationEvent, TRUE);
#endif // HANDLE_DEVICE_USAGE
/
* Attach the new device object to the top of the device stack.
/
devExt->topDevObj = IoAttachDeviceToDeviceStack(filterDevObj,
physicalDevObj);
ASSERT(devExt->topDevObj);
DBGOUT((“created filterDevObj %ph attached to %ph.”, filterDevObj,
devExt->topDevObj));
//
// As a filter driver, we do not want to change the power or I/O
// behavior of the driver stack in any way. Recall that a filter
// driver should “appear” the same (almost) as the underlying
device.
// Therefore we must copy some bits from the device object
directly
// below us in the device stack (notice: DON’T copy from the PDO!)
//
/ Various I/O-related flags which should be maintained /
/ (copy from lower device object) /
filterDevObj->Flags |=
(devExt->topDevObj->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO));
/ Various Power-related flags which should be maintained /
/ (copy from lower device object) /
filterDevObj->Flags |= (devExt->topDevObj->Flags &
(DO_POWER_INRUSH | DO_POWER_PAGABLE /| DO_POWER_NOOP/));
#ifdef HANDLE_DEVICE_USAGE
//
// To determine whether some of our routines should initially be
// pageable, we must consider the DO_POWER_xxxx flags of the
// device object directly below us in the device stack.
//
// * We make ourselves pageable if:
// - that devobj has its PAGABLE bit set (so we know our power
// routines won’t be called at DISPATCH_LEVEL)
// -OR-
// - that devobj has its NOOP bit set (so we know we won’t be
// participating in power-management at all). NOTE, currently
// DO_POWER_NOOP is not implemented.
//
// * Otherwise, we make ourselves non-pageable because either:
// - that devobj has its INRUSH bit set (so we also have to be
// INRUSH, and code that handles INRUSH irps can’t be
pageable)
// -OR-
// - that devobj does NOT have its PAGABLE bit set (and NOOP
isn’t
// set, so some of our code might be called at DISPATCH_LEVEL)
//
if ((devExt->topDevObj->Flags & DO_POWER_PAGABLE)
/|| (devExt->topDevObj->Flags & DO_POWER_NOOP)/)
{
// We’re initially pageable.
//
// Don’t need to do anything else here, for now.
}
else
{
// We’re initially non-pageable.
//
// We need to lock-down the code for all routines
// that could be called at IRQL >= DISPATCH_LEVEL.
DBGOUT(( “LOCKing some driver code (non-pageable) (b/c init
conditions)” ));
devExt->initUnlockHandle = MmLockPagableCodeSection( VA_Power );
// some func that’s inside the code section that we want to lock
ASSERT( NULL != devExt->initUnlockHandle );
}
/
* Remember our initial flag settings.
* (Need remember initial settings to correctly handle
* setting of PAGABLE bit later.)
/
devExt->initialFlags = filterDevObj->Flags &
~DO_DEVICE_INITIALIZING;
#endif // HANDLE_DEVICE_USAGE
/
* Clear the initializing bit from the new device object’s flags.
* NOTE: must not do this until after setting DO_POWER_xxxx flags
/
filterDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
/
* This is a do-nothing call to a sample function which
* demonstrates how to read the device’s registry area.
* Note that you cannot make this call on devExt->filterDevObj
* because a filter device object does not have a devNode.
* We pass devExt->physicalDevObj, which is the device object
* for which this driver is a filter driver.
/
RegistryAccessSample(devExt, devExt->physicalDevObj);
}
ASSERT(NT_SUCCESS(status));
return status;
}
VOID VA_DriverUnload(IN PDRIVER_OBJECT DriverObject)
/++
Routine Description:
Free all the allocated resources, etc.
Note: Although the DriverUnload function often does nothing,
the driver must set a DriverUnload function in
DriverEntry; otherwise, the kernel will never unload
the driver.
Arguments:
DriverObject - pointer to a driver object.
Return Value:
VOID.
–/
{
PAGED_CODE();
DBGOUT((“VA_DriverUnload”));
}
void testread(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp){
/*
PFILE_OBJECT pFileObject;
PIO_STACK_LOCATION Current = IoGetCurrentIrpStackLocation(Irp);
if(Current == NULL){
DbgPrint(“Current = NULL”);
}else{
DbgPrint(“Current != NULL”);
}
pFileObject = Current->FileObject;
if(!pFileObject){
DbgPrint(“this is null”);
}else{
DbgPrint(“this is not null”);
}
/
/
ULONG pathLen, prefixLen;
PCHAR pathOffset;
PFILE_OBJECT relatedFileObject;
PHASH_ENTRY hashEntry, newEntry;
ANSI_STRING componentName;
PFILE_NAME_INFORMATION fileNameInfo;
UNICODE_STRING fullUniName;
/
BOOLEAN createPath = FALSE;
PFILE_OBJECT fileObject;
PHOOK_EXTENSION hookExt;
CHAR fullPathName = NULL;
PIO_STACK_LOCATION Current = IoGetCurrentIrpStackLocation(Irp);
fileObject = Current->FileObject;
hookExt = DeviceObject->DeviceExtension;
fullPathName = ExAllocatePool(NonPagedPool,512);
if(Current == NULL)
DbgPrint(“Current = NULL”);
if(hookExt == NULL)
DbgPrint(“hookExt = NULL”);
if(fullPathName == NULL)
DbgPrint(“fullPathName = NULL”);
if(KeGetCurrentIrql() == DISPATCH_LEVEL)
DbgPrint(“fullPathName = DISPATCH_LEVEL”);
else if(KeGetCurrentIrql() == PASSIVE_LEVEL)
DbgPrint(“fullPathName = PASSIVE_LEVEL”);
else if(KeGetCurrentIrql() == APC_LEVEL)
DbgPrint(“fullPathName = APC_LEVEL”);
else
DbgPrint(“Unknow Level”);
if(fileObject == NULL)
DbgPrint(“fileObject = NULL”);
}
NTSTATUS VA_Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/++
Routine Description:
Common entrypoint for all Io Request Packets
Arguments:
DeviceObject - pointer to a device object.
Irp - Io Request Packet
Return Value:
NT status code.
–/
{
struct DEVICE_EXTENSION devExt;
PIO_STACK_LOCATION irpSp;
BOOLEAN passIrpDown = TRUE;
UCHAR majorFunc, minorFunc;
NTSTATUS status;
PFILE_OBJECT pFileObject ;
devExt = DeviceObject->DeviceExtension;
ASSERT(devExt->signature == DEVICE_EXTENSION_SIGNATURE);
irpSp = IoGetCurrentIrpStackLocation(Irp);
/
* Get major/minor function codes in private variables
* so we can access them after the IRP is completed.
/
majorFunc = irpSp->MajorFunction;
minorFunc = irpSp->MinorFunction;
DBGOUT((“VA_Dispatch: majorFunc=%d, minorFunc=%d”,
(ULONG)majorFunc, (ULONG)minorFunc));
//DbgPrint(“######### —VA_Dispatch— #########”);
/
* For all IRPs except REMOVE, we increment the PendingActionCount
* across the dispatch routine in order to prevent a race condition
with
* the REMOVE_DEVICE IRP (without this increment, if REMOVE_DEVICE
* preempted another IRP, device object and extension might get
* freed while the second thread was still using it).
/
if (!((majorFunc == IRP_MJ_PNP) && (minorFunc ==
IRP_MN_REMOVE_DEVICE))){
IncrementPendingActionCount(devExt);
}
if ((majorFunc != IRP_MJ_PNP) &&
(majorFunc != IRP_MJ_CLOSE) &&
((devExt->state == STATE_REMOVING) ||
(devExt->state == STATE_REMOVED))){
/
* While the device is being removed,
* we only pass down the PNP and CLOSE IRPs.
* We fail all other IRPs.
/
status = Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
passIrpDown = FALSE;
}
else {
switch (majorFunc){
case IRP_MJ_READ:
DbgPrint(“######### IRP_MJ_READ #########”);
testread(DeviceObject,Irp);
break;
case IRP_MJ_WRITE:
DbgPrint(“######### IRP_MJ_WRITE #########”);
testread(DeviceObject,Irp);
break;
case IRP_MJ_PNP:
status = VA_PnP(devExt, Irp);
passIrpDown = FALSE;
break;
case IRP_MJ_POWER:
status = VA_Power(devExt, Irp);
passIrpDown = FALSE;
break;
case IRP_MJ_DEVICE_CONTROL:
DbgPrint(“######### IRP_MJ_DEVICE_CONTROL #########”);
testread(DeviceObject,Irp);
break;
case IRP_MJ_CREATE:
DbgPrint(“######### IRP_MJ_CREATE #########”);
testread(DeviceObject,Irp);
break;
case IRP_MJ_CLOSE:
DbgPrint(“######### IRP_MJ_CLOSE #########”);
break;
case IRP_MJ_SYSTEM_CONTROL:
DbgPrint(“######### IRP_MJ_SYSTEM_CONTROL #########”);
break;
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
DbgPrint(“######### IRP_MJ_INTERNAL_DEVICE_CONTROL #########”);
break;
case IRP_MJ_CLEANUP:
DbgPrint(“######### IRP_MJ_CLEANUP #########”);
break;
case IRP_MJ_FLUSH_BUFFERS:
DbgPrint(“######### IRP_MJ_FLUSH_BUFFERS #########”);
break;
case IRP_MJ_QUERY_INFORMATION:
DbgPrint(“######### IRP_MJ_QUERY_INFORMATION #########”);
break;
case IRP_MJ_SET_INFORMATION:
DbgPrint(“######### IRP_MJ_SET_INFORMATION #########”);
break;
case IRP_MJ_SHUTDOWN:
DbgPrint(“######### IRP_MJ_SHUTDOWN #########”);
break;
default:
/
* For unsupported IRPs, we simply send the IRP
* down the driver stack.
/
break;
}
}
if (passIrpDown){
IoCopyCurrentIrpStackLocationToNext(Irp);
status = IoCallDriver(devExt->topDevObj, Irp);
}
/
* Balance the increment to PendingActionCount above.
*/
if (!((majorFunc == IRP_MJ_PNP) && (minorFunc ==
IRP_MN_REMOVE_DEVICE))){
DecrementPendingActionCount(devExt);
}
return status;
}
this is my INF file
; This .INF file demonstrates how to install a filter driver
; for a USB device.
;
; The lines marked with the comment “Filter driver install”
; identify those lines that were specifically added in order to install
; the upper filter driver onto the “driver stack” for this USB device
;
; If one were to remove these lines, what remains is the original
; .INF file to install just the one driver for the USB device.
;
[Version]
Signature=“$WINDOWS NT$”
Class=DiskDrive
ClassGUID={4D36E967-E325-11CE-BFC1-08002BE10318}
[Manufacturer]
%MfgName%=MyDriver
[MyDriver]
%USB\VID_07CC&PID_0003.DeviceDesc%=SESUSB.Dev, GenDisk
[DestinationDirs]
SESUSB.Files.Ext = 10,System32\Drivers
[SESUSB.Dev.NT]
CopyFiles=SESUSB.Files.Ext
[SESUSB.Files.Ext]
disk.sys
FILTER.SYS ; “Filter driver install”
[SESUSB.Dev.NT.Services]
Addservice = SESUSB, 0x00000002, SESUSB.AddService
Addservice = FILTER, , SESFILTER.AddService ; “Filter driver install”
[SESUSB.AddService]
DisplayName = %SESUSB.SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\disk.sys
LoadOrderGroup = Base
[SESFILTER.AddService] ; “Filter driver install”
DisplayName = %SESFILTER.SvcDesc% ; “Filter driver install”
ServiceType = 1 ; “Filter driver install”
StartType = 3 ; “Filter driver install”
ErrorControl = 1 ; “Filter driver install”
ServiceBinary = %12%\FILTER.SYS ; “Filter driver install”
LoadOrderGroup = PnP Filter ; “Filter driver install”
[SESUSB.Dev.NT.HW] ; “Filter driver install”
Addreg=SESFILTER_Filter_Reg ; “Filter driver install”
[SESFILTER_Filter_Reg] ; “Filter driver install”
HKR,“UpperFilters”,0x00010000,“FILTER” ; “Filter driver install”
[Strings]
MfgName=“Barry Test Filter Driver”
USB\VID_07CC&PID_0003.DeviceDesc=“Sample USB device”
SESUSB.SvcDesc=“SESUSB.SYS Sample USB device driver”
SESFILTER.SvcDesc=“FILTER.SYS Upper filter driver” ; “Filter driver install”</stdio.h></wdm.h>