IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED ?

Hi, all

During IRP_MJ_CREATE, I need to open file, make some checks
and eventually deny the create request (Imagine
it is an antivirus).

I reuse the IRP for opening the file, only with
changing file object to another one created using
IoCreateStreamFileObject, then I send the IRP down.

When the file operation is done, I dereference
the stream FileObject. This operation seems to keep
the file opened (because they cannot be opened again
with STATUS_SHARING_VIOLATION).

My opinion is that the IRP_MJ_CLEANUP is not called
during ObDereferenceObject (I do not receive it in
my filter). I noticed that the file object returned
by IoCreateStreamFileObject has the flag FO_HANDLE_CREATED
set. This flag is then tested in IopDeleteFile and
if it is set, the IopCloseFile is not called there.

Should I retrieve the handle and close it manually ?

I tried to use IoCreateStreamFileObjectLite,
but the file object has the FO_HANDLE_CREATED flag too.
I made some dissassembly to compare the two functions,
and they seems to be very similar, except that the
“Non-Lite” version calls ObInsertObject, which creates
the handle. The “Lite” version does not call ObInsertObject,
but it sets the FO_HANDLE_CREATED too !!!
(Observed on Win2000 SP4). But where is the handle, if the
returned file object has only one reference (both Lite and
Non-Lite versions) ?

L.

If you want to obtain the handle, use IoCreateStreamFileObjectEx.

In the case of IoCreateStreamFileObject, the handle is closed prior to
returning to the caller. In that case, the IRP_MJ_CLEANUP is sent prior
to the IoCreateStreamFileObject call returning to you.
IoCreateStreamFileObjectLite is really what you want in the case you
outline, however, because you don’t want the IRP_MJ_CLEANUP sent at that
point. (In all fairness, I am not sure how you are creating your stream
file object, so I don’t even know where the I/O Manager is sending your
IRP_MJ_CLEANUP.)

When you are done, YOU are going to need to send the IRP_MJ_CLEANUP down
to the underlying file system - otherwise the file system won’t have
any idea that the file has been “closed”. Then you can deref the file
object and when the ref count on it drops to zero you’ll see the
IRP_MJ_CLOSE. I believe that - if you use IoCreateStreamFileObjectLite

  • you can just use IoCancelFileOpen.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 12:49 AM
To: ntfsd redirect
Subject: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED ?

Hi, all

During IRP_MJ_CREATE, I need to open file, make some checks and
eventually deny the create request (Imagine it is an antivirus).

I reuse the IRP for opening the file, only with changing file object to
another one created using IoCreateStreamFileObject, then I send the IRP
down.

When the file operation is done, I dereference the stream FileObject.
This operation seems to keep the file opened (because they cannot be
opened again with STATUS_SHARING_VIOLATION).

My opinion is that the IRP_MJ_CLEANUP is not called during
ObDereferenceObject (I do not receive it in my filter). I noticed that
the file object returned by IoCreateStreamFileObject has the flag
FO_HANDLE_CREATED set. This flag is then tested in IopDeleteFile and if
it is set, the IopCloseFile is not called there.

Should I retrieve the handle and close it manually ?

I tried to use IoCreateStreamFileObjectLite, but the file object has the
FO_HANDLE_CREATED flag too.
I made some dissassembly to compare the two functions, and they seems to
be very similar, except that the “Non-Lite” version calls
ObInsertObject, which creates the handle. The “Lite” version does not
call ObInsertObject, but it sets the FO_HANDLE_CREATED too !!!
(Observed on Win2000 SP4). But where is the handle, if the returned file
object has only one reference (both Lite and Non-Lite versions) ?

L.


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

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

Tony,

thank you for the response.

If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within
IRP_MJ_CREATE handler is a thing which does not seem
well to me.

In all fairness, I am not sure how you are creating your stream
file object, so I don’t even know where the I/O Manager is sending your
IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

I believe that - if you use IoCreateStreamFileObjectLite

  • you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects
with FO_HANDLE_CREATED flag set ?

L.

Ladislav,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object) which is why you would want
IoCreateStreamFileObjectLite (which does not set this bit).

