Bläddra i källkod

Bump Microsoft/go-winio to v0.4.11

Signed-off-by: John Howard <jhoward@microsoft.com>
John Howard 6 år sedan
förälder
incheckning
a906968a3f

+ 1 - 1
libnetwork/vendor.conf

@@ -1,6 +1,6 @@
 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
 github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
-github.com/Microsoft/go-winio v0.4.7
+github.com/Microsoft/go-winio v0.4.11
 github.com/Microsoft/hcsshim v0.7.3
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80

+ 137 - 137
libnetwork/vendor/github.com/Microsoft/go-winio/ea.go

@@ -1,137 +1,137 @@
-package winio
-
-import (
-	"bytes"
-	"encoding/binary"
-	"errors"
-)
-
-type fileFullEaInformation struct {
-	NextEntryOffset uint32
-	Flags           uint8
-	NameLength      uint8
-	ValueLength     uint16
-}
-
-var (
-	fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})
-
-	errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
-	errEaNameTooLarge  = errors.New("extended attribute name too large")
-	errEaValueTooLarge = errors.New("extended attribute value too large")
-)
-
-// ExtendedAttribute represents a single Windows EA.
-type ExtendedAttribute struct {
-	Name  string
-	Value []byte
-	Flags uint8
-}
-
-func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
-	var info fileFullEaInformation
-	err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
-	if err != nil {
-		err = errInvalidEaBuffer
-		return
-	}
-
-	nameOffset := fileFullEaInformationSize
-	nameLen := int(info.NameLength)
-	valueOffset := nameOffset + int(info.NameLength) + 1
-	valueLen := int(info.ValueLength)
-	nextOffset := int(info.NextEntryOffset)
-	if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
-		err = errInvalidEaBuffer
-		return
-	}
-
-	ea.Name = string(b[nameOffset : nameOffset+nameLen])
-	ea.Value = b[valueOffset : valueOffset+valueLen]
-	ea.Flags = info.Flags
-	if info.NextEntryOffset != 0 {
-		nb = b[info.NextEntryOffset:]
-	}
-	return
-}
-
-// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
-// buffer retrieved from BackupRead, ZwQueryEaFile, etc.
-func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {
-	for len(b) != 0 {
-		ea, nb, err := parseEa(b)
-		if err != nil {
-			return nil, err
-		}
-
-		eas = append(eas, ea)
-		b = nb
-	}
-	return
-}
-
-func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {
-	if int(uint8(len(ea.Name))) != len(ea.Name) {
-		return errEaNameTooLarge
-	}
-	if int(uint16(len(ea.Value))) != len(ea.Value) {
-		return errEaValueTooLarge
-	}
-	entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))
-	withPadding := (entrySize + 3) &^ 3
-	nextOffset := uint32(0)
-	if !last {
-		nextOffset = withPadding
-	}
-	info := fileFullEaInformation{
-		NextEntryOffset: nextOffset,
-		Flags:           ea.Flags,
-		NameLength:      uint8(len(ea.Name)),
-		ValueLength:     uint16(len(ea.Value)),
-	}
-
-	err := binary.Write(buf, binary.LittleEndian, &info)
-	if err != nil {
-		return err
-	}
-
-	_, err = buf.Write([]byte(ea.Name))
-	if err != nil {
-		return err
-	}
-
-	err = buf.WriteByte(0)
-	if err != nil {
-		return err
-	}
-
-	_, err = buf.Write(ea.Value)
-	if err != nil {
-		return err
-	}
-
-	_, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION
-// buffer for use with BackupWrite, ZwSetEaFile, etc.
-func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {
-	var buf bytes.Buffer
-	for i := range eas {
-		last := false
-		if i == len(eas)-1 {
-			last = true
-		}
-
-		err := writeEa(&buf, &eas[i], last)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return buf.Bytes(), nil
-}
+package winio
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+)
+
+type fileFullEaInformation struct {
+	NextEntryOffset uint32
+	Flags           uint8
+	NameLength      uint8
+	ValueLength     uint16
+}
+
+var (
+	fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})
+
+	errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
+	errEaNameTooLarge  = errors.New("extended attribute name too large")
+	errEaValueTooLarge = errors.New("extended attribute value too large")
+)
+
+// ExtendedAttribute represents a single Windows EA.
+type ExtendedAttribute struct {
+	Name  string
+	Value []byte
+	Flags uint8
+}
+
+func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
+	var info fileFullEaInformation
+	err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
+	if err != nil {
+		err = errInvalidEaBuffer
+		return
+	}
+
+	nameOffset := fileFullEaInformationSize
+	nameLen := int(info.NameLength)
+	valueOffset := nameOffset + int(info.NameLength) + 1
+	valueLen := int(info.ValueLength)
+	nextOffset := int(info.NextEntryOffset)
+	if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
+		err = errInvalidEaBuffer
+		return
+	}
+
+	ea.Name = string(b[nameOffset : nameOffset+nameLen])
+	ea.Value = b[valueOffset : valueOffset+valueLen]
+	ea.Flags = info.Flags
+	if info.NextEntryOffset != 0 {
+		nb = b[info.NextEntryOffset:]
+	}
+	return
+}
+
+// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
+// buffer retrieved from BackupRead, ZwQueryEaFile, etc.
+func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {
+	for len(b) != 0 {
+		ea, nb, err := parseEa(b)
+		if err != nil {
+			return nil, err
+		}
+
+		eas = append(eas, ea)
+		b = nb
+	}
+	return
+}
+
+func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {
+	if int(uint8(len(ea.Name))) != len(ea.Name) {
+		return errEaNameTooLarge
+	}
+	if int(uint16(len(ea.Value))) != len(ea.Value) {
+		return errEaValueTooLarge
+	}
+	entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))
+	withPadding := (entrySize + 3) &^ 3
+	nextOffset := uint32(0)
+	if !last {
+		nextOffset = withPadding
+	}
+	info := fileFullEaInformation{
+		NextEntryOffset: nextOffset,
+		Flags:           ea.Flags,
+		NameLength:      uint8(len(ea.Name)),
+		ValueLength:     uint16(len(ea.Value)),
+	}
+
+	err := binary.Write(buf, binary.LittleEndian, &info)
+	if err != nil {
+		return err
+	}
+
+	_, err = buf.Write([]byte(ea.Name))
+	if err != nil {
+		return err
+	}
+
+	err = buf.WriteByte(0)
+	if err != nil {
+		return err
+	}
+
+	_, err = buf.Write(ea.Value)
+	if err != nil {
+		return err
+	}
+
+	_, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION
+// buffer for use with BackupWrite, ZwSetEaFile, etc.
+func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {
+	var buf bytes.Buffer
+	for i := range eas {
+		last := false
+		if i == len(eas)-1 {
+			last = true
+		}
+
+		err := writeEa(&buf, &eas[i], last)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return buf.Bytes(), nil
+}

+ 2 - 1
libnetwork/vendor/github.com/Microsoft/go-winio/fileinfo.go

@@ -20,7 +20,8 @@ const (
 // FileBasicInfo contains file access time and file attributes information.
 type FileBasicInfo struct {
 	CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
-	FileAttributes                                          uintptr // includes padding
+	FileAttributes                                          uint32
+	pad                                                     uint32 // padding
 }
 
 // GetFileBasicInfo retrieves times and attributes for a file.

+ 27 - 30
libnetwork/vendor/github.com/Microsoft/go-winio/pipe.go

@@ -15,7 +15,6 @@ import (
 //sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
 //sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error)  [failretval==syscall.InvalidHandle] = CreateNamedPipeW
 //sys createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
-//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
 //sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
 //sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
 //sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
@@ -121,6 +120,11 @@ func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
 		// zero-byte message, ensure that all future Read() calls
 		// also return EOF.
 		f.readEOF = true
+	} else if err == syscall.ERROR_MORE_DATA {
+		// ERROR_MORE_DATA indicates that the pipe's read mode is message mode
+		// and the message still has more bytes. Treat this as a success, since
+		// this package presents all named pipes as byte streams.
+		err = nil
 	}
 	return n, err
 }
@@ -134,12 +138,14 @@ func (s pipeAddress) String() string {
 }
 
 // DialPipe connects to a named pipe by path, timing out if the connection
-// takes longer than the specified duration. If timeout is nil, then the timeout
-// is the default timeout established by the pipe server.
+// takes longer than the specified duration. If timeout is nil, then we use
+// a default timeout of 5 seconds.  (We do not use WaitNamedPipe.)
 func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
 	var absTimeout time.Time
 	if timeout != nil {
 		absTimeout = time.Now().Add(*timeout)
+	} else {
+		absTimeout = time.Now().Add(time.Second * 2)
 	}
 	var err error
 	var h syscall.Handle
@@ -148,22 +154,13 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
 		if err != cERROR_PIPE_BUSY {
 			break
 		}
-		now := time.Now()
-		var ms uint32
-		if absTimeout.IsZero() {
-			ms = cNMPWAIT_USE_DEFAULT_WAIT
-		} else if now.After(absTimeout) {
-			ms = cNMPWAIT_NOWAIT
-		} else {
-			ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000)
-		}
-		err = waitNamedPipe(path, ms)
-		if err != nil {
-			if err == cERROR_SEM_TIMEOUT {
-				return nil, ErrTimeout
-			}
-			break
+		if time.Now().After(absTimeout) {
+			return nil, ErrTimeout
 		}
+
+		// Wait 10 msec and try again. This is a rather simplistic
+		// view, as we always try each 10 milliseconds.
+		time.Sleep(time.Millisecond * 10)
 	}
 	if err != nil {
 		return nil, &os.PathError{Op: "open", Path: path, Err: err}
@@ -175,16 +172,6 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
 		return nil, err
 	}
 
