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))
示例#2
0
    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))
示例#3
0
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
示例#4
0
    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()
示例#5
0
def open_file(file_name, mode=GENERIC_READ):
    file_handle = CreateFileW(file_name, mode, 0, None, OPEN_EXISTING, 0, None)
    return file_handle
示例#6
0
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