I believe the best choice is to use IoCreateStreamFileObjectLite and
then IoCancelFileOpen when you are done. I haven’t done this in a long
time (read: before IoCancelFileOpen was added as an API) so it is
possible that there is some subtle interaction that I’m missing here.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 6:15 AM
To: ntfsd redirect
Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

Tony,

thank you for the response.

If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within
IRP_MJ_CREATE handler is a thing which does not seem
well to me.

In all fairness, I am not sure how you are creating your stream
file object, so I don’t even know where the I/O Manager is sending
your
IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

I believe that - if you use IoCreateStreamFileObjectLite

  • you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects
with FO_HANDLE_CREATED flag set ?

L.


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

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

Tony,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object)

Yes, the FO_HANDLE_CREATED is the point what’s going
on here. Maybe I will clear the flag manually from the stream file object
(although this seems as a little hackery), or think something else of.
I will post the solution here when I’m complete, maybe someone else
finds it useful.

Anyway, thanks for the advices.

L.

Another idea:

  • catch CREATE in the filter.
  • save the original filename, RelatedFileObject and the stack location
  • patch them with the new filename, RelatedFileObject and new stack
    location flags
  • pass the IRP down
  • wait for it
  • work with a file
  • send CLEANUP manually (using the same IRP, for instance)
  • send CLOSE manually
  • reset file object’s flag FO_CLEANUP_COMPLETE
  • restore the original filename, RelatedFileObject and the stack location
  • now pass CREATE of the user-requested file down.

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

----- Original Message -----
From: “Tony Mason”
To: “Windows File Systems Devs Interest List”
Sent: Monday, May 10, 2004 2:48 PM
Subject: RE: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED ?

> Ladislav,
>
> IoCancelFileOpen should not be used with files that have handles (the
> code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
> set in the File Object) which is why you would want
> IoCreateStreamFileObjectLite (which does not set this bit).
>
> I believe the best choice is to use IoCreateStreamFileObjectLite and
> then IoCancelFileOpen when you are done. I haven’t done this in a long
> time (read: before IoCancelFileOpen was added as an API) so it is
> possible that there is some subtle interaction that I’m missing here.
>
> Regards,
>
> Tony
>
> Tony Mason
> Consulting Partner
> OSR Open Systems Resources Inc
> http://www.osr.com
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
> Sent: Monday, May 10, 2004 6:15 AM
> To: ntfsd redirect
> Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
> ?
>
> Tony,
>
> thank you for the response.
>
> > If you want to obtain the handle, use IoCreateStreamFileObjectEx.
>
> No, this is what I want to avoid. Calling ZwClose within
> IRP_MJ_CREATE handler is a thing which does not seem
> well to me.
>
> > In all fairness, I am not sure how you are creating your stream
> > file object, so I don’t even know where the I/O Manager is sending
> your
> > IRP_MJ_CLEANUP.)
>
> The file object is simply created by calling IoCreateStreamFileObject.
> As the source, the file object from the create IRP is used.
> I tried also the “Lite” version.
>
> > I believe that - if you use IoCreateStreamFileObjectLite
> > - you can just use IoCancelFileOpen.
>
> I’m not sure where I’ve heard that, but - is it TRUE that
> IoCancelFileOpen should not be used on file objects
> with FO_HANDLE_CREATED flag set ?
>
> L.
>
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@osr.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
> —
> Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

I’m not sure if IoCancelFileOpen is safe to use in this case. File object
may be referenced by several parties (like Mm, Vm, and filter itself) making
ref count > 2. OP noticed that some complex checks may be performed on
stream file objects (like AV checks) which would initialize caching on the
file object.

In this case, I would use IoCreateStreamFileObjectLite (or
IoCreateStreamFileObject on NT4; lite version just makes things a lil bit
cleaner and faster) and after I’m done, send IRP_MJ_CLEANUP manually (don’t
forget to put FO_HANDLE_CREATED flag before that) and dereference stream
file object.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
Ladislav,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object) which is why you would want
IoCreateStreamFileObjectLite (which does not set this bit).

I believe the best choice is to use IoCreateStreamFileObjectLite and
then IoCancelFileOpen when you are done. I haven’t done this in a long
time (read: before IoCancelFileOpen was added as an API) so it is
possible that there is some subtle interaction that I’m missing here.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 6:15 AM
To: ntfsd redirect
Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

Tony,

thank you for the response.