-	var state uint32
-	err = getNamedPipeHandleState(h, &state, nil, nil, nil, nil, 0)
-	if err != nil {
-		return nil, err
-	}
-
-	if state&cPIPE_READMODE_MESSAGE != 0 {
-		return nil, &os.PathError{Op: "open", Path: path, Err: errors.New("message readmode pipes not supported")}
-	}
-
 	f, err := makeWin32File(h)
 	if err != nil {
 		syscall.Close(h)
@@ -354,13 +341,23 @@ func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
 	if err != nil {
 		return nil, err
 	}
-	// Immediately open and then close a client handle so that the named pipe is
-	// created but not currently accepting connections.
+	// Create a client handle and connect it.  This results in the pipe
+	// instance always existing, so that clients see ERROR_PIPE_BUSY
+	// rather than ERROR_FILE_NOT_FOUND.  This ties the first instance
+	// up so that no other instances can be used.  This would have been
+	// cleaner if the Win32 API matched CreateFile with ConnectNamedPipe
+	// instead of CreateNamedPipe.  (Apparently created named pipes are
+	// considered to be in listening state regardless of whether any
+	// active calls to ConnectNamedPipe are outstanding.)
 	h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
 	if err != nil {
 		syscall.Close(h)
 		return nil, err
 	}
+	// Close the client handle. The server side of the instance will
+	// still be busy, leading to ERROR_PIPE_BUSY instead of
+	// ERROR_NOT_FOUND, as long as we don't close the server handle,
+	// or disconnect the client with DisconnectNamedPipe.
 	syscall.Close(h2)
 	l := &win32PipeListener{
 		firstHandle:        h,