Implementing IoCancelFileOpen

I implement the following scenario in my FSFD:

  1. In IRP_MJ_CREATE completion routine I check if file was opened
    successfuly.
  2. If it was I read contents of file using custom-rolled IRPs.
  3. After first IRP_MJ_READ request file object reference counter increases
    by 2 (Cc I guess).
  4. At some point I may decide that I want to deny access to the file.

The question is how do I cancel file open? I send IRP_MJ_CLEANUP and
IRP_MJ_CLOSE. But reference counter stays 1 after I return
STATUS_ACCESS_DENIED to IO Manager. This causes delete requests on file to
fail. Actually this happens even if I allowed file to be created
successfuly. What’s wrong in this situation.

And one more question. Why do I have to send IRP_MJ_CLOSE. Doesn’t
dereferencing file object to 0 cause IRP_MJ_CLOSE to be sent?

My driver also issues an IRP_MJ_READ during its create processing (for
some files), but I don’t see the refcount on the file object changing
because of that. If you issue non-paging I/O instead of paging I/O, then
yes, I suppose Cc may grab a reference to the file object, which is
expected behavior. Solution is always use paging I/O during the create
handler if you intend on using IoCancelFileOpen.

  • Nicholas Ryan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Friday, November 01, 2002 1:52 AM
To: File Systems Developers
Subject: [ntfsd] Implementing IoCancelFileOpen

I implement the following scenario in my FSFD:

  1. In IRP_MJ_CREATE completion routine I check if file was
    opened successfuly. 2. If it was I read contents of file
    using custom-rolled IRPs. 3. After first IRP_MJ_READ request
    file object reference counter increases by 2 (Cc I guess). 4.
    At some point I may decide that I want to deny access to the file.

The question is how do I cancel file open? I send
IRP_MJ_CLEANUP and IRP_MJ_CLOSE. But reference counter stays
1 after I return STATUS_ACCESS_DENIED to IO Manager. This
causes delete requests on file to fail. Actually this happens
even if I allowed file to be created successfuly. What’s
wrong in this situation.

And one more question. Why do I have to send IRP_MJ_CLOSE.
Doesn’t dereferencing file object to 0 cause IRP_MJ_CLOSE to be sent?


You are currently subscribed to ntfsd as: xxxxx@nryan.com
To unsubscribe send a blank email to %%email.unsub%%

Using paging IO is not effective. The work with the file is pretty massive.
I do need Cc functionality. I just want to know how to approach the
behaviour correctly.

And what about my last question (the one about IRP_MJ_CLOSE request)?

----- Original Message -----
From: “Nicholas Ryan”
To: “File Systems Developers”
Sent: Friday, November 01, 2002 9:26 PM
Subject: [ntfsd] RE: Implementing IoCancelFileOpen

> My driver also issues an IRP_MJ_READ during its create processing (for
> some files), but I don’t see the refcount on the file object changing
> because of that. If you issue non-paging I/O instead of paging I/O, then
> yes, I suppose Cc may grab a reference to the file object, which is
> expected behavior. Solution is always use paging I/O during the create
> handler if you intend on using IoCancelFileOpen.
>
> - Nicholas Ryan
>
>
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
> > Sent: Friday, November 01, 2002 1:52 AM
> > To: File Systems Developers
> > Subject: [ntfsd] Implementing IoCancelFileOpen
> >
> >
> > I implement the following scenario in my FSFD:
> > 1. In IRP_MJ_CREATE completion routine I check if file was
> > opened successfuly. 2. If it was I read contents of file
> > using custom-rolled IRPs. 3. After first IRP_MJ_READ request
> > file object reference counter increases by 2 (Cc I guess). 4.
> > At some point I may decide that I want to deny access to the file.
> >
> > The question is how do I cancel file open? I send
> > IRP_MJ_CLEANUP and IRP_MJ_CLOSE. But reference counter stays
> > 1 after I return STATUS_ACCESS_DENIED to IO Manager. This
> > causes delete requests on file to fail. Actually this happens
> > even if I allowed file to be created successfuly. What’s
> > wrong in this situation.
> >
> > And one more question. Why do I have to send IRP_MJ_CLOSE.
> > Doesn’t dereferencing file object to 0 cause IRP_MJ_CLOSE to be sent?
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@nryan.com
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> To unsubscribe send a blank email to %%email.unsub%%
>

Yes, dereferencing the file object to 0 will cause a close operation on
the file object, AS LONG AS FileObject->DeviceObject is set to non-NULL
before ObfDereferenceObject is called. If you fail an open request,
Windows will clear FileObject->DeviceObject then call
ObfDereferenceObject, which guarantees that no close will be sent. This
makes sense, since if the open failed, then no close need be generated.
This is why IoCancelOpen must send down the close in addition to the
cleanup (because nobody else is going to do it).