> If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within
IRP_MJ_CREATE handler is a thing which does not seem
well to me.

> In all fairness, I am not sure how you are creating your stream
> file object, so I don’t even know where the I/O Manager is sending
your
> IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

> I believe that - if you use IoCreateStreamFileObjectLite
> - you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects
with FO_HANDLE_CREATED flag set ?

L.


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

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

As I have previously mentioned in this forum (and documented on
OSRONLINE), ANY filter that uses a file object passed to it in the
IRP_MJ_CREATE handler is unstable/unreliable for a number of reasons.
So pointing out that some other filter might be using the file object
you pass down is really immaterial, since they are already broken, even
without your filter installed.

But even if we take Alexey’s concern into account, it argues for sending
down the IRP_MJ_CLEANUP - but we can’t do that until after the
IRP_MJ_CREATE has been sent to the underlying file system, so we can’t
use IoCreateStreamFileObject to do it for us. Thus, an alternative here
would be to create the new stream file object, pass that (via
IRP_MJ_CREATE) to the underlying FSD, perform an IRP_MJ_CLEANUP on the
file object, and then dereference the file object. If there are no
other references to the file object, the IRP_MJ_CLOSE will be generated
and the close processing proceeds. Otherwise, you have a file object
that is in the “between CLEANUP and CLOSE” state (in other words, paging
I/O operations allowed but nothing else.)

Of course, the complexity of all of this underscores the reason we have
so many interesting interop issues.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 4:19 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

I’m not sure if IoCancelFileOpen is safe to use in this case. File
object
may be referenced by several parties (like Mm, Vm, and filter itself)
making
ref count > 2. OP noticed that some complex checks may be performed on
stream file objects (like AV checks) which would initialize caching on
the
file object.

In this case, I would use IoCreateStreamFileObjectLite (or
IoCreateStreamFileObject on NT4; lite version just makes things a lil
bit
cleaner and faster) and after I’m done, send IRP_MJ_CLEANUP manually
(don’t
forget to put FO_HANDLE_CREATED flag before that) and dereference stream

file object.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
Ladislav,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object) which is why you would want
IoCreateStreamFileObjectLite (which does not set this bit).

I believe the best choice is to use IoCreateStreamFileObjectLite and
then IoCancelFileOpen when you are done. I haven’t done this in a long
time (read: before IoCancelFileOpen was added as an API) so it is
possible that there is some subtle interaction that I’m missing here.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 6:15 AM
To: ntfsd redirect
Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

Tony,

thank you for the response.

> If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within
IRP_MJ_CREATE handler is a thing which does not seem
well to me.

> In all fairness, I am not sure how you are creating your stream
> file object, so I don’t even know where the I/O Manager is sending
your
> IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

> I believe that - if you use IoCreateStreamFileObjectLite
> - you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects
with FO_HANDLE_CREATED flag set ?

L.


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

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


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

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

First of all I was not talking about other filters. Even in case where there
is only one filter and an FSD itself there’s a posibility of created stream
file object to have ref count > 2.

I don’t think that using IoCreateStreamFileObject will cause any problem.
According to IFS docs, filters might expect to receive IRP_MJ_CLEANUP
requests for previously unseen file objects. According to FastFat and CDFS
sources, file system ignores (completes with STATUS_SUCCESS) IRP_MJ_CLEANUP
requests for unopened file objects. When we send IRP_MJ_CLEANUP request
after create request completed, file system decodes the file object
successfuly and performs all necessary actions.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
As I have previously mentioned in this forum (and documented on
OSRONLINE), ANY filter that uses a file object passed to it in the
IRP_MJ_CREATE handler is unstable/unreliable for a number of reasons.
So pointing out that some other filter might be using the file object
you pass down is really immaterial, since they are already broken, even
without your filter installed.

But even if we take Alexey’s concern into account, it argues for sending
down the IRP_MJ_CLEANUP - but we can’t do that until after the
IRP_MJ_CREATE has been sent to the underlying file system, so we can’t
use IoCreateStreamFileObject to do it for us. Thus, an alternative here
would be to create the new stream file object, pass that (via
IRP_MJ_CREATE) to the underlying FSD, perform an IRP_MJ_CLEANUP on the
file object, and then dereference the file object. If there are no
other references to the file object, the IRP_MJ_CLOSE will be generated
and the close processing proceeds. Otherwise, you have a file object
that is in the “between CLEANUP and CLOSE” state (in other words, paging
I/O operations allowed but nothing else.)

