# Extend std::fs::Permissions on Windows

**URL:** <https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943>\
**Category:** language design\
**Created:** [May 30, 2024, 9:49am UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943 "2024-05-30T09:49:23Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![E-Mans-Application](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/e-mans-application/32/12230_2.png) [@E-Mans-Application](https://internals.rust-lang.org/u/E-Mans-Application)\
**Post date:** [May 30, 2024, 9:49am UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/1 "2024-05-30T09:49:23Z")

</div>

Hi,

I need to set file attributes on Windows, and I found it's exactly what `std::fs::set_permissions` does. However, struct `std::fs::Permissions` only exposes attribute `readonly`. I would also need to set other attributes, such as `FILE_ATTRIBUTE_SYSTEM` or `FILE_ATTRIBUTE_TEMPORARY`.

On Linux, there is extension trait `std::os::unix::fs::PermissionsExt`, but it seems Windows has no such thing, making struct `Permissions` not as useful as it may be.

Adding a `Default` implementation to create a `FILE_ATTRIBUTE_NORMAL` could be great as well.

Currently, I'm calling system API `SetFileAttributesW` directly, but this forces me to resort to unsafe code and to re-implement conversion from `Path` to `Vec<u16>` (in a way that's probably less efficient than the standard library).

Another possibility would be to compute the mask manually and to transmute the result to `Permissions` (which is basically a `u32`), but I don't like this solution because there is no guarantee that `Permissions` will remain equivalent to a `u32` in the future.

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [May 30, 2024, 10:12am UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/2 "2024-05-30T10:12:50Z")

</div>

There is a `attributes` method on the Windows extension trait for `OpenOptions`: [https://doc.rust-lang.org/nightly/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.attributes](https://doc.rust-lang.org/nightly/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.attributes) If you want to create/open the file and at the same time set attributes you can probably use this method.

> [@E-Mans-Application](#):
>
> but this forces me to resort to unsafe code and to re-implement conversion from `Path` to `Vec<u16>` (in a way that's probably less efficient than the standard library).

The standard library uses `path.encode_wide()` from `std::os::windows::ffi::OsStrExt` I believe.

---

<div class="post-metadata">

**Author:** ![E-Mans-Application](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/e-mans-application/32/12230_2.png) [@E-Mans-Application](https://internals.rust-lang.org/u/E-Mans-Application)\
**Post date:** [May 30, 2024, 10:36am UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/3 "2024-05-30T10:36:34Z")

</div>

> There is a attributes method on the Windows extension trait for OpenOptions

This is indeed the solution I'm using for new files. However, according to the doc, the attributes given to `OpenOptions` are only applied to existing files if the files are open with `.create(true).truncate(true)`, which truncates the files. Anyway, using `std::fs::OpenOptions::new().create(true).truncate(true).attributes(attrs).open(path)` gives me an "InvalidInput" error.

I need to set the attributes to an existing file, without changing its contents.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [May 31, 2024, 5:48pm UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/4 "2024-05-31T17:48:02Z")

</div>

The [Microsoft docs](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-createfile2_extended_parameters) suggest that the attributes being ignored when opening an existing file is a property of the Win32 API, not the Rust API:

> When [CreateFile2](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2) opens an existing file, it generally combines the file flags with the file attributes of the existing file, and ignores any file attributes supplied as part of _dwFlagsAndAttributes_. Special cases are detailed in [Creating and Opening Files](https://learn.microsoft.com/en-us/windows/win32/FileIO/creating-and-opening-files).

If you want to change the attributes of an existing file, AIUI that's [SetFileAttributes](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileattributesw). This gets exposed into Rust as [`File::set_permissions`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.set_permissions). We have a Unix `PermissionsExt` for low level manipulation, but no version for Windows.

If you can open/modify the file as you want to with the raw Win32 API, it should ideally be possible with the Rust std API, at least when using the OS specific extensions. If std doesn't expose the necessary knobs yet, it deserves an ACP to expose them as needed.

---

<div class="post-metadata">

**Author:** ![E-Mans-Application](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/e-mans-application/32/12230_2.png) [@E-Mans-Application](https://internals.rust-lang.org/u/E-Mans-Application)\
**Post date:** [June 2, 2024, 10:56am UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/5 "2024-06-02T10:56:11Z")

</div>

Hi,

> The [Microsoft docs](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-createfile2_extended_parameters) suggest that the attributes being ignored when opening an existing file is a property of the Win32 API, not the Rust API

Thanks for the information, now I understand better why `OpenOptions` was not working.

> This gets exposed into Rust as File::set\_permissions. We have a Unix PermissionsExt for low level manipulation, but no version for Windows.

Well... That's exactly what my first message was about. Sorry if I wasn't clear. I **do** want to use `std::fs::set_permissions` (or `File::set_permissions` which I guess is equivalent), but type `Permissions` only exposes attribute "readonly" on Windows, whereas I need to set other attributes as well.

> If std doesn't expose the necessary knobs yet, it deserves an ACP to expose them as needed.

How can I do an ACP? I thought this thread was already a sort of ACP.

---

<div class="post-metadata">

**Author:** ![pitaj](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pitaj/32/11262_2.png) [@pitaj](https://internals.rust-lang.org/u/pitaj)\
**Post date:** [June 2, 2024, 2:48pm UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/6 "2024-06-02T14:48:47Z")

</div>

[Open an ACP issue on the libs-team repo](https://github.com/rust-lang/libs-team/issues/new?assignees=&labels=api-change-proposal%2C+T-libs-api&projects=&template=api-change-proposal.md&title=%28My+API+Change+Proposal%29)

---

<div class="post-metadata">

**Author:** ![binarycat](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/binarycat/32/12210_2.png) [@binarycat](https://internals.rust-lang.org/u/binarycat)\
**Post date:** [June 4, 2024, 8:18am UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/7 "2024-06-04T08:18:26Z")

</div>

> [@CAD97](#):
>
> The [Microsoft docs](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-createfile2_extended_parameters) suggest that the attributes being ignored when opening an existing file is a property of the Win32 API, not the Rust API:

it's an attribute of every filesystem api i've worked with (plan9 and linux), which is probably why libstd is able to guarantee it.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [September 2, 2024, 8:19am UTC](https://internals.rust-lang.org/t/extend-std-permissions-on-windows/20943/8 "2024-09-02T08:19:06Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