If you are doing something that causes the file object refcount to be >
1 after an IoCancelOpen, and you fail the create, then you have a bug.
The system will assume the file object can be trashed, and will zero out
FileObject->DeviceObject and then dereference it. (It will also
dereference FileObject->Vpb, which means the underlying volume may
disappear out from under you). If other entities still have references
to this stale file object (like Cc), things will start to go downhill
really fast.

  • Nicholas Ryan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Friday, November 01, 2002 1:42 PM
To: File Systems Developers
Subject: [ntfsd] RE: Implementing IoCancelFileOpen

Using paging IO is not effective. The work with the file is
pretty massive. I do need Cc functionality. I just want to
know how to approach the behaviour correctly.

And what about my last question (the one about IRP_MJ_CLOSE request)?

----- Original Message -----
From: “Nicholas Ryan”
> To: “File Systems Developers”
> Sent: Friday, November 01, 2002 9:26 PM
> Subject: [ntfsd] RE: Implementing IoCancelFileOpen
>
>
> > My driver also issues an IRP_MJ_READ during its create
> processing (for
> > some files), but I don’t see the refcount on the file
> object changing
> > because of that. If you issue non-paging I/O instead of paging I/O,
> > then yes, I suppose Cc may grab a reference to the file
> object, which
> > is expected behavior. Solution is always use paging I/O during the
> > create handler if you intend on using IoCancelFileOpen.
> >
> > - Nicholas Ryan
> >
> >
> >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > Logachyov
> > > Sent: Friday, November 01, 2002 1:52 AM
> > > To: File Systems Developers
> > > Subject: [ntfsd] Implementing IoCancelFileOpen
> > >
> > >
> > > I implement the following scenario in my FSFD:
> > > 1. In IRP_MJ_CREATE completion routine I check if file was opened
> > > successfuly. 2. If it was I read contents of file using
> > > custom-rolled IRPs. 3. After first IRP_MJ_READ request
> file object
> > > reference counter increases by 2 (Cc I guess). 4. At some point I
> > > may decide that I want to deny access to the file.
> > >
> > > The question is how do I cancel file open? I send
> IRP_MJ_CLEANUP and
> > > IRP_MJ_CLOSE. But reference counter stays 1 after I return
> > > STATUS_ACCESS_DENIED to IO Manager. This causes delete
> requests on
> > > file to fail. Actually this happens even if I allowed file to be
> > > created successfuly. What’s wrong in this situation.
> > >
> > > And one more question. Why do I have to send
> IRP_MJ_CLOSE. Doesn’t
> > > dereferencing file object to 0 cause IRP_MJ_CLOSE to be sent?
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@nryan.com
> To unsubscribe send a blank email to %%email.unsub%%
>

And what about IRP_MJ_CLEANUP? Will it be sent on dereferencing file object
to 0? What if I fail to send it before IRP_MJ_CLOSE?

----- Original Message -----
From: “Nicholas Ryan”
To: “File Systems Developers”
Sent: Saturday, November 02, 2002 2:40 AM
Subject: [ntfsd] RE: Implementing IoCancelFileOpen