Of course, the complexity of all of this underscores the reason we have
so many interesting interop issues.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 4:19 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

I’m not sure if IoCancelFileOpen is safe to use in this case. File
object
may be referenced by several parties (like Mm, Vm, and filter itself)
making
ref count > 2. OP noticed that some complex checks may be performed on
stream file objects (like AV checks) which would initialize caching on
the
file object.

In this case, I would use IoCreateStreamFileObjectLite (or
IoCreateStreamFileObject on NT4; lite version just makes things a lil
bit
cleaner and faster) and after I’m done, send IRP_MJ_CLEANUP manually
(don’t
forget to put FO_HANDLE_CREATED flag before that) and dereference stream

file object.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
Ladislav,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object) which is why you would want
IoCreateStreamFileObjectLite (which does not set this bit).

I believe the best choice is to use IoCreateStreamFileObjectLite and
then IoCancelFileOpen when you are done. I haven’t done this in a long
time (read: before IoCancelFileOpen was added as an API) so it is
possible that there is some subtle interaction that I’m missing here.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 6:15 AM
To: ntfsd redirect
Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

Tony,

thank you for the response.

> If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within
IRP_MJ_CREATE handler is a thing which does not seem
well to me.

> In all fairness, I am not sure how you are creating your stream
> file object, so I don’t even know where the I/O Manager is sending
your
> IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

> I believe that - if you use IoCreateStreamFileObjectLite
> - you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects
with FO_HANDLE_CREATED flag set ?

L.


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

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


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

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

If you want to check the data in file, I recommend the caching method or
ZwCreateFile & ZwReadFile mothod.

  • caching method : if the fileobject is not null and the file is chached by
    Cache Manager,
    try to check the file data in cache memory.
    this method does not create new
    fileobject…it’s good…

  • ZwCreateFile & ZwReadFile :
    first, create (open) the file with ZwCreateFile and read the file
    with ZwReadFile and check
    the file’s data. this method need to be synchronized…


°í… °¨… µµ… »ç… ¶û… ¸¸… µé… ±â… MSN ·¯ºê
http://www.msn.co.kr/love/

You will have to explain to me how Mm or Cc can obtain a reference to
the file object without someone issuing a read against that file object

  • I’ve certainly never seen such a case, and I’m having a tough time
    envisioning how this could arise during normal usage.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 7:59 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

First of all I was not talking about other filters. Even in case where
there is only one filter and an FSD itself there’s a posibility of
created stream file object to have ref count > 2.

I don’t think that using IoCreateStreamFileObject will cause any
problem.
According to IFS docs, filters might expect to receive IRP_MJ_CLEANUP
requests for previously unseen file objects. According to FastFat and
CDFS sources, file system ignores (completes with STATUS_SUCCESS)
IRP_MJ_CLEANUP requests for unopened file objects. When we send
IRP_MJ_CLEANUP request after create request completed, file system
decodes the file object successfuly and performs all necessary actions.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
As I have previously mentioned in this forum (and documented on
OSRONLINE), ANY filter that uses a file object passed to it in the
IRP_MJ_CREATE handler is unstable/unreliable for a number of reasons.
So pointing out that some other filter might be using the file object
you pass down is really immaterial, since they are already broken, even
without your filter installed.

But even if we take Alexey’s concern into account, it argues for sending
down the IRP_MJ_CLEANUP - but we can’t do that until after the
IRP_MJ_CREATE has been sent to the underlying file system, so we can’t
use IoCreateStreamFileObject to do it for us. Thus, an alternative here
would be to create the new stream file object, pass that (via
IRP_MJ_CREATE) to the underlying FSD, perform an IRP_MJ_CLEANUP on the
file object, and then dereference the file object. If there are no
other references to the file object, the IRP_MJ_CLOSE will be generated
and the close processing proceeds. Otherwise, you have a file object
that is in the “between CLEANUP and CLOSE” state (in other words, paging
I/O operations allowed but nothing else.)

Of course, the complexity of all of this underscores the reason we have
so many interesting interop issues.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 4:19 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

