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 }