> Yes, dereferencing the file object to 0 will cause a close operation on
> the file object, AS LONG AS FileObject->DeviceObject is set to non-NULL
> before ObfDereferenceObject is called. If you fail an open request,
> Windows will clear FileObject->DeviceObject then call
> ObfDereferenceObject, which guarantees that no close will be sent. This
> makes sense, since if the open failed, then no close need be generated.
> This is why IoCancelOpen must send down the close in addition to the
> cleanup (because nobody else is going to do it).
>
> If you are doing something that causes the file object refcount to be >
> 1 after an IoCancelOpen, and you fail the create, then you have a bug.
> The system will assume the file object can be trashed, and will zero out
> FileObject->DeviceObject and then dereference it. (It will also
> dereference FileObject->Vpb, which means the underlying volume may
> disappear out from under you). If other entities still have references
> to this stale file object (like Cc), things will start to go downhill
> really fast.
>
> - Nicholas Ryan
>
>
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
> > Sent: Friday, November 01, 2002 1:42 PM
> > To: File Systems Developers
> > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> >
> >
> > Using paging IO is not effective. The work with the file is
> > pretty massive. I do need Cc functionality. I just want to
> > know how to approach the behaviour correctly.
> >
> > And what about my last question (the one about IRP_MJ_CLOSE request)?
> >
> >
> > ----- Original Message -----
> > From: “Nicholas Ryan”
> > To: “File Systems Developers”
> > Sent: Friday, November 01, 2002 9:26 PM
> > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> >
> >
> > > My driver also issues an IRP_MJ_READ during its create
> > processing (for
> > > some files), but I don’t see the refcount on the file
> > object changing
> > > because of that. If you issue non-paging I/O instead of paging I/O,
> > > then yes, I suppose Cc may grab a reference to the file
> > object, which
> > > is expected behavior. Solution is always use paging I/O during the
> > > create handler if you intend on using IoCancelFileOpen.
> > >
> > > - Nicholas Ryan
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: xxxxx@lists.osr.com
> > > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > > Logachyov
> > > > Sent: Friday, November 01, 2002 1:52 AM
> > > > To: File Systems Developers
> > > > Subject: [ntfsd] Implementing IoCancelFileOpen
> > > >
> > > >
> > > > I implement the following scenario in my FSFD:
> > > > 1. In IRP_MJ_CREATE completion routine I check if file was opened
> > > > successfuly. 2. If it was I read contents of file using
> > > > custom-rolled IRPs. 3. After first IRP_MJ_READ request
> > file object
> > > > reference counter increases by 2 (Cc I guess). 4. At some point I
> > > > may decide that I want to deny access to the file.
> > > >
> > > > The question is how do I cancel file open? I send
> > IRP_MJ_CLEANUP and
> > > > IRP_MJ_CLOSE. But reference counter stays 1 after I return
> > > > STATUS_ACCESS_DENIED to IO Manager. This causes delete
> > requests on
> > > > file to fail. Actually this happens even if I allowed file to be
> > > > created successfuly. What’s wrong in this situation.
> > > >
> > > > And one more question. Why do I have to send
> > IRP_MJ_CLOSE. Doesn’t
> > > > dereferencing file object to 0 cause IRP_MJ_CLOSE to be sent?
> > > >
> > > >
> > > >
> > > >
> > > > —
> > > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > > unsubscribe send a blank email to %%email.unsub%%
> > > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@nryan.com
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> To unsubscribe send a blank email to %%email.unsub%%
>

Cleanup isn’t sent automatically. Cleanup is sent for a different
purpose, when all USER HANDLES to a file object are closed. This is the
handle the requestor receives from ZwCreateFile, etc. Each handle refers
to a single file object. When the user closes all handles to a given
file object (handles can be duplicated), a cleanup is sent.

The reason close is separate from cleanup is because entities like the
cache manager can keep the file object ‘alive’ long after all user
handles are gone by upping the refcount with ObReferenceObject. Once the
refcount goes to 0, THEN the close is sent. The reason you need to send
cleanup as well as close with IoCancelFileOpen is because IRP_MJ_CREATE
properly represents the creation of a user handle to the file (this is
why the stream file object apis, which create file objects but not
handles, don’t sent down IRP_MJ_CREATES). Since you are canceling the
creation of this handle, you need to signal that the handle is going
away (cleanup) and the file object is going away (close).

(Most of this is in the OSR faq, item Q55.)

  • Nicholas Ryan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, November 04, 2002 1:47 AM
To: File Systems Developers
Subject: [ntfsd] RE: Implementing IoCancelFileOpen

And what about IRP_MJ_CLEANUP? Will it be sent on
dereferencing file object to 0? What if I fail to send it
before IRP_MJ_CLOSE?

