Create File error to file system filter driver

Hi,

I am trying to create a handle to the file system filter driver device, and I am getting an error with error code 1 (Incorrect function). Here is some code:

Section in user mode cpp file:

hDevice = CreateFile(
“\\.\APfilter”, // lpFileName
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDistribution
0, // dwFlagsAndAttributes
NULL // hTemplateFile
);

Section in kernel mode DriverEntry function of filter driver (minimal modification of sfilter example which comes with the IFS kit). Also the startup type of this driver is SERVICE_AUTO_START.

RtlInitUnicodeString( &nameString, L"\FileSystem\Filters\SFilter" );

status = IoCreateDevice( DriverObject,
0, //has no device extension
&nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&gSFilterControlDeviceObject );

RtlInitUnicodeString( &linkString, L"\DosDevices\APfilter" );
status2 = IoCreateSymbolicLink(&linkString, &nameString);

The devicetree utility in IFS kit shows the SFilter driver installed, and attached to the NTFS filesystem. I am unable to manually check is there is a device \DosDevices\APfilter installed. Is there a way I can do that?

Thanks,
Aman

Use the debugger to verify your objects and links are where you think
they should be (“!object ” will do the trick.) Or use
one of the object name space viewers (like the one you can download from
osronline, or the one from Microsoft’s Sysinternals website.)

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

Are you sure you have DispatchCreate in your driver?


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntfsd…
> Hi,
>
> I am trying to create a handle to the file system filter driver device, and I
am getting an error with error code 1 (Incorrect function). Here is some code:
>
> Section in user mode cpp file:
>
> hDevice = CreateFile(
> “\\.\APfilter”, // lpFileName
> GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
> FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
> NULL, //
lpSecurityAttributes
> OPEN_EXISTING, //
dwCreationDistribution
> 0, //
dwFlagsAndAttributes
> NULL // hTemplateFile
> );
>
> Section in kernel mode DriverEntry function of filter driver (minimal
modification of sfilter example which comes with the IFS kit). Also the startup
type of this driver is SERVICE_AUTO_START.
>
> RtlInitUnicodeString( &nameString, L"\FileSystem\Filters\SFilter" );
>
> status = IoCreateDevice( DriverObject,
> 0, //has no device
extension
> &nameString,
> FILE_DEVICE_DISK_FILE_SYSTEM,
> FILE_DEVICE_SECURE_OPEN,
> FALSE,
> &gSFilterControlDeviceObject );
>
> RtlInitUnicodeString( &linkString, L"\DosDevices\APfilter" );
> status2 = IoCreateSymbolicLink(&linkString, &nameString);
>
> The devicetree utility in IFS kit shows the SFilter driver installed, and
attached to the NTFS filesystem. I am unable to manually check is there is a
device \DosDevices\APfilter installed. Is there a way I can do that?
>
> Thanks,
> Aman
>
>

Hi,

First of all, thanks for the replies.

Tony, I used WinObj utility, and APfilter does occur in the list of objects in the GLOBAL?? folder. This should mean that APfilter is installed in correct location, as other devices like /DosDevices/C: also appear as C: in that folder. This was also apparent from the fact that error was not ERROR_FILE_NOT_FOUND.

Maxim, I have dispatch routines registered for all IRPs, and most of them just pass through the IRP (exceptions are in the listing below). Is this what you meant? Also, how would that make a difference, as I am not sending an IRP yet, just creating a handle?

The listing below shows how I register for all IRPs.

for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {

DriverObject->MajorFunction[i] = SfPassThrough;
}

//
// We will use SfCreate for all the create operations
//

DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = UserModeHandle;

DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SfCleanupClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SfCleanupClose;

Also, here is an example of a very similar thing which DOES WORK:

CreateFile call:

hDevice = CreateFile(
“\\.\Event_Sample”, // lpFileName
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDistribution
0, // dwFlagsAndAttributes
NULL // hTemplateFile
);

