// openConsole opens a console handle, using a backup if it fails. // This is used to get the exact console handle instead of the redirected // handles from panicwrap. func openConsole(name string, backup *os.File) *os.File { // Convert to UTF16 path, err := syscall.UTF16PtrFromString(name) if err != nil { log.Printf("[ERROR] wrappedstreams: %s", err) return backup } // Determine the share mode var shareMode uint32 switch name { case "CONIN$": shareMode = syscall.FILE_SHARE_READ case "CONOUT$": shareMode = syscall.FILE_SHARE_WRITE } // Get the file h, err := syscall.CreateFile( path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, shareMode, nil, syscall.OPEN_EXISTING, 0, 0) if err != nil { log.Printf("[ERROR] wrappedstreams: %s", err) return backup } // Create the Go file return os.NewFile(uintptr(h), name) }
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 }
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 }
func (p *Port) openHandle() (err error) { device := p.config.Device // add a "\\.\" prefix, e.g. "\\.\COM2" // optional for COM1-9, required for COM10 and up // if !strings.HasPrefix(device, `\\.\`) { device = `\\.\` + device } device_utf16, err := syscall.UTF16PtrFromString(device) if err != nil { return } p.handle, err = syscall.CreateFile(device_utf16, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL, 0) return }
func Read(path string) (string, uint32, error) { ptr, err := syscall.UTF16PtrFromString(path) if err != nil { return "", protocol.FlagSymlinkMissingTarget, err } handle, err := syscall.CreateFile(ptr, 0, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS|Win32FileFlagOpenReparsePoint, 0) if err != nil || handle == syscall.InvalidHandle { return "", protocol.FlagSymlinkMissingTarget, err } defer syscall.Close(handle) var ret uint16 var data reparseData r1, _, err := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), Win32FsctlGetReparsePoint, 0, 0, uintptr(unsafe.Pointer(&data)), unsafe.Sizeof(data), uintptr(unsafe.Pointer(&ret)), 0, 0) if r1 == 0 { return "", protocol.FlagSymlinkMissingTarget, err } var flags uint32 attr, err := syscall.GetFileAttributes(ptr) if err != nil { flags = protocol.FlagSymlinkMissingTarget } else if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { flags = protocol.FlagDirectory } return osutil.NormalizedFilename(data.PrintName()), flags, nil }
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 }
// dial is a helper to initiate a connection to a named pipe that has been started by a server. // The timeout is only enforced if the pipe server has already created the pipe, otherwise // this function will return immediately. func dial(address string, timeout uint32) (*PipeConn, error) { name, err := syscall.UTF16PtrFromString(string(address)) if err != nil { return nil, err } // If at least one instance of the pipe has been created, this function // will wait timeout milliseconds for it to become available. // It will return immediately regardless of timeout, if no instances // of the named pipe have been created yet. // If this returns with no error, there is a pipe available. if err := waitNamedPipe(name, timeout); err != nil { if err == error_bad_pathname { // badly formatted pipe name return nil, badAddr(address) } return nil, err } pathp, err := syscall.UTF16PtrFromString(address) if err != nil { return nil, err } handle, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, uint32(syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE), nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { return nil, err } return &PipeConn{handle: handle, addr: PipeAddr(address)}, nil }
func (BasicFilesystem) ReadSymlink(path string) (string, LinkTargetType, error) { ptr, err := syscall.UTF16PtrFromString(path) if err != nil { return "", LinkTargetUnknown, err } handle, err := syscall.CreateFile(ptr, 0, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS|win32FileFlagOpenReparsePoint, 0) if err != nil || handle == syscall.InvalidHandle { return "", LinkTargetUnknown, err } defer syscall.Close(handle) var ret uint16 var data reparseData r1, _, err := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), win32FsctlGetReparsePoint, 0, 0, uintptr(unsafe.Pointer(&data)), unsafe.Sizeof(data), uintptr(unsafe.Pointer(&ret)), 0, 0) if r1 == 0 { return "", LinkTargetUnknown, err } tt := LinkTargetUnknown if attr, err := syscall.GetFileAttributes(ptr); err == nil { if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { tt = LinkTargetDirectory } else { tt = LinkTargetFile } } return osutil.NormalizedFilename(data.printName()), tt, nil }
func OpenFileForRedirect(name string, read bool) (*os.File, error) { var wmode, cmode uint32 if read { wmode = syscall.GENERIC_READ cmode = syscall.OPEN_EXISTING } else { wmode = syscall.GENERIC_WRITE cmode = syscall.CREATE_ALWAYS } h, e := syscall.CreateFile( syscall.StringToUTF16Ptr(name), wmode, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, nil, cmode, win32.FILE_FLAG_SEQUENTIAL_SCAN, 0) if e != nil { return nil, e } return os.NewFile(uintptr(h), name), nil }
func open(path string, flag int, perm os.FileMode) (*os.File, error) { if path == "" { return nil, fmt.Errorf("cannot open empty filename") } var access uint32 switch flag { case syscall.O_RDONLY: access = syscall.GENERIC_READ case syscall.O_WRONLY: access = syscall.GENERIC_WRITE case syscall.O_RDWR: access = syscall.GENERIC_READ | syscall.GENERIC_WRITE case syscall.O_WRONLY | syscall.O_CREAT: access = syscall.GENERIC_ALL default: panic(fmt.Errorf("flag %v is not supported", flag)) } fd, err := syscall.CreateFile(&(syscall.StringToUTF16(path)[0]), access, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, nil, syscall.OPEN_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0) if err != nil { return nil, err } return os.NewFile(uintptr(fd), path), nil }
func dialSerial(path string) (io.ReadWriteCloser, error) { log.Debug("ron dialSerial: %v", path) h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(path), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { return nil, err } f := os.NewFile(uintptr(h), path) ro, err := newOverlapped() if err != nil { return nil, err } wo, err := newOverlapped() if err != nil { return nil, err } conn := new(virtioPort) conn.f = f conn.fd = h conn.ro = ro conn.wo = wo return conn, nil }
func OpenPort(name string, baud int) (rwc io.ReadWriteCloser, err error) { if len(name) > 0 && name[0] != '\\' { name = "\\\\.\\" + name } fd, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { return nil, err } f := os.NewFile(uintptr(fd), name) defer func() { if err != nil { f.Close() } }() if err = syscallEvent(fd, "state"); err != nil { fmt.Printf("[ERROR] oops! %#v\n", err) return } if err = syscallEvent(fd, "setup"); err != nil { fmt.Printf("[ERROR] oops! %#v\n", err) return } if err = syscallEvent(fd, "timeouts"); err != nil { fmt.Printf("[ERROR] oops! %#v\n", err) return } if err = syscallEvent(fd, "mask"); err != nil { fmt.Printf("[ERROR] oops! %#v\n", err) return } ro, err := genOverlap() if err != nil { return } wo, err := genOverlap() if err != nil { return } dev := new(SerialDevice) dev.f = f dev.fd = fd dev.ro = ro dev.wo = wo return dev, nil }
func Open(file string, inictl string) (p Port, err error) { const ( access = syscall.GENERIC_READ | syscall.GENERIC_WRITE sharemode = 0 createmode = syscall.OPEN_EXISTING flags = win.FILE_FLAG_OVERLAPPED ) // make sure COM interfaces with numbers >9 get prefixed properly if match, _ := filepath.Match("[cC][oO][mM]1[0-9]", file); match { file = `\\.\` + file } fd, e := syscall.CreateFile(syscall.StringToUTF16Ptr(file), access, sharemode, nil, createmode, flags, 0) if e != nil { goto error } goto try error: err = &os.PathError{"open", file, e} return try: d := new(dev) d.fd = fd d.name = file d.encaps = d if err = d.Ctl(initDefault, inictl); err != nil { return } d.initDone = true if d.ev.r, e = win.CreateEvent(win.EvManualReset, !win.EvInitiallyOn); e != nil { goto error } if d.ev.w, e = win.CreateEvent(win.EvManualReset, !win.EvInitiallyOn); e != nil { goto error } cto := win.CommTimeouts{ // ReadIntervalTimeout: ^uint32(0), // ReadTotalTimeoutMultiplier: ^uint32(0), // ReadTotalTimeoutConstant: ^uint32(0)-1, ReadIntervalTimeout: 10, } if e = win.SetCommTimeouts(d.fd, &cto); e != nil { goto error } if e = win.SetupComm(d.fd, 4096, 4096); e != nil { goto error } p = d return }
func newHandle(c *Config) (handle syscall.Handle, err error) { handle, err = syscall.CreateFile( syscall.StringToUTF16Ptr(c.Address), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, // mode nil, // security syscall.OPEN_EXISTING, // create mode 0, // attributes 0) // templates if err != nil { return } defer func() { if err != nil { syscall.CloseHandle(handle) } }() var dcb C.DCB dcb.BaudRate = C.DWORD(c.BaudRate) // Data bits if c.DataBits == 0 { dcb.ByteSize = 8 } else { dcb.ByteSize = C.BYTE(c.DataBits) } // Stop bits switch c.StopBits { case 0, 1: // Default is one stop bit. dcb.StopBits = C.ONESTOPBIT case 2: dcb.StopBits = C.TWOSTOPBITS default: err = fmt.Errorf("serial: unsupported stop bits %v", c.StopBits) return } // Parity switch c.Parity { case "", "E": // Default parity mode is Even. dcb.Parity = C.EVENPARITY case "O": dcb.Parity = C.ODDPARITY case "N": dcb.Parity = C.NOPARITY default: err = fmt.Errorf("serial: unsupported parity %v", c.Parity) return } if C.SetCommState(C.HANDLE(handle), &dcb) == 0 { err = fmt.Errorf("serial: could not set device state: %v", syscall.GetLastError()) return } return }
func MakeFileMutex(filename string) *FileMutex { if filename == "" { return &FileMutex{fd: INVALID_FILE_HANDLE} } fd, err := syscall.CreateFile(&(syscall.StringToUTF16(filename)[0]), syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, nil, syscall.OPEN_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0) if err != nil { panic(err) } return &FileMutex{fd: fd} }
func newLock(fileName string) (Releaser, error) { pathp, err := syscall.UTF16PtrFromString(fileName) if err != nil { return nil, err } fd, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0) if err != nil { return nil, err } return &windowsLock{fd}, nil }
func (l *locker) Lock(lockfilename string) error { if l.fd != INVALID_FILE_HANDLE { return ErrFailedToAcquireLock } var flags uint32 if l.nonblock { flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY } else { flags = LOCKFILE_EXCLUSIVE_LOCK } if lockfilename == "" { return ErrLockFileEmpty } fd, err := syscall.CreateFile(&(syscall.StringToUTF16(lockfilename)[0]), syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, nil, syscall.OPEN_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0) if err != nil { return fmt.Errorf("setlock: fatal: unable to open %s: temporary failure", lockfilename) } if fd == INVALID_FILE_HANDLE { return ErrFailedToAcquireLock } defer func() { // Close this descriptor if we failed to lock if l.fd == INVALID_FILE_HANDLE { // l.fd is not set, I guess we didn't suceed syscall.CloseHandle(fd) } }() var ol syscall.Overlapped var mu sync.RWMutex mu.Lock() defer mu.Unlock() r1, _, _ := syscall.Syscall6( procLockFileEx.Addr(), 6, uintptr(fd), // handle uintptr(flags), uintptr(0), // reserved uintptr(1), // locklow uintptr(0), // lockhigh uintptr(unsafe.Pointer(&ol)), ) if r1 == 0 { return ErrFailedToAcquireLock } l.fd = fd return nil }
func newFileLock(path string) (fl fileLock, err error) { pathp, err := syscall.UTF16PtrFromString(path) if err != nil { return } fd, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0) if err != nil { return } fl = &windowsFileLock{fd: fd} return }
func (p *Port) openHandle() (err error) { device := p.config.Device if !strings.HasPrefix(device, `\\.\`) { device = `\\.\` + device } device_utf16, err := syscall.UTF16PtrFromString(device) if err != nil { return } p.handle, err = syscall.CreateFile(device_utf16, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL, 0) return }
func openPort(name string, baud int) (rwc io.ReadWriteCloser, err os.Error) { if len(name) > 0 && name[0] != '\\' { name = "\\\\.\\" + name } const FILE_FLAGS_OVERLAPPED = 0x40000000 h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(name), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL|FILE_FLAGS_OVERLAPPED, 0) if e != 0 { err = &os.PathError{"open", name, os.Errno(e)} return } f := os.NewFile(h, name) defer func() { if err != nil { f.Close() } }() if err = setCommState(h, baud); err != nil { return } if err = setupComm(h, 64, 64); err != nil { return } if err = setCommTimeouts(h); err != nil { return } if err = setCommMask(h); err != nil { return } ro, err := newOverlapped() if err != nil { return } wo, err := newOverlapped() if err != nil { return } port := new(serialPort) port.f = f port.fd = h port.ro = ro port.wo = wo return port, nil }
// OpenForBackup opens a file or directory, potentially skipping access checks if the backup // or restore privileges have been acquired. // // If the file opened was a directory, it cannot be used with Readdir(). func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) { winPath, err := syscall.UTF16FromString(path) if err != nil { return nil, err } h, err := syscall.CreateFile(&winPath[0], access, share, nil, createmode, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) if err != nil { err = &os.PathError{Op: "open", Path: path, Err: err} return nil, err } return os.NewFile(uintptr(h), path), nil }
func openPort(name string, c *Config) (rwc io.ReadWriteCloser, err error) { if len(name) > 0 && name[0] != '\\' { name = "\\\\.\\" + name } h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { return nil, err } f := os.NewFile(uintptr(h), name) defer func() { if err != nil { f.Close() } }() if err = setCommState(h, c); err != nil { return } if err = setupComm(h, 64, 64); err != nil { return } if err = setCommMask(h); err != nil { return } ro, err := newOverlapped() if err != nil { return } wo, err := newOverlapped() if err != nil { return } port := new(serialPort) port.f = f port.fd = h port.ro = ro port.wo = wo var timeouts structTimeouts port.st = &timeouts port.SetTimeouts(c.ReadTimeout) return port, nil }
func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os.File, err error) { winPath, err := syscall.UTF16FromString(path) if err != nil { return } h, err := syscall.CreateFile(&winPath[0], mode, syscall.FILE_SHARE_READ, nil, createDisposition, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) if err != nil { err = &os.PathError{"open", path, err} return } file = os.NewFile(uintptr(h), path) return }
//func openPort(name string) (rwc io.ReadWriteCloser, err error) { // TODO func Open(name string) (rwc SerialPort, err error) { if len(name) > 0 && name[0] != '\\' { name = "\\\\.\\" + name } h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { return nil, opError{"open", name, err} } f := os.NewFile(uintptr(h), name) defer func() { if err != nil { f.Close() } }() /*if err = setCommState(h, baud); err != nil { return }*/ if err = setupComm(h, 64, 64); err != nil { return } if err = setCommTimeouts(h, 0.0); err != nil { return } if err = setCommMask(h); err != nil { return } ro, err := newOverlapped() if err != nil { return } wo, err := newOverlapped() if err != nil { return } port := new(serialPort) port.f = f port.fd = h port.ro = ro port.wo = wo return port, nil }
func openPort(name string, baud int, databits byte, parity byte, stopbits byte, readTimeout time.Duration) (p *Port, err error) { if len(name) > 0 && name[0] != '\\' { name = "\\\\.\\" + name } h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { return nil, err } f := os.NewFile(uintptr(h), name) defer func() { if err != nil { f.Close() } }() if err = setCommState(h, baud, databits, parity, stopbits); err != nil { return } if err = setupComm(h, 64, 64); err != nil { return } if err = setCommTimeouts(h, readTimeout); err != nil { return } if err = setCommMask(h); err != nil { return } ro, err := newOverlapped() if err != nil { return } wo, err := newOverlapped() if err != nil { return } port := new(Port) port.f = f port.fd = h port.ro = ro port.wo = wo return port, nil }
func openInternal(options OpenOptions) (io.ReadWriteCloser, error) { if len(options.PortName) > 0 && options.PortName[0] != '\\' { options.PortName = "\\\\.\\" + options.PortName } h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(options.PortName), syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { return nil, err } f := os.NewFile(uintptr(h), options.PortName) defer func() { if err != nil { f.Close() } }() if err = setCommState(h, options); err != nil { return nil, err } if err = setupComm(h, 64, 64); err != nil { return nil, err } if err = setCommTimeouts(h); err != nil { return nil, err } if err = setCommMask(h); err != nil { return nil, err } ro, err := newOverlapped() if err != nil { return nil, err } wo, err := newOverlapped() if err != nil { return nil, err } port := new(serialPort) port.f = f port.fd = h port.ro = ro port.wo = wo return port, nil }
func openDir(path string) (fd syscall.Handle, err error) { if len(path) == 0 { return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND } pathp, err := syscall.UTF16PtrFromString(path) if err != nil { return syscall.InvalidHandle, err } access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE) sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE) createmode := uint32(syscall.OPEN_EXISTING) fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS) return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0) }
func syscallOpenSequential(path string, mode int, _ uint32) (fd syscall.Handle, err error) { if len(path) == 0 { return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND } pathp, err := syscall.UTF16PtrFromString(path) if err != nil { return syscall.InvalidHandle, err } var access uint32 switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) { case syscall.O_RDONLY: access = syscall.GENERIC_READ case syscall.O_WRONLY: access = syscall.GENERIC_WRITE case syscall.O_RDWR: access = syscall.GENERIC_READ | syscall.GENERIC_WRITE } if mode&syscall.O_CREAT != 0 { access |= syscall.GENERIC_WRITE } if mode&syscall.O_APPEND != 0 { access &^= syscall.GENERIC_WRITE access |= syscall.FILE_APPEND_DATA } sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE) var sa *syscall.SecurityAttributes if mode&syscall.O_CLOEXEC == 0 { sa = makeInheritSa() } var createmode uint32 switch { case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL): createmode = syscall.CREATE_NEW case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC): createmode = syscall.CREATE_ALWAYS case mode&syscall.O_CREAT == syscall.O_CREAT: createmode = syscall.OPEN_ALWAYS case mode&syscall.O_TRUNC == syscall.O_TRUNC: createmode = syscall.TRUNCATE_EXISTING default: createmode = syscall.OPEN_EXISTING } // Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang. //https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0) return h, e }
// NewFileLock try to lock the file, if failed return nil. func NewFileLock(path string) (*FileLock, error) { pathp, err := syscall.UTF16PtrFromString(path) if err != nil { return nil, err } fd, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0, ) if err != nil { return nil, err } return &FileLock{fd: fd}, nil }
func Lock(name string) (io.Closer, error) { p, err := syscall.UTF16PtrFromString(name) if err != nil { return nil, err } fd, err := syscall.CreateFile(p, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0, ) if err != nil { return nil, err } return lockCloser{fd: fd}, nil }