----- Original Message -----
From: “Nicholas Ryan”
> To: “File Systems Developers”
> Sent: Saturday, November 02, 2002 2:40 AM
> Subject: [ntfsd] RE: Implementing IoCancelFileOpen
>
>
> > Yes, dereferencing the file object to 0 will cause a close
> operation
> > on the file object, AS LONG AS FileObject->DeviceObject is set to
> > non-NULL before ObfDereferenceObject is called. If you fail an open
> > request, Windows will clear FileObject->DeviceObject then call
> > ObfDereferenceObject, which guarantees that no close will be sent.
> > This makes sense, since if the open failed, then no close need be
> > generated. This is why IoCancelOpen must send down the close in
> > addition to the cleanup (because nobody else is going to do it).
> >
> > If you are doing something that causes the file object
> refcount to be
> > > 1 after an IoCancelOpen, and you fail the create, then you have a
> > bug. The system will assume the file object can be trashed,
> and will
> > zero out
> > FileObject->DeviceObject and then dereference it. (It will also
> > dereference FileObject->Vpb, which means the underlying volume may
> > disappear out from under you). If other entities still have
> references
> > to this stale file object (like Cc), things will start to
> go downhill
> > really fast.
> >
> > - Nicholas Ryan
> >
> >
> >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > Logachyov
> > > Sent: Friday, November 01, 2002 1:42 PM
> > > To: File Systems Developers
> > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > >
> > >
> > > Using paging IO is not effective. The work with the file
> is pretty
> > > massive. I do need Cc functionality. I just want to know how to
> > > approach the behaviour correctly.
> > >
> > > And what about my last question (the one about IRP_MJ_CLOSE
> > > request)?
> > >
> > >
> > > ----- Original Message -----
> > > From: “Nicholas Ryan”
> > > To: “File Systems Developers”
> > > Sent: Friday, November 01, 2002 9:26 PM
> > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > >
> > >
> > > > My driver also issues an IRP_MJ_READ during its create
> > > processing (for
> > > > some files), but I don’t see the refcount on the file
> > > object changing
> > > > because of that. If you issue non-paging I/O instead of paging
> > > > I/O, then yes, I suppose Cc may grab a reference to the file
> > > object, which
> > > > is expected behavior. Solution is always use paging I/O
> during the
> > > > create handler if you intend on using IoCancelFileOpen.
> > > >
> > > > - Nicholas Ryan
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: xxxxx@lists.osr.com
> > > > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > > > Logachyov
> > > > > Sent: Friday, November 01, 2002 1:52 AM
> > > > > To: File Systems Developers
> > > > > Subject: [ntfsd] Implementing IoCancelFileOpen
> > > > >
> > > > >
> > > > > I implement the following scenario in my FSFD:
> > > > > 1. In IRP_MJ_CREATE completion routine I check if file was
> > > > > opened successfuly. 2. If it was I read contents of
> file using
> > > > > custom-rolled IRPs. 3. After first IRP_MJ_READ request
> > > file object
> > > > > reference counter increases by 2 (Cc I guess). 4. At
> some point
> > > > > I may decide that I want to deny access to the file.
> > > > >
> > > > > The question is how do I cancel file open? I send
> > > IRP_MJ_CLEANUP and
> > > > > IRP_MJ_CLOSE. But reference counter stays 1 after I return
> > > > > STATUS_ACCESS_DENIED to IO Manager. This causes delete
> > > requests on
> > > > > file to fail. Actually this happens even if I allowed
> file to be
> > > > > created successfuly. What’s wrong in this situation.
> > > > >
> > > > > And one more question. Why do I have to send
> > > IRP_MJ_CLOSE. Doesn’t
> > > > > dereferencing file object to 0 cause IRP_MJ_CLOSE to be sent?
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > —
> > > > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > >
> > > >
> > > >
> > > >
> > > > —
> > > > You are currently subscribed to ntfsd as: xxxxx@vba.com.by To
> > > > unsubscribe send a blank email to %%email.unsub%%
> > > >
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@nryan.com
> To unsubscribe send a blank email to %%email.unsub%%
>

How Cc finds all file objects which represent the same on-disk stream. I
mean, when stream is opened several times the same number of file objects is
created. They all have the same FCB header and share the same cache. Imagine
now that all handles are closed but Cc still has references to file objects
(or just one file object for which Cc was initialized first?). When this
stream opened with DELETE access and FileDispositionInformation is sent do
FSD how Cc is teared down?

----- Original Message -----
From: “Nicholas Ryan”
To: “File Systems Developers”
Sent: Monday, November 04, 2002 7:22 PM
Subject: [ntfsd] RE: Implementing IoCancelFileOpen