DriverEntry section:

//
// Create the device object
//
RtlInitUnicodeString( &ntDeviceName, NTDEVICE_NAME_STRING );

status = IoCreateDevice(
DriverObject, // DriverObject
sizeof( DEVICE_EXTENSION ), // DeviceExtensionSize
&ntDeviceName, // DeviceName
FILE_DEVICE_UNKNOWN, // DeviceType
FILE_DEVICE_SECURE_OPEN, // DeviceCharacteristics
FALSE, // Not Exclusive
&deviceObject // DeviceObject
);

if ( !NT_SUCCESS(status) ) {
DebugPrint((“\tIoCreateDevice returned 0x%x\n”, status));
return( status );
}

//
// Set up dispatch entry points for the driver.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = EventCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = EventCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EventDispatchIoControl;
DriverObject->DriverUnload = EventUnload;

//
// Create a symbolic link for userapp to interact with the driver.
//
RtlInitUnicodeString( &symbolicLinkName, SYMBOLIC_NAME_STRING );
status = IoCreateSymbolicLink( &symbolicLinkName, &ntDeviceName );

if ( !NT_SUCCESS(status) ) {

IoDeleteDevice( deviceObject );
DebugPrint((“\tIoCreateSymbolicLink returned 0x%x\n”, status));
return( status );
}

I am perplexed. Please help!

P.S. I’ve just been doing windows programming 3 days. It would be kind if replies were more descriptive.

Thanks,
Aman

> P.S. I’ve just been doing windows programming 3 days. It would be kind if

replies were more descriptive.
Also, how would that make a difference, as I am not sending an IRP yet,
just creating a handle?

I suppose that you used to be a *nix programmer.
Actually, an IRP is sent by the system on behalf of you, this is
IRP_MJ_CREATE request.

An IRP_MJ_CREATE request analogy for the UNIX world is a pathname lookup and
fs_op->open() method calling- when you call open() the VFS performs a
pathname lookup and finds the corresponding inode and this inode is
associated with a file object, then a fs_op->open() method is called.
Windows uses IRP_MJ_CREATE request for the both pathname lookup and
fs_op->open(). The major difference between Windows and UNIX is that in UNIX
the root of objects is a file system( all in UNIX are file system objects )
but Windows has a specially dedicated objects manager( Ob* functions ) and
drivers extend the name space of this object manager through IRP_MJ_CREATE
request. The Windows analogy( not exact ) for inode is
FILE_OBJECT->FsContext field initialized by a driver while processing
IRP_MJ_CREATE request and this field might be NULL because the object
manager operates on objects( object’s headers and object types ) and doesn’t
use FILE_OBJECT->FsContext field.