I’m not sure if IoCancelFileOpen is safe to use in this case. File
object may be referenced by several parties (like Mm, Vm, and filter
itself) making ref count > 2. OP noticed that some complex checks may be
performed on stream file objects (like AV checks) which would initialize
caching on the file object.

In this case, I would use IoCreateStreamFileObjectLite (or
IoCreateStreamFileObject on NT4; lite version just makes things a lil
bit cleaner and faster) and after I’m done, send IRP_MJ_CLEANUP manually
(don’t forget to put FO_HANDLE_CREATED flag before that) and dereference
stream

file object.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
Ladislav,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object) which is why you would want
IoCreateStreamFileObjectLite (which does not set this bit).

I believe the best choice is to use IoCreateStreamFileObjectLite and
then IoCancelFileOpen when you are done. I haven’t done this in a long
time (read: before IoCancelFileOpen was added as an API) so it is
possible that there is some subtle interaction that I’m missing here.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 6:15 AM
To: ntfsd redirect
Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

Tony,

thank you for the response.

> If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within IRP_MJ_CREATE
handler is a thing which does not seem well to me.

> In all fairness, I am not sure how you are creating your stream file
> object, so I don’t even know where the I/O Manager is sending
your
> IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

> I believe that - if you use IoCreateStreamFileObjectLite
> - you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects with
FO_HANDLE_CREATED flag set ?

L.


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

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


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

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


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

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

This is an excerpt from original post:

“During IRP_MJ_CREATE, I need to open file, make some checks and eventually
deny the create request (Imagine
it is an antivirus).”

I can hardly imagine AV activity without utilizing Cc/Vm services. That’s
what I held in my mind. Sorry for any confusion introduced from my side.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
You will have to explain to me how Mm or Cc can obtain a reference to
the file object without someone issuing a read against that file object
- I’ve certainly never seen such a case, and I’m having a tough time
envisioning how this could arise during normal usage.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 7:59 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

First of all I was not talking about other filters. Even in case where
there is only one filter and an FSD itself there’s a posibility of
created stream file object to have ref count > 2.

I don’t think that using IoCreateStreamFileObject will cause any
problem.
According to IFS docs, filters might expect to receive IRP_MJ_CLEANUP
requests for previously unseen file objects. According to FastFat and
CDFS sources, file system ignores (completes with STATUS_SUCCESS)
IRP_MJ_CLEANUP requests for unopened file objects. When we send
IRP_MJ_CLEANUP request after create request completed, file system
decodes the file object successfuly and performs all necessary actions.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
As I have previously mentioned in this forum (and documented on
OSRONLINE), ANY filter that uses a file object passed to it in the
IRP_MJ_CREATE handler is unstable/unreliable for a number of reasons.
So pointing out that some other filter might be using the file object
you pass down is really immaterial, since they are already broken, even
without your filter installed.

But even if we take Alexey’s concern into account, it argues for sending
down the IRP_MJ_CLEANUP - but we can’t do that until after the
IRP_MJ_CREATE has been sent to the underlying file system, so we can’t
use IoCreateStreamFileObject to do it for us. Thus, an alternative here
would be to create the new stream file object, pass that (via
IRP_MJ_CREATE) to the underlying FSD, perform an IRP_MJ_CLEANUP on the
file object, and then dereference the file object. If there are no
other references to the file object, the IRP_MJ_CLOSE will be generated
and the close processing proceeds. Otherwise, you have a file object
that is in the “between CLEANUP and CLOSE” state (in other words, paging
I/O operations allowed but nothing else.)

Of course, the complexity of all of this underscores the reason we have
so many interesting interop issues.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 4:19 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

I’m not sure if IoCancelFileOpen is safe to use in this case. File
object may be referenced by several parties (like Mm, Vm, and filter
itself) making ref count > 2. OP noticed that some complex checks may be
performed on stream file objects (like AV checks) which would initialize
caching on the file object.

In this case, I would use IoCreateStreamFileObjectLite (or
IoCreateStreamFileObject on NT4; lite version just makes things a lil
bit cleaner and faster) and after I’m done, send IRP_MJ_CLEANUP manually
(don’t forget to put FO_HANDLE_CREATED flag before that) and dereference
stream

