how to use IoCreateStreamFileObjectLite ?

In my encryption filter I have to decide when opening files if they are
encrypted or not and that means reading the header of the file. But I
saw the problem raised by Tony about receiving fake file objects for
opening files and I decided to correct my code. After the open succeeds
I call IoCreateStreamFileObjectLite(FileObject,NULL) to get an alternate
true file object to use for quering the file length and reading the
header. But that query and the read request are not working. I get a
STATUS_INVALID_PARAMETER for the query and STATUS_INVALID_DEVICE_REQUEST
for the read. All I have done is change the original file object from
those requests with the alternate one. Has anyone used this function? Am
I missing a step in configuring the alternate file object or the requests?

Daniel

Daniel,

When are you calling IoCreateStreamFileObjectLite? Since we really haven’t
specified an alternative algorithm yet within the group (we’ve identified
the problem) all we’ve been throwing around are potential solutions.

I believe (but keep in mind, I have not yet implemented this) that the
stream file object solution is to:

  • Intercept the IRP_MJ_CREATE call. At that point, create the stream file
    object. When you set up the next IRP stack location, make it point to your
    stack location (IoGetNextIrpStackLocation(Irp)->FileObject =
    MyStreamFileObject). Then pass that synchronously (in XP and W2K3
    IoForwardIrpSynchronously or for earlier versions via your own mechanism).

  • Now, you have an initialized file object. Use that for your IRP_MJ_READ
    or IRP_MJ_WRITE call to read your header.

  • If you decide to allow this access, you should then send the IRP_MJ_CREATE
    down to the lower driver using the original file object. You will also need
    to tear down your stream file object at some point, but you might wish to
    hold on to it for a while (it probably won’t go away very soon in any case
    since the odds are that the stream file object is now backing a section
    object).

  • If you decide to disallow this access, you can complete the original
    IRP_MJ_CREATE request with an error. You’re still responsible for dealing
    with your stream file object, but the original file object is now the
    issue/problem of the caller, not you (whether it is from stack, or not.)

If this still is causing you problems, I’d suggest walking into the FAT file
system (hopefully you aren’t NTFS only!) with the debugger and seeing why it
is unhappy - after all, full source is available in the IFS Kit. If you are
feeling ambitious, you can build the FAT file system driver and replace the
original (ah, but that’s a separate struggle - use the debugger to replace
it, since that works best.) Then you’ll be able to do full symbolic
debugging with it.

Perhaps Ted or Nick have some feedback on here as well, since I know that
they were thinking about this as well.

Regards,

Tony

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

-----Original Message-----
From: Daniel Turcanu [mailto:xxxxx@ipdevel.ro]
Sent: Wednesday, May 07, 2003 9:17 AM
To: File Systems Developers
Subject: [ntfsd] how to use IoCreateStreamFileObjectLite ?

In my encryption filter I have to decide when opening files if they are
encrypted or not and that means reading the header of the file. But I
saw the problem raised by Tony about receiving fake file objects for
opening files and I decided to correct my code. After the open succeeds
I call IoCreateStreamFileObjectLite(FileObject,NULL) to get an alternate
true file object to use for quering the file length and reading the
header. But that query and the read request are not working. I get a
STATUS_INVALID_PARAMETER for the query and STATUS_INVALID_DEVICE_REQUEST
for the read. All I have done is change the original file object from
those requests with the alternate one. Has anyone used this function? Am
I missing a step in configuring the alternate file object or the requests?

Daniel


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

So you say that IoCreateStreamFileObjectLite does not create an
alternate file object for the original and I have to make a separate
MJ_CREATE for that alternate to be valid? I think this is my problem, I
just noticed that the FsContext field is not set for the alternate. What
is with the FileObject parameter from IoCreateStreamFileObjectLite then ?

Before trying this I have tried an algorithm more close to what you
propose, but using ZwCreateFile instead and it worked. I could not
afford to open each file twice for every open so I restricted the
algorithm only for the file objects that are on the thread stack or for
the network files. I noticed that many opens for dirs and files from the
network use that fake file object shortcut. If not all (that come from
Explorer). My driver used to hang when quering for file/dir length from
network, but now it works fine if I open another file object first.

As far as I noticed not all fake file objects are set on the current
stack, and I don’t know a way to determine this for sure, that is why I
have tried the IoCreateStreamFileObjectLite. I thought that I will not
need another open after it.
So, is there a sure way to determine a file object as being fake ?

Daniel

Tony Mason wrote:

Daniel,

When are you calling IoCreateStreamFileObjectLite? Since we really haven’t
specified an alternative algorithm yet within the group (we’ve identified
the problem) all we’ve been throwing around are potential solutions.

I believe (but keep in mind, I have not yet implemented this) that the
stream file object solution is to:

  • Intercept the IRP_MJ_CREATE call. At that point, create the stream file
    object. When you set up the next IRP stack location, make it point to your
    stack location (IoGetNextIrpStackLocation(Irp)->FileObject =
    MyStreamFileObject). Then pass that synchronously (in XP and W2K3
    IoForwardIrpSynchronously or for earlier versions via your own mechanism).

  • Now, you have an initialized file object. Use that for your IRP_MJ_READ
    or IRP_MJ_WRITE call to read your header.

  • If you decide to allow this access, you should then send the IRP_MJ_CREATE
    down to the lower driver using the original file object. You will also need
    to tear down your stream file object at some point, but you might wish to
    hold on to it for a while (it probably won’t go away very soon in any case
    since the odds are that the stream file object is now backing a section
    object).

  • If you decide to disallow this access, you can complete the original
    IRP_MJ_CREATE request with an error. You’re still responsible for dealing
    with your stream file object, but the original file object is now the
    issue/problem of the caller, not you (whether it is from stack, or not.)

If this still is causing you problems, I’d suggest walking into the FAT file
system (hopefully you aren’t NTFS only!) with the debugger and seeing why it
is unhappy - after all, full source is available in the IFS Kit. If you are
feeling ambitious, you can build the FAT file system driver and replace the
original (ah, but that’s a separate struggle - use the debugger to replace
it, since that works best.) Then you’ll be able to do full symbolic
debugging with it.

Perhaps Ted or Nick have some feedback on here as well, since I know that
they were thinking about this as well.

Regards,

Tony

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

-----Original Message-----
From: Daniel Turcanu [mailto:xxxxx@ipdevel.ro]
Sent: Wednesday, May 07, 2003 9:17 AM
To: File Systems Developers
Subject: [ntfsd] how to use IoCreateStreamFileObjectLite ?

In my encryption filter I have to decide when opening files if they are
encrypted or not and that means reading the header of the file. But I
saw the problem raised by Tony about receiving fake file objects for
opening files and I decided to correct my code. After the open succeeds
I call IoCreateStreamFileObjectLite(FileObject,NULL) to get an alternate
true file object to use for quering the file length and reading the
header. But that query and the read request are not working. I get a
STATUS_INVALID_PARAMETER for the query and STATUS_INVALID_DEVICE_REQUEST
for the read. All I have done is change the original file object from
those requests with the alternate one. Has anyone used this function? Am
I missing a step in configuring the alternate file object or the requests?

Daniel


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


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

> So you say that IoCreateStreamFileObjectLite does not create an

alternate file object for the original and I have to make a separate
MJ_CREATE for that alternate to be valid? I think this is my
problem, I
just noticed that the FsContext field is not set for the alternate.
What

Yes, IoCreateStreamFileObjectLite creates an empty file object with no
FS context associated with it. Associate the context manually, or pass
CREATE down to the FSD.

Max