github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libdokan/createfile_test.go (about)

     1  // Copyright 2017 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build windows
     6  // +build windows
     7  
     8  package libdokan
     9  
    10  import (
    11  	"os"
    12  	"syscall"
    13  )
    14  
    15  func isSet(bit, value int) bool {
    16  	return value&bit == bit
    17  }
    18  
    19  // OpenFile opens a file with FILE_SHARE_DELETE set.
    20  // This means that the file can be renamed or deleted while it is open.
    21  func OpenFile(filename string, mode, perm int) (*os.File, error) {
    22  	path, err := syscall.UTF16PtrFromString(filename)
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  	var access uint32 = syscall.GENERIC_READ
    27  	if isSet(os.O_WRONLY, mode) || isSet(os.O_RDWR, mode) || isSet(os.O_CREATE, mode) {
    28  		access |= syscall.GENERIC_WRITE
    29  	}
    30  	var create uint32 = syscall.OPEN_EXISTING
    31  	switch {
    32  	case isSet(os.O_CREATE, mode) && isSet(os.O_EXCL, mode):
    33  		create = syscall.CREATE_NEW
    34  	case isSet(os.O_CREATE, mode) && isSet(os.O_TRUNC, mode):
    35  		create = syscall.CREATE_ALWAYS
    36  	case isSet(os.O_CREATE, mode):
    37  		create = syscall.OPEN_ALWAYS
    38  	case isSet(os.O_TRUNC, mode):
    39  		create = syscall.TRUNCATE_EXISTING
    40  	}
    41  	h, err := syscall.CreateFile(path, access,
    42  		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
    43  		nil, create, syscall.FILE_ATTRIBUTE_NORMAL, 0)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	return os.NewFile(uintptr(h), filename), nil
    48  }
    49  
    50  func Open(filename string) (*os.File, error) {
    51  	return OpenFile(filename, os.O_RDONLY, 0666)
    52  }
    53  func Create(filename string) (*os.File, error) {
    54  	return OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    55  }