file object.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
Ladislav,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object) which is why you would want
IoCreateStreamFileObjectLite (which does not set this bit).

I believe the best choice is to use IoCreateStreamFileObjectLite and
then IoCancelFileOpen when you are done. I haven’t done this in a long
time (read: before IoCancelFileOpen was added as an API) so it is
possible that there is some subtle interaction that I’m missing here.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 6:15 AM
To: ntfsd redirect
Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

Tony,

thank you for the response.

> If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within IRP_MJ_CREATE
handler is a thing which does not seem well to me.

> In all fairness, I am not sure how you are creating your stream file
> object, so I don’t even know where the I/O Manager is sending
your
> IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

> I believe that - if you use IoCreateStreamFileObjectLite
> - you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects with
FO_HANDLE_CREATED flag set ?

L.


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

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


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

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


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

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

Alexy,

Good point - we’d moved far enough away from the original query that I
had missed that detail.

That suggests that if the filter is going to perform cached I/O against
the file, they need to send the IRP_MJ_CLEANUP and then rely upon the
ObDereferenceObject mechanism to “do the right thing”.

I’d be more inclined to do this using non-cached I/O in any case (if I
were writing an A/V filter, I wouldn’t want to potentially pollute the
cache with a potential virus.)

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 10:21 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

This is an excerpt from original post:

“During IRP_MJ_CREATE, I need to open file, make some checks and
eventually
deny the create request (Imagine
it is an antivirus).”

I can hardly imagine AV activity without utilizing Cc/Vm services.
That’s
what I held in my mind. Sorry for any confusion introduced from my side.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
You will have to explain to me how Mm or Cc can obtain a reference to
the file object without someone issuing a read against that file object
- I’ve certainly never seen such a case, and I’m having a tough time
envisioning how this could arise during normal usage.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 7:59 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

First of all I was not talking about other filters. Even in case where
there is only one filter and an FSD itself there’s a posibility of
created stream file object to have ref count > 2.

I don’t think that using IoCreateStreamFileObject will cause any
problem.
According to IFS docs, filters might expect to receive IRP_MJ_CLEANUP
requests for previously unseen file objects. According to FastFat and
CDFS sources, file system ignores (completes with STATUS_SUCCESS)
IRP_MJ_CLEANUP requests for unopened file objects. When we send
IRP_MJ_CLEANUP request after create request completed, file system
decodes the file object successfuly and performs all necessary actions.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
As I have previously mentioned in this forum (and documented on
OSRONLINE), ANY filter that uses a file object passed to it in the
IRP_MJ_CREATE handler is unstable/unreliable for a number of reasons.
So pointing out that some other filter might be using the file object
you pass down is really immaterial, since they are already broken, even
without your filter installed.

But even if we take Alexey’s concern into account, it argues for sending
down the IRP_MJ_CLEANUP - but we can’t do that until after the
IRP_MJ_CREATE has been sent to the underlying file system, so we can’t
use IoCreateStreamFileObject to do it for us. Thus, an alternative here
would be to create the new stream file object, pass that (via
IRP_MJ_CREATE) to the underlying FSD, perform an IRP_MJ_CLEANUP on the
file object, and then dereference the file object. If there are no
other references to the file object, the IRP_MJ_CLOSE will be generated
and the close processing proceeds. Otherwise, you have a file object
that is in the “between CLEANUP and CLOSE” state (in other words, paging
I/O operations allowed but nothing else.)