> Cleanup isn’t sent automatically. Cleanup is sent for a different
> purpose, when all USER HANDLES to a file object are closed. This is the
> handle the requestor receives from ZwCreateFile, etc. Each handle refers
> to a single file object. When the user closes all handles to a given
> file object (handles can be duplicated), a cleanup is sent.
>
> The reason close is separate from cleanup is because entities like the
> cache manager can keep the file object ‘alive’ long after all user
> handles are gone by upping the refcount with ObReferenceObject. Once the
> refcount goes to 0, THEN the close is sent. The reason you need to send
> cleanup as well as close with IoCancelFileOpen is because IRP_MJ_CREATE
> properly represents the creation of a user handle to the file (this is
> why the stream file object apis, which create file objects but not
> handles, don’t sent down IRP_MJ_CREATES). Since you are canceling the
> creation of this handle, you need to signal that the handle is going
> away (cleanup) and the file object is going away (close).
>
> (Most of this is in the OSR faq, item Q55.)
>
> - Nicholas Ryan
>
>
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
> > Sent: Monday, November 04, 2002 1:47 AM
> > To: File Systems Developers
> > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> >
> >
> > And what about IRP_MJ_CLEANUP? Will it be sent on
> > dereferencing file object to 0? What if I fail to send it
> > before IRP_MJ_CLOSE?
> >
> >
> > ----- Original Message -----
> > From: “Nicholas Ryan”
> > To: “File Systems Developers”
> > Sent: Saturday, November 02, 2002 2:40 AM
> > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> >
> >
> > > Yes, dereferencing the file object to 0 will cause a close
> > operation
> > > on the file object, AS LONG AS FileObject->DeviceObject is set to
> > > non-NULL before ObfDereferenceObject is called. If you fail an open
> > > request, Windows will clear FileObject->DeviceObject then call
> > > ObfDereferenceObject, which guarantees that no close will be sent.
> > > This makes sense, since if the open failed, then no close need be
> > > generated. This is why IoCancelOpen must send down the close in
> > > addition to the cleanup (because nobody else is going to do it).
> > >
> > > If you are doing something that causes the file object
> > refcount to be
> > > > 1 after an IoCancelOpen, and you fail the create, then you have a
> > > bug. The system will assume the file object can be trashed,
> > and will
> > > zero out
> > > FileObject->DeviceObject and then dereference it. (It will also
> > > dereference FileObject->Vpb, which means the underlying volume may
> > > disappear out from under you). If other entities still have
> > references
> > > to this stale file object (like Cc), things will start to
> > go downhill
> > > really fast.
> > >
> > > - Nicholas Ryan
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: xxxxx@lists.osr.com
> > > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > > Logachyov
> > > > Sent: Friday, November 01, 2002 1:42 PM
> > > > To: File Systems Developers
> > > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > > >
> > > >
> > > > Using paging IO is not effective. The work with the file
> > is pretty
> > > > massive. I do need Cc functionality. I just want to know how to
> > > > approach the behaviour correctly.
> > > >
> > > > And what about my last question (the one about IRP_MJ_CLOSE
> > > > request)?
> > > >
> > > >
> > > > ----- Original Message -----
> > > > From: “Nicholas Ryan”
> > > > To: “File Systems Developers”
> > > > Sent: Friday, November 01, 2002 9:26 PM
> > > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > > >
> > > >
> > > > > My driver also issues an IRP_MJ_READ during its create
> > > > processing (for
> > > > > some files), but I don’t see the refcount on the file
> > > > object changing
> > > > > because of that. If you issue non-paging I/O instead of paging
> > > > > I/O, then yes, I suppose Cc may grab a reference to the file
> > > > object, which
> > > > > is expected behavior. Solution is always use paging I/O
> > during the
> > > > > create handler if you intend on using IoCancelFileOpen.
> > > > >
> > > > > - Nicholas Ryan
> > > > >
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: xxxxx@lists.osr.com
> > > > > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > > > > Logachyov
> > > > > > Sent: Friday, November 01, 2002 1:52 AM
> > > > > > To: File Systems Developers
> > > > > > Subject: [ntfsd] Implementing IoCancelFileOpen
> > > > > >
> > > > > >
> > > > > > I implement the following scenario in my FSFD:
> > > > > > 1. In IRP_MJ_CREATE completion routine I check if file was
> > > > > > opened successfuly. 2. If it was I read contents of
> > file using
> > > > > > custom-rolled IRPs. 3. After first IRP_MJ_READ request
> > > > file object
> > > > > > reference counter increases by 2 (Cc I guess). 4. At
> > some point
> > > > > > I may decide that I want to deny access to the file.
> > > > > >
> > > > > > The question is how do I cancel file open? I send
> > > > IRP_MJ_CLEANUP and
> > > > > > IRP_MJ_CLOSE. But reference counter stays 1 after I return
> > > > > > STATUS_ACCESS_DENIED to IO Manager. This causes delete
> > > > requests on
> > > > > > file to fail. Actually this happens even if I allowed
> > file to be
> > > > > > created successfuly. What’s wrong in this situation.
> > > > > >
> > > > > > And one more question. Why do I have to send
> > > > IRP_MJ_CLOSE. Doesn’t
> > > > > > dereferencing file object to 0 cause IRP_MJ_CLOSE to be sent?
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > —
> > > > > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > > —
> > > > > You are currently subscribed to ntfsd as: xxxxx@vba.com.by To
> > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > >
> > > >
> > > >
> > > >
> > > >
> > > > —
> > > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > > unsubscribe send a blank email to %%email.unsub%%
> > > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@nryan.com
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> To unsubscribe send a blank email to %%email.unsub%%
>

Cc just needs a reference to a single file object for a given stream. I
suppose this usually turns out to be the first cached file object
opened.

Caching for a given file object is torn down when the filesystem calls
CcUnintializeCacheMap in its cleanup handler.

I don’t think the fact that the file is marked for delete affects Cc’s
behavior in any way. As far as I can tell, Cc is never told (although
perhaps it may look at FileObject->DeletePending at some point). Note
that FastFat sets Fcb->Header.FileSize to 0 in its cleanup handler if
the file is marked for delete. If then Cc decides to issue any more
paging reads/writes, the requests will be failed/eaten as appropriate
for paging I/O that starts beyond EOF.

  • Nicholas Ryan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alexey Logachyov
Sent: Monday, November 04, 2002 1:50 PM
To: File Systems Developers
Subject: [ntfsd] RE: Implementing IoCancelFileOpen

