Eryk Sun <eryk...@gmail.com> added the comment:

> copystat() and copymode() should be able to copy the same 
> metadata/security-bits/etc as CopyFileExW. 

Regarding metadata, CopyFileExW copies the basic file info (i.e. 
FileAttributes, LastAccessTime, LastWriteTime, and ChangeTime). This metadata 
can be copied separately as the FileBasicInfo, via GetFileInformationByHandleEx 
and SetFileInformationByHandle. (Zero the CreationTime field to skip setting 
it.) Note that this includes the change time (i.e. Unix st_ctime) in file 
systems that support it, such as NTFS and ReFS. It also includes all settable 
file attributes, including readonly, hidden, system, archive, temporary, and 
not-content-indexed. Currently we only copy the readonly attribute.

Regarding security bits, CopyFileExW copies security resource attributes (i.e. 
ATTRIBUTE_SECURITY_INFORMATION), which in Windows 8+ can be referenced by 
arbitrarily complex expressions in conditional ACEs. See "[MS-DTYP] 2.4.4.17 
Conditional ACEs" [1] for details. Security resource attributes can be queried 
and set by handle via GetSecurityInfo and SetSecurityInfo. This information is 
set in the system access control list (SACL), but it does not require the 
privileged ACCESS_SYSTEM_SECURITY right. It only requires READ_CONTROL and 
WRITE_DAC access.

CopyFileExW also copies extended attributes. These are commonly set on system 
files, but in this case they're usually "$Kernel." attributes [2], which cannot 
be set from user mode. IIRC, WSL also uses them. Otherwise extended attributes 
are not used much at all because the Windows API provides no way to query and 
set them separately. (They're supported in the NT API via NtQueryEaFile and 
NtSetEaFile.) When creating a new file via CreateFileW, we can pass it a handle 
to a template file from which to copy extended attributes. But that doesn't 
help with copystat(), which requires copying extended attributes onto an 
existing file.

Regarding data, CopyFileExW copies all $DATA streams [3] in a file, not just 
the anonymous $DATA stream. The stream names and sizes can be read via 
GetFileInformationByHandleEx: FileStreamInfo. Just loop over the stream names 
to try copying them individually.

For complete consistency, copytree should copy named data streams in 
directories. (A directory can't have an anonymous data stream, but it can have 
named streams, and it's not uncommon to store metadata about a directory like 
this. Ignoring this data is inconsistent, but it's a matter of opinion whether 
complete consistency is worthwhile.) This can be implemented at a high level 
via CreateDirectoryExW by passing the source directory path as the 
lpTemplateDirectory parameter. However, CreateDirectoryExW also preserves 
whether the directory is compressed or encrypted. I don't know whether copytree 
should preserve those attributes.

[1] 
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/10dc22eb-788d-4343-b556-0b6969fe58ca
[2] 
https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/kernel-extended-attributes
[3] https://docs.microsoft.com/en-us/windows/win32/fileio/file-streams

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue38906>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to