Skip to content

Commit

Permalink
fix(windows): Fix "Access is defined." error on Windows when renaming.
Browse files Browse the repository at this point in the history
  • Loading branch information
dustmop committed Dec 18, 2019
1 parent f2ed024 commit 0d11744
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 43 deletions.
34 changes: 34 additions & 0 deletions base/hidden_file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// +build !windows

package base

import (
"fmt"
"io/ioutil"
"path/filepath"
"strings"
)

// SetFileHidden ensures the filename begins with a dot. Other OSes may do more
func SetFileHidden(path string) error {
basename := filepath.Base(path)
if !strings.HasPrefix(basename, ".") {
return fmt.Errorf("hidden files must begin with \".\"")
}
return nil
}

// WriteHiddenFile ensures the filename begins with a dot, and writes content to it. Other
// Operating Systems may do more
func WriteHiddenFile(path, content string) error {
// Ensure the filename begins with a dot
basename := filepath.Base(path)
if !strings.HasPrefix(basename, ".") {
return fmt.Errorf("hidden files must begin with \".\"")
}
// Write the contents
if err := ioutil.WriteFile(path, []byte(content), 0644); err != nil {
return err
}
return nil
}
58 changes: 58 additions & 0 deletions base/hidden_file_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package base

import (
"fmt"
"path/filepath"
"strings"
"syscall"
)

// SetFileHidden sets the hidden attribute on the given file. Windows specific functionality
func SetFileHidden(path string) error {
basename := filepath.Base(path)
if !strings.HasPrefix(basename, ".") {
return fmt.Errorf("hidden files must begin with \".\"")
}
filenamePtr, err := syscall.UTF16PtrFromString(path)
if err != nil {
return err
}
return syscall.SetFileAttributes(filenamePtr, syscall.FILE_ATTRIBUTE_HIDDEN)
}

// WriteHiddenFile writes content to the file and sets the hidden attribute on it. For a hidden
// file, using ioutil.WriteFile instead will result in "Access is denied." so use this instead.
// Windows specific functionality
func WriteHiddenFile(path, content string) error {
// Ensure the filename begins with a dot
basename := filepath.Base(path)
if !strings.HasPrefix(basename, ".") {
return fmt.Errorf("hidden files must begin with \".\"")
}

// Create the file to write, making sure to set the hidden file attribute
filenamePtr, err := syscall.UTF16PtrFromString(path)
if err != nil {
return err
}
h, err := syscall.CreateFile(
filenamePtr, // filename
syscall.GENERIC_WRITE, // access
uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE), // share mode
nil, // security attributes
syscall.CREATE_ALWAYS, // creation disposition
syscall.FILE_ATTRIBUTE_HIDDEN, // flags and attributes
0, // template file handle
)
if err != nil {
return err
}
defer syscall.Close(h)

// Write contents
_, err = syscall.Write(h, []byte(content))
if err != nil {
return err
}
return nil
}
18 changes: 0 additions & 18 deletions base/set_file.go

This file was deleted.

21 changes: 0 additions & 21 deletions base/set_file_windows.go

This file was deleted.

5 changes: 1 addition & 4 deletions fsi/fsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,7 @@ func (fsi *FSI) getRepoRef(refStr string) (ref repo.DatasetRef, err error) {

func writeLinkFile(dir, linkstr string) (string, error) {
linkFile := filepath.Join(dir, QriRefFilename)
if err := ioutil.WriteFile(linkFile, []byte(linkstr), os.ModePerm); err != nil {
return "", err
}
return linkFile, base.SetFileHidden(linkFile)
return linkFile, base.WriteHiddenFile(linkFile, linkstr)
}

func removeLinkFile(dir string) error {
Expand Down

0 comments on commit 0d11744

Please sign in to comment.