Prevent file deletion

Jamey,

If I add access flags (anything will do; read, write, write attributes, delete, &c.) then the file is prevented from being deleted.
So without providing any access flags (FILE_SPECIAL_ACCESS is what I am using) you can delete a file with an exclusively
opened handle.

Let’s make sure we understand one another. Are you saying that, by opening a file with read, write, write attributes or delete access in a driver, you prevent the target file from getting deleted until a handle to it gets closed, but opening it for exclusive access does not prevent it from getting deleted?

I do not like having my file yanked out from underneath me.

But how may it possibly happen while you keep an open handle to it ( which means the target file object’s refcount is non-zero) ???

Anton Bassov

This is the behavior I am trying to understand. Also if I have my file opened as I describe (exclusive and special) and chkdsk /f runs at boot the chkdsk command runs as expected. If I have any access flags set as described above then chkdsk will fail to run because there is an open file on the volume.

I’ve worked around it in my code now. I am curious why it is so.

This is the behavior I am trying to understand.

But what does the whole thing look like from the driver’s perspective? Let’s say you’ve got an open handle to the file, so that you have written some data to it. Then you go and manually delete the file in Windows Explorer while the handle is still open. What happens when your driver tries to,say, read data back from the file that you have just deleted?

Anton Bassov

I rarely do IO to the file via the handle except when created for the first time. I call the file system to give me the extents for my file. I do not want anyone else opening, using, or deleting this file. I do all IO directly to the volume by mapping file system extent records to volume sectors/clusters. I look at my file as the system would look at pagefil.sys; hands off. If the file is deleted I could/would be writing to clusters that may be occupied by some other file or files. I need the handle to be opened exclusively so that no one else can access or delete the file. Like I said, I’ve worked around it. Would like for it to have worked as expected.

Try it. On NTFS at least, it does not work.
I tried this even from a System thread, in the driver (kernel code is top
caller)

IO_IGNORE_SHARE_ACCESS_CHECK is not a certain thing.

This thread is too long to read - and full of too much nonsense to read without getting angry anyways

so to the origional problem. No file or regisry key or anthing else can persist in this way, as you already know, and then not have thse sharing issues

Dejan,

Try it. On NTFS at least, it does not work.

I was just trying to find some logical explanation to the scenario described by Jamey. All my statements were made with the assumption that the correct description of the situation/behavior had been provided. However, it does not really seem to be the case, because the described behavior (i.e. an assumption file may get ACTUALLY deleted while some handles to it are still open) contradicts all the “rules of thought”.

Therefore, I have no option, other than simply retracting all the statements on the subject that I made on this thread…

Anton Bassov

This thread is too long to read - and full of too much nonsense to read without getting angry anyways

This is what may happen if the wrong description of the original problem gets provided…

Anton Bassov

1 Like

@Jamey_Kirby said:
This is the behavior I am trying to understand. Also if I have my file opened as I describe (exclusive and special) and chkdsk /f runs at boot the chkdsk command runs as expected. If I have any access flags set as described above then chkdsk will fail to run because there is an open file on the volume.

Opens without data access do not affect share access. This is just the way it’s always been.

chkdsk needs to lock the volume to do its thing and the file system will reject the lock if there are any opens for data access. FsRtlAreVolumeStartupApplicationsComplete lets you know when chkdsk is done running at boot so you can avoid preventing it from running (though unfortunately it’s a polling API and not a callback)

@anton_bassov said:

This is the behavior I am trying to understand.

But what does the whole thing look like from the driver’s perspective? Let’s say you’ve got an open handle to the file, so that you have written some data to it. Then you go and manually delete the file in Windows Explorer while the handle is still open. What happens when your driver tries to,say, read data back from the file that you have just deleted?

FILE_SHARE_DELETE is a thing so this “just works”. The file system doesn’t actually delete the file until the last handle is closed.

Are people (other than Mr. Noone) forgetting that delete in Windows is a disposition that takes place only when the file is ultimately closed?

Mr. Kirby certainly knows this. The file isn’t “yanked out” from underneath you. You have a handle to it. It’s open. So, what’s the issue? Before you close the file, set its disposition to not be deleted, if that’s what you want.

Also, unless I am mistaken, you can now delete files without even opening them, via the WSL, like so:

remove (const char *filename)

Peter

How does WSL remove translate into the FS stack then?

@“Peter_Viscarola_(OSR)” said:
Are people (other than Mr. Noone) forgetting that delete in Windows is a disposition that takes place only when the file is ultimately closed?

Mr. Kirby certainly knows this. The file isn’t “yanked out” from underneath you. You have a handle to it. It’s open. So, what’s the issue? Before you close the file, set its disposition to not be deleted, if that’s what you want.

Also, unless I am mistaken, you can now delete files without even opening them, via the WSL, like so:

remove (const char *filename)

Peter

I don’t see open in procmon and filespy during remove call, but both set_information calls(first rename, then set disposition) come with non-null file object.

How does WSL remove translate into the FS stack then?

Apologies… but I don’t recall. I was only involved in this tangentially. I remember discussions about a bunch of weird “no handle required” stuff being added for WSL… which broke one of our product. Sorry I can’t recall the details now. Maybe somebody else??

Peter

I don’t see open in procmon and filespy during remove call, but both set_information calls(first rename, then set disposition) come with non-null file object.

I realize I’m stating the obvious here: the file MUST have been opened at SOME point, right? Otherwise there wouldn’t be a FILE_OBJECT for it.

Peter

@“Peter_Viscarola_(OSR)” said:

I don’t see open in procmon and filespy during remove call, but both set_information calls(first rename, then set disposition) come with non-null file object.

I realize I’m stating the obvious here: the file MUST have been opened at SOME point, right? Otherwise there wouldn’t be a FILE_OBJECT for it.

Peter
Yes Peter. This is my point in this discussion - you need to open file to delete it. But reading your previous post(about no handle required) maybe this is not always true in modern windows.

The POSIX delete stuff is just FileDispositionInformationEx with some flags. You still need to open and send the set information call. The only real differences are:

  1. The link name disappears when the handle used to delete the file is closed (as opposed to the last handle)
  2. You can delete a link to a running executable (just not the last link)

@“Scott_Noone_(OSR)” said:
The POSIX delete stuff is just FileDispositionInformationEx with some flags. You still need to open and send the set information call. The only real differences are:

  1. The link name disappears when the handle used to delete the file is closed (as opposed to the last handle)
  2. You can delete a link to a running executable (just not the last link)

Thank you Scott !
I was starting to doubt basic things I know about windows :slight_smile:

Thank you, Scott for clearing up the confusion I created. Ugh… That’s what I get for answering too many posts at once.

Peter