You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
Expected the write call to succeed
What do you see instead?
$ node writeHiddenFile.js
node:internal/fs/utils:344
throw err;
^
Error: EPERM: operation not permitted, open 'file.txt'
at Object.openSync (node:fs:585:3)
at Object.writeFileSync (node:fs:2153:35)
at Object.<anonymous> (E:\Projects\Issues\nodejs-hidden-file-bug\writeHiddenFile.js:3:4)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47 {
errno: -4048,
syscall: 'open',
code: 'EPERM',
path: 'file.txt'
}
Additional information
When the file is opened via fs.open, this call to CreateFileW fails:
I did some debugging and noticed that the issue occurs because the dwCreationDisposition argument passed to CreateFileW() is set to CREATE_ALWAYS. If the file mode flag is changed to something that causes writeFileSync to use OPEN_EXISTING or OPEN_ALWAYS instead, it works, e.g.:
// Writes to an existing file or fails if it doesn't exist; same as OPEN_EXISTINGfs.writeFileSync('file.txt','test',{encoding: 'utf-8',flag: fs.constants.O_EXCL|fs.constants.O_WRONLY});
// Writes to an existing file and creates it if it doesn't exist, same as OPEN_ALWAYSfs.writeFileSync('file.txt','test',{encoding: 'utf-8',flag: fs.constants.O_CREAT|fs.constants.O_WRONLY});
So basically one can use this ^^^ workaround to support writing to hidden files on Windows systems.
Documentation page for CreateFile mentions the following:
If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile fails and sets the last error to ERROR_ACCESS_DENIED if the file exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM attribute. To avoid the error, specify the same attributes as the existing file.
I think to fix this inside Node.js, one needs to query the file attributes first before opening a file, and then apply the hidden attribute accordingly when opening it. I'm not sure if this should be handled inside Node or UV. I can try to create a pull request if this sounds like a good solution.
The text was updated successfully, but these errors were encountered:
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 674070400b..9afc8bba1d 100644
--- a/deps/uv/src/win/fs.c+++ b/deps/uv/src/win/fs.c@@ -606,6 +606,15 @@ void fs__open(uv_fs_t* req) {
goto einval;
}
++ /* Copy existing attributes to prevent an "Access is denied" error for hidden+ * and system files. */+ DWORD existing_attributes = GetFileAttributesW(req->file.pathw);+ if (existing_attributes != INVALID_FILE_ATTRIBUTES) {+ attributes |= (existing_attributes+ & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM));+ }+
/* Setting this flag makes it possible to open a directory. */
attributes |= FILE_FLAG_BACKUP_SEMANTICS;
Version
18-pre (from master branch)
Platform
Windows
Subsystem
fs
What steps will reproduce the bug?
touch file.txt && attrib +h file.txt
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
Expected the write call to succeed
What do you see instead?
Additional information
When the file is opened via
fs.open
, this call toCreateFileW
fails:node/deps/uv/src/win/fs.c
Line 612 in b323cec
I did some debugging and noticed that the issue occurs because the
dwCreationDisposition
argument passed toCreateFileW()
is set toCREATE_ALWAYS
. If the file mode flag is changed to something that causeswriteFileSync
to useOPEN_EXISTING
orOPEN_ALWAYS
instead, it works, e.g.:So basically one can use this ^^^ workaround to support writing to hidden files on Windows systems.
Documentation page for CreateFile mentions the following:
I think to fix this inside Node.js, one needs to query the file attributes first before opening a file, and then apply the hidden attribute accordingly when opening it. I'm not sure if this should be handled inside Node or UV. I can try to create a pull request if this sounds like a good solution.
The text was updated successfully, but these errors were encountered: