svenstaro/miniserve

Unable to upload a/o create folder on any other disk than C:\ on Win10

LaurentGrenet opened this issue · 16 comments

Hi,
I'm using miniserve on a Windows 10 laptop

When miniserve's path to serve is on C:\ disk, upload of file a/o directory creation works fine, and is possible, at least as soon as appropriate access rights are granted on local NTFS disk.

But if the path to serve is on another local disk (eg "miniserve D:\Temp\ -u -U" ), upload of files a/o directory creation systematically fail with the error message "Insufficient permissions to create file in \?\D:\Temp", and this even if full control has been granted to everyone at OS level in this target folder.
On the other hand, it works "sometimes" even on disk D:
For example, if I create a new folder D:\Test (at Win10 level), then launch "miniserve D:\Test -u -U", I'm able to upload files a/o create directories... while access rights are exactly the same at OS level for D:\Test and D:\Temp....

Moreover, in case access rights are NOT granted to users in target dir, upload and directory creation are (hopefully...) not possible, but the error message is not at all the same, but rather "Failed to create mysubdir / caused by: Accès refusé. (os error 5)", or "Failed to create \?\D:\Test\P1080514.JPG / caused by: Accès refusé. (os error 5)"

ViRb3 commented

For me on Windows 11, not even C:\Users\user\Downloads works, same error is output.

Can you try running miniserve using admin permissions?

ViRb3 commented

Same result when run as administrator.

Frankly I got no clue then. I don't do anything special in miniserve here. I'm not sure whether I have to somehow request special permissions from Windows here or whatever. Could you research this a bit and maybe figure out what's wrong? I can then try to fix it.

I confirm that on my side too, running it as admin doesn't change anything

ViRb3 commented

@svenstaro Did some research and found out the problem.

You have a check for the target directory being readonly, and abort if true:

From Rust docs:

On Windows this returns FILE_ATTRIBUTE_READONLY. If FILE_ATTRIBUTE_READONLY is set then writes to the file will fail but the user may still have permission to change this flag. If FILE_ATTRIBUTE_READONLY is not set then writes may still fail due to lack of write permission. The behavior of this attribute for directories depends on the Windows version.

I checked a bunch of folders on my system, and to my surprise, guess what?

Screenshot 2023-02-19 at 20 00 56

This applies to EVERY SINGLE folder in my computer! I quickly spun up a VM and installed a brand new, fresh Windows 11, and it had the exact same behavior. I have to note, the checkbox has three states, the above one meaning "default", as opposed to "enabled":

Screenshot 2023-02-19 at 20 08 13

So, it turns out that Rust detects both the "default" and "enabled" state as "readonly".

I dug some more, and found out this:

apparently it was a "feature" of Windows Defender that decided to turn itself on after the update. Go to Windows Defender > Virus protection > Settings > Control access to folders (or stuff like this) and turn if off

The read only checkbox for folders in File Explorer doesn't do anything other than tell FE to look for a desktop.ini inside the folder. You can ignore it

Whatever is the cause, I think the solution is simple — skip readonly check for Windows. I'd even dare to go a step further and drop the check for all platforms, since a folder may not be readonly but write still fail due to insufficient permissions. Also who knows how many other platforms can have edge cases like this. Just let the OS error us if writing can't happen.

I think the solution is simple — skip readonly check for Windows.

+1

This check doesn't make any sense in windows, in which the R attribute on a folder doesn't mean at all that the folder is "read only". This attribute doesn't prevent at all to create new files in the folder, nore remove files from the folder, nor to update files content in the folder.
It only means that the potential desktop.ini has to be taken into consideration.
For example, if in your desktop.ini there is an entry like

[.ShellClassInfo]
LocalizedResourceName=.....

to localize folder's name in Win explorer, folder's name is actually localized ONLY if the folder has the R attribute. Without this attribute, folder's name remains unchanged.

Great analysis! Would one of you folks like to try to implement a fix?

ViRb3 commented

My solution is to remove readonly check altogether for all platforms. If you're happy with that, can send a PR.

I wonder if we can still properly handle the specific errors we get from the OSs in case writing fails due to an actual read only situation. I'd like to be able to still show users good error output if possible. Could you check what that error output actually looks like if attempting to write a read only location?

Other than that, I'm fine with it.

@ViRb3 Hey, are you still interested in sending a PR?