github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/base/hiddenfile/hidden_file_windows.go (about)

     1  package hiddenfile
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  	"syscall"
     8  )
     9  
    10  // SetFileHidden sets the hidden attribute on the given file. Windows specific functionality
    11  func SetFileHidden(path string) error {
    12  	basename := filepath.Base(path)
    13  	if !strings.HasPrefix(basename, ".") {
    14  		return fmt.Errorf("hidden files must begin with \".\"")
    15  	}
    16  	filenamePtr, err := syscall.UTF16PtrFromString(path)
    17  	if err != nil {
    18  		return err
    19  	}
    20  	return syscall.SetFileAttributes(filenamePtr, syscall.FILE_ATTRIBUTE_HIDDEN)
    21  }
    22  
    23  // WriteHiddenFile writes content to the file and sets the hidden attribute on it. For a hidden
    24  // file, using ioutil.WriteFile instead will result in "Access is denied." so use this instead.
    25  // Windows specific functionality
    26  func WriteHiddenFile(path, content string) error {
    27  	// Ensure the filename begins with a dot
    28  	basename := filepath.Base(path)
    29  	if !strings.HasPrefix(basename, ".") {
    30  		return fmt.Errorf("hidden files must begin with \".\"")
    31  	}
    32  
    33  	// Create the file to write, making sure to set the hidden file attribute
    34  	filenamePtr, err := syscall.UTF16PtrFromString(path)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	h, err := syscall.CreateFile(
    39  		filenamePtr,           // filename
    40  		syscall.GENERIC_WRITE, // access
    41  		uint32(syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE), // share mode
    42  		nil,                           // security attributes
    43  		syscall.CREATE_ALWAYS,         // creation disposition
    44  		syscall.FILE_ATTRIBUTE_HIDDEN, // flags and attributes
    45  		0,                             // template file handle
    46  	)
    47  	if err != nil {
    48  		return err
    49  	}
    50  	defer syscall.Close(h)
    51  
    52  	// Write contents
    53  	_, err = syscall.Write(h, []byte(content))
    54  	if err != nil {
    55  		return err
    56  	}
    57  	return nil
    58  }