예제 #1
0
// 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)
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
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
}
예제 #5
0
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
}
예제 #6
0
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
}
예제 #7
0
// 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
}
예제 #8
0
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
}
예제 #9
0
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
}
예제 #10
0
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
}
예제 #11
0
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
}
예제 #12
0
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
}
예제 #13
0
파일: windows.go 프로젝트: jeffallen/g
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
}
예제 #14
0
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
}
예제 #15
0
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}
}
예제 #16
0
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
}
예제 #17
0
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
}
예제 #18
0
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
}
예제 #19
0
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
}
예제 #20
0
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
}
예제 #21
0
// 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
}
예제 #22
0
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
}
예제 #23
0
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
}
예제 #24
0
//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
}
예제 #25
0
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
}
예제 #26
0
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
}
예제 #27
0
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)
}
예제 #28
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
}
예제 #29
0
// 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
}
예제 #30
0
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
}