How Cc finds all file objects which represent the same
on-disk stream. I mean, when stream is opened several times
the same number of file objects is created. They all have the
same FCB header and share the same cache. Imagine now that
all handles are closed but Cc still has references to file
objects (or just one file object for which Cc was initialized
first?). When this stream opened with DELETE access and
FileDispositionInformation is sent do FSD how Cc is teared down?

----- Original Message -----
From: “Nicholas Ryan”
> To: “File Systems Developers”
> Sent: Monday, November 04, 2002 7:22 PM
> Subject: [ntfsd] RE: Implementing IoCancelFileOpen
>
>
> > Cleanup isn’t sent automatically. Cleanup is sent for a different
> > purpose, when all USER HANDLES to a file object are closed. This is
> > the handle the requestor receives from ZwCreateFile, etc.
> Each handle
> > refers to a single file object. When the user closes all
> handles to a
> > given file object (handles can be duplicated), a cleanup is sent.
> >
> > The reason close is separate from cleanup is because
> entities like the
> > cache manager can keep the file object ‘alive’ long after all user
> > handles are gone by upping the refcount with
> ObReferenceObject. Once
> > the refcount goes to 0, THEN the close is sent. The reason
> you need to
> > send cleanup as well as close with IoCancelFileOpen is because
> > IRP_MJ_CREATE properly represents the creation of a user
> handle to the
> > file (this is why the stream file object apis, which create file
> > objects but not handles, don’t sent down IRP_MJ_CREATES). Since you
> > are canceling the creation of this handle, you need to
> signal that the
> > handle is going away (cleanup) and the file object is going away
> > (close).
> >
> > (Most of this is in the OSR faq, item Q55.)
> >
> > - Nicholas Ryan
> >
> >
> >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > Logachyov
> > > Sent: Monday, November 04, 2002 1:47 AM
> > > To: File Systems Developers
> > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > >
> > >
> > > And what about IRP_MJ_CLEANUP? Will it be sent on
> dereferencing file
> > > object to 0? What if I fail to send it before IRP_MJ_CLOSE?
> > >
> > >
> > > ----- Original Message -----
> > > From: “Nicholas Ryan”
> > > To: “File Systems Developers”
> > > Sent: Saturday, November 02, 2002 2:40 AM
> > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > >
> > >
> > > > Yes, dereferencing the file object to 0 will cause a close
> > > operation
> > > > on the file object, AS LONG AS FileObject->DeviceObject
> is set to
> > > > non-NULL before ObfDereferenceObject is called. If you fail an
> > > > open request, Windows will clear FileObject->DeviceObject then
> > > > call ObfDereferenceObject, which guarantees that no
> close will be
> > > > sent. This makes sense, since if the open failed, then no close
> > > > need be generated. This is why IoCancelOpen must send down the
> > > > close in addition to the cleanup (because nobody else
> is going to
> > > > do it).
> > > >
> > > > If you are doing something that causes the file object
> > > refcount to be
> > > > > 1 after an IoCancelOpen, and you fail the create,
> then you have
> > > > > a
> > > > bug. The system will assume the file object can be trashed,
> > > and will
> > > > zero out
> > > > FileObject->DeviceObject and then dereference it. (It will also
> > > > dereference FileObject->Vpb, which means the underlying
> volume may
> > > > disappear out from under you). If other entities still have
> > > references
> > > > to this stale file object (like Cc), things will start to
> > > go downhill
> > > > really fast.
> > > >
> > > > - Nicholas Ryan
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: xxxxx@lists.osr.com
> > > > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > > > Logachyov
> > > > > Sent: Friday, November 01, 2002 1:42 PM
> > > > > To: File Systems Developers
> > > > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > > > >
> > > > >
> > > > > Using paging IO is not effective. The work with the file
> > > is pretty
> > > > > massive. I do need Cc functionality. I just want to
> know how to
> > > > > approach the behaviour correctly.
> > > > >
> > > > > And what about my last question (the one about IRP_MJ_CLOSE
> > > > > request)?
> > > > >
> > > > >
> > > > > ----- Original Message -----
> > > > > From: “Nicholas Ryan”
> > > > > To: “File Systems Developers”
> > > > > Sent: Friday, November 01, 2002 9:26 PM
> > > > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > > > >
> > > > >
> > > > > > My driver also issues an IRP_MJ_READ during its create
> > > > > processing (for
> > > > > > some files), but I don’t see the refcount on the file
> > > > > object changing
> > > > > > because of that. If you issue non-paging I/O
> instead of paging
> > > > > > I/O, then yes, I suppose Cc may grab a reference to the file
> > > > > object, which
> > > > > > is expected behavior. Solution is always use paging I/O
> > > during the
> > > > > > create handler if you intend on using IoCancelFileOpen.
> > > > > >
> > > > > > - Nicholas Ryan
> > > > > >
> > > > > >
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: xxxxx@lists.osr.com
> > > > > > > [mailto:xxxxx@lists.osr.com] On
> Behalf Of Alexey
> > > > > > > Logachyov
> > > > > > > Sent: Friday, November 01, 2002 1:52 AM
> > > > > > > To: File Systems Developers
> > > > > > > Subject: [ntfsd] Implementing IoCancelFileOpen
> > > > > > >
> > > > > > >
> > > > > > > I implement the following scenario in my FSFD:
> > > > > > > 1. In IRP_MJ_CREATE completion routine I check if
> file was
> > > > > > > opened successfuly. 2. If it was I read contents of
> > > file using
> > > > > > > custom-rolled IRPs. 3. After first IRP_MJ_READ request
> > > > > file object
> > > > > > > reference counter increases by 2 (Cc I guess). 4. At
> > > some point
> > > > > > > I may decide that I want to deny access to the file.
> > > > > > >
> > > > > > > The question is how do I cancel file open? I send
> > > > > IRP_MJ_CLEANUP and
> > > > > > > IRP_MJ_CLOSE. But reference counter stays 1 after
> I return
> > > > > > > STATUS_ACCESS_DENIED to IO Manager. This causes delete
> > > > > requests on
> > > > > > > file to fail. Actually this happens even if I allowed
> > > file to be
> > > > > > > created successfuly. What’s wrong in this situation.
> > > > > > >
> > > > > > > And one more question. Why do I have to send
> > > > > IRP_MJ_CLOSE. Doesn’t
> > > > > > > dereferencing file object to 0 cause IRP_MJ_CLOSE to be
> > > > > > > sent?
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > —
> > > > > > > You are currently subscribed to ntfsd as:
> xxxxx@nryan.com To
> > > > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > —
> > > > > > You are currently subscribed to ntfsd as:
> xxxxx@vba.com.by To
> > > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > —
> > > > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > >
> > > >
> > > >
> > > >
> > > > —
> > > > You are currently subscribed to ntfsd as: xxxxx@vba.com.by To
> > > > unsubscribe send a blank email to %%email.unsub%%
> > > >
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@nryan.com
> To unsubscribe send a blank email to %%email.unsub%%
>