Handle is a descriptor for a system object, handle is an index in the
process’ handle table which contains descriptors of system objects( a
FILE_OBJECT in your case ), the UNIX analogy is the same - a table of
descriptors for file objects.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
> Hi,
>
> First of all, thanks for the replies.
>
> Tony, I used WinObj utility, and APfilter does occur in the list of
> objects in the GLOBAL?? folder. This should mean that APfilter is
> installed in correct location, as other devices like /DosDevices/C: also
> appear as C: in that folder. This was also apparent from the fact that
> error was not ERROR_FILE_NOT_FOUND.
>
> Maxim, I have dispatch routines registered for all IRPs, and most of them
> just pass through the IRP (exceptions are in the listing below). Is this
> what you meant? Also, how would that make a difference, as I am not
> sending an IRP yet, just creating a handle?
>
> The listing below shows how I register for all IRPs.
>
> for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
>
> DriverObject->MajorFunction[i] = SfPassThrough;
> }
>
> //
> // We will use SfCreate for all the create operations
> //
>
> DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;
> DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate;
> DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate;
> DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = UserModeHandle;
>
> DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl;
> DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SfCleanupClose;
> DriverObject->MajorFunction[IRP_MJ_CLOSE] = SfCleanupClose;
>
> Also, here is an example of a very similar thing which DOES WORK:
>
> CreateFile call:
>
> hDevice = CreateFile(
> “\\.\Event_Sample”, //
> lpFileName
> GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
> FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
> NULL, //
> lpSecurityAttributes
> OPEN_EXISTING, //
> dwCreationDistribution
> 0, //
> dwFlagsAndAttributes
> NULL // hTemplateFile
> );
>
> DriverEntry section:
>
> //
> // Create the device object
> //
> RtlInitUnicodeString( &ntDeviceName, NTDEVICE_NAME_STRING );
>
> status = IoCreateDevice(
> DriverObject, // DriverObject
> sizeof( DEVICE_EXTENSION ), // DeviceExtensionSize
> &ntDeviceName, // DeviceName
> FILE_DEVICE_UNKNOWN, // DeviceType
> FILE_DEVICE_SECURE_OPEN, // DeviceCharacteristics
> FALSE, // Not Exclusive
> &deviceObject // DeviceObject
> );
>
> if ( !NT_SUCCESS(status) ) {
> DebugPrint((“\tIoCreateDevice returned 0x%x\n”, status));
> return( status );
> }
>
> //
> // Set up dispatch entry points for the driver.
> //
> DriverObject->MajorFunction[IRP_MJ_CREATE] =
> DriverObject->MajorFunction[IRP_MJ_CLOSE] = EventCreateClose;
> DriverObject->MajorFunction[IRP_MJ_CLEANUP] = EventCleanup;
> DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
> EventDispatchIoControl;
> DriverObject->DriverUnload = EventUnload;
>
> //
> // Create a symbolic link for userapp to interact with the driver.
> //
> RtlInitUnicodeString( &symbolicLinkName, SYMBOLIC_NAME_STRING );
> status = IoCreateSymbolicLink( &symbolicLinkName, &ntDeviceName );
>
> if ( !NT_SUCCESS(status) ) {
>
> IoDeleteDevice( deviceObject );
> DebugPrint((“\tIoCreateSymbolicLink returned 0x%x\n”, status));
> return( status );
> }
>
> I am perplexed. Please help!
>
> P.S. I’ve just been doing windows programming 3 days. It would be kind if
> replies were more descriptive.
>
> Thanks,
> Aman
>

I bet you aren’t clearing the “DO_DEVICE_INITIALIZING” flag…

-Jeff

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Slava Imameyev
Sent: Saturday, April 21, 2007 6:10 PM
To: Windows File Systems Devs Interest List
Subject: Re:[ntfsd] Create File error to file system filter driver

P.S. I’ve just been doing windows programming 3 days. It would be kind
if
replies were more descriptive.
Also, how would that make a difference, as I am not sending an IRP
yet,
just creating a handle?

I suppose that you used to be a *nix programmer.
Actually, an IRP is sent by the system on behalf of you, this is
IRP_MJ_CREATE request.

An IRP_MJ_CREATE request analogy for the UNIX world is a pathname lookup
and
fs_op->open() method calling- when you call open() the VFS performs a
pathname lookup and finds the corresponding inode and this inode is
associated with a file object, then a fs_op->open() method is called.
Windows uses IRP_MJ_CREATE request for the both pathname lookup and
fs_op->open(). The major difference between Windows and UNIX is that in
UNIX
the root of objects is a file system( all in UNIX are file system
objects )
but Windows has a specially dedicated objects manager( Ob* functions )
and
drivers extend the name space of this object manager through
IRP_MJ_CREATE
request. The Windows analogy( not exact ) for inode is
FILE_OBJECT->FsContext field initialized by a driver while processing
IRP_MJ_CREATE request and this field might be NULL because the object
manager operates on objects( object’s headers and object types ) and
doesn’t
use FILE_OBJECT->FsContext field.

