def _preserve_timestamps(file_entry, output_path): """Obtain and set (to preserve) original timestamps of exported files.""" stat_object = file_entry.GetStat() if os.name == WINDOWS_IDENTIFIER: accessed = created = modified = dt.now() if stat_object.atime: if stat_object.atime_nano: accessed = dt.fromtimestamp((float(str(stat_object.atime) + '.' + str(stat_object.atime_nano)))) else: accessed = dt.fromtimestamp(stat_object.atime) if stat_object.crtime: if stat_object.crtime_nano: created = dt.fromtimestamp((float(str(stat_object.crtime) + '.' + str(stat_object.crtime_nano)))) else: created = dt.fromtimestamp(stat_object.crtime) if stat_object.mtime: if stat_object.mtime_nano: modified = dt.fromtimestamp((float(str(stat_object.mtime) + '.' + str(stat_object.mtime_nano)))) else: modified = dt.fromtimestamp(stat_object.mtime) handle = CreateFileW(output_path, GENERIC_WRITE, FILE_SHARE_WRITE, None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, None) SetFileTime(handle, created, accessed, modified) # does not seem to preserve nano precision of timestamps CloseHandle(handle) else: os.utime(output_path, (stat_object.atime, stat_object.mtime))
def _getdirinfo(path): from collections import namedtuple from win32file import ( # pylint: disable=import-error CreateFileW, GetFileInformationByHandle, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_READ, OPEN_EXISTING, ) # NOTE: use FILE_FLAG_OPEN_REPARSE_POINT to open symlink itself and not # the target See https://docs.microsoft.com/en-us/windows/desktop/api/ # fileapi/nf-fileapi-createfilew#symbolic-link-behavior flags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT hfile = CreateFileW(path, 0, FILE_SHARE_READ, None, OPEN_EXISTING, flags, None) # See BY_HANDLE_FILE_INFORMATION structure from fileapi.h Info = namedtuple( "BY_HANDLE_FILE_INFORMATION", [ "dwFileAttributes", "ftCreationTime", "ftLastAccessTime", "ftLastWriteTime", "dwVolumeSerialNumber", "nFileSizeHigh", "nFileSizeLow", "nNumberOfLinks", "nFileIndexHigh", "nFileIndexLow", ], ) return Info(*GetFileInformationByHandle(hfile))
def readlink(path: str, *, dir_fd=None) -> str: """ Cross-platform implementation of readlink for Python < 3.8 Supports Windows NT symbolic links and reparse points. """ if sys.version_info >= (3, 8) or sys.platform != "win32": return os.readlink(path, dir_fd=dir_fd) if not os.path.exists(path): raise OSError(22, 'Invalid argument', path) elif islink(path): # may be a symbolic link. return os.readlink(path, dir_fd=dir_fd) if sys.platform == "win32": # FILE_FLAG_OPEN_REPARSE_POINT alone is not enough if 'path' # is a symbolic link to a directory or a NTFS junction. # We need to set FILE_FLAG_BACKUP_SEMANTICS as well. # See https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea handle = CreateFileW(path, GENERIC_READ, 0, None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0) MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024 buf = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, None, MAXIMUM_REPARSE_DATA_BUFFER_SIZE) CloseHandle(handle) result = _parse_reparse_buffer(buf) if result['tag'] in (stat.IO_REPARSE_TAG_MOUNT_POINT, stat.IO_REPARSE_TAG_SYMLINK): offset = result['substitute_name_offset'] ending = offset + result['substitute_name_length'] rpath = result['buffer'][offset:ending].decode('UTF-16-LE') else: rpath = result['buffer'] if result['tag'] == stat.IO_REPARSE_TAG_MOUNT_POINT: rpath[:0] = '\\??\\' return rpath
def addWatch(self, path, mask=0): """Add watcher for path""" super(WinFileSysMonitor, self).addWatch(path, mask) handle = CreateFileW( path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, None) buf = AllocateReadBuffer(self.buf_size) if not mask: mask = self.defaultMask self.__lock.acquire() self.ioComPort = CreateIoCompletionPort(handle, self.ioComPort, self.comKey, 0) self.watchList.append({'mask': mask, 'path': path, 'handle': handle, 'buffer': buf}) self.comKey += 1 self.__lock.release()
def open_file(file_name, mode=GENERIC_READ): file_handle = CreateFileW(file_name, mode, 0, None, OPEN_EXISTING, 0, None) return file_handle
def open_file(file_name, mode=GENERIC_READ): file_handle = CreateFileW(file_name, mode, 0, None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, None) return file_handle