??PurgeCacheSection does this.

----- Original Message -----
From: “Alexey Logachyov”
To: “File Systems Developers”
Sent: Tuesday, November 05, 2002 12:50 AM
Subject: [ntfsd] RE: Implementing IoCancelFileOpen

> How Cc finds all file objects which represent the same on-disk
stream. I
> mean, when stream is opened several times the same number of file
objects is
> created. They all have the same FCB header and share the same cache.
Imagine
> now that all handles are closed but Cc still has references to file
objects
> (or just one file object for which Cc was initialized first?). When
this
> stream opened with DELETE access and FileDispositionInformation is
sent do
> FSD how Cc is teared down?
>
>
>
> ----- Original Message -----
> From: “Nicholas Ryan”
> To: “File Systems Developers”
> Sent: Monday, November 04, 2002 7:22 PM
> Subject: [ntfsd] RE: Implementing IoCancelFileOpen
>
>
> > Cleanup isn’t sent automatically. Cleanup is sent for a different
> > purpose, when all USER HANDLES to a file object are closed. This
is the
> > handle the requestor receives from ZwCreateFile, etc. Each handle
refers
> > to a single file object. When the user closes all handles to a
given
> > file object (handles can be duplicated), a cleanup is sent.
> >
> > The reason close is separate from cleanup is because entities like
the
> > cache manager can keep the file object ‘alive’ long after all user
> > handles are gone by upping the refcount with ObReferenceObject.
Once the
> > refcount goes to 0, THEN the close is sent. The reason you need to
send
> > cleanup as well as close with IoCancelFileOpen is because
IRP_MJ_CREATE
> > properly represents the creation of a user handle to the file
(this is
> > why the stream file object apis, which create file objects but not
> > handles, don’t sent down IRP_MJ_CREATES). Since you are canceling
the
> > creation of this handle, you need to signal that the handle is
going
> > away (cleanup) and the file object is going away (close).
> >
> > (Most of this is in the OSR faq, item Q55.)
> >
> > - Nicholas Ryan
> >
> >
> >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
Logachyov
> > > Sent: Monday, November 04, 2002 1:47 AM
> > > To: File Systems Developers
> > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > >
> > >
> > > And what about IRP_MJ_CLEANUP? Will it be sent on
> > > dereferencing file object to 0? What if I fail to send it
> > > before IRP_MJ_CLOSE?
> > >
> > >
> > > ----- Original Message -----
> > > From: “Nicholas Ryan”
> > > To: “File Systems Developers”
> > > Sent: Saturday, November 02, 2002 2:40 AM
> > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > >
> > >
> > > > Yes, dereferencing the file object to 0 will cause a close
> > > operation
> > > > on the file object, AS LONG AS FileObject->DeviceObject is set
to
> > > > non-NULL before ObfDereferenceObject is called. If you fail an
open
> > > > request, Windows will clear FileObject->DeviceObject then call
> > > > ObfDereferenceObject, which guarantees that no close will be
sent.
> > > > This makes sense, since if the open failed, then no close need
be
> > > > generated. This is why IoCancelOpen must send down the close
in
> > > > addition to the cleanup (because nobody else is going to do
it).
> > > >
> > > > If you are doing something that causes the file object
> > > refcount to be
> > > > > 1 after an IoCancelOpen, and you fail the create, then you
have a
> > > > bug. The system will assume the file object can be trashed,
> > > and will
> > > > zero out
> > > > FileObject->DeviceObject and then dereference it. (It will
also
> > > > dereference FileObject->Vpb, which means the underlying volume
may
> > > > disappear out from under you). If other entities still have
> > > references
> > > > to this stale file object (like Cc), things will start to
> > > go downhill
> > > > really fast.
> > > >
> > > > - Nicholas Ryan
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: xxxxx@lists.osr.com
> > > > > [mailto:xxxxx@lists.osr.com] On Behalf Of Alexey
> > > > > Logachyov
> > > > > Sent: Friday, November 01, 2002 1:42 PM
> > > > > To: File Systems Developers
> > > > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > > > >
> > > > >
> > > > > Using paging IO is not effective. The work with the file
> > > is pretty
> > > > > massive. I do need Cc functionality. I just want to know how
to
> > > > > approach the behaviour correctly.
> > > > >
> > > > > And what about my last question (the one about IRP_MJ_CLOSE
> > > > > request)?
> > > > >
> > > > >
> > > > > ----- Original Message -----
> > > > > From: “Nicholas Ryan”
> > > > > To: “File Systems Developers”
> > > > > Sent: Friday, November 01, 2002 9:26 PM
> > > > > Subject: [ntfsd] RE: Implementing IoCancelFileOpen
> > > > >
> > > > >
> > > > > > My driver also issues an IRP_MJ_READ during its create
> > > > > processing (for
> > > > > > some files), but I don’t see the refcount on the file
> > > > > object changing
> > > > > > because of that. If you issue non-paging I/O instead of
paging
> > > > > > I/O, then yes, I suppose Cc may grab a reference to the
file
> > > > > object, which
> > > > > > is expected behavior. Solution is always use paging I/O
> > > during the
> > > > > > create handler if you intend on using IoCancelFileOpen.
> > > > > >
> > > > > > - Nicholas Ryan
> > > > > >
> > > > > >
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: xxxxx@lists.osr.com
> > > > > > > [mailto:xxxxx@lists.osr.com] On Behalf Of
Alexey
> > > > > > > Logachyov
> > > > > > > Sent: Friday, November 01, 2002 1:52 AM
> > > > > > > To: File Systems Developers
> > > > > > > Subject: [ntfsd] Implementing IoCancelFileOpen
> > > > > > >
> > > > > > >
> > > > > > > I implement the following scenario in my FSFD:
> > > > > > > 1. In IRP_MJ_CREATE completion routine I check if file
was
> > > > > > > opened successfuly. 2. If it was I read contents of
> > > file using
> > > > > > > custom-rolled IRPs. 3. After first IRP_MJ_READ request
> > > > > file object
> > > > > > > reference counter increases by 2 (Cc I guess). 4. At
> > > some point
> > > > > > > I may decide that I want to deny access to the file.
> > > > > > >
> > > > > > > The question is how do I cancel file open? I send
> > > > > IRP_MJ_CLEANUP and
> > > > > > > IRP_MJ_CLOSE. But reference counter stays 1 after I
return
> > > > > > > STATUS_ACCESS_DENIED to IO Manager. This causes delete
> > > > > requests on
> > > > > > > file to fail. Actually this happens even if I allowed
> > > file to be
> > > > > > > created successfuly. What’s wrong in this situation.
> > > > > > >
> > > > > > > And one more question. Why do I have to send
> > > > > IRP_MJ_CLOSE. Doesn’t
> > > > > > > dereferencing file object to 0 cause IRP_MJ_CLOSE to be
sent?
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > —
> > > > > > > You are currently subscribed to ntfsd as:
xxxxx@nryan.com To
> > > > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > —
> > > > > > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
To
> > > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > —
> > > > > You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> > > > > unsubscribe send a blank email to %%email.unsub%%
> > > > >
> > > >
> > > >
> > > >
> > > > —
> > > > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> > > > To unsubscribe send a blank email to %%email.unsub%%
> > > >
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntfsd as: xxxxx@nryan.com
> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@vba.com.by
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to %%email.unsub%%
>