Handle is a descriptor for a system object, handle is an index in the
process’ handle table which contains descriptors of system objects( a
FILE_OBJECT in your case ), the UNIX analogy is the same - a table of
descriptors for file objects.


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
> Hi,
>
> First of all, thanks for the replies.
>
> Tony, I used WinObj utility, and APfilter does occur in the list of
> objects in the GLOBAL?? folder. This should mean that APfilter is
> installed in correct location, as other devices like /DosDevices/C:
also
> appear as C: in that folder. This was also apparent from the fact that

> error was not ERROR_FILE_NOT_FOUND.
>
> Maxim, I have dispatch routines registered for all IRPs, and most of
them
> just pass through the IRP (exceptions are in the listing below). Is
this
> what you meant? Also, how would that make a difference, as I am not
> sending an IRP yet, just creating a handle?
>
> The listing below shows how I register for all IRPs.
>
> for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
>
> DriverObject->MajorFunction[i] = SfPassThrough;
> }
>
> //
> // We will use SfCreate for all the create operations
> //
>
> DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;
> DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate;
> DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate;
> DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
UserModeHandle;
>
> DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
SfFsControl;
> DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SfCleanupClose;
> DriverObject->MajorFunction[IRP_MJ_CLOSE] = SfCleanupClose;
>
> Also, here is an example of a very similar thing which DOES WORK:
>
> CreateFile call:
>
> hDevice = CreateFile(
> “\\.\Event_Sample”, //
> lpFileName
> GENERIC_READ | GENERIC_WRITE, //
dwDesiredAccess
> FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
> NULL, //
> lpSecurityAttributes
> OPEN_EXISTING, //
> dwCreationDistribution
> 0, //
> dwFlagsAndAttributes
> NULL //
hTemplateFile
> );
>
> DriverEntry section:
>
> //
> // Create the device object
> //
> RtlInitUnicodeString( &ntDeviceName, NTDEVICE_NAME_STRING );
>
> status = IoCreateDevice(
> DriverObject, // DriverObject
> sizeof( DEVICE_EXTENSION ), // DeviceExtensionSize
> &ntDeviceName, // DeviceName
> FILE_DEVICE_UNKNOWN, // DeviceType
> FILE_DEVICE_SECURE_OPEN, // DeviceCharacteristics
> FALSE, // Not Exclusive
> &deviceObject // DeviceObject
> );
>
> if ( !NT_SUCCESS(status) ) {
> DebugPrint((“\tIoCreateDevice returned 0x%x\n”, status));
> return( status );
> }
>
> //
> // Set up dispatch entry points for the driver.
> //
> DriverObject->MajorFunction[IRP_MJ_CREATE] =
> DriverObject->MajorFunction[IRP_MJ_CLOSE] =
EventCreateClose;
> DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
EventCleanup;
> DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
> EventDispatchIoControl;
> DriverObject->DriverUnload = EventUnload;
>
> //
> // Create a symbolic link for userapp to interact with the driver.
> //
> RtlInitUnicodeString( &symbolicLinkName, SYMBOLIC_NAME_STRING );
> status = IoCreateSymbolicLink( &symbolicLinkName, &ntDeviceName );
>
> if ( !NT_SUCCESS(status) ) {
>
> IoDeleteDevice( deviceObject );
> DebugPrint((“\tIoCreateSymbolicLink returned 0x%x\n”, status));
> return( status );
> }
>
> I am perplexed. Please help!
>
> P.S. I’ve just been doing windows programming 3 days. It would be kind
if
> replies were more descriptive.
>
> Thanks,
> Aman
>


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@emc.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hi,

Thanks for all the help guys. The problem was some bug in my dispatch function for IRP_MJ_CREATE that was letting the IRP passthrough even when the device object was my own driver’s CDO. Your replies were helpful in locating the bug in the way that it made me check the specific dispatch function carefully.

And Slava, thanks for the explanation - you are right that I am from the *nix environment. But even in linux, I’ve rarely done kernel mode programming, though I know more about its kernel due to its open source nature.

Thanks again,
Aman