예제 #1
0
func (fs *fileStat) loadFileId() error {
	fs.Lock()
	defer fs.Unlock()
	if fs.path == "" {
		// already done
		return nil
	}
	pathp, err := syscall.UTF16PtrFromString(fs.path)
	if err != nil {
		return err
	}
	h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if err != nil {
		return err
	}
	defer syscall.CloseHandle(h)
	var i syscall.ByHandleFileInformation
	err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
	if err != nil {
		return err
	}
	fs.path = ""
	fs.vol = i.VolumeSerialNumber
	fs.idxhi = i.FileIndexHigh
	fs.idxlo = i.FileIndexLow
	return nil
}
예제 #2
0
// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (file *File) Stat() (fi FileInfo, err error) {
	if file == nil || file.fd < 0 {
		return nil, syscall.EINVAL
	}
	if file.isdir() {
		// I don't know any better way to do that for directory
		return Stat(file.name)
	}
	if file.name == DevNull {
		return &devNullStat, nil
	}
	var d syscall.ByHandleFileInformation
	e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
	if e != nil {
		return nil, &PathError{"GetFileInformationByHandle", file.name, e}
	}
	return &fileStat{
		name: basename(file.name),
		sys: syscall.Win32FileAttributeData{
			FileAttributes: d.FileAttributes,
			CreationTime:   d.CreationTime,
			LastAccessTime: d.LastAccessTime,
			LastWriteTime:  d.LastWriteTime,
			FileSizeHigh:   d.FileSizeHigh,
			FileSizeLow:    d.FileSizeLow,
		},
		vol:   d.VolumeSerialNumber,
		idxhi: d.FileIndexHigh,
		idxlo: d.FileIndexLow,
	}, nil
}
예제 #3
0
func (s *winSys) loadFileId() error {
	if s.path == "" {
		// already done
		return nil
	}
	s.Lock()
	defer s.Unlock()
	pathp, e := syscall.UTF16PtrFromString(s.path)
	if e != nil {
		return e
	}
	h, e := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if e != nil {
		return e
	}
	defer syscall.CloseHandle(h)
	var i syscall.ByHandleFileInformation
	e = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
	if e != nil {
		return e
	}
	s.path = ""
	s.vol = i.VolumeSerialNumber
	s.idxhi = i.FileIndexHigh
	s.idxlo = i.FileIndexLow
	return nil
}
예제 #4
0
func (file *File) statFile(name string) (fi *FileInfo, err Error) {
	var stat syscall.ByHandleFileInformation
	if ok, e := syscall.GetFileInformationByHandle(int32(file.fd), &stat); !ok {
		return nil, &PathError{"stat", file.name, Errno(e)}
	}
	return fileInfoFromByHandleInfo(new(FileInfo), file.name, &stat), nil
}
예제 #5
0
func getIno(path string) (ino *inode, err error) {
	pathp, e := syscall.UTF16PtrFromString(path)
	if e != nil {
		return nil, e
	}
	h, e := syscall.CreateFile(pathp,
		syscall.FILE_LIST_DIRECTORY,
		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
		nil, syscall.OPEN_EXISTING,
		syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0)
	if e != nil {
		return nil, os.NewSyscallError("CreateFile", e)
	}
	var fi syscall.ByHandleFileInformation
	if e = syscall.GetFileInformationByHandle(h, &fi); e != nil {
		syscall.CloseHandle(h)
		return nil, os.NewSyscallError("GetFileInformationByHandle", e)
	}
	ino = &inode{
		handle: h,
		volume: fi.VolumeSerialNumber,
		index:  uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow),
	}
	return ino, nil
}
예제 #6
0
// Stat returns the FileInfo structure describing file.
// It returns the FileInfo and an error, if any.
func (file *File) Stat() (fi FileInfo, err error) {
	if file == nil || file.fd < 0 {
		return nil, EINVAL
	}
	if file.isdir() {
		// I don't know any better way to do that for directory
		return Stat(file.name)
	}
	var d syscall.ByHandleFileInformation
	e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
	if e != nil {
		return nil, &PathError{"GetFileInformationByHandle", file.name, e}
	}
	return toFileInfo(basename(file.name), d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime), nil
}
예제 #7
0
func loadFileId(filepath string) (string, error) {
	pathp, err := syscall.UTF16PtrFromString(filepath)
	if err != nil {
		return "", err
	}
	h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
	if err != nil {
		return "", err
	}
	defer syscall.CloseHandle(h)
	var i syscall.ByHandleFileInformation
	err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%x-%x-%x", i.VolumeSerialNumber, i.FileIndexHigh, i.FileIndexLow), nil
}
예제 #8
0
// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (file *File) Stat() (FileInfo, error) {
	if file == nil {
		return nil, ErrInvalid
	}
	if file == nil || file.fd < 0 {
		return nil, syscall.EINVAL
	}
	if file.isdir() {
		// I don't know any better way to do that for directory
		return Stat(file.dirinfo.path)
	}
	if file.name == DevNull {
		return &devNullStat, nil
	}

	ft, err := syscall.GetFileType(file.fd)
	if err != nil {
		return nil, &PathError{"GetFileType", file.name, err}
	}
	if ft == syscall.FILE_TYPE_PIPE {
		return &fileStat{name: basename(file.name), pipe: true}, nil
	}

	var d syscall.ByHandleFileInformation
	err = syscall.GetFileInformationByHandle(file.fd, &d)
	if err != nil {
		return nil, &PathError{"GetFileInformationByHandle", file.name, err}
	}
	return &fileStat{
		name: basename(file.name),
		sys: syscall.Win32FileAttributeData{
			FileAttributes: d.FileAttributes,
			CreationTime:   d.CreationTime,
			LastAccessTime: d.LastAccessTime,
			LastWriteTime:  d.LastWriteTime,
			FileSizeHigh:   d.FileSizeHigh,
			FileSizeLow:    d.FileSizeLow,
		},
		vol:   d.VolumeSerialNumber,
		idxhi: d.FileIndexHigh,
		idxlo: d.FileIndexLow,
		pipe:  false,
	}, nil
}
예제 #9
0
// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (file *File) Stat() (fi FileInfo, err error) {
	if file == nil || file.fd < 0 {
		return nil, syscall.EINVAL
	}
	if file.isdir() {
		// I don't know any better way to do that for directory
		return Stat(file.name)
	}
	if file.name == DevNull {
		return statDevNull()
	}
	var d syscall.ByHandleFileInformation
	e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
	if e != nil {
		return nil, &PathError{"GetFileInformationByHandle", file.name, e}
	}
	return &fileStat{
		name:    basename(file.name),
		size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
		modTime: mkModTime(d.LastWriteTime),
		mode:    mkMode(d.FileAttributes),
		sys:     mkSysFromFI(&d),
	}, nil
}