question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Question: Why the file dragged into a UWP app is read-only?

See original GitHub issue

Hey folks,

I have a question bothers me for quite a while: “If user drag a storage file into a UWP app, it will be read-only by default. If you try to save changes on top of this file, you will get UnauthorizedAccessException, but why?”

For example, this is how you get the file(s) from DragEventArgs:

var storageItems = await args.DataView.GetStorageItemsAsync();

And this will be true for the files you dragged in:

public static bool IsFileReadOnly(StorageFile file)
{
    return (file.Attributes & Windows.Storage.FileAttributes.ReadOnly) != 0;
}

And you will see exception if you do this:

using (var stream = await file.OpenStreamForWriteAsync()) { }

This does not make any sense to me, because if user drag a file into an app, he or she is fully aware of the operation and should just give the app same permission just like what the file open picker does. Another approach would be asking for broadSystemAccess, but it makes little sense to me as well for just enabling write to a dragged file? (+ @soumyamahunt for visibility)

Last year, when I started my notepads app. I did some research online and found out that not only me, but also thousands of developers voted for this change on MS Voice (I am not sure if it is this forum) but never received official response from MSFT. Not only that, the website is now deprecated so I cannot find and paste the link here.

Now here comes the interesting part: I recently knows that from @yaichenbaum that if you use PathIO API to write, you can workaround this limitation. Then we have a community member (@Maickonn) sent out a PR for this workaround, let me paste the interesting workaround logic here:

if (IsFileReadOnly(file) || !await FileIsWritable(file))
{
    // For file(s) dragged into Notepads, they are read-only
    // StorageFile API won't work but can be overwritten by Win32 PathIO API (exploit?)
    // In case the file is actually read-only, WriteBytesAsync will throw UnauthorizedAccessException exception
    var content = encoding.GetBytes(text);
    var result = encoding.GetPreamble().Concat(content).ToArray();
    await PathIO.WriteBytesAsync(file.Path, result);
}
else // Use StorageFile API to save 
{
    using (var stream = await file.OpenStreamForWriteAsync())
    using (var writer = new StreamWriter(stream, encoding))
    {
        stream.Position = 0;
        await writer.WriteAsync(text);
        await writer.FlushAsync();
        // Truncate
        stream.SetLength(stream.Position);
    }
}

So basically PathIO.WriteBytesAsync can write to the file although it is marked as read-only for the StorageFile item. This looks like an exploit to me and I am very confused.

So, here are my questions:

  1. Why the file dragged into a UWP app is read-only, what is the reason behind it? Why we never change this behavior for so many years? This literally stops any notepad like or VSCode like document editing UWP app from working properly with dragged file. And further making them weaker comparing to their win32 counterparts.
  2. Why PathIO.WriteBytesAsync can write to a read-only StorageFile? I know I am using the “file.Path” here instead of the runtime object, but it should be caught by the file security model, isn’t it? Or is this intended?
  3. Is there any plan for changing this behavior in the future or is there any plan to address it as part of WinUI 3.0 or post WinUI 3.0?

Note: If the file is already “read-only” before dragging or becoming “read-only” after dragging, none of these API will work anyway. So we are safe here. There is no bugs or concerns regarding to that topic.

Thanks, Jackie

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:15
  • Comments:14 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
soumyamahuntcommented, May 10, 2020

I think this has to do with DataPackage and DataPackageView classes especially how DataPackage.SetStorageItems method is implemented. The default behavior of SetStorageItems is to make the provided storage items readonly unless the app explicitly provides readonly attribute as false when drag of an item is starting from a given app. MS has to change this default behavior or make changes to set the readonly attribute as false in file explorer code behind.

1reaction
0x7c13commented, May 15, 2020

I’ve resorted to warning the users that they need to enable BroadFileSystemAccess just to accept dragged file properly (in apps where it needs to save over/rename, etc)

frustrating and not a good experience for dev or user.

Exactly, and it makes no sense to let user give BroadFileSystemAccess to a simple notepad app at all.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Drag&Drop File Attribute is ReadOnly
I created an Attached Property which registers the drag and drop events and requests the operations: move, link, copy.
Read more >
File access permissions - UWP applications
The app's install directory is a read-only location. You can't gain access to the install directory through the file picker.
Read more >
Why doesn't the Drop event fire in my UWP test app?
The effect returned by DragEnter and DragOver indicates if dropping is possible and if so if data are copied or moved (usually by...
Read more >
[UWP][C#] File drag and drop is not working on some devices
Recently we found one machine where we were able to reproduce this issue. We created a sample app with the following MainPage.xaml: Copy....
Read more >
Drag and Drop File into Application under run as ...
Click on open in file menu and enter * in file name and press enter. Now you can drag files from there to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found