Of course, the complexity of all of this underscores the reason we have
so many interesting interop issues.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, May 10, 2004 4:19 PM
To: ntfsd redirect
Subject: Re:[ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

I’m not sure if IoCancelFileOpen is safe to use in this case. File
object may be referenced by several parties (like Mm, Vm, and filter
itself) making ref count > 2. OP noticed that some complex checks may be
performed on stream file objects (like AV checks) which would initialize
caching on the file object.

In this case, I would use IoCreateStreamFileObjectLite (or
IoCreateStreamFileObject on NT4; lite version just makes things a lil
bit cleaner and faster) and after I’m done, send IRP_MJ_CLEANUP manually
(don’t forget to put FO_HANDLE_CREATED flag before that) and dereference
stream

file object.

–htfv

“Tony Mason” wrote in message news:xxxxx@ntfsd…
Ladislav,

IoCancelFileOpen should not be used with files that have handles (the
code bug checks if the reference count is > 2 or if FO_HANDLE_CREATED is
set in the File Object) which is why you would want
IoCreateStreamFileObjectLite (which does not set this bit).

I believe the best choice is to use IoCreateStreamFileObjectLite and
then IoCancelFileOpen when you are done. I haven’t done this in a long
time (read: before IoCancelFileOpen was added as an API) so it is
possible that there is some subtle interaction that I’m missing here.

Regards,

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Ladislav Zezula
Sent: Monday, May 10, 2004 6:15 AM
To: ntfsd redirect
Subject: Re: [ntfsd] IoCreateStreamFileObjectLite sets FO_HANDLE_CREATED
?

Tony,

thank you for the response.

> If you want to obtain the handle, use IoCreateStreamFileObjectEx.

No, this is what I want to avoid. Calling ZwClose within IRP_MJ_CREATE
handler is a thing which does not seem well to me.

> In all fairness, I am not sure how you are creating your stream file
> object, so I don’t even know where the I/O Manager is sending
your
> IRP_MJ_CLEANUP.)

The file object is simply created by calling IoCreateStreamFileObject.
As the source, the file object from the create IRP is used.
I tried also the “Lite” version.

> I believe that - if you use IoCreateStreamFileObjectLite
> - you can just use IoCancelFileOpen.

I’m not sure where I’ve heard that, but - is it TRUE that
IoCancelFileOpen should not be used on file objects with
FO_HANDLE_CREATED flag set ?

L.


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

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


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

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


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

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


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

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

> I’d be more inclined to do this using non-cached I/O in any case (if I

were writing an A/V filter, I wouldn’t want to potentially pollute the
cache with a potential virus.)

Hmm, interesting point. Never thought about it. But reimplementing cache
might not be an easy task. And besides, we’re gonna need the contents of the
file in memory at some point, anyways.

–htfv

Hi, all

Thank for you oppinions. Here some my notes to your
advices

If you want to check the data in file, I recommend the caching method or
ZwCreateFile & ZwReadFile mothod.

I’m not sure I understand you. Not because I don’t know
what these functions do, but because using ZwCreateFile,
ZwReadFile (or ZwNearlyAnythingElseExceptZwClose :-))
will cause a recursion problems with upper filters.
I think this method cannot be used.

I can hardly imagine AV activity without utilizing Cc/Vm services. That’s
what I held in my mind. Sorry for any confusion introduced from my side.

I apologize for that, I’ve forgot to write that the checks (which I’ve told
about)
will include one *non-cached* read, which is an important detail
for the question.

ANY filter that uses a file object passed to it in the
IRP_MJ_CREATE handler is unstable/unreliable for a number of reasons.

This is one thing I’m taking into account. The logic expects that no filter
below me uses the file object for cache read. I think because this
is documented enough, I can assume it.

Well, now the conclusion.

I choose the following algorithm:

  1. Create the file object using IoCreateStreamFileObjectLite.
    I assume the filter will not run on WinNT 4.0, so functions like
    IoCancelFileOpen and the Lite version of stream object creation
    function is OK.

  2. I allocate the buffer for the file name, using lookaside list
    in non-paged pool. This is not because I want to change the name,
    but because sometimes NTFS upcases the file name when the open
    is unsuccessful (Although I don’t see any reason for it).

  3. Setup the next IRP stack location in the original IRP.
    Change the request to FILE_OPEN with FILE_READ_DATA
    and set the completion routine which will pause the IRP completion.

  4. Send the request down

  5. If the create operation succeeded, and the file is not actually a
    directory,
    *clear the FO_HANDLE_CREATED*

  6. Do any checks (incluse one non-cached read)

  7. Delete the file name from the stream file object and zero
    the entire UNICODE_STRING within file object.
    This will prevent system from deleting the file name
    using ExFreePool.

  8. Dereference the file object. Because I cleared the
    FO_HANDLE_CREATED, the ObDereferenceObject
    will call IRP_MJ_CLEANUP, which closes the file.

  9. Restore the complete IRP and send the create request
    down (of course, only if I haven’t decided I’ll deny the request).

Maybe something will change after some more thorough tests,
but at first sight, the approach should work.

L.