Prevent file deletion

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

The file system doesn’t actually delete the file until the last handle is closed.

Well, this part is understandable - if it worked otherwise, it would just defeat the purpose of the very concept of reference counting, as well of using file handles/descriptors, in the first place…

However, this is NOT what Jamey’s most recent post about the target file “getting yanked away from underneath him” suggests, which, in turn, simply invalidates (at least IMHO) all his observations.

In other words, it looks like this thread has been nonsensical right from the original post, because the original problem (at least in the form it has been presented) eventually turns out to be simply non-existent one. Therefore, I have no option other than retracting all the statements that I made on this thread. As they say, “garbage in, garbage out”…

Anton Bassov

I may have not been clear in my original post but I can assure you of my observations. If file access is set to zero and no sharing with an open handle, another user can delete the file right out from under you. It is easy to reproduce. I deleted the file right from explorer while my driver had it open. I am not asking if this happens. I know for a fact that it happens. I am curious why it happens. I assumed the file is protected because of the open handle regardless of the access flags.

I may have not been clear in my original post but I can assure you of my observations. If file access is set to zero and no sharing
with an open handle, another user can delete the file right out from under you. It is easy to reproduce. I

Assuming that this is, indeed, the case, it means that you may have simply discovered a MAJOR bug in Windows NT IO Manager, Object Manager and/or NTFS.

On one hand, there is nothing particularly “exceptional” here. For example, I had personally discovered an easy and “100%-reliable” way of “bluescreening” Windows XP from the userland (IIRC, by means of ZwRaiseHardError()), which worked just like a piece of cake on both Admin and restricted accounts, around 15 years ago (OK, I have to shut up now - otherwise,“The Hanging Judge” may get upset).

The only surprising part here is that, assuming that your observations are,indeed, correct, this behavior had not been noticed before. After all, unlike ZwRaiseHardError() calls, file creation,RW operations and deletion are, probably, the most frequent things (or at least are in the Top 10 list of the ones) that computers do, so that I would normally expect a bug like that to be detected pretty quickly…

Anton Bassov

@anton_bassov said:

I may have not been clear in my original post but I can assure you of my observations. If file access is set to zero and no sharing
with an open handle, another user can delete the file right out from under you. It is easy to reproduce. I

Assuming that this is, indeed, the case, it means that you may have simply discovered a MAJOR bug in Windows NT IO Manager, Object Manager and/or NTFS.

This thread has gotten so out of control that any useful information is being lost…This is not a major bug. This is expected behavior if you do not open for data access. This is the way it has always worked. Full stop. Go disassemble IoUpdateShareAccess and IoCheckShareAccess on NT 3.51 if you want.

Ask for data access and the user won’t be able to delete the file. The fact that you can request no data access but still read/write the file object is an artifact of the way the I/O subsystem works (access check is done at the NT API level so you can bypass it using IRPs).

Also, remember that a link to a file is just one piece of metadata associated with the file. You can remove all links to the file but not delete the other metadata (e.g. file attributes) or file data until the last handle goes away. Nothing magic and nothing specific to Windows. It’s all just a small matter of programming.

Now, you could argue about whether or not the semantics provided by the Windows I/O subsystem are reasonable, but that ship sailed long ago.

This is not a major bug. This is expected behavior if you do not open for data access. This is the way it has always worked.
Full stop. Go disassemble IoUpdateShareAccess and IoCheckShareAccess on NT 3.51 if you want.

Ask for data access and the user won’t be able to delete the file.

I am getting more and more confused …

First of all, what do we mean by “deleting an open file” here? On my books, it means that you have opened a file handle for some access
(for example, FILE_READ_ATTRIBUTES or FILE_WRITE_EA), and then, once in a sudden, you are unable to perform the requested operation because the target file has been deleted, although a handle to it is still open. If this is the case, then we are speaking about a major bug.

However, if you have opened a file handle for,say, FILE_READ_ATTRIBUTES access, and then, at some point, discover that you cannot read file data because the target file has been deleted…well, then this is simply a non-issue, at least on my books. After all, if you have opened a file for reading file attributes, you should not read or write its data, even if IO manager does not explicitly prohibit it. More on it below.

The fact that you can request no data access but still read/write the file object is an artifact of the way the I/O subsystem works
(access check is done at the NT API level

Well, in such case you are doing something that you are not supposed to, so that you have to either make sure you know what you are actually doing, or to be ready to deal with the potential “consequences” if something goes not the way you have planned. Therefore, all your possible complaints are simply pointless in this situation.

So my question to Jamey is “which scenario are we speaking about on this thread”? If we are speaking about the latter one, it means that this thread has been nonsensical right from the original post

Anton Bassov

I open the file for no access expecting the file to be exclusively opened. While the system is running I regularly update this file with state and status information. I do this using file extents I got from calling FSCTL. I/O is directly to the volume as to not have to deal with file system entry issues. Since I have the file open (regardless of access) I expect the file to be exclusive and protected until I close it. I have a handle. I worked around the issue so it is not halting any progress on my end. I just found it a bit strange and wondered if anyone else experienced it and was it expected behavior.

I open the file for no access expecting the file to be exclusively opened. While the system is running I regularly
update this file with state and status information. I do this using file extents I got from calling FSCTL. I/O is directly
to the volume as to not have to deal with file system entry issues. Since I have the file open (regardless of access)
I expect the file to be exclusive and protected until I close it. I have a handle. I worked around the issue so it is not
halting any progress on my end. I just found it a bit strange and wondered if anyone else experienced it and was it expected behavior.

To put it simply, you have opened a file for no access, but are still accessing it by means of some “clever” workaround that you have found.
Why should one expect anything, apart from"undefined behavior", under these circumstances???

In other words, this thread has been nonsensical right from the original post…

Anton Bassov

Nonsensical? I have an exclusive handle to a file. That file should not be pulled out from underneath me while I have an exclusive open handle. Either way, I guess this is expected behavior.

Nonsensical? I have an exclusive handle to a file.

Just think about the very phrase “exclusive no-access”. Does it make any sense to you?

In fact, the whole thing reminds me of an old joke about the bloke who orders a “black coffee, i.e. the one without the cream” in a restaurant, and gets told something along the lines of “the only black coffee that we can serve you is the one without the milk, because we ran out of cream”…

Anton Bassov

I am watching a rerun of Cheers, and Coach is making more sense to me :slight_smile:

On that note… I am outta this thread :wink:

‘Nonsensical? I have an exclusive handle to a file’ - exactly. you have exclusive access for no operations. no reading, writing or deleting etc. so none of these requested by others will conflict with the access you have. the handle you have will of course remain valid until you close it, but you can’t do anything with it, so that makes little matter. the same could be true if you oppened for somthing like FILE_READ_ATTRIBUTES