Kaynağa Gözat

Merge pull request #1412 from msabansal/dnsv2

DNS support for Windows
Madhu Venugopal 8 yıl önce
ebeveyn
işleme
9fae5d1779
89 değiştirilmiş dosya ile 11000 ekleme ve 504 silme
  1. 7 4
      libnetwork/Godeps/Godeps.json
  2. 25 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/backup.go
  3. 28 4
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/fileinfo.go
  4. 60 19
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/privilege.go
  5. 8 4
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/reparse.go
  6. 8 4
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/zsyscall.go
  7. 12 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/README.md
  8. 172 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/baselayer.go
  9. 79 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/callback.go
  10. 7 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/cgo.go
  11. 565 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/container.go
  12. 0 22
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/createcomputesystem.go
  13. 0 101
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/createprocess.go
  14. 190 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/errors.go
  15. 26 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/expandsandboxsize.go
  16. 8 6
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/exportlayer.go
  17. 63 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/hcsshim.go
  18. 25 12
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/hnsfuncs.go
  19. 52 12
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/importlayer.go
  20. 144 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/interface.go
  21. 90 42
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/legacy.go
  22. 15 1
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/mksyscall_windows.go
  23. 389 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/process.go
  24. 0 22
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/resizeconsole.go
  25. 0 43
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/shutdownterminatecomputesystem.go
  26. 0 21
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/startcomputesystem.go
  27. 0 20
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/terminateprocess.go
  28. 39 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/utils.go
  29. 126 0
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/waithelper.go
  30. 0 20
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/waitprocess.go
  31. 579 6
      libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/zhcsshim.go
  32. 8 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/asm.s
  33. 13 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/asm_windows_386.s
  34. 13 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/asm_windows_amd64.s
  35. 275 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/dll_windows.go
  36. 14 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/env_unset.go
  37. 25 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/env_windows.go
  38. 20 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/eventlog.go
  39. 97 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/exec_windows.go
  40. 30 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/race.go
  41. 25 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/race0.go
  42. 178 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/key.go
  43. 33 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/syscall.go
  44. 384 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/value.go
  45. 82 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/zsyscall_windows.go
  46. 435 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/security_windows.go
  47. 143 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/service.go
  48. 22 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/str.go
  49. 56 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/debug/log.go
  50. 45 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/debug/service.go
  51. 48 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/event.go
  52. 80 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/eventlog/install.go
  53. 70 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/eventlog/log.go
  54. 22 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/beep.go
  55. 92 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/install.go
  56. 76 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/main.go
  57. 62 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/manage.go
  58. 82 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/service.go
  59. 24 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/go12.c
  60. 11 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/go12.go
  61. 31 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/go13.go
  62. 139 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/mgr/config.go
  63. 119 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/mgr/mgr.go
  64. 74 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/mgr/service.go
  65. 62 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/security.go
  66. 316 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/service.go
  67. 67 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/sys_386.s
  68. 41 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/sys_amd64.s
  69. 77 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/syscall.go
  70. 990 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/syscall_windows.go
  71. 2220 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/zsyscall_windows.go
  72. 1242 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/ztypes_windows.go
  73. 22 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/ztypes_windows_386.go
  74. 22 0
      libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/ztypes_windows_amd64.go
  75. 2 0
      libnetwork/controller.go
  76. 15 0
      libnetwork/drivers/windows/labels.go
  77. 69 1
      libnetwork/drivers/windows/windows.go
  78. 1 1
      libnetwork/drivers/windows/windows_test.go
  79. 8 0
      libnetwork/endpoint.go
  80. 5 9
      libnetwork/libnetwork_internal_test.go
  81. 2 2
      libnetwork/libnetwork_test.go
  82. 3 0
      libnetwork/netlabel/labels.go
  83. 128 0
      libnetwork/network.go
  84. 8 0
      libnetwork/network_unix.go
  85. 52 0
      libnetwork/network_windows.go
  86. 72 32
      libnetwork/resolver.go
  87. 2 2
      libnetwork/resolver_unix.go
  88. 27 92
      libnetwork/sandbox.go
  89. 2 2
      libnetwork/sandbox_dns_unix.go

+ 7 - 4
libnetwork/Godeps/Godeps.json

@@ -20,12 +20,11 @@
 		},
 		{
 			"ImportPath": "github.com/Microsoft/go-winio",
-			"Comment": "v0.1.0",
-			"Rev": "8f9387ea7efabb228a981b9c381142be7667967f"
+			"Rev": "ce2922f643c8fd76b46cadc7f404a06282678b34"
 		},
 		{
 			"ImportPath": "github.com/Microsoft/hcsshim",
-			"Rev": "116e0e9f5ced0cec94ae46d0aa1b3002a325f532"
+			"Rev": "6611816fb4c1693b429ada0f358102119a0b1466"
 		},
 		{
 			"ImportPath": "github.com/Sirupsen/logrus",
@@ -429,6 +428,10 @@
 		{
 			"ImportPath": "golang.org/x/sys/unix",
 			"Rev": "5eaf0df67e70d6997a9fe0ed24383fa1b01638d3"
-		}
+		},
+		{
+			"ImportPath": "golang.org/x/sys/windows",
+			"Rev": "5eaf0df67e70d6997a9fe0ed24383fa1b01638d3"
+ 		}
 	]
 }

+ 25 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/backup.go

@@ -26,10 +26,18 @@ const (
 	BackupReparseData
 	BackupSparseBlock
 	BackupTxfsData
+)
 
+const (
 	StreamSparseAttributes = uint32(8)
 )
 
+const (
+	WRITE_DAC              = 0x40000
+	WRITE_OWNER            = 0x80000
+	ACCESS_SYSTEM_SECURITY = 0x1000000
+)
+
 // BackupHeader represents a backup stream of a file.
 type BackupHeader struct {
 	Id         uint32 // The backup stream ID
@@ -239,3 +247,20 @@ func (w *BackupFileWriter) Close() error {
 	}
 	return 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|syscall.FILE_FLAG_OPEN_REPARSE_POINT, 0)
+	if err != nil {
+		err = &os.PathError{Op: "open", Path: path, Err: err}
+		return nil, err
+	}
+	return os.NewFile(uintptr(h), path), nil
+}

+ 28 - 4
libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/fileinfo.go

@@ -9,22 +9,46 @@ import (
 //sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
 //sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
 
+const (
+	fileBasicInfo = 0
+	fileIDInfo    = 0x12
+)
+
+// FileBasicInfo contains file access time and file attributes information.
 type FileBasicInfo struct {
 	CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
 	FileAttributes                                          uintptr // includes padding
 }
 
+// GetFileBasicInfo retrieves times and attributes for a file.
 func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
 	bi := &FileBasicInfo{}
-	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), 0, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
-		return nil, &os.PathError{"GetFileInformationByHandleEx", f.Name(), err}
+	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
+		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
 	}
 	return bi, nil
 }
 
+// SetFileBasicInfo sets times and attributes for a file.
 func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
-	if err := setFileInformationByHandle(syscall.Handle(f.Fd()), 0, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
-		return &os.PathError{"SetFileInformationByHandle", f.Name(), err}
+	if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
+		return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
 	}
 	return nil
 }
+
+// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
+// unique on a system.
+type FileIDInfo struct {
+	VolumeSerialNumber uint64
+	FileID             [16]byte
+}
+
+// GetFileID retrieves the unique (volume, file ID) pair for a file.
+func GetFileID(f *os.File) (*FileIDInfo, error) {
+	fileID := &FileIDInfo{}
+	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
+		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
+	}
+	return fileID, nil
+}

+ 60 - 19
libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/privilege.go

@@ -5,14 +5,17 @@ import (
 	"encoding/binary"
 	"fmt"
 	"runtime"
+	"sync"
 	"syscall"
 	"unicode/utf16"
+
+	"golang.org/x/sys/windows"
 )
 
-//sys adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
+//sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
 //sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf
 //sys revertToSelf() (err error) = advapi32.RevertToSelf
-//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) = advapi32.OpenThreadToken
+//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken
 //sys getCurrentThread() (h syscall.Handle) = GetCurrentThread
 //sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW
 //sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
@@ -34,6 +37,12 @@ const (
 	securityDelegation
 )
 
+var (
+	privNames     = make(map[string]uint64)
+	privNameMutex sync.Mutex
+)
+
+// PrivilegeError represents an error enabling privileges.
 type PrivilegeError struct {
 	privileges []uint64
 }
@@ -56,19 +65,16 @@ func (e *PrivilegeError) Error() string {
 	return s
 }
 
+// RunWithPrivilege enables a single privilege for a function call.
 func RunWithPrivilege(name string, fn func() error) error {
 	return RunWithPrivileges([]string{name}, fn)
 }
 
+// RunWithPrivileges enables privileges for a function call.
 func RunWithPrivileges(names []string, fn func() error) error {
-	var privileges []uint64
-	for _, name := range names {
-		p := uint64(0)
-		err := lookupPrivilegeValue("", name, &p)
-		if err != nil {
-			return err
-		}
-		privileges = append(privileges, p)
+	privileges, err := mapPrivileges(names)
+	if err != nil {
+		return err
 	}
 	runtime.LockOSThread()
 	defer runtime.UnlockOSThread()
@@ -84,7 +90,43 @@ func RunWithPrivileges(names []string, fn func() error) error {
 	return fn()
 }
 
-func adjustPrivileges(token syscall.Handle, privileges []uint64) error {
+func mapPrivileges(names []string) ([]uint64, error) {
+	var privileges []uint64
+	privNameMutex.Lock()
+	defer privNameMutex.Unlock()
+	for _, name := range names {
+		p, ok := privNames[name]
+		if !ok {
+			err := lookupPrivilegeValue("", name, &p)
+			if err != nil {
+				return nil, err
+			}
+			privNames[name] = p
+		}
+		privileges = append(privileges, p)
+	}
+	return privileges, nil
+}
+
+// EnableProcessPrivileges enables privileges globally for the process.
+func EnableProcessPrivileges(names []string) error {
+	privileges, err := mapPrivileges(names)
+	if err != nil {
+		return err
+	}
+
+	p, _ := windows.GetCurrentProcess()
+	var token windows.Token
+	err = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token)
+	if err != nil {
+		return err
+	}
+
+	defer token.Close()
+	return adjustPrivileges(token, privileges)
+}
+
+func adjustPrivileges(token windows.Token, privileges []uint64) error {
 	var b bytes.Buffer
 	binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
 	for _, p := range privileges {
@@ -113,23 +155,22 @@ func getPrivilegeName(luid uint64) string {
 
 	var displayNameBuffer [256]uint16
 	displayBufSize := uint32(len(displayNameBuffer))
-	var langId uint32
-	err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langId)
+	var langID uint32
+	err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langID)
 	if err != nil {
-		return fmt.Sprintf("<unknown privilege %s>", utf16.Decode(nameBuffer[:bufSize]))
+		return fmt.Sprintf("<unknown privilege %s>", string(utf16.Decode(nameBuffer[:bufSize])))
 	}
 
 	return string(utf16.Decode(displayNameBuffer[:displayBufSize]))
 }
 
-func newThreadToken() (syscall.Handle, error) {
+func newThreadToken() (windows.Token, error) {
 	err := impersonateSelf(securityImpersonation)
 	if err != nil {
-		panic(err)
 		return 0, err
 	}
 
-	var token syscall.Handle
+	var token windows.Token
 	err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token)
 	if err != nil {
 		rerr := revertToSelf()
@@ -141,10 +182,10 @@ func newThreadToken() (syscall.Handle, error) {
 	return token, nil
 }
 
-func releaseThreadToken(h syscall.Handle) {
+func releaseThreadToken(h windows.Token) {
 	err := revertToSelf()
 	if err != nil {
 		panic(err)
 	}
-	syscall.Close(h)
+	h.Close()
 }

+ 8 - 4
libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/reparse.go

@@ -43,8 +43,12 @@ func (e *UnsupportedReparsePointError) Error() string {
 // DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink
 // or a mount point.
 func DecodeReparsePoint(b []byte) (*ReparsePoint, error) {
-	isMountPoint := false
 	tag := binary.LittleEndian.Uint32(b[0:4])
+	return DecodeReparsePointData(tag, b[8:])
+}
+
+func DecodeReparsePointData(tag uint32, b []byte) (*ReparsePoint, error) {
+	isMountPoint := false
 	switch tag {
 	case reparseTagMountPoint:
 		isMountPoint = true
@@ -52,11 +56,11 @@ func DecodeReparsePoint(b []byte) (*ReparsePoint, error) {
 	default:
 		return nil, &UnsupportedReparsePointError{tag}
 	}
-	nameOffset := 16 + binary.LittleEndian.Uint16(b[12:14])
+	nameOffset := 8 + binary.LittleEndian.Uint16(b[4:6])
 	if !isMountPoint {
 		nameOffset += 4
 	}
-	nameLength := binary.LittleEndian.Uint16(b[14:16])
+	nameLength := binary.LittleEndian.Uint16(b[6:8])
 	name := make([]uint16, nameLength/2)
 	err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name)
 	if err != nil {
@@ -76,7 +80,7 @@ func EncodeReparsePoint(rp *ReparsePoint) []byte {
 	var ntTarget string
 	relative := false
 	if strings.HasPrefix(rp.Target, `\\?\`) {
-		ntTarget = rp.Target
+		ntTarget = `\??\` + rp.Target[4:]
 	} else if strings.HasPrefix(rp.Target, `\\`) {
 		ntTarget = `\??\UNC\` + rp.Target[2:]
 	} else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' {

+ 8 - 4
libnetwork/Godeps/_workspace/src/github.com/Microsoft/go-winio/zsyscall.go

@@ -2,8 +2,12 @@
 
 package winio
 
-import "unsafe"
-import "syscall"
+import (
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
 
 var _ unsafe.Pointer
 
@@ -300,7 +304,7 @@ func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, si
 	return
 }
 
-func adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
+func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
 	var _p0 uint32
 	if releaseAll {
 		_p0 = 1
@@ -343,7 +347,7 @@ func revertToSelf() (err error) {
 	return
 }
 
-func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) {
+func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
 	var _p0 uint32
 	if openAsSelf {
 		_p0 = 1

+ 12 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/README.md

@@ -0,0 +1,12 @@
+# hcsshim
+
+This package supports launching Windows Server containers from Go. It is
+primarily used in the [Docker Engine](https://github.com/docker/docker) project,
+but it can be freely used by other projects as well.
+
+This project has adopted the [Microsoft Open Source Code of
+Conduct](https://opensource.microsoft.com/codeofconduct/). For more information
+see the [Code of Conduct
+FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
+[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional
+questions or comments.

+ 172 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/baselayer.go

@@ -0,0 +1,172 @@
+package hcsshim
+
+import (
+	"errors"
+	"os"
+	"path/filepath"
+	"syscall"
+
+	"github.com/Microsoft/go-winio"
+)
+
+type baseLayerWriter struct {
+	root         string
+	f            *os.File
+	bw           *winio.BackupFileWriter
+	err          error
+	hasUtilityVM bool
+	dirInfo      []dirInfo
+}
+
+type dirInfo struct {
+	path     string
+	fileInfo winio.FileBasicInfo
+}
+
+func (w *baseLayerWriter) closeCurrentFile() error {
+	if w.f != nil {
+		err := w.bw.Close()
+		err2 := w.f.Close()
+		w.f = nil
+		w.bw = nil
+		if err != nil {
+			return err
+		}
+		if err2 != nil {
+			return err2
+		}
+	}
+	return nil
+}
+
+func (w *baseLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) (err error) {
+	defer func() {
+		if err != nil {
+			w.err = err
+		}
+	}()
+
+	err = w.closeCurrentFile()
+	if err != nil {
+		return err
+	}
+
+	if filepath.ToSlash(name) == `UtilityVM/Files` {
+		w.hasUtilityVM = true
+	}
+
+	path := filepath.Join(w.root, name)
+	path, err = makeLongAbsPath(path)
+	if err != nil {
+		return err
+	}
+
+	var f *os.File
+	defer func() {
+		if f != nil {
+			f.Close()
+		}
+	}()
+
+	createmode := uint32(syscall.CREATE_NEW)
+	if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+		err := os.Mkdir(path, 0)
+		if err != nil && !os.IsExist(err) {
+			return err
+		}
+		createmode = syscall.OPEN_EXISTING
+		if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
+			w.dirInfo = append(w.dirInfo, dirInfo{path, *fileInfo})
+		}
+	}
+
+	mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY)
+	f, err = winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createmode)
+	if err != nil {
+		return makeError(err, "Failed to OpenForBackup", path)
+	}
+
+	err = winio.SetFileBasicInfo(f, fileInfo)
+	if err != nil {
+		return makeError(err, "Failed to SetFileBasicInfo", path)
+	}
+
+	w.f = f
+	w.bw = winio.NewBackupFileWriter(f, true)
+	f = nil
+	return nil
+}
+
+func (w *baseLayerWriter) AddLink(name string, target string) (err error) {
+	defer func() {
+		if err != nil {
+			w.err = err
+		}
+	}()
+
+	err = w.closeCurrentFile()
+	if err != nil {
+		return err
+	}
+
+	linkpath, err := makeLongAbsPath(filepath.Join(w.root, name))
+	if err != nil {
+		return err
+	}
+
+	linktarget, err := makeLongAbsPath(filepath.Join(w.root, target))
+	if err != nil {
+		return err
+	}
+
+	return os.Link(linktarget, linkpath)
+}
+
+func (w *baseLayerWriter) Remove(name string) error {
+	return errors.New("base layer cannot have tombstones")
+}
+
+func (w *baseLayerWriter) Write(b []byte) (int, error) {
+	n, err := w.bw.Write(b)
+	if err != nil {
+		w.err = err
+	}
+	return n, err
+}
+
+func (w *baseLayerWriter) Close() error {
+	err := w.closeCurrentFile()
+	if err != nil {
+		return err
+	}
+	if w.err == nil {
+		// Restore the file times of all the directories, since they may have
+		// been modified by creating child directories.
+		for i := range w.dirInfo {
+			di := &w.dirInfo[len(w.dirInfo)-i-1]
+			f, err := winio.OpenForBackup(di.path, uint32(syscall.GENERIC_READ|syscall.GENERIC_WRITE), syscall.FILE_SHARE_READ, syscall.OPEN_EXISTING)
+			if err != nil {
+				return makeError(err, "Failed to OpenForBackup", di.path)
+			}
+
+			err = winio.SetFileBasicInfo(f, &di.fileInfo)
+			f.Close()
+			if err != nil {
+				return makeError(err, "Failed to SetFileBasicInfo", di.path)
+			}
+		}
+
+		err = ProcessBaseLayer(w.root)
+		if err != nil {
+			return err
+		}
+
+		if w.hasUtilityVM {
+			err = ProcessUtilityVMImage(filepath.Join(w.root, "UtilityVM"))
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return w.err
+}

+ 79 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/callback.go

@@ -0,0 +1,79 @@
+package hcsshim
+
+import (
+	"sync"
+	"syscall"
+)
+
+var (
+	nextCallback    uintptr
+	callbackMap     = map[uintptr]*notifcationWatcherContext{}
+	callbackMapLock = sync.RWMutex{}
+
+	notificationWatcherCallback = syscall.NewCallback(notificationWatcher)
+
+	// Notifications for HCS_SYSTEM handles
+	hcsNotificationSystemExited          hcsNotification = 0x00000001
+	hcsNotificationSystemCreateCompleted hcsNotification = 0x00000002
+	hcsNotificationSystemStartCompleted  hcsNotification = 0x00000003
+	hcsNotificationSystemPauseCompleted  hcsNotification = 0x00000004
+	hcsNotificationSystemResumeCompleted hcsNotification = 0x00000005
+
+	// Notifications for HCS_PROCESS handles
+	hcsNotificationProcessExited hcsNotification = 0x00010000
+
+	// Common notifications
+	hcsNotificationInvalid           hcsNotification = 0x00000000
+	hcsNotificationServiceDisconnect hcsNotification = 0x01000000
+)
+
+type hcsNotification uint32
+type notificationChannel chan error
+
+type notifcationWatcherContext struct {
+	channels notificationChannels
+	handle   hcsCallback
+}
+
+type notificationChannels map[hcsNotification]notificationChannel
+
+func newChannels() notificationChannels {
+	channels := make(notificationChannels)
+
+	channels[hcsNotificationSystemExited] = make(notificationChannel, 1)
+	channels[hcsNotificationSystemCreateCompleted] = make(notificationChannel, 1)
+	channels[hcsNotificationSystemStartCompleted] = make(notificationChannel, 1)
+	channels[hcsNotificationSystemPauseCompleted] = make(notificationChannel, 1)
+	channels[hcsNotificationSystemResumeCompleted] = make(notificationChannel, 1)
+	channels[hcsNotificationProcessExited] = make(notificationChannel, 1)
+	channels[hcsNotificationServiceDisconnect] = make(notificationChannel, 1)
+	return channels
+}
+func closeChannels(channels notificationChannels) {
+	close(channels[hcsNotificationSystemExited])
+	close(channels[hcsNotificationSystemCreateCompleted])
+	close(channels[hcsNotificationSystemStartCompleted])
+	close(channels[hcsNotificationSystemPauseCompleted])
+	close(channels[hcsNotificationSystemResumeCompleted])
+	close(channels[hcsNotificationProcessExited])
+	close(channels[hcsNotificationServiceDisconnect])
+}
+
+func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
+	var result error
+	if int32(notificationStatus) < 0 {
+		result = syscall.Errno(win32FromHresult(notificationStatus))
+	}
+
+	callbackMapLock.RLock()
+	context := callbackMap[callbackNumber]
+	callbackMapLock.RUnlock()
+
+	if context == nil {
+		return 0
+	}
+
+	context.channels[notificationType] <- result
+
+	return 0
+}

+ 7 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/cgo.go

@@ -0,0 +1,7 @@
+package hcsshim
+
+import "C"
+
+// This import is needed to make the library compile as CGO because HCSSHIM
+// only works with CGO due to callbacks from HCS comming back from a C thread
+// which is not supported without CGO. See https://github.com/golang/go/issues/10973

+ 565 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/container.go

@@ -0,0 +1,565 @@
+package hcsshim
+
+import (
+	"encoding/json"
+	"runtime"
+	"syscall"
+	"time"
+
+	"github.com/Sirupsen/logrus"
+)
+
+var (
+	defaultTimeout = time.Minute * 4
+)
+
+const (
+	pendingUpdatesQuery = `{ "PropertyTypes" : ["PendingUpdates"]}`
+	statisticsQuery     = `{ "PropertyTypes" : ["Statistics"]}`
+	processListQuery    = `{ "PropertyTypes" : ["ProcessList"]}`
+)
+
+type container struct {
+	handle         hcsSystem
+	id             string
+	callbackNumber uintptr
+}
+
+type containerProperties struct {
+	ID                string `json:"Id"`
+	Name              string
+	SystemType        string
+	Owner             string
+	SiloGUID          string            `json:"SiloGuid,omitempty"`
+	IsDummy           bool              `json:",omitempty"`
+	RuntimeID         string            `json:"RuntimeId,omitempty"`
+	Stopped           bool              `json:",omitempty"`
+	ExitType          string            `json:",omitempty"`
+	AreUpdatesPending bool              `json:",omitempty"`
+	ObRoot            string            `json:",omitempty"`
+	Statistics        Statistics        `json:",omitempty"`
+	ProcessList       []ProcessListItem `json:",omitempty"`
+}
+
+// MemoryStats holds the memory statistics for a container
+type MemoryStats struct {
+	UsageCommitBytes            uint64 `json:"MemoryUsageCommitBytes,omitempty"`
+	UsageCommitPeakBytes        uint64 `json:"MemoryUsageCommitPeakBytes,omitempty"`
+	UsagePrivateWorkingSetBytes uint64 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
+}
+
+// ProcessorStats holds the processor statistics for a container
+type ProcessorStats struct {
+	TotalRuntime100ns  uint64 `json:",omitempty"`
+	RuntimeUser100ns   uint64 `json:",omitempty"`
+	RuntimeKernel100ns uint64 `json:",omitempty"`
+}
+
+// StorageStats holds the storage statistics for a container
+type StorageStats struct {
+	ReadCountNormalized  uint64 `json:",omitempty"`
+	ReadSizeBytes        uint64 `json:",omitempty"`
+	WriteCountNormalized uint64 `json:",omitempty"`
+	WriteSizeBytes       uint64 `json:",omitempty"`
+}
+
+// NetworkStats holds the network statistics for a container
+type NetworkStats struct {
+	BytesReceived          uint64 `json:",omitempty"`
+	BytesSent              uint64 `json:",omitempty"`
+	PacketsReceived        uint64 `json:",omitempty"`
+	PacketsSent            uint64 `json:",omitempty"`
+	DroppedPacketsIncoming uint64 `json:",omitempty"`
+	DroppedPacketsOutgoing uint64 `json:",omitempty"`
+	EndpointId             string `json:",omitempty"`
+	InstanceId             string `json:",omitempty"`
+}
+
+// Statistics is the structure returned by a statistics call on a container
+type Statistics struct {
+	Timestamp          time.Time      `json:",omitempty"`
+	ContainerStartTime time.Time      `json:",omitempty"`
+	Uptime100ns        uint64         `json:",omitempty"`
+	Memory             MemoryStats    `json:",omitempty"`
+	Processor          ProcessorStats `json:",omitempty"`
+	Storage            StorageStats   `json:",omitempty"`
+	Network            []NetworkStats `json:",omitempty"`
+}
+
+// ProcessList is the structure of an item returned by a ProcessList call on a container
+type ProcessListItem struct {
+	CreateTimestamp              time.Time `json:",omitempty"`
+	ImageName                    string    `json:",omitempty"`
+	KernelTime100ns              uint64    `json:",omitempty"`
+	MemoryCommitBytes            uint64    `json:",omitempty"`
+	MemoryWorkingSetPrivateBytes uint64    `json:",omitempty"`
+	MemoryWorkingSetSharedBytes  uint64    `json:",omitempty"`
+	ProcessId                    uint32    `json:",omitempty"`
+	UserTime100ns                uint64    `json:",omitempty"`
+}
+
+// CreateContainer creates a new container with the given configuration but does not start it.
+func CreateContainer(id string, c *ContainerConfig) (Container, error) {
+	operation := "CreateContainer"
+	title := "HCSShim::" + operation
+
+	container := &container{
+		id: id,
+	}
+
+	configurationb, err := json.Marshal(c)
+	if err != nil {
+		return nil, err
+	}
+
+	configuration := string(configurationb)
+	logrus.Debugf(title+" id=%s config=%s", id, configuration)
+
+	var (
+		resultp     *uint16
+		createError error
+	)
+	if hcsCallbacksSupported {
+		var identity syscall.Handle
+		createError = hcsCreateComputeSystem(id, configuration, identity, &container.handle, &resultp)
+
+		if createError == nil || IsPending(createError) {
+			if err := container.registerCallback(); err != nil {
+				return nil, makeContainerError(container, operation, "", err)
+			}
+		}
+	} else {
+		createError = hcsCreateComputeSystemTP5(id, configuration, &container.handle, &resultp)
+	}
+
+	err = processAsyncHcsResult(createError, resultp, container.callbackNumber, hcsNotificationSystemCreateCompleted, &defaultTimeout)
+	if err != nil {
+		return nil, makeContainerError(container, operation, configuration, err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s handle=%d", id, container.handle)
+	runtime.SetFinalizer(container, closeContainer)
+	return container, nil
+}
+
+// OpenContainer opens an existing container by ID.
+func OpenContainer(id string) (Container, error) {
+	operation := "OpenContainer"
+	title := "HCSShim::" + operation
+	logrus.Debugf(title+" id=%s", id)
+
+	container := &container{
+		id: id,
+	}
+
+	var (
+		handle  hcsSystem
+		resultp *uint16
+	)
+	err := hcsOpenComputeSystem(id, &handle, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return nil, makeContainerError(container, operation, "", err)
+	}
+
+	container.handle = handle
+
+	logrus.Debugf(title+" succeeded id=%s handle=%d", id, handle)
+	runtime.SetFinalizer(container, closeContainer)
+	return container, nil
+}
+
+// Start synchronously starts the container.
+func (container *container) Start() error {
+	operation := "Start"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	var resultp *uint16
+	err := hcsStartComputeSystemTP5(container.handle, nil, &resultp)
+	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout)
+	if err != nil {
+		return makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+// Shutdown requests a container shutdown, if IsPending() on the error returned is true,
+// it may not actually be shut down until Wait() succeeds.
+func (container *container) Shutdown() error {
+	operation := "Shutdown"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	var resultp *uint16
+	err := hcsShutdownComputeSystemTP5(container.handle, nil, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+// Terminate requests a container terminate, if IsPending() on the error returned is true,
+// it may not actually be shut down until Wait() succeeds.
+func (container *container) Terminate() error {
+	operation := "Terminate"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	var resultp *uint16
+	err := hcsTerminateComputeSystemTP5(container.handle, nil, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+// Wait synchronously waits for the container to shutdown or terminate.
+func (container *container) Wait() error {
+	operation := "Wait"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	if hcsCallbacksSupported {
+		err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, nil)
+		if err != nil {
+			return makeContainerError(container, operation, "", err)
+		}
+	} else {
+		_, err := container.waitTimeoutInternal(syscall.INFINITE)
+		if err != nil {
+			return makeContainerError(container, operation, "", err)
+		}
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+func (container *container) waitTimeoutInternal(timeout uint32) (bool, error) {
+	return waitTimeoutInternalHelper(container, timeout)
+}
+
+// WaitTimeout synchronously waits for the container to terminate or the duration to elapse.
+// If the timeout expires, IsTimeout(err) == true
+func (container *container) WaitTimeout(timeout time.Duration) error {
+	operation := "WaitTimeout"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	if hcsCallbacksSupported {
+		err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, &timeout)
+		if err != nil {
+			return makeContainerError(container, operation, "", err)
+		}
+	} else {
+		finished, err := waitTimeoutHelper(container, timeout)
+		if !finished {
+			err = ErrTimeout
+		}
+		if err != nil {
+			return makeContainerError(container, operation, "", err)
+		}
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+func (container *container) hcsWait(timeout uint32) (bool, error) {
+	var (
+		resultp   *uint16
+		exitEvent syscall.Handle
+	)
+
+	err := hcsCreateComputeSystemWait(container.handle, &exitEvent, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return false, err
+	}
+	defer syscall.CloseHandle(exitEvent)
+
+	return waitForSingleObject(exitEvent, timeout)
+}
+
+func (container *container) properties(query string) (*containerProperties, error) {
+	var (
+		resultp     *uint16
+		propertiesp *uint16
+	)
+	err := hcsGetComputeSystemProperties(container.handle, query, &propertiesp, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return nil, err
+	}
+
+	if propertiesp == nil {
+		return nil, ErrUnexpectedValue
+	}
+	propertiesRaw := convertAndFreeCoTaskMemBytes(propertiesp)
+	properties := &containerProperties{}
+	if err := json.Unmarshal(propertiesRaw, properties); err != nil {
+		return nil, err
+	}
+	return properties, nil
+}
+
+// HasPendingUpdates returns true if the container has updates pending to install
+func (container *container) HasPendingUpdates() (bool, error) {
+	operation := "HasPendingUpdates"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+	properties, err := container.properties(pendingUpdatesQuery)
+	if err != nil {
+		return false, makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return properties.AreUpdatesPending, nil
+}
+
+// Statistics returns statistics for the container
+func (container *container) Statistics() (Statistics, error) {
+	operation := "Statistics"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+	properties, err := container.properties(statisticsQuery)
+	if err != nil {
+		return Statistics{}, makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return properties.Statistics, nil
+}
+
+// ProcessList returns an array of ProcessListItems for the container
+func (container *container) ProcessList() ([]ProcessListItem, error) {
+	operation := "ProcessList"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+	properties, err := container.properties(processListQuery)
+	if err != nil {
+		return nil, makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return properties.ProcessList, nil
+}
+
+// Pause pauses the execution of the container. This feature is not enabled in TP5.
+func (container *container) Pause() error {
+	operation := "Pause"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	var resultp *uint16
+	err := hcsPauseComputeSystemTP5(container.handle, nil, &resultp)
+	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemPauseCompleted, &defaultTimeout)
+	if err != nil {
+		return makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+// Resume resumes the execution of the container. This feature is not enabled in TP5.
+func (container *container) Resume() error {
+	operation := "Resume"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+	var (
+		resultp *uint16
+	)
+
+	err := hcsResumeComputeSystemTP5(container.handle, nil, &resultp)
+	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemResumeCompleted, &defaultTimeout)
+	if err != nil {
+		return makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+// CreateProcess launches a new process within the container.
+func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
+	operation := "CreateProcess"
+	title := "HCSShim::Container::" + operation
+	var (
+		processInfo   hcsProcessInformation
+		processHandle hcsProcess
+		resultp       *uint16
+	)
+
+	// If we are not emulating a console, ignore any console size passed to us
+	if !c.EmulateConsole {
+		c.ConsoleSize[0] = 0
+		c.ConsoleSize[1] = 0
+	}
+
+	configurationb, err := json.Marshal(c)
+	if err != nil {
+		return nil, makeContainerError(container, operation, "", err)
+	}
+
+	configuration := string(configurationb)
+	logrus.Debugf(title+" id=%s config=%s", container.id, configuration)
+
+	err = hcsCreateProcess(container.handle, configuration, &processInfo, &processHandle, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return nil, makeContainerError(container, operation, configuration, err)
+	}
+
+	process := &process{
+		handle:    processHandle,
+		processID: int(processInfo.ProcessId),
+		container: container,
+		cachedPipes: &cachedPipes{
+			stdIn:  processInfo.StdInput,
+			stdOut: processInfo.StdOutput,
+			stdErr: processInfo.StdError,
+		},
+	}
+
+	if hcsCallbacksSupported {
+		if err := process.registerCallback(); err != nil {
+			return nil, makeContainerError(container, operation, "", err)
+		}
+	}
+
+	logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
+	runtime.SetFinalizer(process, closeProcess)
+	return process, nil
+}
+
+// OpenProcess gets an interface to an existing process within the container.
+func (container *container) OpenProcess(pid int) (Process, error) {
+	operation := "OpenProcess"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s, processid=%d", container.id, pid)
+	var (
+		processHandle hcsProcess
+		resultp       *uint16
+	)
+
+	err := hcsOpenProcess(container.handle, uint32(pid), &processHandle, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return nil, makeContainerError(container, operation, "", err)
+	}
+
+	process := &process{
+		handle:    processHandle,
+		processID: pid,
+		container: container,
+	}
+
+	if hcsCallbacksSupported {
+		if err := process.registerCallback(); err != nil {
+			return nil, makeContainerError(container, operation, "", err)
+		}
+	}
+
+	logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
+	runtime.SetFinalizer(process, closeProcess)
+	return process, nil
+}
+
+// Close cleans up any state associated with the container but does not terminate or wait for it.
+func (container *container) Close() error {
+	operation := "Close"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	// Don't double free this
+	if container.handle == 0 {
+		return nil
+	}
+
+	if hcsCallbacksSupported {
+		if err := container.unregisterCallback(); err != nil {
+			return makeContainerError(container, operation, "", err)
+		}
+	}
+
+	if err := hcsCloseComputeSystem(container.handle); err != nil {
+		return makeContainerError(container, operation, "", err)
+	}
+
+	container.handle = 0
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return nil
+}
+
+// closeContainer wraps container.Close for use by a finalizer
+func closeContainer(container *container) {
+	container.Close()
+}
+
+func (container *container) registerCallback() error {
+	context := &notifcationWatcherContext{
+		channels: newChannels(),
+	}
+
+	callbackMapLock.Lock()
+	callbackNumber := nextCallback
+	nextCallback++
+	callbackMap[callbackNumber] = context
+	callbackMapLock.Unlock()
+
+	var callbackHandle hcsCallback
+	err := hcsRegisterComputeSystemCallback(container.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
+	if err != nil {
+		return err
+	}
+	context.handle = callbackHandle
+	container.callbackNumber = callbackNumber
+
+	return nil
+}
+
+func (container *container) unregisterCallback() error {
+	callbackNumber := container.callbackNumber
+
+	callbackMapLock.RLock()
+	context := callbackMap[callbackNumber]
+	callbackMapLock.RUnlock()
+
+	if context == nil {
+		return nil
+	}
+
+	handle := context.handle
+
+	if handle == 0 {
+		return nil
+	}
+
+	// hcsUnregisterComputeSystemCallback has its own syncronization
+	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
+	err := hcsUnregisterComputeSystemCallback(handle)
+	if err != nil {
+		return err
+	}
+
+	closeChannels(context.channels)
+
+	callbackMapLock.Lock()
+	callbackMap[callbackNumber] = nil
+	callbackMapLock.Unlock()
+
+	handle = 0
+
+	return nil
+}

+ 0 - 22
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/createcomputesystem.go

@@ -1,22 +0,0 @@
-package hcsshim
-
-import "github.com/Sirupsen/logrus"
-
-// CreateComputeSystem creates a container, initializing its configuration in
-// the Host Compute Service such that it can be started by a call to the
-// StartComputeSystem method.
-func CreateComputeSystem(id string, configuration string) error {
-
-	title := "HCSShim::CreateComputeSystem"
-	logrus.Debugln(title+" id=%s, configuration=%s", id, configuration)
-
-	err := createComputeSystem(id, configuration)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s configuration=%s", id, configuration)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"- succeeded %s", id)
-	return nil
-}

+ 0 - 101
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/createprocess.go

@@ -1,101 +0,0 @@
-package hcsshim
-
-import (
-	"encoding/json"
-	"io"
-	"syscall"
-
-	"github.com/Microsoft/go-winio"
-	"github.com/Sirupsen/logrus"
-)
-
-// CreateProcessParams is used as both the input of CreateProcessInComputeSystem
-// and to convert the parameters to JSON for passing onto the HCS
-type CreateProcessParams struct {
-	ApplicationName  string
-	CommandLine      string
-	WorkingDirectory string
-	Environment      map[string]string
-	EmulateConsole   bool
-	ConsoleSize      [2]int
-}
-
-// makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
-// if there is an error.
-func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
-	fs := make([]io.ReadWriteCloser, len(hs))
-	for i, h := range hs {
-		if h != syscall.Handle(0) {
-			if err == nil {
-				fs[i], err = winio.MakeOpenFile(h)
-			}
-			if err != nil {
-				syscall.Close(h)
-			}
-		}
-	}
-	if err != nil {
-		for _, f := range fs {
-			if f != nil {
-				f.Close()
-			}
-		}
-		return nil, err
-	}
-	return fs, nil
-}
-
-// CreateProcessInComputeSystem starts a process in a container. This is invoked, for example,
-// as a result of docker run, docker exec, or RUN in Dockerfile. If successful,
-// it returns the PID of the process.
-func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useStderr bool, params CreateProcessParams) (_ uint32, _ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
-	title := "HCSShim::CreateProcessInComputeSystem"
-	logrus.Debugf(title+" id=%s", id)
-
-	// If we are not emulating a console, ignore any console size passed to us
-	if !params.EmulateConsole {
-		params.ConsoleSize[0] = 0
-		params.ConsoleSize[1] = 0
-	}
-
-	paramsJson, err := json.Marshal(params)
-	if err != nil {
-		return
-	}
-
-	logrus.Debugf(title+" - Calling Win32 %s %s", id, paramsJson)
-
-	var pid uint32
-
-	handles := make([]syscall.Handle, 3)
-	var stdinParam, stdoutParam, stderrParam *syscall.Handle
-	if useStdin {
-		stdinParam = &handles[0]
-	}
-	if useStdout {
-		stdoutParam = &handles[1]
-	}
-	if useStderr {
-		stderrParam = &handles[2]
-	}
-
-	err = createProcessWithStdHandlesInComputeSystem(id, string(paramsJson), &pid, stdinParam, stdoutParam, stderrParam)
-	if err != nil {
-		herr := makeErrorf(err, title, "id=%s params=%v", id, params)
-		// Windows TP4: Hyper-V Containers may return this error with more than one
-		// concurrent exec. Do not log it as an error
-		if err != WSAEINVAL {
-			logrus.Error(herr)
-		}
-		err = herr
-		return
-	}
-
-	pipes, err := makeOpenFiles(handles)
-	if err != nil {
-		return
-	}
-
-	logrus.Debugf(title+" - succeeded id=%s params=%s pid=%d", id, paramsJson, pid)
-	return pid, pipes[0], pipes[1], pipes[2], nil
-}

+ 190 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/errors.go

@@ -0,0 +1,190 @@
+package hcsshim
+
+import (
+	"errors"
+	"fmt"
+	"syscall"
+)
+
+var (
+	// ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists
+	ErrComputeSystemDoesNotExist = syscall.Errno(0xc037010e)
+
+	// ErrElementNotFound is an error encountered when the object being referenced does not exist
+	ErrElementNotFound = syscall.Errno(0x490)
+
+	// ErrHandleClose is an error encountered when the handle generating the notification being waited on has been closed
+	ErrHandleClose = errors.New("hcsshim: the handle generating this notification has been closed")
+
+	// ErrInvalidNotificationType is an error encountered when an invalid notification type is used
+	ErrInvalidNotificationType = errors.New("hcsshim: invalid notification type")
+
+	// ErrInvalidProcessState is an error encountered when the process is not in a valid state for the requested operation
+	ErrInvalidProcessState = errors.New("the process is in an invalid state for the attempted operation")
+
+	// ErrTimeout is an error encountered when waiting on a notification times out
+	ErrTimeout = errors.New("hcsshim: timeout waiting for notification")
+
+	// ErrUnexpectedContainerExit is the error encountered when a container exits while waiting for
+	// a different expected notification
+	ErrUnexpectedContainerExit = errors.New("unexpected container exit")
+
+	// ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
+	// is lost while waiting for a notification
+	ErrUnexpectedProcessAbort = errors.New("lost communication with compute service")
+
+	// ErrUnexpectedValue is an error encountered when hcs returns an invalid value
+	ErrUnexpectedValue = errors.New("unexpected value returned from hcs")
+
+	// ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container
+	ErrVmcomputeAlreadyStopped = syscall.Errno(0xc0370110)
+
+	// ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
+	ErrVmcomputeOperationPending = syscall.Errno(0xC0370103)
+
+	// ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation
+	ErrVmcomputeOperationInvalidState = syscall.Errno(0xc0370105)
+
+	// ErrProcNotFound is an error encountered when the the process cannot be found
+	ErrProcNotFound = syscall.Errno(0x7f)
+)
+
+// ProcessError is an error encountered in HCS during an operation on a Process object
+type ProcessError struct {
+	Process   *process
+	Operation string
+	ExtraInfo string
+	Err       error
+}
+
+// ContainerError is an error encountered in HCS during an operation on a Container object
+type ContainerError struct {
+	Container *container
+	Operation string
+	ExtraInfo string
+	Err       error
+}
+
+func (e *ContainerError) Error() string {
+	if e == nil {
+		return "<nil>"
+	}
+
+	if e.Container == nil {
+		return "unexpected nil container for error: " + e.Err.Error()
+	}
+
+	s := "container " + e.Container.id
+
+	if e.Operation != "" {
+		s += " encountered an error during " + e.Operation
+	}
+
+	if e.Err != nil {
+		s += fmt.Sprintf(" failed in Win32: %s (0x%x)", e.Err, win32FromError(e.Err))
+	}
+
+	if e.ExtraInfo != "" {
+		s += " extra info: " + e.ExtraInfo
+	}
+
+	return s
+}
+
+func makeContainerError(container *container, operation string, extraInfo string, err error) error {
+	// Don't double wrap errors
+	if _, ok := err.(*ContainerError); ok {
+		return err
+	}
+	containerError := &ContainerError{Container: container, Operation: operation, ExtraInfo: extraInfo, Err: err}
+	return containerError
+}
+
+func (e *ProcessError) Error() string {
+	if e == nil {
+		return "<nil>"
+	}
+
+	if e.Process == nil {
+		return "Unexpected nil process for error: " + e.Err.Error()
+	}
+
+	s := fmt.Sprintf("process %d", e.Process.processID)
+
+	if e.Process.container != nil {
+		s += " in container " + e.Process.container.id
+	}
+
+	if e.Operation != "" {
+		s += " " + e.Operation
+	}
+
+	switch e.Err.(type) {
+	case nil:
+		break
+	case syscall.Errno:
+		s += fmt.Sprintf(" failed in Win32: %s (0x%x)", e.Err, win32FromError(e.Err))
+	default:
+		s += fmt.Sprintf(" failed: %s", e.Error())
+	}
+
+	return s
+}
+
+func makeProcessError(process *process, operation string, extraInfo string, err error) error {
+	// Don't double wrap errors
+	if _, ok := err.(*ProcessError); ok {
+		return err
+	}
+	processError := &ProcessError{Process: process, Operation: operation, ExtraInfo: extraInfo, Err: err}
+	return processError
+}
+
+// IsNotExist checks if an error is caused by the Container or Process not existing.
+// Note: Currently, ErrElementNotFound can mean that a Process has either
+// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
+// will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
+func IsNotExist(err error) bool {
+	err = getInnerError(err)
+	return err == ErrComputeSystemDoesNotExist ||
+		err == ErrElementNotFound ||
+		err == ErrProcNotFound
+}
+
+// IsPending returns a boolean indicating whether the error is that
+// the requested operation is being completed in the background.
+func IsPending(err error) bool {
+	err = getInnerError(err)
+	return err == ErrVmcomputeOperationPending
+}
+
+// IsTimeout returns a boolean indicating whether the error is caused by
+// a timeout waiting for the operation to complete.
+func IsTimeout(err error) bool {
+	err = getInnerError(err)
+	return err == ErrTimeout
+}
+
+// IsAlreadyStopped returns a boolean indicating whether the error is caused by
+// a Container or Process being already stopped.
+// Note: Currently, ErrElementNotFound can mean that a Process has either
+// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
+// will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
+func IsAlreadyStopped(err error) bool {
+	err = getInnerError(err)
+	return err == ErrVmcomputeAlreadyStopped ||
+		err == ErrElementNotFound ||
+		err == ErrProcNotFound
+}
+
+func getInnerError(err error) error {
+	switch pe := err.(type) {
+	case nil:
+		return nil
+	case *ContainerError:
+		err = pe.Err
+	case *ProcessError:
+		err = pe.Err
+	}
+	return err
+}

+ 26 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/expandsandboxsize.go

@@ -0,0 +1,26 @@
+package hcsshim
+
+import "github.com/Sirupsen/logrus"
+
+// ExpandSandboxSize expands the size of a layer to at least size bytes.
+func ExpandSandboxSize(info DriverInfo, layerId string, size uint64) error {
+	title := "hcsshim::ExpandSandboxSize "
+	logrus.Debugf(title+"layerId=%s size=%d", layerId, size)
+
+	// Convert info to API calling convention
+	infop, err := convertDriverInfo(info)
+	if err != nil {
+		logrus.Error(err)
+		return err
+	}
+
+	err = expandSandboxSize(&infop, layerId, size)
+	if err != nil {
+		err = makeErrorf(err, title, "layerId=%s  size=%d", layerId, size)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+"- succeeded layerId=%s size=%d", layerId, size)
+	return nil
+}

+ 8 - 6
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/exportlayer.go

@@ -112,7 +112,9 @@ func (r *FilterLayerReader) Close() (err error) {
 }
 
 // NewLayerReader returns a new layer reader for reading the contents of an on-disk layer.
-func NewLayerReader(info DriverInfo, layerId string, parentLayerPaths []string) (LayerReader, error) {
+// The caller must have taken the SeBackupPrivilege privilege
+// to call this and any methods on the resulting LayerReader.
+func NewLayerReader(info DriverInfo, layerID string, parentLayerPaths []string) (LayerReader, error) {
 	if procExportLayerBegin.Find() != nil {
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// legacy export code path.
@@ -120,12 +122,12 @@ func NewLayerReader(info DriverInfo, layerId string, parentLayerPaths []string)
 		if err != nil {
 			return nil, err
 		}
-		err = ExportLayer(info, layerId, path, parentLayerPaths)
+		err = ExportLayer(info, layerID, path, parentLayerPaths)
 		if err != nil {
 			os.RemoveAll(path)
 			return nil, err
 		}
-		return &legacyLayerReaderWrapper{NewLegacyLayerReader(path)}, nil
+		return &legacyLayerReaderWrapper{newLegacyLayerReader(path)}, nil
 	}
 
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -137,7 +139,7 @@ func NewLayerReader(info DriverInfo, layerId string, parentLayerPaths []string)
 		return nil, err
 	}
 	r := &FilterLayerReader{}
-	err = exportLayerBegin(&infop, layerId, layers, &r.context)
+	err = exportLayerBegin(&infop, layerID, layers, &r.context)
 	if err != nil {
 		return nil, makeError(err, "ExportLayerBegin", "")
 	}
@@ -146,11 +148,11 @@ func NewLayerReader(info DriverInfo, layerId string, parentLayerPaths []string)
 }
 
 type legacyLayerReaderWrapper struct {
-	*LegacyLayerReader
+	*legacyLayerReader
 }
 
 func (r *legacyLayerReaderWrapper) Close() error {
-	err := r.LegacyLayerReader.Close()
+	err := r.legacyLayerReader.Close()
 	os.RemoveAll(r.root)
 	return err
 }

+ 63 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/hcsshim.go

@@ -7,16 +7,20 @@ import (
 	"fmt"
 	"syscall"
 	"unsafe"
+
+	"github.com/Sirupsen/logrus"
 )
 
 //go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
 
 //sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree
+//sys SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) = iphlpapi.SetCurrentThreadCompartmentId
 
 //sys activateLayer(info *driverInfo, id string) (hr error) = vmcompute.ActivateLayer?
 //sys copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CopyLayer?
 //sys createLayer(info *driverInfo, id string, parent string) (hr error) = vmcompute.CreateLayer?
 //sys createSandboxLayer(info *driverInfo, id string, parent string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CreateSandboxLayer?
+//sys expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) = vmcompute.ExpandSandboxSize?
 //sys deactivateLayer(info *driverInfo, id string) (hr error) = vmcompute.DeactivateLayer?
 //sys destroyLayer(info *driverInfo, id string) (hr error) = vmcompute.DestroyLayer?
 //sys exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ExportLayer?
@@ -48,6 +52,41 @@ import (
 //sys terminateComputeSystem(id string) (hr error) = vmcompute.TerminateComputeSystem?
 //sys terminateProcessInComputeSystem(id string, pid uint32) (hr error) = vmcompute.TerminateProcessInComputeSystem?
 //sys waitForProcessInComputeSystem(id string, pid uint32, timeout uint32, exitCode *uint32) (hr error) = vmcompute.WaitForProcessInComputeSystem?
+//sys getComputeSystemProperties(id string, flags uint32, properties **uint16) (hr error) = vmcompute.GetComputeSystemProperties?
+
+//sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems?
+//sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
+//sys hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem?
+//sys hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem?
+//sys hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
+//sys hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
+//sys hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
+//sys hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
+//sys hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
+//sys hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties?
+//sys hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem?
+//sys hcsCreateComputeSystemWait(computeSystem hcsSystem, exitEvent *syscall.Handle, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystemWait?
+//sys hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess?
+//sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
+//sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess?
+//sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
+//sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
+//sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
+//sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?
+//sys hcsCreateProcessWait(process hcsProcess, settings *syscall.Handle, result **uint16) (hr error) = vmcompute.HcsCreateProcessWait?
+//sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties?
+//sys hcsModifyServiceSettings(settings string, result **uint16) (hr error) = vmcompute.HcsModifyServiceSettings?
+
+//sys hcsCreateComputeSystemTP5(id string, configuration string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
+//sys hcsStartComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
+//sys hcsShutdownComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
+//sys hcsTerminateComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
+//sys hcsPauseComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
+//sys hcsResumeComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
+//sys hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
+//sys hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
+//sys hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback?
+//sys hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback?
 
 //sys _hnsCall(method string, path string, object string, response **uint16) (hr error) = vmcompute.HNSCall?
 
@@ -69,6 +108,18 @@ type HcsError struct {
 	Err   error
 }
 
+type hcsSystem syscall.Handle
+type hcsProcess syscall.Handle
+type hcsCallback syscall.Handle
+
+type hcsProcessInformation struct {
+	ProcessId uint32
+	Reserved  uint32
+	StdInput  syscall.Handle
+	StdOutput syscall.Handle
+	StdError  syscall.Handle
+}
+
 func makeError(err error, title, rest string) error {
 	// Pass through DLL errors directly since they do not originate from HCS.
 	if _, ok := err.(*syscall.DLLError); ok {
@@ -118,3 +169,15 @@ func convertAndFreeCoTaskMemString(buffer *uint16) string {
 	coTaskMemFree(unsafe.Pointer(buffer))
 	return str
 }
+
+func convertAndFreeCoTaskMemBytes(buffer *uint16) []byte {
+	return []byte(convertAndFreeCoTaskMemString(buffer))
+}
+
+func processHcsResult(err error, resultp *uint16) error {
+	if resultp != nil {
+		result := convertAndFreeCoTaskMemString(resultp)
+		logrus.Debugf("Result: %s", result)
+	}
+	return err
+}

+ 25 - 12
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/hnsfuncs.go

@@ -20,11 +20,22 @@ type QosPolicy struct {
 	MaximumOutgoingBandwidthInBytes uint64
 }
 
+type VlanPolicy struct {
+	Type string
+	VLAN uint
+}
+
+type VsidPolicy struct {
+	Type string
+	VSID uint
+}
+
 // Subnet is assoicated with a network and represents a list
 // of subnets available to the network
 type Subnet struct {
-	AddressPrefix  string `json:",omitempty"`
-	GatewayAddress string `json:",omitempty"`
+	AddressPrefix  string            `json:",omitempty"`
+	GatewayAddress string            `json:",omitempty"`
+	Policies       []json.RawMessage `json:",omitempty"`
 }
 
 // MacPool is assoicated with a network and represents a list
@@ -36,16 +47,17 @@ type MacPool struct {
 
 // HNSNetwork represents a network in HNS
 type HNSNetwork struct {
-	Id                 string            `json:",omitempty"`
-	Name               string            `json:",omitempty"`
-	Type               string            `json:",omitempty"`
-	NetworkAdapterName string            `json:",omitempty"`
-	SourceMac          string            `json:",omitempty"`
-	Policies           []json.RawMessage `json:",omitempty"`
-	MacPools           []MacPool         `json:",omitempty"`
-	Subnets            []Subnet          `json:",omitempty"`
-	DNSSuffix          string            `json:",omitempty"`
-	DNSServerList      string            `json:",omitempty"`
+	Id                   string            `json:",omitempty"`
+	Name                 string            `json:",omitempty"`
+	Type                 string            `json:",omitempty"`
+	NetworkAdapterName   string            `json:",omitempty"`
+	SourceMac            string            `json:",omitempty"`
+	Policies             []json.RawMessage `json:",omitempty"`
+	MacPools             []MacPool         `json:",omitempty"`
+	Subnets              []Subnet          `json:",omitempty"`
+	DNSSuffix            string            `json:",omitempty"`
+	DNSServerList        string            `json:",omitempty"`
+	DNSServerCompartment uint32            `json:",omitempty"`
 }
 
 // HNSEndpoint represents a network endpoint in HNS
@@ -60,6 +72,7 @@ type HNSEndpoint struct {
 	DNSSuffix          string            `json:",omitempty"`
 	DNSServerList      string            `json:",omitempty"`
 	GatewayAddress     string            `json:",omitempty"`
+	EnableInternalDNS  bool              `json:",omitempty"`
 	PrefixLength       uint8             `json:",omitempty"`
 }
 

+ 52 - 12
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/importlayer.go

@@ -1,8 +1,10 @@
 package hcsshim
 
 import (
+	"errors"
 	"io/ioutil"
 	"os"
+	"path/filepath"
 	"runtime"
 
 	"github.com/Microsoft/go-winio"
@@ -13,9 +15,9 @@ import (
 // that into a layer with the id layerId.  Note that in order to correctly populate
 // the layer and interperet the transport format, all parent layers must already
 // be present on the system at the paths provided in parentLayerPaths.
-func ImportLayer(info DriverInfo, layerId string, importFolderPath string, parentLayerPaths []string) error {
+func ImportLayer(info DriverInfo, layerID string, importFolderPath string, parentLayerPaths []string) error {
 	title := "hcsshim::ImportLayer "
-	logrus.Debugf(title+"flavour %d layerId %s folder %s", info.Flavour, layerId, importFolderPath)
+	logrus.Debugf(title+"flavour %d layerId %s folder %s", info.Flavour, layerID, importFolderPath)
 
 	// Generate layer descriptors
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -30,21 +32,29 @@ func ImportLayer(info DriverInfo, layerId string, importFolderPath string, paren
 		return err
 	}
 
-	err = importLayer(&infop, layerId, importFolderPath, layers)
+	err = importLayer(&infop, layerID, importFolderPath, layers)
 	if err != nil {
-		err = makeErrorf(err, title, "layerId=%s flavour=%d folder=%s", layerId, info.Flavour, importFolderPath)
+		err = makeErrorf(err, title, "layerId=%s flavour=%d folder=%s", layerID, info.Flavour, importFolderPath)
 		logrus.Error(err)
 		return err
 	}
 
-	logrus.Debugf(title+"succeeded flavour=%d layerId=%s folder=%s", info.Flavour, layerId, importFolderPath)
+	logrus.Debugf(title+"succeeded flavour=%d layerId=%s folder=%s", info.Flavour, layerID, importFolderPath)
 	return nil
 }
 
+// LayerWriter is an interface that supports writing a new container image layer.
 type LayerWriter interface {
+	// Add adds a file to the layer with given metadata.
 	Add(name string, fileInfo *winio.FileBasicInfo) error
+	// AddLink adds a hard link to the layer. The target must already have been added.
+	AddLink(name string, target string) error
+	// Remove removes a file that was present in a parent layer from the layer.
 	Remove(name string) error
+	// Write writes data to the current file. The data must be in the format of a Win32
+	// backup stream.
 	Write(b []byte) (int, error)
+	// Close finishes the layer writing process and releases any resources.
 	Close() error
 }
 
@@ -69,6 +79,11 @@ func (w *FilterLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 	return nil
 }
 
+// AddLink adds a hard link to the layer. The target of the link must have already been added.
+func (w *FilterLayerWriter) AddLink(name string, target string) error {
+	return errors.New("hard links not yet supported")
+}
+
 // Remove removes a file from the layer. The file must have been present in the parent layer.
 //
 // name contains the file's relative path.
@@ -107,23 +122,42 @@ func (w *FilterLayerWriter) Close() (err error) {
 }
 
 type legacyLayerWriterWrapper struct {
-	*LegacyLayerWriter
+	*legacyLayerWriter
 	info             DriverInfo
-	layerId          string
+	layerID          string
+	path             string
 	parentLayerPaths []string
 }
 
 func (r *legacyLayerWriterWrapper) Close() error {
-	err := r.LegacyLayerWriter.Close()
+	err := r.legacyLayerWriter.Close()
 	if err == nil {
-		err = ImportLayer(r.info, r.layerId, r.root, r.parentLayerPaths)
+		var fullPath string
+		// Use the original path here because ImportLayer does not support long paths for the source in TP5.
+		// But do use a long path for the destination to work around another bug with directories
+		// with MAX_PATH - 12 < length < MAX_PATH.
+		info := r.info
+		fullPath, err = makeLongAbsPath(filepath.Join(info.HomeDir, r.layerID))
+		if err == nil {
+			info.HomeDir = ""
+			err = ImportLayer(info, fullPath, r.path, r.parentLayerPaths)
+		}
 	}
 	os.RemoveAll(r.root)
 	return err
 }
 
 // NewLayerWriter returns a new layer writer for creating a layer on disk.
-func NewLayerWriter(info DriverInfo, layerId string, parentLayerPaths []string) (LayerWriter, error) {
+// The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges
+// to call this and any methods on the resulting LayerWriter.
+func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string) (LayerWriter, error) {
+	if len(parentLayerPaths) == 0 {
+		// This is a base layer. It gets imported differently.
+		return &baseLayerWriter{
+			root: filepath.Join(info.HomeDir, layerID),
+		}, nil
+	}
+
 	if procImportLayerBegin.Find() != nil {
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// legacy export code path.
@@ -131,7 +165,13 @@ func NewLayerWriter(info DriverInfo, layerId string, parentLayerPaths []string)
 		if err != nil {
 			return nil, err
 		}
-		return &legacyLayerWriterWrapper{NewLegacyLayerWriter(path), info, layerId, parentLayerPaths}, nil
+		return &legacyLayerWriterWrapper{
+			legacyLayerWriter: newLegacyLayerWriter(path),
+			info:              info,
+			layerID:           layerID,
+			path:              path,
+			parentLayerPaths:  parentLayerPaths,
+		}, nil
 	}
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
 	if err != nil {
@@ -144,7 +184,7 @@ func NewLayerWriter(info DriverInfo, layerId string, parentLayerPaths []string)
 	}
 
 	w := &FilterLayerWriter{}
-	err = importLayerBegin(&infop, layerId, layers, &w.context)
+	err = importLayerBegin(&infop, layerID, layers, &w.context)
 	if err != nil {
 		return nil, makeError(err, "ImportLayerStart", "")
 	}

+ 144 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/interface.go

@@ -0,0 +1,144 @@
+package hcsshim
+
+import (
+	"io"
+	"time"
+)
+
+// ProcessConfig is used as both the input of Container.CreateProcess
+// and to convert the parameters to JSON for passing onto the HCS
+type ProcessConfig struct {
+	ApplicationName  string
+	CommandLine      string
+	WorkingDirectory string
+	Environment      map[string]string
+	EmulateConsole   bool
+	CreateStdInPipe  bool
+	CreateStdOutPipe bool
+	CreateStdErrPipe bool
+	ConsoleSize      [2]int
+}
+
+type Layer struct {
+	ID   string
+	Path string
+}
+
+type MappedDir struct {
+	HostPath      string
+	ContainerPath string
+	ReadOnly      bool
+}
+
+type HvRuntime struct {
+	ImagePath    string `json:",omitempty"`
+	SkipTemplate bool   `json:",omitempty"`
+}
+
+// ContainerConfig is used as both the input of CreateContainer
+// and to convert the parameters to JSON for passing onto the HCS
+type ContainerConfig struct {
+	SystemType               string      // HCS requires this to be hard-coded to "Container"
+	Name                     string      // Name of the container. We use the docker ID.
+	Owner                    string      // The management platform that created this container
+	IsDummy                  bool        // Used for development purposes.
+	VolumePath               string      // Windows volume path for scratch space
+	IgnoreFlushesDuringBoot  bool        // Optimization hint for container startup in Windows
+	LayerFolderPath          string      // Where the layer folders are located
+	Layers                   []Layer     // List of storage layers
+	Credentials              string      `json:",omitempty"` // Credentials information
+	ProcessorCount           uint32      `json:",omitempty"` // Number of processors to assign to the container.
+	ProcessorWeight          uint64      `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default.
+	ProcessorMaximum         int64       `json:",omitempty"` // CPU maximum usage percent 1..100
+	StorageIOPSMaximum       uint64      `json:",omitempty"` // Maximum Storage IOPS
+	StorageBandwidthMaximum  uint64      `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
+	StorageSandboxSize       uint64      `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
+	MemoryMaximumInMB        int64       `json:",omitempty"` // Maximum memory available to the container in Megabytes
+	HostName                 string      // Hostname
+	MappedDirectories        []MappedDir // List of mapped directories (volumes/mounts)
+	SandboxPath              string      // Location of unmounted sandbox (used for Hyper-V containers)
+	HvPartition              bool        // True if it a Hyper-V Container
+	EndpointList             []string    // List of networking endpoints to be attached to container
+	HvRuntime                *HvRuntime  // Hyper-V container settings
+	Servicing                bool        // True if this container is for servicing
+	AllowUnqualifiedDNSQuery bool        // True to allow unqualified DNS name resolution
+}
+
+// Container represents a created (but not necessarily running) container.
+type Container interface {
+	// Start synchronously starts the container.
+	Start() error
+
+	// Shutdown requests a container shutdown, but it may not actually be shutdown until Wait() succeeds.
+	Shutdown() error
+
+	// Terminate requests a container terminate, but it may not actually be terminated until Wait() succeeds.
+	Terminate() error
+
+	// Waits synchronously waits for the container to shutdown or terminate.
+	Wait() error
+
+	// WaitTimeout synchronously waits for the container to terminate or the duration to elapse. It
+	// returns false if timeout occurs.
+	WaitTimeout(time.Duration) error
+
+	// Pause pauses the execution of a container.
+	Pause() error
+
+	// Resume resumes the execution of a container.
+	Resume() error
+
+	// HasPendingUpdates returns true if the container has updates pending to install.
+	HasPendingUpdates() (bool, error)
+
+	// Statistics returns statistics for a container.
+	Statistics() (Statistics, error)
+
+	// ProcessList returns details for the processes in a container.
+	ProcessList() ([]ProcessListItem, error)
+
+	// CreateProcess launches a new process within the container.
+	CreateProcess(c *ProcessConfig) (Process, error)
+
+	// OpenProcess gets an interface to an existing process within the container.
+	OpenProcess(pid int) (Process, error)
+
+	// Close cleans up any state associated with the container but does not terminate or wait for it.
+	Close() error
+}
+
+// Process represents a running or exited process.
+type Process interface {
+	// Pid returns the process ID of the process within the container.
+	Pid() int
+
+	// Kill signals the process to terminate but does not wait for it to finish terminating.
+	Kill() error
+
+	// Wait waits for the process to exit.
+	Wait() error
+
+	// WaitTimeout waits for the process to exit or the duration to elapse. It returns
+	// false if timeout occurs.
+	WaitTimeout(time.Duration) error
+
+	// ExitCode returns the exit code of the process. The process must have
+	// already terminated.
+	ExitCode() (int, error)
+
+	// ResizeConsole resizes the console of the process.
+	ResizeConsole(width, height uint16) error
+
+	// Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
+	// these pipes does not close the underlying pipes; it should be possible to
+	// call this multiple times to get multiple interfaces.
+	Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error)
+
+	// CloseStdin closes the write side of the stdin pipe so that the process is
+	// notified on the read side that there is no more data in stdin.
+	CloseStdin() error
+
+	// Close cleans up any state associated with the process but does not kill
+	// or wait on it.
+	Close() error
+}

+ 90 - 42
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/legacy.go

@@ -4,6 +4,7 @@ import (
 	"bufio"
 	"encoding/binary"
 	"errors"
+	"fmt"
 	"io"
 	"os"
 	"path/filepath"
@@ -16,17 +17,24 @@ import (
 var errorIterationCanceled = errors.New("")
 
 func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os.File, err error) {
-	winPath, err := syscall.UTF16FromString(path)
-	if err != nil {
-		return
+	return winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createDisposition)
+}
+
+func makeLongAbsPath(path string) (string, error) {
+	if strings.HasPrefix(path, `\\?\`) || strings.HasPrefix(path, `\\.\`) {
+		return path, nil
 	}
-	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
+	if !filepath.IsAbs(path) {
+		absPath, err := filepath.Abs(path)
+		if err != nil {
+			return "", err
+		}
+		path = absPath
 	}
-	file = os.NewFile(uintptr(h), path)
-	return
+	if strings.HasPrefix(path, `\\`) {
+		return `\\?\UNC\` + path[2:], nil
+	}
+	return `\\?\` + path, nil
 }
 
 type fileEntry struct {
@@ -35,7 +43,7 @@ type fileEntry struct {
 	err  error
 }
 
-type LegacyLayerReader struct {
+type legacyLayerReader struct {
 	root         string
 	result       chan *fileEntry
 	proceed      chan bool
@@ -44,10 +52,10 @@ type LegacyLayerReader struct {
 	isTP4Format  bool
 }
 
-// NewLegacyLayerReader returns a new LayerReader that can read the Windows
+// newLegacyLayerReader returns a new LayerReader that can read the Windows
 // TP4 transport format from disk.
-func NewLegacyLayerReader(root string) *LegacyLayerReader {
-	r := &LegacyLayerReader{
+func newLegacyLayerReader(root string) *legacyLayerReader {
+	r := &legacyLayerReader{
 		root:        root,
 		result:      make(chan *fileEntry),
 		proceed:     make(chan bool),
@@ -70,7 +78,7 @@ func readTombstones(path string) (map[string]([]string), error) {
 
 	ts := make(map[string]([]string))
 	for s.Scan() {
-		t := s.Text()[1:] // skip leading `\`
+		t := filepath.Join("Files", s.Text()[1:]) // skip leading `\`
 		dir := filepath.Dir(t)
 		ts[dir] = append(ts[dir], t)
 	}
@@ -81,15 +89,16 @@ func readTombstones(path string) (map[string]([]string), error) {
 	return ts, nil
 }
 
-func (r *LegacyLayerReader) walk() {
-	defer close(r.result)
-	if !<-r.proceed {
-		return
+func (r *legacyLayerReader) walkUntilCancelled() error {
+	root, err := makeLongAbsPath(r.root)
+	if err != nil {
+		return err
 	}
 
+	r.root = root
 	ts, err := readTombstones(r.root)
 	if err != nil {
-		goto ErrorLoop
+		return err
 	}
 
 	err = filepath.Walk(r.root, func(path string, info os.FileInfo, err error) error {
@@ -99,6 +108,7 @@ func (r *LegacyLayerReader) walk() {
 		if path == r.root || path == filepath.Join(r.root, "tombstones.txt") || strings.HasSuffix(path, ".$wcidirs$") {
 			return nil
 		}
+
 		r.result <- &fileEntry{path, info, nil}
 		if !<-r.proceed {
 			return errorIterationCanceled
@@ -112,7 +122,7 @@ func (r *LegacyLayerReader) walk() {
 			}
 			if dts, ok := ts[relPath]; ok {
 				for _, t := range dts {
-					r.result <- &fileEntry{t, nil, nil}
+					r.result <- &fileEntry{filepath.Join(r.root, t), nil, nil}
 					if !<-r.proceed {
 						return errorIterationCanceled
 					}
@@ -122,22 +132,32 @@ func (r *LegacyLayerReader) walk() {
 		return nil
 	})
 	if err == errorIterationCanceled {
-		return
+		return nil
 	}
 	if err == nil {
-		err = io.EOF
+		return io.EOF
 	}
+	return err
+}
 
-ErrorLoop:
-	for {
-		r.result <- &fileEntry{err: err}
-		if !<-r.proceed {
-			break
+func (r *legacyLayerReader) walk() {
+	defer close(r.result)
+	if !<-r.proceed {
+		return
+	}
+
+	err := r.walkUntilCancelled()
+	if err != nil {
+		for {
+			r.result <- &fileEntry{err: err}
+			if !<-r.proceed {
+				return
+			}
 		}
 	}
 }
 
-func (r *LegacyLayerReader) reset() {
+func (r *legacyLayerReader) reset() {
 	if r.backupReader != nil {
 		r.backupReader.Close()
 		r.backupReader = nil
@@ -164,7 +184,7 @@ func findBackupStreamSize(r io.Reader) (int64, error) {
 	}
 }
 
-func (r *LegacyLayerReader) Next() (path string, size int64, fileInfo *winio.FileBasicInfo, err error) {
+func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.FileBasicInfo, err error) {
 	r.reset()
 	r.proceed <- true
 	fe := <-r.result
@@ -247,7 +267,7 @@ func (r *LegacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
 		if !fe.fi.IsDir() {
 			size, err = findBackupStreamSize(f)
 			if err != nil {
-				err = &os.PathError{"findBackupStreamSize", fe.path, err}
+				err = &os.PathError{Op: "findBackupStreamSize", Path: fe.path, Err: err}
 				return
 			}
 		}
@@ -264,7 +284,7 @@ func (r *LegacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
 	return
 }
 
-func (r *LegacyLayerReader) Read(b []byte) (int, error) {
+func (r *legacyLayerReader) Read(b []byte) (int, error) {
 	if r.backupReader == nil {
 		if r.currentFile == nil {
 			return 0, io.EOF
@@ -274,31 +294,44 @@ func (r *LegacyLayerReader) Read(b []byte) (int, error) {
 	return r.backupReader.Read(b)
 }
 
-func (r *LegacyLayerReader) Close() error {
+func (r *legacyLayerReader) Close() error {
 	r.proceed <- false
 	<-r.result
 	r.reset()
 	return nil
 }
 
-type LegacyLayerWriter struct {
+type legacyLayerWriter struct {
 	root         string
 	currentFile  *os.File
 	backupWriter *winio.BackupFileWriter
 	tombstones   []string
 	isTP4Format  bool
+	pathFixed    bool
 }
 
-// NewLegacyLayerWriter returns a LayerWriter that can write the TP4 transport format
+// newLegacyLayerWriter returns a LayerWriter that can write the TP4 transport format
 // to disk.
-func NewLegacyLayerWriter(root string) *LegacyLayerWriter {
-	return &LegacyLayerWriter{
+func newLegacyLayerWriter(root string) *legacyLayerWriter {
+	return &legacyLayerWriter{
 		root:        root,
 		isTP4Format: IsTP4(),
 	}
 }
 
-func (w *LegacyLayerWriter) reset() {
+func (w *legacyLayerWriter) init() error {
+	if !w.pathFixed {
+		path, err := makeLongAbsPath(w.root)
+		if err != nil {
+			return err
+		}
+		w.root = path
+		w.pathFixed = true
+	}
+	return nil
+}
+
+func (w *legacyLayerWriter) reset() {
 	if w.backupWriter != nil {
 		w.backupWriter.Close()
 		w.backupWriter = nil
@@ -309,8 +342,12 @@ func (w *LegacyLayerWriter) reset() {
 	}
 }
 
-func (w *LegacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) error {
+func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) error {
 	w.reset()
+	err := w.init()
+	if err != nil {
+		return err
+	}
 	path := filepath.Join(w.root, name)
 
 	createDisposition := uint32(syscall.CREATE_NEW)
@@ -357,12 +394,19 @@ func (w *LegacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 	return nil
 }
 
-func (w *LegacyLayerWriter) Remove(name string) error {
-	w.tombstones = append(w.tombstones, name)
+func (w *legacyLayerWriter) AddLink(name string, target string) error {
+	return errors.New("hard links not supported with legacy writer")
+}
+
+func (w *legacyLayerWriter) Remove(name string) error {
+	if !strings.HasPrefix(name, `Files\`) {
+		return fmt.Errorf("invalid tombstone %s", name)
+	}
+	w.tombstones = append(w.tombstones, name[len(`Files\`):])
 	return nil
 }
 
-func (w *LegacyLayerWriter) Write(b []byte) (int, error) {
+func (w *legacyLayerWriter) Write(b []byte) (int, error) {
 	if w.backupWriter == nil {
 		if w.currentFile == nil {
 			return 0, errors.New("closed")
@@ -372,8 +416,12 @@ func (w *LegacyLayerWriter) Write(b []byte) (int, error) {
 	return w.backupWriter.Write(b)
 }
 
-func (w *LegacyLayerWriter) Close() error {
+func (w *legacyLayerWriter) Close() error {
 	w.reset()
+	err := w.init()
+	if err != nil {
+		return err
+	}
 	tf, err := os.Create(filepath.Join(w.root, "tombstones.txt"))
 	if err != nil {
 		return err

+ 15 - 1
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/mksyscall_windows.go

@@ -598,6 +598,19 @@ func (f *Fn) HasStringParam() bool {
 	return false
 }
 
+var uniqDllFuncName = make(map[string]bool)
+
+// IsNotDuplicate is true if f is not a duplicated function
+func (f *Fn) IsNotDuplicate() bool {
+	funcName := f.DLLFuncName()
+	if uniqDllFuncName[funcName] == false {
+		uniqDllFuncName[funcName] = true
+		return true
+	}
+
+	return false
+}
+
 // HelperName returns name of function f helper.
 func (f *Fn) HelperName() string {
 	if !f.HasStringParam() {
@@ -748,6 +761,7 @@ const srcTemplate = `
 
 package {{packagename}}
 
+import "github.com/Microsoft/go-winio"
 import "unsafe"{{if syscalldot}}
 import "syscall"{{end}}
 
@@ -764,7 +778,7 @@ var (
 {{define "dlls"}}{{range .DLLs}}	mod{{.}} = {{syscalldot}}NewLazyDLL("{{.}}.dll")
 {{end}}{{end}}
 
-{{define "funcnames"}}{{range .Funcs}}	proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}")
+{{define "funcnames"}}{{range .Funcs}}{{if .IsNotDuplicate}}	proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}"){{end}}
 {{end}}{{end}}
 
 {{define "helperbody"}}

+ 389 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/process.go

@@ -0,0 +1,389 @@
+package hcsshim
+
+import (
+	"encoding/json"
+	"io"
+	"syscall"
+	"time"
+
+	"github.com/Sirupsen/logrus"
+)
+
+// ContainerError is an error encountered in HCS
+type process struct {
+	handle         hcsProcess
+	processID      int
+	container      *container
+	cachedPipes    *cachedPipes
+	callbackNumber uintptr
+}
+
+type cachedPipes struct {
+	stdIn  syscall.Handle
+	stdOut syscall.Handle
+	stdErr syscall.Handle
+}
+
+type processModifyRequest struct {
+	Operation   string
+	ConsoleSize *consoleSize `json:",omitempty"`
+	CloseHandle *closeHandle `json:",omitempty"`
+}
+
+type consoleSize struct {
+	Height uint16
+	Width  uint16
+}
+
+type closeHandle struct {
+	Handle string
+}
+
+type processStatus struct {
+	ProcessID      uint32
+	Exited         bool
+	ExitCode       uint32
+	LastWaitResult int32
+}
+
+const (
+	stdIn  string = "StdIn"
+	stdOut string = "StdOut"
+	stdErr string = "StdErr"
+)
+
+const (
+	modifyConsoleSize string = "ConsoleSize"
+	modifyCloseHandle string = "CloseHandle"
+)
+
+// Pid returns the process ID of the process within the container.
+func (process *process) Pid() int {
+	return process.processID
+}
+
+// Kill signals the process to terminate but does not wait for it to finish terminating.
+func (process *process) Kill() error {
+	operation := "Kill"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	var resultp *uint16
+	err := hcsTerminateProcess(process.handle, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return makeProcessError(process, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// Wait waits for the process to exit.
+func (process *process) Wait() error {
+	operation := "Wait"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	if hcsCallbacksSupported {
+		err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil)
+		if err != nil {
+			return makeProcessError(process, operation, "", err)
+		}
+	} else {
+		_, err := process.waitTimeoutInternal(syscall.INFINITE)
+		if err != nil {
+			return makeProcessError(process, operation, "", err)
+		}
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// WaitTimeout waits for the process to exit or the duration to elapse. It returns
+// false if timeout occurs.
+func (process *process) WaitTimeout(timeout time.Duration) error {
+	operation := "WaitTimeout"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	if hcsCallbacksSupported {
+		err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, &timeout)
+		if err != nil {
+			return makeProcessError(process, operation, "", err)
+		}
+	} else {
+		finished, err := waitTimeoutHelper(process, timeout)
+		if !finished {
+			err = ErrTimeout
+		}
+		if err != nil {
+			return makeProcessError(process, operation, "", err)
+		}
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+func (process *process) hcsWait(timeout uint32) (bool, error) {
+	var (
+		resultp   *uint16
+		exitEvent syscall.Handle
+	)
+	err := hcsCreateProcessWait(process.handle, &exitEvent, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return false, err
+	}
+	defer syscall.CloseHandle(exitEvent)
+
+	return waitForSingleObject(exitEvent, timeout)
+}
+
+func (process *process) waitTimeoutInternal(timeout uint32) (bool, error) {
+	return waitTimeoutInternalHelper(process, timeout)
+}
+
+// ExitCode returns the exit code of the process. The process must have
+// already terminated.
+func (process *process) ExitCode() (int, error) {
+	operation := "ExitCode"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	properties, err := process.properties()
+	if err != nil {
+		return 0, makeProcessError(process, operation, "", err)
+	}
+
+	if properties.Exited == false {
+		return 0, makeProcessError(process, operation, "", ErrInvalidProcessState)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d exitCode=%d", process.processID, properties.ExitCode)
+	return int(properties.ExitCode), nil
+}
+
+// ResizeConsole resizes the console of the process.
+func (process *process) ResizeConsole(width, height uint16) error {
+	operation := "ResizeConsole"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	modifyRequest := processModifyRequest{
+		Operation: modifyConsoleSize,
+		ConsoleSize: &consoleSize{
+			Height: height,
+			Width:  width,
+		},
+	}
+
+	modifyRequestb, err := json.Marshal(modifyRequest)
+	if err != nil {
+		return err
+	}
+
+	modifyRequestStr := string(modifyRequestb)
+
+	var resultp *uint16
+	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return makeProcessError(process, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+func (process *process) properties() (*processStatus, error) {
+	operation := "properties"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	var (
+		resultp     *uint16
+		propertiesp *uint16
+	)
+	err := hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return nil, err
+	}
+
+	if propertiesp == nil {
+		return nil, ErrUnexpectedValue
+	}
+	propertiesRaw := convertAndFreeCoTaskMemBytes(propertiesp)
+
+	properties := &processStatus{}
+	if err := json.Unmarshal(propertiesRaw, properties); err != nil {
+		return nil, err
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d, properties=%s", process.processID, propertiesRaw)
+	return properties, nil
+}
+
+// Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
+// these pipes does not close the underlying pipes; it should be possible to
+// call this multiple times to get multiple interfaces.
+func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
+	operation := "Stdio"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	var stdIn, stdOut, stdErr syscall.Handle
+
+	if process.cachedPipes == nil {
+		var (
+			processInfo hcsProcessInformation
+			resultp     *uint16
+		)
+		err := hcsGetProcessInfo(process.handle, &processInfo, &resultp)
+		err = processHcsResult(err, resultp)
+		if err != nil {
+			return nil, nil, nil, makeProcessError(process, operation, "", err)
+		}
+
+		stdIn, stdOut, stdErr = processInfo.StdInput, processInfo.StdOutput, processInfo.StdError
+	} else {
+		// Use cached pipes
+		stdIn, stdOut, stdErr = process.cachedPipes.stdIn, process.cachedPipes.stdOut, process.cachedPipes.stdErr
+
+		// Invalidate the cache
+		process.cachedPipes = nil
+	}
+
+	pipes, err := makeOpenFiles([]syscall.Handle{stdIn, stdOut, stdErr})
+	if err != nil {
+		return nil, nil, nil, makeProcessError(process, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return pipes[0], pipes[1], pipes[2], nil
+}
+
+// CloseStdin closes the write side of the stdin pipe so that the process is
+// notified on the read side that there is no more data in stdin.
+func (process *process) CloseStdin() error {
+	operation := "CloseStdin"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	modifyRequest := processModifyRequest{
+		Operation: modifyCloseHandle,
+		CloseHandle: &closeHandle{
+			Handle: stdIn,
+		},
+	}
+
+	modifyRequestb, err := json.Marshal(modifyRequest)
+	if err != nil {
+		return err
+	}
+
+	modifyRequestStr := string(modifyRequestb)
+
+	var resultp *uint16
+	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
+	err = processHcsResult(err, resultp)
+	if err != nil {
+		return makeProcessError(process, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// Close cleans up any state associated with the process but does not kill
+// or wait on it.
+func (process *process) Close() error {
+	operation := "Close"
+	title := "HCSShim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	// Don't double free this
+	if process.handle == 0 {
+		return nil
+	}
+
+	if hcsCallbacksSupported {
+		if err := process.unregisterCallback(); err != nil {
+			return makeProcessError(process, operation, "", err)
+		}
+	}
+
+	if err := hcsCloseProcess(process.handle); err != nil {
+		return makeProcessError(process, operation, "", err)
+	}
+
+	process.handle = 0
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// closeProcess wraps process.Close for use by a finalizer
+func closeProcess(process *process) {
+	process.Close()
+}
+
+func (process *process) registerCallback() error {
+	context := &notifcationWatcherContext{
+		channels: newChannels(),
+	}
+
+	callbackMapLock.Lock()
+	callbackNumber := nextCallback
+	nextCallback++
+	callbackMap[callbackNumber] = context
+	callbackMapLock.Unlock()
+
+	var callbackHandle hcsCallback
+	err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
+	if err != nil {
+		return err
+	}
+	context.handle = callbackHandle
+	process.callbackNumber = callbackNumber
+
+	return nil
+}
+
+func (process *process) unregisterCallback() error {
+	callbackNumber := process.callbackNumber
+
+	callbackMapLock.RLock()
+	context := callbackMap[callbackNumber]
+	callbackMapLock.RUnlock()
+
+	if context == nil {
+		return nil
+	}
+
+	handle := context.handle
+
+	if handle == 0 {
+		return nil
+	}
+
+	// hcsUnregisterProcessCallback has its own syncronization
+	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
+	err := hcsUnregisterProcessCallback(handle)
+	if err != nil {
+		return err
+	}
+
+	closeChannels(context.channels)
+
+	callbackMapLock.Lock()
+	callbackMap[callbackNumber] = nil
+	callbackMapLock.Unlock()
+
+	handle = 0
+
+	return nil
+}

+ 0 - 22
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/resizeconsole.go

@@ -1,22 +0,0 @@
-package hcsshim
-
-import "github.com/Sirupsen/logrus"
-
-// ResizeConsoleInComputeSystem updates the height and width of the console
-// session for the process with the given id in the container with the given id.
-func ResizeConsoleInComputeSystem(id string, processid uint32, h, w int) error {
-
-	title := "HCSShim::ResizeConsoleInComputeSystem"
-	logrus.Debugf(title+" id=%s processid=%d (%d,%d)", id, processid, h, w)
-
-	err := resizeConsoleInComputeSystem(id, processid, uint16(h), uint16(w), 0)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s pid=%d", id, processid)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+" succeeded id=%s processid=%d (%d,%d)", id, processid, h, w)
-	return nil
-
-}

+ 0 - 43
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/shutdownterminatecomputesystem.go

@@ -1,43 +0,0 @@
-package hcsshim
-
-import "github.com/Sirupsen/logrus"
-
-// TerminateComputeSystem force terminates a container.
-func TerminateComputeSystem(id string, timeout uint32, context string) error {
-	return shutdownTerminate(false, id, timeout, context)
-}
-
-// ShutdownComputeSystem shuts down a container by requesting a shutdown within
-// the container operating system.
-func ShutdownComputeSystem(id string, timeout uint32, context string) error {
-	return shutdownTerminate(true, id, timeout, context)
-}
-
-// shutdownTerminate is a wrapper for ShutdownComputeSystem and TerminateComputeSystem
-// which have very similar calling semantics
-func shutdownTerminate(shutdown bool, id string, timeout uint32, context string) error {
-
-	var (
-		title = "HCSShim::"
-	)
-	if shutdown {
-		title = title + "ShutdownComputeSystem"
-	} else {
-		title = title + "TerminateComputeSystem"
-	}
-	logrus.Debugf(title+" id=%s context=%s", id, context)
-
-	var err error
-	if shutdown {
-		err = shutdownComputeSystem(id, timeout)
-	} else {
-		err = terminateComputeSystem(id)
-	}
-
-	if err != nil {
-		return makeErrorf(err, title, "id=%s context=%s", id, context)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s context=%s", id, context)
-	return nil
-}

+ 0 - 21
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/startcomputesystem.go

@@ -1,21 +0,0 @@
-package hcsshim
-
-import "github.com/Sirupsen/logrus"
-
-// StartComputeSystem starts a container that has previously been created via
-// CreateComputeSystem.
-func StartComputeSystem(id string) error {
-
-	title := "HCSShim::StartComputeSystem"
-	logrus.Debugf(title+" id=%s", id)
-
-	err := startComputeSystem(id)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s", id)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", id)
-	return nil
-}

+ 0 - 20
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/terminateprocess.go

@@ -1,20 +0,0 @@
-package hcsshim
-
-import "github.com/Sirupsen/logrus"
-
-// TerminateProcessInComputeSystem kills a process in a running container.
-func TerminateProcessInComputeSystem(id string, processid uint32) (err error) {
-
-	title := "HCSShim::TerminateProcessInComputeSystem"
-	logrus.Debugf(title+" id=%s processid=%d", id, processid)
-
-	err = terminateProcessInComputeSystem(id, processid)
-	if err != nil {
-		err = makeErrorf(err, title, "err=%s id=%s", id)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", id)
-	return nil
-}

+ 39 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/utils.go

@@ -0,0 +1,39 @@
+package hcsshim
+
+import (
+	"io"
+	"syscall"
+
+	"github.com/Microsoft/go-winio"
+)
+
+var (
+	vmcomputedll          = syscall.NewLazyDLL("vmcompute.dll")
+	hcsCallbackAPI        = vmcomputedll.NewProc("HcsRegisterComputeSystemCallback")
+	hcsCallbacksSupported = hcsCallbackAPI.Find() == nil
+)
+
+// makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
+// if there is an error.
+func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
+	fs := make([]io.ReadWriteCloser, len(hs))
+	for i, h := range hs {
+		if h != syscall.Handle(0) {
+			if err == nil {
+				fs[i], err = winio.MakeOpenFile(h)
+			}
+			if err != nil {
+				syscall.Close(h)
+			}
+		}
+	}
+	if err != nil {
+		for _, f := range fs {
+			if f != nil {
+				f.Close()
+			}
+		}
+		return nil, err
+	}
+	return fs, nil
+}

+ 126 - 0
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/waithelper.go

@@ -0,0 +1,126 @@
+package hcsshim
+
+import (
+	"github.com/Sirupsen/logrus"
+	"syscall"
+	"time"
+)
+
+type waitable interface {
+	waitTimeoutInternal(timeout uint32) (bool, error)
+	hcsWait(timeout uint32) (bool, error)
+}
+
+func waitTimeoutHelper(object waitable, timeout time.Duration) (bool, error) {
+	var (
+		millis uint32
+	)
+
+	for totalMillis := uint64(timeout / time.Millisecond); totalMillis > 0; totalMillis = totalMillis - uint64(millis) {
+		if totalMillis >= syscall.INFINITE {
+			millis = syscall.INFINITE - 1
+		} else {
+			millis = uint32(totalMillis)
+		}
+
+		result, err := object.waitTimeoutInternal(millis)
+
+		if err != nil {
+			return result, err
+		}
+	}
+	return true, nil
+}
+
+func waitTimeoutInternalHelper(object waitable, timeout uint32) (bool, error) {
+	return object.hcsWait(timeout)
+}
+
+func waitForSingleObject(handle syscall.Handle, timeout uint32) (bool, error) {
+	s, e := syscall.WaitForSingleObject(handle, timeout)
+	switch s {
+	case syscall.WAIT_OBJECT_0:
+		return true, nil
+	case syscall.WAIT_TIMEOUT:
+		return false, nil
+	default:
+		return false, e
+	}
+}
+
+func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
+	err = processHcsResult(err, resultp)
+	if IsPending(err) {
+		return waitForNotification(callbackNumber, expectedNotification, timeout)
+	}
+
+	return err
+}
+
+func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
+	callbackMapLock.RLock()
+	channels := callbackMap[callbackNumber].channels
+	callbackMapLock.RUnlock()
+
+	expectedChannel := channels[expectedNotification]
+	if expectedChannel == nil {
+		logrus.Errorf("unknown notification type in waitForNotification %x", expectedNotification)
+		return ErrInvalidNotificationType
+	}
+
+	if timeout != nil {
+		timer := time.NewTimer(*timeout)
+		defer timer.Stop()
+
+		select {
+		case err, ok := <-expectedChannel:
+			if !ok {
+				return ErrHandleClose
+			}
+			return err
+		case err, ok := <-channels[hcsNotificationSystemExited]:
+			if !ok {
+				return ErrHandleClose
+			}
+			// If the expected notification is hcsNotificationSystemExited which of the two selects
+			// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
+			if channels[hcsNotificationSystemExited] == expectedChannel {
+				return err
+			}
+			return ErrUnexpectedContainerExit
+		case _, ok := <-channels[hcsNotificationServiceDisconnect]:
+			if !ok {
+				return ErrHandleClose
+			}
+			// hcsNotificationServiceDisconnect should never be an expected notification
+			// it does not need the same handling as hcsNotificationSystemExited
+			return ErrUnexpectedProcessAbort
+		case <-timer.C:
+			return ErrTimeout
+		}
+	}
+	select {
+	case err, ok := <-expectedChannel:
+		if !ok {
+			return ErrHandleClose
+		}
+		return err
+	case err, ok := <-channels[hcsNotificationSystemExited]:
+		if !ok {
+			return ErrHandleClose
+		}
+		// If the expected notification is hcsNotificationSystemExited which of the two selects
+		// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
+		if channels[hcsNotificationSystemExited] == expectedChannel {
+			return err
+		}
+		return ErrUnexpectedContainerExit
+	case _, ok := <-channels[hcsNotificationServiceDisconnect]:
+		if !ok {
+			return ErrHandleClose
+		}
+		// hcsNotificationServiceDisconnect should never be an expected notification
+		// it does not need the same handling as hcsNotificationSystemExited
+		return ErrUnexpectedProcessAbort
+	}
+}

+ 0 - 20
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/waitprocess.go

@@ -1,20 +0,0 @@
-package hcsshim
-
-import "github.com/Sirupsen/logrus"
-
-// WaitForProcessInComputeSystem waits for a process ID to terminate and returns
-// the exit code. Returns exitcode, error
-func WaitForProcessInComputeSystem(id string, processid uint32, timeout uint32) (int32, error) {
-
-	title := "HCSShim::WaitForProcessInComputeSystem"
-	logrus.Debugf(title+" id=%s processid=%d", id, processid)
-
-	var exitCode uint32
-	err := waitForProcessInComputeSystem(id, processid, timeout, &exitCode)
-	if err != nil {
-		return 0, makeErrorf(err, title, "id=%s", id)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s processid=%d exitcode=%d", id, processid, exitCode)
-	return int32(exitCode), nil
-}

+ 579 - 6
libnetwork/Godeps/_workspace/src/github.com/Microsoft/hcsshim/zhcsshim.go

@@ -2,24 +2,24 @@
 
 package hcsshim
 
-import (
-	"unsafe"
-
-	"github.com/Microsoft/go-winio"
-)
+import "github.com/Microsoft/go-winio"
+import "unsafe"
 import "syscall"
 
 var _ unsafe.Pointer
 
 var (
 	modole32     = syscall.NewLazyDLL("ole32.dll")
+	modiphlpapi  = syscall.NewLazyDLL("iphlpapi.dll")
 	modvmcompute = syscall.NewLazyDLL("vmcompute.dll")
 
 	procCoTaskMemFree                              = modole32.NewProc("CoTaskMemFree")
+	procSetCurrentThreadCompartmentId              = modiphlpapi.NewProc("SetCurrentThreadCompartmentId")
 	procActivateLayer                              = modvmcompute.NewProc("ActivateLayer")
 	procCopyLayer                                  = modvmcompute.NewProc("CopyLayer")
 	procCreateLayer                                = modvmcompute.NewProc("CreateLayer")
 	procCreateSandboxLayer                         = modvmcompute.NewProc("CreateSandboxLayer")
+	procExpandSandboxSize                          = modvmcompute.NewProc("ExpandSandboxSize")
 	procDeactivateLayer                            = modvmcompute.NewProc("DeactivateLayer")
 	procDestroyLayer                               = modvmcompute.NewProc("DestroyLayer")
 	procExportLayer                                = modvmcompute.NewProc("ExportLayer")
@@ -48,7 +48,35 @@ var (
 	procTerminateComputeSystem                     = modvmcompute.NewProc("TerminateComputeSystem")
 	procTerminateProcessInComputeSystem            = modvmcompute.NewProc("TerminateProcessInComputeSystem")
 	procWaitForProcessInComputeSystem              = modvmcompute.NewProc("WaitForProcessInComputeSystem")
-	procHNSCall                                    = modvmcompute.NewProc("HNSCall")
+	procGetComputeSystemProperties                 = modvmcompute.NewProc("GetComputeSystemProperties")
+	procHcsEnumerateComputeSystems                 = modvmcompute.NewProc("HcsEnumerateComputeSystems")
+	procHcsCreateComputeSystem                     = modvmcompute.NewProc("HcsCreateComputeSystem")
+	procHcsOpenComputeSystem                       = modvmcompute.NewProc("HcsOpenComputeSystem")
+	procHcsCloseComputeSystem                      = modvmcompute.NewProc("HcsCloseComputeSystem")
+	procHcsStartComputeSystem                      = modvmcompute.NewProc("HcsStartComputeSystem")
+	procHcsShutdownComputeSystem                   = modvmcompute.NewProc("HcsShutdownComputeSystem")
+	procHcsTerminateComputeSystem                  = modvmcompute.NewProc("HcsTerminateComputeSystem")
+	procHcsPauseComputeSystem                      = modvmcompute.NewProc("HcsPauseComputeSystem")
+	procHcsResumeComputeSystem                     = modvmcompute.NewProc("HcsResumeComputeSystem")
+	procHcsGetComputeSystemProperties              = modvmcompute.NewProc("HcsGetComputeSystemProperties")
+	procHcsModifyComputeSystem                     = modvmcompute.NewProc("HcsModifyComputeSystem")
+	procHcsCreateComputeSystemWait                 = modvmcompute.NewProc("HcsCreateComputeSystemWait")
+	procHcsCreateProcess                           = modvmcompute.NewProc("HcsCreateProcess")
+	procHcsOpenProcess                             = modvmcompute.NewProc("HcsOpenProcess")
+	procHcsCloseProcess                            = modvmcompute.NewProc("HcsCloseProcess")
+	procHcsTerminateProcess                        = modvmcompute.NewProc("HcsTerminateProcess")
+	procHcsGetProcessInfo                          = modvmcompute.NewProc("HcsGetProcessInfo")
+	procHcsGetProcessProperties                    = modvmcompute.NewProc("HcsGetProcessProperties")
+	procHcsModifyProcess                           = modvmcompute.NewProc("HcsModifyProcess")
+	procHcsCreateProcessWait                       = modvmcompute.NewProc("HcsCreateProcessWait")
+	procHcsGetServiceProperties                    = modvmcompute.NewProc("HcsGetServiceProperties")
+	procHcsModifyServiceSettings                   = modvmcompute.NewProc("HcsModifyServiceSettings")
+
+	procHcsRegisterComputeSystemCallback   = modvmcompute.NewProc("HcsRegisterComputeSystemCallback")
+	procHcsUnregisterComputeSystemCallback = modvmcompute.NewProc("HcsUnregisterComputeSystemCallback")
+	procHcsRegisterProcessCallback         = modvmcompute.NewProc("HcsRegisterProcessCallback")
+	procHcsUnregisterProcessCallback       = modvmcompute.NewProc("HcsUnregisterProcessCallback")
+	procHNSCall                            = modvmcompute.NewProc("HNSCall")
 )
 
 func coTaskMemFree(buffer unsafe.Pointer) {
@@ -56,6 +84,14 @@ func coTaskMemFree(buffer unsafe.Pointer) {
 	return
 }
 
+func SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) {
+	r0, _, _ := syscall.Syscall(procSetCurrentThreadCompartmentId.Addr(), 1, uintptr(compartmentId), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
 func activateLayer(info *driverInfo, id string) (hr error) {
 	var _p0 *uint16
 	_p0, hr = syscall.UTF16PtrFromString(id)
@@ -159,6 +195,26 @@ func _createSandboxLayer(info *driverInfo, id *uint16, parent *uint16, descripto
 	return
 }
 
+func expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _expandSandboxSize(info, _p0, size)
+}
+
+func _expandSandboxSize(info *driverInfo, id *uint16, size uint64) (hr error) {
+	if hr = procExpandSandboxSize.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procExpandSandboxSize.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(size))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
 func deactivateLayer(info *driverInfo, id string) (hr error) {
 	var _p0 *uint16
 	_p0, hr = syscall.UTF16PtrFromString(id)
@@ -713,6 +769,523 @@ func _waitForProcessInComputeSystem(id *uint16, pid uint32, timeout uint32, exit
 	return
 }
 
+func getComputeSystemProperties(id string, flags uint32, properties **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _getComputeSystemProperties(_p0, flags, properties)
+}
+
+func _getComputeSystemProperties(id *uint16, flags uint32, properties **uint16) (hr error) {
+	if hr = procGetComputeSystemProperties.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procGetComputeSystemProperties.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(unsafe.Pointer(properties)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(query)
+	if hr != nil {
+		return
+	}
+	return _hcsEnumerateComputeSystems(_p0, computeSystems, result)
+}
+
+func _hcsEnumerateComputeSystems(query *uint16, computeSystems **uint16, result **uint16) (hr error) {
+	if hr = procHcsEnumerateComputeSystems.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsEnumerateComputeSystems.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(computeSystems)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(configuration)
+	if hr != nil {
+		return
+	}
+	return _hcsCreateComputeSystem(_p0, _p1, identity, computeSystem, result)
+}
+
+func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
+	if hr = procHcsCreateComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsCreateComputeSystem.Addr(), 5, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(configuration)), uintptr(identity), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)), 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _hcsOpenComputeSystem(_p0, computeSystem, result)
+}
+
+func _hcsOpenComputeSystem(id *uint16, computeSystem *hcsSystem, result **uint16) (hr error) {
+	if hr = procHcsOpenComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsOpenComputeSystem.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) {
+	if hr = procHcsCloseComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsCloseComputeSystem.Addr(), 1, uintptr(computeSystem), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsStartComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsStartComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsStartComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsStartComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsShutdownComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsShutdownComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsShutdownComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsShutdownComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsTerminateComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsTerminateComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsTerminateComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsTerminateComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsPauseComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsPauseComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsPauseComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsPauseComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsResumeComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsResumeComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsResumeComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsResumeComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
+	if hr != nil {
+		return
+	}
+	return _hcsGetComputeSystemProperties(computeSystem, _p0, properties, result)
+}
+
+func _hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
+	if hr = procHcsGetComputeSystemProperties.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsGetComputeSystemProperties.Addr(), 4, uintptr(computeSystem), uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(configuration)
+	if hr != nil {
+		return
+	}
+	return _hcsModifyComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsModifyComputeSystem(computeSystem hcsSystem, configuration *uint16, result **uint16) (hr error) {
+	if hr = procHcsModifyComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsModifyComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(configuration)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsCreateComputeSystemWait(computeSystem hcsSystem, exitEvent *syscall.Handle, result **uint16) (hr error) {
+	if hr = procHcsCreateComputeSystemWait.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsCreateComputeSystemWait.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(exitEvent)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(processParameters)
+	if hr != nil {
+		return
+	}
+	return _hcsCreateProcess(computeSystem, _p0, processInformation, process, result)
+}
+
+func _hcsCreateProcess(computeSystem hcsSystem, processParameters *uint16, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
+	if hr = procHcsCreateProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsCreateProcess.Addr(), 5, uintptr(computeSystem), uintptr(unsafe.Pointer(processParameters)), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) {
+	if hr = procHcsOpenProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsOpenProcess.Addr(), 4, uintptr(computeSystem), uintptr(pid), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsCloseProcess(process hcsProcess) (hr error) {
+	if hr = procHcsCloseProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsCloseProcess.Addr(), 1, uintptr(process), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
+	if hr = procHcsTerminateProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 2, uintptr(process), uintptr(unsafe.Pointer(result)), 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) {
+	if hr = procHcsGetProcessInfo.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsGetProcessInfo.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) {
+	if hr = procHcsGetProcessProperties.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsGetProcessProperties.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processProperties)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(settings)
+	if hr != nil {
+		return
+	}
+	return _hcsModifyProcess(process, _p0, result)
+}
+
+func _hcsModifyProcess(process hcsProcess, settings *uint16, result **uint16) (hr error) {
+	if hr = procHcsModifyProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsModifyProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsCreateProcessWait(process hcsProcess, settings *syscall.Handle, result **uint16) (hr error) {
+	if hr = procHcsCreateProcessWait.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsCreateProcessWait.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
+	if hr != nil {
+		return
+	}
+	return _hcsGetServiceProperties(_p0, properties, result)
+}
+
+func _hcsGetServiceProperties(propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
+	if hr = procHcsGetServiceProperties.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsGetServiceProperties.Addr(), 3, uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsModifyServiceSettings(settings string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(settings)
+	if hr != nil {
+		return
+	}
+	return _hcsModifyServiceSettings(_p0, result)
+}
+
+func _hcsModifyServiceSettings(settings *uint16, result **uint16) (hr error) {
+	if hr = procHcsModifyServiceSettings.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsModifyServiceSettings.Addr(), 2, uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)), 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsCreateComputeSystemTP5(id string, configuration string, computeSystem *hcsSystem, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(configuration)
+	if hr != nil {
+		return
+	}
+	return _hcsCreateComputeSystemTP5(_p0, _p1, computeSystem, result)
+}
+
+func _hcsCreateComputeSystemTP5(id *uint16, configuration *uint16, computeSystem *hcsSystem, result **uint16) (hr error) {
+	if hr = procHcsCreateComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsCreateComputeSystem.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(configuration)), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsStartComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsStartComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsStartComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsShutdownComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsShutdownComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsShutdownComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsTerminateComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsTerminateComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsTerminateComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsPauseComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsPauseComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsPauseComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsResumeComputeSystemTP5(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsResumeComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsResumeComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
+	if hr = procHcsRegisterComputeSystemCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsRegisterComputeSystemCallback.Addr(), 4, uintptr(computeSystem), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) {
+	if hr = procHcsUnregisterComputeSystemCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsUnregisterComputeSystemCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
+	if hr = procHcsRegisterProcessCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsRegisterProcessCallback.Addr(), 4, uintptr(process), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
+func hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) {
+	if hr = procHcsUnregisterProcessCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsUnregisterProcessCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
+	if int32(r0) < 0 {
+		hr = syscall.Errno(win32FromHresult(r0))
+	}
+	return
+}
+
 func _hnsCall(method string, path string, object string, response **uint16) (hr error) {
 	var _p0 *uint16
 	_p0, hr = syscall.UTF16PtrFromString(method)

+ 8 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/asm.s

@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·use(SB),NOSPLIT,$0
+	RET

+ 13 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/asm_windows_386.s

@@ -0,0 +1,13 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls for 386, Windows are implemented in runtime/syscall_windows.goc
+//
+
+TEXT ·getprocaddress(SB), 7, $0-8
+	JMP	syscall·getprocaddress(SB)
+
+TEXT ·loadlibrary(SB), 7, $0-4
+	JMP	syscall·loadlibrary(SB)

+ 13 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/asm_windows_amd64.s

@@ -0,0 +1,13 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls for amd64, Windows are implemented in runtime/syscall_windows.goc
+//
+
+TEXT ·getprocaddress(SB), 7, $0-32
+	JMP	syscall·getprocaddress(SB)
+
+TEXT ·loadlibrary(SB), 7, $0-8
+	JMP	syscall·loadlibrary(SB)

+ 275 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/dll_windows.go

@@ -0,0 +1,275 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+import (
+	"sync"
+	"sync/atomic"
+	"syscall"
+	"unsafe"
+)
+
+// DLLError describes reasons for DLL load failures.
+type DLLError struct {
+	Err     error
+	ObjName string
+	Msg     string
+}
+
+func (e *DLLError) Error() string { return e.Msg }
+
+// Implemented in runtime/syscall_windows.goc; we provide jumps to them in our assembly file.
+func loadlibrary(filename *uint16) (handle uintptr, err syscall.Errno)
+func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err syscall.Errno)
+
+// A DLL implements access to a single DLL.
+type DLL struct {
+	Name   string
+	Handle Handle
+}
+
+// LoadDLL loads DLL file into memory.
+func LoadDLL(name string) (dll *DLL, err error) {
+	namep, err := UTF16PtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	h, e := loadlibrary(namep)
+	if e != 0 {
+		return nil, &DLLError{
+			Err:     e,
+			ObjName: name,
+			Msg:     "Failed to load " + name + ": " + e.Error(),
+		}
+	}
+	d := &DLL{
+		Name:   name,
+		Handle: Handle(h),
+	}
+	return d, nil
+}
+
+// MustLoadDLL is like LoadDLL but panics if load operation failes.
+func MustLoadDLL(name string) *DLL {
+	d, e := LoadDLL(name)
+	if e != nil {
+		panic(e)
+	}
+	return d
+}
+
+// FindProc searches DLL d for procedure named name and returns *Proc
+// if found. It returns an error if search fails.
+func (d *DLL) FindProc(name string) (proc *Proc, err error) {
+	namep, err := BytePtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	a, e := getprocaddress(uintptr(d.Handle), namep)
+	if e != 0 {
+		return nil, &DLLError{
+			Err:     e,
+			ObjName: name,
+			Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
+		}
+	}
+	p := &Proc{
+		Dll:  d,
+		Name: name,
+		addr: a,
+	}
+	return p, nil
+}
+
+// MustFindProc is like FindProc but panics if search fails.
+func (d *DLL) MustFindProc(name string) *Proc {
+	p, e := d.FindProc(name)
+	if e != nil {
+		panic(e)
+	}
+	return p
+}
+
+// Release unloads DLL d from memory.
+func (d *DLL) Release() (err error) {
+	return FreeLibrary(d.Handle)
+}
+
+// A Proc implements access to a procedure inside a DLL.
+type Proc struct {
+	Dll  *DLL
+	Name string
+	addr uintptr
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *Proc) Addr() uintptr {
+	return p.addr
+}
+
+// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
+// are supplied.
+//
+// The returned error is always non-nil, constructed from the result of GetLastError.
+// Callers must inspect the primary return value to decide whether an error occurred
+// (according to the semantics of the specific function being called) before consulting
+// the error. The error will be guaranteed to contain windows.Errno.
+func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	switch len(a) {
+	case 0:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0)
+	case 1:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0)
+	case 2:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0)
+	case 3:
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2])
+	case 4:
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
+	case 5:
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
+	case 6:
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
+	case 7:
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
+	case 8:
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
+	case 9:
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
+	case 10:
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
+	case 11:
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
+	case 12:
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
+	case 13:
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
+	case 14:
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
+	case 15:
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
+	default:
+		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
+	}
+	return
+}
+
+// A LazyDLL implements access to a single DLL.
+// It will delay the load of the DLL until the first
+// call to its Handle method or to one of its
+// LazyProc's Addr method.
+type LazyDLL struct {
+	mu   sync.Mutex
+	dll  *DLL // non nil once DLL is loaded
+	Name string
+}
+
+// Load loads DLL file d.Name into memory. It returns an error if fails.
+// Load will not try to load DLL, if it is already loaded into memory.
+func (d *LazyDLL) Load() error {
+	// Non-racy version of:
+	// if d.dll == nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) == nil {
+		d.mu.Lock()
+		defer d.mu.Unlock()
+		if d.dll == nil {
+			dll, e := LoadDLL(d.Name)
+			if e != nil {
+				return e
+			}
+			// Non-racy version of:
+			// d.dll = dll
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
+		}
+	}
+	return nil
+}
+
+// mustLoad is like Load but panics if search fails.
+func (d *LazyDLL) mustLoad() {
+	e := d.Load()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Handle returns d's module handle.
+func (d *LazyDLL) Handle() uintptr {
+	d.mustLoad()
+	return uintptr(d.dll.Handle)
+}
+
+// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
+func (d *LazyDLL) NewProc(name string) *LazyProc {
+	return &LazyProc{l: d, Name: name}
+}
+
+// NewLazyDLL creates new LazyDLL associated with DLL file.
+func NewLazyDLL(name string) *LazyDLL {
+	return &LazyDLL{Name: name}
+}
+
+// A LazyProc implements access to a procedure inside a LazyDLL.
+// It delays the lookup until the Addr method is called.
+type LazyProc struct {
+	mu   sync.Mutex
+	Name string
+	l    *LazyDLL
+	proc *Proc
+}
+
+// Find searches DLL for procedure named p.Name. It returns
+// an error if search fails. Find will not search procedure,
+// if it is already found and loaded into memory.
+func (p *LazyProc) Find() error {
+	// Non-racy version of:
+	// if p.proc == nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
+		p.mu.Lock()
+		defer p.mu.Unlock()
+		if p.proc == nil {
+			e := p.l.Load()
+			if e != nil {
+				return e
+			}
+			proc, e := p.l.dll.FindProc(p.Name)
+			if e != nil {
+				return e
+			}
+			// Non-racy version of:
+			// p.proc = proc
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
+		}
+	}
+	return nil
+}
+
+// mustFind is like Find but panics if search fails.
+func (p *LazyProc) mustFind() {
+	e := p.Find()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *LazyProc) Addr() uintptr {
+	p.mustFind()
+	return p.proc.Addr()
+}
+
+// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
+// are supplied.
+//
+// The returned error is always non-nil, constructed from the result of GetLastError.
+// Callers must inspect the primary return value to decide whether an error occurred
+// (according to the semantics of the specific function being called) before consulting
+// the error. The error will be guaranteed to contain windows.Errno.
+func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	p.mustFind()
+	return p.proc.Call(a...)
+}

+ 14 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/env_unset.go

@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.4
+
+package windows
+
+import "syscall"
+
+func Unsetenv(key string) error {
+	// This was added in Go 1.4.
+	return syscall.Unsetenv(key)
+}

+ 25 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/env_windows.go

@@ -0,0 +1,25 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Windows environment variables.
+
+package windows
+
+import "syscall"
+
+func Getenv(key string) (value string, found bool) {
+	return syscall.Getenv(key)
+}
+
+func Setenv(key, value string) error {
+	return syscall.Setenv(key, value)
+}
+
+func Clearenv() {
+	syscall.Clearenv()
+}
+
+func Environ() []string {
+	return syscall.Environ()
+}

+ 20 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/eventlog.go

@@ -0,0 +1,20 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package windows
+
+const (
+	EVENTLOG_SUCCESS          = 0
+	EVENTLOG_ERROR_TYPE       = 1
+	EVENTLOG_WARNING_TYPE     = 2
+	EVENTLOG_INFORMATION_TYPE = 4
+	EVENTLOG_AUDIT_SUCCESS    = 8
+	EVENTLOG_AUDIT_FAILURE    = 16
+)
+
+//sys	RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW
+//sys	DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource
+//sys	ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW

+ 97 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/exec_windows.go

@@ -0,0 +1,97 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Fork, exec, wait, etc.
+
+package windows
+
+// EscapeArg rewrites command line argument s as prescribed
+// in http://msdn.microsoft.com/en-us/library/ms880421.
+// This function returns "" (2 double quotes) if s is empty.
+// Alternatively, these transformations are done:
+// - every back slash (\) is doubled, but only if immediately
+//   followed by double quote (");
+// - every double quote (") is escaped by back slash (\);
+// - finally, s is wrapped with double quotes (arg -> "arg"),
+//   but only if there is space or tab inside s.
+func EscapeArg(s string) string {
+	if len(s) == 0 {
+		return "\"\""
+	}
+	n := len(s)
+	hasSpace := false
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		case '"', '\\':
+			n++
+		case ' ', '\t':
+			hasSpace = true
+		}
+	}
+	if hasSpace {
+		n += 2
+	}
+	if n == len(s) {
+		return s
+	}
+
+	qs := make([]byte, n)
+	j := 0
+	if hasSpace {
+		qs[j] = '"'
+		j++
+	}
+	slashes := 0
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		default:
+			slashes = 0
+			qs[j] = s[i]
+		case '\\':
+			slashes++
+			qs[j] = s[i]
+		case '"':
+			for ; slashes > 0; slashes-- {
+				qs[j] = '\\'
+				j++
+			}
+			qs[j] = '\\'
+			j++
+			qs[j] = s[i]
+		}
+		j++
+	}
+	if hasSpace {
+		for ; slashes > 0; slashes-- {
+			qs[j] = '\\'
+			j++
+		}
+		qs[j] = '"'
+		j++
+	}
+	return string(qs[:j])
+}
+
+func CloseOnExec(fd Handle) {
+	SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
+}
+
+// FullPath retrieves the full path of the specified file.
+func FullPath(name string) (path string, err error) {
+	p, err := UTF16PtrFromString(name)
+	if err != nil {
+		return "", err
+	}
+	n := uint32(100)
+	for {
+		buf := make([]uint16, n)
+		n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
+		if err != nil {
+			return "", err
+		}
+		if n <= uint32(len(buf)) {
+			return UTF16ToString(buf[:n]), nil
+		}
+	}
+}

+ 30 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/race.go

@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows,race
+
+package windows
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+const raceenabled = true
+
+func raceAcquire(addr unsafe.Pointer) {
+	runtime.RaceAcquire(addr)
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+	runtime.RaceReleaseMerge(addr)
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+	runtime.RaceReadRange(addr, len)
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+	runtime.RaceWriteRange(addr, len)
+}

+ 25 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/race0.go

@@ -0,0 +1,25 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows,!race
+
+package windows
+
+import (
+	"unsafe"
+)
+
+const raceenabled = false
+
+func raceAcquire(addr unsafe.Pointer) {
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+}

+ 178 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/key.go

@@ -0,0 +1,178 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package registry provides access to the Windows registry.
+//
+// Here is a simple example, opening a registry key and reading a string value from it.
+//
+//	k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
+//	if err != nil {
+//		log.Fatal(err)
+//	}
+//	defer k.Close()
+//
+//	s, _, err := k.GetStringValue("SystemRoot")
+//	if err != nil {
+//		log.Fatal(err)
+//	}
+//	fmt.Printf("Windows system root is %q\n", s)
+//
+package registry
+
+import (
+	"io"
+	"syscall"
+	"time"
+)
+
+const (
+	// Registry key security and access rights.
+	// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
+	// for details.
+	ALL_ACCESS         = 0xf003f
+	CREATE_LINK        = 0x00020
+	CREATE_SUB_KEY     = 0x00004
+	ENUMERATE_SUB_KEYS = 0x00008
+	EXECUTE            = 0x20019
+	NOTIFY             = 0x00010
+	QUERY_VALUE        = 0x00001
+	READ               = 0x20019
+	SET_VALUE          = 0x00002
+	WOW64_32KEY        = 0x00200
+	WOW64_64KEY        = 0x00100
+	WRITE              = 0x20006
+)
+
+// Key is a handle to an open Windows registry key.
+// Keys can be obtained by calling OpenKey; there are
+// also some predefined root keys such as CURRENT_USER.
+// Keys can be used directly in the Windows API.
+type Key syscall.Handle
+
+const (
+	// Windows defines some predefined root keys that are always open.
+	// An application can use these keys as entry points to the registry.
+	// Normally these keys are used in OpenKey to open new keys,
+	// but they can also be used anywhere a Key is required.
+	CLASSES_ROOT   = Key(syscall.HKEY_CLASSES_ROOT)
+	CURRENT_USER   = Key(syscall.HKEY_CURRENT_USER)
+	LOCAL_MACHINE  = Key(syscall.HKEY_LOCAL_MACHINE)
+	USERS          = Key(syscall.HKEY_USERS)
+	CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG)
+)
+
+// Close closes open key k.
+func (k Key) Close() error {
+	return syscall.RegCloseKey(syscall.Handle(k))
+}
+
+// OpenKey opens a new key with path name relative to key k.
+// It accepts any open key, including CURRENT_USER and others,
+// and returns the new key and an error.
+// The access parameter specifies desired access rights to the
+// key to be opened.
+func OpenKey(k Key, path string, access uint32) (Key, error) {
+	p, err := syscall.UTF16PtrFromString(path)
+	if err != nil {
+		return 0, err
+	}
+	var subkey syscall.Handle
+	err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
+	if err != nil {
+		return 0, err
+	}
+	return Key(subkey), nil
+}
+
+// ReadSubKeyNames returns the names of subkeys of key k.
+// The parameter n controls the number of returned names,
+// analogous to the way os.File.Readdirnames works.
+func (k Key) ReadSubKeyNames(n int) ([]string, error) {
+	ki, err := k.Stat()
+	if err != nil {
+		return nil, err
+	}
+	names := make([]string, 0, ki.SubKeyCount)
+	buf := make([]uint16, ki.MaxSubKeyLen+1) // extra room for terminating zero byte
+loopItems:
+	for i := uint32(0); ; i++ {
+		if n > 0 {
+			if len(names) == n {
+				return names, nil
+			}
+		}
+		l := uint32(len(buf))
+		for {
+			err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
+			if err == nil {
+				break
+			}
+			if err == syscall.ERROR_MORE_DATA {
+				// Double buffer size and try again.
+				l = uint32(2 * len(buf))
+				buf = make([]uint16, l)
+				continue
+			}
+			if err == _ERROR_NO_MORE_ITEMS {
+				break loopItems
+			}
+			return names, err
+		}
+		names = append(names, syscall.UTF16ToString(buf[:l]))
+	}
+	if n > len(names) {
+		return names, io.EOF
+	}
+	return names, nil
+}
+
+// CreateKey creates a key named path under open key k.
+// CreateKey returns the new key and a boolean flag that reports
+// whether the key already existed.
+// The access parameter specifies the access rights for the key
+// to be created.
+func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
+	var h syscall.Handle
+	var d uint32
+	err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
+		0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
+	if err != nil {
+		return 0, false, err
+	}
+	return Key(h), d == _REG_OPENED_EXISTING_KEY, nil
+}
+
+// DeleteKey deletes the subkey path of key k and its values.
+func DeleteKey(k Key, path string) error {
+	return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
+}
+
+// A KeyInfo describes the statistics of a key. It is returned by Stat.
+type KeyInfo struct {
+	SubKeyCount     uint32
+	MaxSubKeyLen    uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
+	ValueCount      uint32
+	MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
+	MaxValueLen     uint32 // longest data component among the key's values, in bytes
+	lastWriteTime   syscall.Filetime
+}
+
+// ModTime returns the key's last write time.
+func (ki *KeyInfo) ModTime() time.Time {
+	return time.Unix(0, ki.lastWriteTime.Nanoseconds())
+}
+
+// Stat retrieves information about the open key k.
+func (k Key) Stat() (*KeyInfo, error) {
+	var ki KeyInfo
+	err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil,
+		&ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount,
+		&ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime)
+	if err != nil {
+		return nil, err
+	}
+	return &ki, nil
+}

+ 33 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/syscall.go

@@ -0,0 +1,33 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package registry
+
+import "syscall"
+
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go
+
+const (
+	_REG_OPTION_NON_VOLATILE = 0
+
+	_REG_CREATED_NEW_KEY     = 1
+	_REG_OPENED_EXISTING_KEY = 2
+
+	_ERROR_NO_MORE_ITEMS syscall.Errno = 259
+)
+
+func LoadRegLoadMUIString() error {
+	return procRegLoadMUIStringW.Find()
+}
+
+//sys	regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW
+//sys	regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW
+//sys	regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW
+//sys	regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW
+//sys	regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW
+//sys   regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW
+
+//sys	expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW

+ 384 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/value.go

@@ -0,0 +1,384 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package registry
+
+import (
+	"errors"
+	"io"
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+)
+
+const (
+	// Registry value types.
+	NONE                       = 0
+	SZ                         = 1
+	EXPAND_SZ                  = 2
+	BINARY                     = 3
+	DWORD                      = 4
+	DWORD_BIG_ENDIAN           = 5
+	LINK                       = 6
+	MULTI_SZ                   = 7
+	RESOURCE_LIST              = 8
+	FULL_RESOURCE_DESCRIPTOR   = 9
+	RESOURCE_REQUIREMENTS_LIST = 10
+	QWORD                      = 11
+)
+
+var (
+	// ErrShortBuffer is returned when the buffer was too short for the operation.
+	ErrShortBuffer = syscall.ERROR_MORE_DATA
+
+	// ErrNotExist is returned when a registry key or value does not exist.
+	ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
+
+	// ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
+	ErrUnexpectedType = errors.New("unexpected key value type")
+)
+
+// GetValue retrieves the type and data for the specified value associated
+// with an open key k. It fills up buffer buf and returns the retrieved
+// byte count n. If buf is too small to fit the stored value it returns
+// ErrShortBuffer error along with the required buffer size n.
+// If no buffer is provided, it returns true and actual buffer size n.
+// If no buffer is provided, GetValue returns the value's type only.
+// If the value does not exist, the error returned is ErrNotExist.
+//
+// GetValue is a low level function. If value's type is known, use the appropriate
+// Get*Value function instead.
+func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
+	pname, err := syscall.UTF16PtrFromString(name)
+	if err != nil {
+		return 0, 0, err
+	}
+	var pbuf *byte
+	if len(buf) > 0 {
+		pbuf = (*byte)(unsafe.Pointer(&buf[0]))
+	}
+	l := uint32(len(buf))
+	err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
+	if err != nil {
+		return int(l), valtype, err
+	}
+	return int(l), valtype, nil
+}
+
+func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
+	p, err := syscall.UTF16PtrFromString(name)
+	if err != nil {
+		return nil, 0, err
+	}
+	var t uint32
+	n := uint32(len(buf))
+	for {
+		err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
+		if err == nil {
+			return buf[:n], t, nil
+		}
+		if err != syscall.ERROR_MORE_DATA {
+			return nil, 0, err
+		}
+		if n <= uint32(len(buf)) {
+			return nil, 0, err
+		}
+		buf = make([]byte, n)
+	}
+}
+
+// GetStringValue retrieves the string value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetStringValue returns ErrNotExist.
+// If value is not SZ or EXPAND_SZ, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
+	if err2 != nil {
+		return "", typ, err2
+	}
+	switch typ {
+	case SZ, EXPAND_SZ:
+	default:
+		return "", typ, ErrUnexpectedType
+	}
+	if len(data) == 0 {
+		return "", typ, nil
+	}
+	u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:]
+	return syscall.UTF16ToString(u), typ, nil
+}
+
+// GetMUIStringValue retrieves the localized string value for
+// the specified value name associated with an open key k.
+// If the value name doesn't exist or the localized string value
+// can't be resolved, GetMUIStringValue returns ErrNotExist.
+// GetMUIStringValue panics if the system doesn't support
+// regLoadMUIString; use LoadRegLoadMUIString to check if
+// regLoadMUIString is supported before calling this function.
+func (k Key) GetMUIStringValue(name string) (string, error) {
+	pname, err := syscall.UTF16PtrFromString(name)
+	if err != nil {
+		return "", err
+	}
+
+	buf := make([]uint16, 1024)
+	var buflen uint32
+	var pdir *uint16
+
+	err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
+	if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
+
+		// Try to resolve the string value using the system directory as
+		// a DLL search path; this assumes the string value is of the form
+		// @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
+
+		// This approach works with tzres.dll but may have to be revised
+		// in the future to allow callers to provide custom search paths.
+
+		var s string
+		s, err = ExpandString("%SystemRoot%\\system32\\")
+		if err != nil {
+			return "", err
+		}
+		pdir, err = syscall.UTF16PtrFromString(s)
+		if err != nil {
+			return "", err
+		}
+
+		err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
+	}
+
+	for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
+		if buflen <= uint32(len(buf)) {
+			break // Buffer not growing, assume race; break
+		}
+		buf = make([]uint16, buflen)
+		err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
+	}
+
+	if err != nil {
+		return "", err
+	}
+
+	return syscall.UTF16ToString(buf), nil
+}
+
+// ExpandString expands environment-variable strings and replaces
+// them with the values defined for the current user.
+// Use ExpandString to expand EXPAND_SZ strings.
+func ExpandString(value string) (string, error) {
+	if value == "" {
+		return "", nil
+	}
+	p, err := syscall.UTF16PtrFromString(value)
+	if err != nil {
+		return "", err
+	}
+	r := make([]uint16, 100)
+	for {
+		n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
+		if err != nil {
+			return "", err
+		}
+		if n <= uint32(len(r)) {
+			u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:]
+			return syscall.UTF16ToString(u), nil
+		}
+		r = make([]uint16, n)
+	}
+}
+
+// GetStringsValue retrieves the []string value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetStringsValue returns ErrNotExist.
+// If value is not MULTI_SZ, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
+	if err2 != nil {
+		return nil, typ, err2
+	}
+	if typ != MULTI_SZ {
+		return nil, typ, ErrUnexpectedType
+	}
+	if len(data) == 0 {
+		return nil, typ, nil
+	}
+	p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2]
+	if len(p) == 0 {
+		return nil, typ, nil
+	}
+	if p[len(p)-1] == 0 {
+		p = p[:len(p)-1] // remove terminating null
+	}
+	val = make([]string, 0, 5)
+	from := 0
+	for i, c := range p {
+		if c == 0 {
+			val = append(val, string(utf16.Decode(p[from:i])))
+			from = i + 1
+		}
+	}
+	return val, typ, nil
+}
+
+// GetIntegerValue retrieves the integer value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetIntegerValue returns ErrNotExist.
+// If value is not DWORD or QWORD, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 8))
+	if err2 != nil {
+		return 0, typ, err2
+	}
+	switch typ {
+	case DWORD:
+		if len(data) != 4 {
+			return 0, typ, errors.New("DWORD value is not 4 bytes long")
+		}
+		return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
+	case QWORD:
+		if len(data) != 8 {
+			return 0, typ, errors.New("QWORD value is not 8 bytes long")
+		}
+		return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
+	default:
+		return 0, typ, ErrUnexpectedType
+	}
+}
+
+// GetBinaryValue retrieves the binary value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetBinaryValue returns ErrNotExist.
+// If value is not BINARY, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
+	if err2 != nil {
+		return nil, typ, err2
+	}
+	if typ != BINARY {
+		return nil, typ, ErrUnexpectedType
+	}
+	return data, typ, nil
+}
+
+func (k Key) setValue(name string, valtype uint32, data []byte) error {
+	p, err := syscall.UTF16PtrFromString(name)
+	if err != nil {
+		return err
+	}
+	if len(data) == 0 {
+		return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
+	}
+	return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
+}
+
+// SetDWordValue sets the data and type of a name value
+// under key k to value and DWORD.
+func (k Key) SetDWordValue(name string, value uint32) error {
+	return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
+}
+
+// SetQWordValue sets the data and type of a name value
+// under key k to value and QWORD.
+func (k Key) SetQWordValue(name string, value uint64) error {
+	return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
+}
+
+func (k Key) setStringValue(name string, valtype uint32, value string) error {
+	v, err := syscall.UTF16FromString(value)
+	if err != nil {
+		return err
+	}
+	buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
+	return k.setValue(name, valtype, buf)
+}
+
+// SetStringValue sets the data and type of a name value
+// under key k to value and SZ. The value must not contain a zero byte.
+func (k Key) SetStringValue(name, value string) error {
+	return k.setStringValue(name, SZ, value)
+}
+
+// SetExpandStringValue sets the data and type of a name value
+// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
+func (k Key) SetExpandStringValue(name, value string) error {
+	return k.setStringValue(name, EXPAND_SZ, value)
+}
+
+// SetStringsValue sets the data and type of a name value
+// under key k to value and MULTI_SZ. The value strings
+// must not contain a zero byte.
+func (k Key) SetStringsValue(name string, value []string) error {
+	ss := ""
+	for _, s := range value {
+		for i := 0; i < len(s); i++ {
+			if s[i] == 0 {
+				return errors.New("string cannot have 0 inside")
+			}
+		}
+		ss += s + "\x00"
+	}
+	v := utf16.Encode([]rune(ss + "\x00"))
+	buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
+	return k.setValue(name, MULTI_SZ, buf)
+}
+
+// SetBinaryValue sets the data and type of a name value
+// under key k to value and BINARY.
+func (k Key) SetBinaryValue(name string, value []byte) error {
+	return k.setValue(name, BINARY, value)
+}
+
+// DeleteValue removes a named value from the key k.
+func (k Key) DeleteValue(name string) error {
+	return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
+}
+
+// ReadValueNames returns the value names of key k.
+// The parameter n controls the number of returned names,
+// analogous to the way os.File.Readdirnames works.
+func (k Key) ReadValueNames(n int) ([]string, error) {
+	ki, err := k.Stat()
+	if err != nil {
+		return nil, err
+	}
+	names := make([]string, 0, ki.ValueCount)
+	buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
+loopItems:
+	for i := uint32(0); ; i++ {
+		if n > 0 {
+			if len(names) == n {
+				return names, nil
+			}
+		}
+		l := uint32(len(buf))
+		for {
+			err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
+			if err == nil {
+				break
+			}
+			if err == syscall.ERROR_MORE_DATA {
+				// Double buffer size and try again.
+				l = uint32(2 * len(buf))
+				buf = make([]uint16, l)
+				continue
+			}
+			if err == _ERROR_NO_MORE_ITEMS {
+				break loopItems
+			}
+			return names, err
+		}
+		names = append(names, syscall.UTF16ToString(buf[:l]))
+	}
+	if n > len(names) {
+		return names, io.EOF
+	}
+	return names, nil
+}

+ 82 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/registry/zsyscall_windows.go

@@ -0,0 +1,82 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package registry
+
+import "unsafe"
+import "syscall"
+
+var _ unsafe.Pointer
+
+var (
+	modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
+	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+	procRegCreateKeyExW           = modadvapi32.NewProc("RegCreateKeyExW")
+	procRegDeleteKeyW             = modadvapi32.NewProc("RegDeleteKeyW")
+	procRegSetValueExW            = modadvapi32.NewProc("RegSetValueExW")
+	procRegEnumValueW             = modadvapi32.NewProc("RegEnumValueW")
+	procRegDeleteValueW           = modadvapi32.NewProc("RegDeleteValueW")
+	procRegLoadMUIStringW         = modadvapi32.NewProc("RegLoadMUIStringW")
+	procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
+)
+
+func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) {
+	r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) {
+	r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) {
+	r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}

+ 435 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/security_windows.go

@@ -0,0 +1,435 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const (
+	STANDARD_RIGHTS_REQUIRED = 0xf0000
+	STANDARD_RIGHTS_READ     = 0x20000
+	STANDARD_RIGHTS_WRITE    = 0x20000
+	STANDARD_RIGHTS_EXECUTE  = 0x20000
+	STANDARD_RIGHTS_ALL      = 0x1F0000
+)
+
+const (
+	NameUnknown          = 0
+	NameFullyQualifiedDN = 1
+	NameSamCompatible    = 2
+	NameDisplay          = 3
+	NameUniqueId         = 6
+	NameCanonical        = 7
+	NameUserPrincipal    = 8
+	NameCanonicalEx      = 9
+	NameServicePrincipal = 10
+	NameDnsDomain        = 12
+)
+
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
+//sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
+//sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
+
+// TranslateAccountName converts a directory service
+// object name from one format to another.
+func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
+	u, e := UTF16PtrFromString(username)
+	if e != nil {
+		return "", e
+	}
+	n := uint32(50)
+	for {
+		b := make([]uint16, n)
+		e = TranslateName(u, from, to, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b[:n]), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", e
+		}
+		if n <= uint32(len(b)) {
+			return "", e
+		}
+	}
+}
+
+const (
+	// do not reorder
+	NetSetupUnknownStatus = iota
+	NetSetupUnjoined
+	NetSetupWorkgroupName
+	NetSetupDomainName
+)
+
+type UserInfo10 struct {
+	Name       *uint16
+	Comment    *uint16
+	UsrComment *uint16
+	FullName   *uint16
+}
+
+//sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
+//sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
+//sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
+
+const (
+	// do not reorder
+	SidTypeUser = 1 + iota
+	SidTypeGroup
+	SidTypeDomain
+	SidTypeAlias
+	SidTypeWellKnownGroup
+	SidTypeDeletedAccount
+	SidTypeInvalid
+	SidTypeUnknown
+	SidTypeComputer
+	SidTypeLabel
+)
+
+type SidIdentifierAuthority struct {
+	Value [6]byte
+}
+
+var (
+	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
+	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
+	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
+	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
+	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
+	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
+	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
+)
+
+const (
+	SECURITY_NULL_RID                   = 0
+	SECURITY_WORLD_RID                  = 0
+	SECURITY_LOCAL_RID                  = 0
+	SECURITY_CREATOR_OWNER_RID          = 0
+	SECURITY_CREATOR_GROUP_RID          = 1
+	SECURITY_DIALUP_RID                 = 1
+	SECURITY_NETWORK_RID                = 2
+	SECURITY_BATCH_RID                  = 3
+	SECURITY_INTERACTIVE_RID            = 4
+	SECURITY_LOGON_IDS_RID              = 5
+	SECURITY_SERVICE_RID                = 6
+	SECURITY_LOCAL_SYSTEM_RID           = 18
+	SECURITY_BUILTIN_DOMAIN_RID         = 32
+	SECURITY_PRINCIPAL_SELF_RID         = 10
+	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
+	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
+	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
+	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
+	SECURITY_PROXY_RID                  = 0x8
+	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
+	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
+	SECURITY_AUTHENTICATED_USER_RID     = 0xb
+	SECURITY_RESTRICTED_CODE_RID        = 0xc
+	SECURITY_NT_NON_UNIQUE_RID          = 0x15
+)
+
+//sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
+//sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
+//sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
+//sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
+//sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
+//sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
+//sys	AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid
+//sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
+//sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
+
+// The security identifier (SID) structure is a variable-length
+// structure used to uniquely identify users or groups.
+type SID struct{}
+
+// StringToSid converts a string-format security identifier
+// sid into a valid, functional sid.
+func StringToSid(s string) (*SID, error) {
+	var sid *SID
+	p, e := UTF16PtrFromString(s)
+	if e != nil {
+		return nil, e
+	}
+	e = ConvertStringSidToSid(p, &sid)
+	if e != nil {
+		return nil, e
+	}
+	defer LocalFree((Handle)(unsafe.Pointer(sid)))
+	return sid.Copy()
+}
+
+// LookupSID retrieves a security identifier sid for the account
+// and the name of the domain on which the account was found.
+// System specify target computer to search.
+func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
+	if len(account) == 0 {
+		return nil, "", 0, syscall.EINVAL
+	}
+	acc, e := UTF16PtrFromString(account)
+	if e != nil {
+		return nil, "", 0, e
+	}
+	var sys *uint16
+	if len(system) > 0 {
+		sys, e = UTF16PtrFromString(system)
+		if e != nil {
+			return nil, "", 0, e
+		}
+	}
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]byte, n)
+		db := make([]uint16, dn)
+		sid = (*SID)(unsafe.Pointer(&b[0]))
+		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
+		if e == nil {
+			return sid, UTF16ToString(db), accType, nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return nil, "", 0, e
+		}
+		if n <= uint32(len(b)) {
+			return nil, "", 0, e
+		}
+	}
+}
+
+// String converts sid to a string format
+// suitable for display, storage, or transmission.
+func (sid *SID) String() (string, error) {
+	var s *uint16
+	e := ConvertSidToStringSid(sid, &s)
+	if e != nil {
+		return "", e
+	}
+	defer LocalFree((Handle)(unsafe.Pointer(s)))
+	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
+}
+
+// Len returns the length, in bytes, of a valid security identifier sid.
+func (sid *SID) Len() int {
+	return int(GetLengthSid(sid))
+}
+
+// Copy creates a duplicate of security identifier sid.
+func (sid *SID) Copy() (*SID, error) {
+	b := make([]byte, sid.Len())
+	sid2 := (*SID)(unsafe.Pointer(&b[0]))
+	e := CopySid(uint32(len(b)), sid2, sid)
+	if e != nil {
+		return nil, e
+	}
+	return sid2, nil
+}
+
+// LookupAccount retrieves the name of the account for this sid
+// and the name of the first domain on which this sid is found.
+// System specify target computer to search for.
+func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
+	var sys *uint16
+	if len(system) > 0 {
+		sys, err = UTF16PtrFromString(system)
+		if err != nil {
+			return "", "", 0, err
+		}
+	}
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]uint16, n)
+		db := make([]uint16, dn)
+		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
+		if e == nil {
+			return UTF16ToString(b), UTF16ToString(db), accType, nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", "", 0, e
+		}
+		if n <= uint32(len(b)) {
+			return "", "", 0, e
+		}
+	}
+}
+
+const (
+	// do not reorder
+	TOKEN_ASSIGN_PRIMARY = 1 << iota
+	TOKEN_DUPLICATE
+	TOKEN_IMPERSONATE
+	TOKEN_QUERY
+	TOKEN_QUERY_SOURCE
+	TOKEN_ADJUST_PRIVILEGES
+	TOKEN_ADJUST_GROUPS
+	TOKEN_ADJUST_DEFAULT
+
+	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
+		TOKEN_ASSIGN_PRIMARY |
+		TOKEN_DUPLICATE |
+		TOKEN_IMPERSONATE |
+		TOKEN_QUERY |
+		TOKEN_QUERY_SOURCE |
+		TOKEN_ADJUST_PRIVILEGES |
+		TOKEN_ADJUST_GROUPS |
+		TOKEN_ADJUST_DEFAULT
+	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
+	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
+		TOKEN_ADJUST_PRIVILEGES |
+		TOKEN_ADJUST_GROUPS |
+		TOKEN_ADJUST_DEFAULT
+	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
+)
+
+const (
+	// do not reorder
+	TokenUser = 1 + iota
+	TokenGroups
+	TokenPrivileges
+	TokenOwner
+	TokenPrimaryGroup
+	TokenDefaultDacl
+	TokenSource
+	TokenType
+	TokenImpersonationLevel
+	TokenStatistics
+	TokenRestrictedSids
+	TokenSessionId
+	TokenGroupsAndPrivileges
+	TokenSessionReference
+	TokenSandBoxInert
+	TokenAuditPolicy
+	TokenOrigin
+	TokenElevationType
+	TokenLinkedToken
+	TokenElevation
+	TokenHasRestrictions
+	TokenAccessInformation
+	TokenVirtualizationAllowed
+	TokenVirtualizationEnabled
+	TokenIntegrityLevel
+	TokenUIAccess
+	TokenMandatoryPolicy
+	TokenLogonSid
+	MaxTokenInfoClass
+)
+
+type SIDAndAttributes struct {
+	Sid        *SID
+	Attributes uint32
+}
+
+type Tokenuser struct {
+	User SIDAndAttributes
+}
+
+type Tokenprimarygroup struct {
+	PrimaryGroup *SID
+}
+
+type Tokengroups struct {
+	GroupCount uint32
+	Groups     [1]SIDAndAttributes
+}
+
+//sys	OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
+//sys	GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
+//sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
+
+// An access token contains the security information for a logon session.
+// The system creates an access token when a user logs on, and every
+// process executed on behalf of the user has a copy of the token.
+// The token identifies the user, the user's groups, and the user's
+// privileges. The system uses the token to control access to securable
+// objects and to control the ability of the user to perform various
+// system-related operations on the local computer.
+type Token Handle
+
+// OpenCurrentProcessToken opens the access token
+// associated with current process.
+func OpenCurrentProcessToken() (Token, error) {
+	p, e := GetCurrentProcess()
+	if e != nil {
+		return 0, e
+	}
+	var t Token
+	e = OpenProcessToken(p, TOKEN_QUERY, &t)
+	if e != nil {
+		return 0, e
+	}
+	return t, nil
+}
+
+// Close releases access to access token.
+func (t Token) Close() error {
+	return CloseHandle(Handle(t))
+}
+
+// getInfo retrieves a specified type of information about an access token.
+func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
+	n := uint32(initSize)
+	for {
+		b := make([]byte, n)
+		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
+		if e == nil {
+			return unsafe.Pointer(&b[0]), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return nil, e
+		}
+		if n <= uint32(len(b)) {
+			return nil, e
+		}
+	}
+}
+
+// GetTokenUser retrieves access token t user account information.
+func (t Token) GetTokenUser() (*Tokenuser, error) {
+	i, e := t.getInfo(TokenUser, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokenuser)(i), nil
+}
+
+// GetTokenGroups retrieves group accounts associated with access token t.
+func (t Token) GetTokenGroups() (*Tokengroups, error) {
+	i, e := t.getInfo(TokenGroups, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokengroups)(i), nil
+}
+
+// GetTokenPrimaryGroup retrieves access token t primary group information.
+// A pointer to a SID structure representing a group that will become
+// the primary group of any objects created by a process using this access token.
+func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
+	i, e := t.getInfo(TokenPrimaryGroup, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokenprimarygroup)(i), nil
+}
+
+// GetUserProfileDirectory retrieves path to the
+// root directory of the access token t user's profile.
+func (t Token) GetUserProfileDirectory() (string, error) {
+	n := uint32(100)
+	for {
+		b := make([]uint16, n)
+		e := GetUserProfileDirectory(t, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", e
+		}
+		if n <= uint32(len(b)) {
+			return "", e
+		}
+	}
+}

+ 143 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/service.go

@@ -0,0 +1,143 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package windows
+
+const (
+	SC_MANAGER_CONNECT            = 1
+	SC_MANAGER_CREATE_SERVICE     = 2
+	SC_MANAGER_ENUMERATE_SERVICE  = 4
+	SC_MANAGER_LOCK               = 8
+	SC_MANAGER_QUERY_LOCK_STATUS  = 16
+	SC_MANAGER_MODIFY_BOOT_CONFIG = 32
+	SC_MANAGER_ALL_ACCESS         = 0xf003f
+)
+
+//sys	OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW
+
+const (
+	SERVICE_KERNEL_DRIVER       = 1
+	SERVICE_FILE_SYSTEM_DRIVER  = 2
+	SERVICE_ADAPTER             = 4
+	SERVICE_RECOGNIZER_DRIVER   = 8
+	SERVICE_WIN32_OWN_PROCESS   = 16
+	SERVICE_WIN32_SHARE_PROCESS = 32
+	SERVICE_WIN32               = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS
+	SERVICE_INTERACTIVE_PROCESS = 256
+	SERVICE_DRIVER              = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER
+	SERVICE_TYPE_ALL            = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS
+
+	SERVICE_BOOT_START   = 0
+	SERVICE_SYSTEM_START = 1
+	SERVICE_AUTO_START   = 2
+	SERVICE_DEMAND_START = 3
+	SERVICE_DISABLED     = 4
+
+	SERVICE_ERROR_IGNORE   = 0
+	SERVICE_ERROR_NORMAL   = 1
+	SERVICE_ERROR_SEVERE   = 2
+	SERVICE_ERROR_CRITICAL = 3
+
+	SC_STATUS_PROCESS_INFO = 0
+
+	SERVICE_STOPPED          = 1
+	SERVICE_START_PENDING    = 2
+	SERVICE_STOP_PENDING     = 3
+	SERVICE_RUNNING          = 4
+	SERVICE_CONTINUE_PENDING = 5
+	SERVICE_PAUSE_PENDING    = 6
+	SERVICE_PAUSED           = 7
+	SERVICE_NO_CHANGE        = 0xffffffff
+
+	SERVICE_ACCEPT_STOP                  = 1
+	SERVICE_ACCEPT_PAUSE_CONTINUE        = 2
+	SERVICE_ACCEPT_SHUTDOWN              = 4
+	SERVICE_ACCEPT_PARAMCHANGE           = 8
+	SERVICE_ACCEPT_NETBINDCHANGE         = 16
+	SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32
+	SERVICE_ACCEPT_POWEREVENT            = 64
+	SERVICE_ACCEPT_SESSIONCHANGE         = 128
+
+	SERVICE_CONTROL_STOP                  = 1
+	SERVICE_CONTROL_PAUSE                 = 2
+	SERVICE_CONTROL_CONTINUE              = 3
+	SERVICE_CONTROL_INTERROGATE           = 4
+	SERVICE_CONTROL_SHUTDOWN              = 5
+	SERVICE_CONTROL_PARAMCHANGE           = 6
+	SERVICE_CONTROL_NETBINDADD            = 7
+	SERVICE_CONTROL_NETBINDREMOVE         = 8
+	SERVICE_CONTROL_NETBINDENABLE         = 9
+	SERVICE_CONTROL_NETBINDDISABLE        = 10
+	SERVICE_CONTROL_DEVICEEVENT           = 11
+	SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12
+	SERVICE_CONTROL_POWEREVENT            = 13
+	SERVICE_CONTROL_SESSIONCHANGE         = 14
+
+	SERVICE_ACTIVE    = 1
+	SERVICE_INACTIVE  = 2
+	SERVICE_STATE_ALL = 3
+
+	SERVICE_QUERY_CONFIG           = 1
+	SERVICE_CHANGE_CONFIG          = 2
+	SERVICE_QUERY_STATUS           = 4
+	SERVICE_ENUMERATE_DEPENDENTS   = 8
+	SERVICE_START                  = 16
+	SERVICE_STOP                   = 32
+	SERVICE_PAUSE_CONTINUE         = 64
+	SERVICE_INTERROGATE            = 128
+	SERVICE_USER_DEFINED_CONTROL   = 256
+	SERVICE_ALL_ACCESS             = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL
+	SERVICE_RUNS_IN_SYSTEM_PROCESS = 1
+	SERVICE_CONFIG_DESCRIPTION     = 1
+	SERVICE_CONFIG_FAILURE_ACTIONS = 2
+
+	NO_ERROR = 0
+)
+
+type SERVICE_STATUS struct {
+	ServiceType             uint32
+	CurrentState            uint32
+	ControlsAccepted        uint32
+	Win32ExitCode           uint32
+	ServiceSpecificExitCode uint32
+	CheckPoint              uint32
+	WaitHint                uint32
+}
+
+type SERVICE_TABLE_ENTRY struct {
+	ServiceName *uint16
+	ServiceProc uintptr
+}
+
+type QUERY_SERVICE_CONFIG struct {
+	ServiceType      uint32
+	StartType        uint32
+	ErrorControl     uint32
+	BinaryPathName   *uint16
+	LoadOrderGroup   *uint16
+	TagId            uint32
+	Dependencies     *uint16
+	ServiceStartName *uint16
+	DisplayName      *uint16
+}
+
+type SERVICE_DESCRIPTION struct {
+	Description *uint16
+}
+
+//sys	CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle
+//sys	CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW
+//sys	OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW
+//sys	DeleteService(service Handle) (err error) = advapi32.DeleteService
+//sys	StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW
+//sys	QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus
+//sys	ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService
+//sys	StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW
+//sys	SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus
+//sys	ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW
+//sys	QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW
+//sys	ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W
+//sys	QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W

+ 22 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/str.go

@@ -0,0 +1,22 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package windows
+
+func itoa(val int) string { // do it here rather than with fmt to avoid dependency
+	if val < 0 {
+		return "-" + itoa(-val)
+	}
+	var buf [32]byte // big enough for int64
+	i := len(buf) - 1
+	for val >= 10 {
+		buf[i] = byte(val%10 + '0')
+		i--
+		val /= 10
+	}
+	buf[i] = byte(val + '0')
+	return string(buf[i:])
+}

+ 56 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/debug/log.go

@@ -0,0 +1,56 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package debug
+
+import (
+	"os"
+	"strconv"
+)
+
+// Log interface allows different log implementations to be used.
+type Log interface {
+	Close() error
+	Info(eid uint32, msg string) error
+	Warning(eid uint32, msg string) error
+	Error(eid uint32, msg string) error
+}
+
+// ConsoleLog provides access to the console.
+type ConsoleLog struct {
+	Name string
+}
+
+// New creates new ConsoleLog.
+func New(source string) *ConsoleLog {
+	return &ConsoleLog{Name: source}
+}
+
+// Close closes console log l.
+func (l *ConsoleLog) Close() error {
+	return nil
+}
+
+func (l *ConsoleLog) report(kind string, eid uint32, msg string) error {
+	s := l.Name + "." + kind + "(" + strconv.Itoa(int(eid)) + "): " + msg + "\n"
+	_, err := os.Stdout.Write([]byte(s))
+	return err
+}
+
+// Info writes an information event msg with event id eid to the console l.
+func (l *ConsoleLog) Info(eid uint32, msg string) error {
+	return l.report("info", eid, msg)
+}
+
+// Warning writes an warning event msg with event id eid to the console l.
+func (l *ConsoleLog) Warning(eid uint32, msg string) error {
+	return l.report("warn", eid, msg)
+}
+
+// Error writes an error event msg with event id eid to the console l.
+func (l *ConsoleLog) Error(eid uint32, msg string) error {
+	return l.report("error", eid, msg)
+}

+ 45 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/debug/service.go

@@ -0,0 +1,45 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package debug provides facilities to execute svc.Handler on console.
+//
+package debug
+
+import (
+	"os"
+	"os/signal"
+	"syscall"
+
+	"golang.org/x/sys/windows/svc"
+)
+
+// Run executes service name by calling appropriate handler function.
+// The process is running on console, unlike real service. Use Ctrl+C to
+// send "Stop" command to your service.
+func Run(name string, handler svc.Handler) error {
+	cmds := make(chan svc.ChangeRequest)
+	changes := make(chan svc.Status)
+
+	sig := make(chan os.Signal)
+	signal.Notify(sig)
+
+	go func() {
+		status := svc.Status{State: svc.Stopped}
+		for {
+			select {
+			case <-sig:
+				cmds <- svc.ChangeRequest{svc.Stop, status}
+			case status = <-changes:
+			}
+		}
+	}()
+
+	_, errno := handler.Execute([]string{name}, cmds, changes)
+	if errno != 0 {
+		return syscall.Errno(errno)
+	}
+	return nil
+}

+ 48 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/event.go

@@ -0,0 +1,48 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package svc
+
+import (
+	"errors"
+
+	"golang.org/x/sys/windows"
+)
+
+// event represents auto-reset, initially non-signaled Windows event.
+// It is used to communicate between go and asm parts of this package.
+type event struct {
+	h windows.Handle
+}
+
+func newEvent() (*event, error) {
+	h, err := windows.CreateEvent(nil, 0, 0, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &event{h: h}, nil
+}
+
+func (e *event) Close() error {
+	return windows.CloseHandle(e.h)
+}
+
+func (e *event) Set() error {
+	return windows.SetEvent(e.h)
+}
+
+func (e *event) Wait() error {
+	s, err := windows.WaitForSingleObject(e.h, windows.INFINITE)
+	switch s {
+	case windows.WAIT_OBJECT_0:
+		break
+	case windows.WAIT_FAILED:
+		return err
+	default:
+		return errors.New("unexpected result from WaitForSingleObject")
+	}
+	return nil
+}

+ 80 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/eventlog/install.go

@@ -0,0 +1,80 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package eventlog
+
+import (
+	"errors"
+
+	"golang.org/x/sys/windows"
+	"golang.org/x/sys/windows/registry"
+)
+
+const (
+	// Log levels.
+	Info    = windows.EVENTLOG_INFORMATION_TYPE
+	Warning = windows.EVENTLOG_WARNING_TYPE
+	Error   = windows.EVENTLOG_ERROR_TYPE
+)
+
+const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
+
+// Install modifies PC registry to allow logging with an event source src.
+// It adds all required keys and values to the event log registry key.
+// Install uses msgFile as the event message file. If useExpandKey is true,
+// the event message file is installed as REG_EXPAND_SZ value,
+// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
+// log.Info to specify events supported by the new event source.
+func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error {
+	appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY)
+	if err != nil {
+		return err
+	}
+	defer appkey.Close()
+
+	sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
+	if err != nil {
+		return err
+	}
+	defer sk.Close()
+	if alreadyExist {
+		return errors.New(addKeyName + `\` + src + " registry key already exists")
+	}
+
+	err = sk.SetDWordValue("CustomSource", 1)
+	if err != nil {
+		return err
+	}
+	if useExpandKey {
+		err = sk.SetExpandStringValue("EventMessageFile", msgFile)
+	} else {
+		err = sk.SetStringValue("EventMessageFile", msgFile)
+	}
+	if err != nil {
+		return err
+	}
+	err = sk.SetDWordValue("TypesSupported", eventsSupported)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// InstallAsEventCreate is the same as Install, but uses
+// %SystemRoot%\System32\EventCreate.exe as the event message file.
+func InstallAsEventCreate(src string, eventsSupported uint32) error {
+	return Install(src, "%SystemRoot%\\System32\\EventCreate.exe", true, eventsSupported)
+}
+
+// Remove deletes all registry elements installed by the correspondent Install.
+func Remove(src string) error {
+	appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.SET_VALUE)
+	if err != nil {
+		return err
+	}
+	defer appkey.Close()
+	return registry.DeleteKey(appkey, src)
+}

+ 70 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/eventlog/log.go

@@ -0,0 +1,70 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package eventlog implements access to Windows event log.
+//
+package eventlog
+
+import (
+	"errors"
+	"syscall"
+
+	"golang.org/x/sys/windows"
+)
+
+// Log provides access to the system log.
+type Log struct {
+	Handle windows.Handle
+}
+
+// Open retrieves a handle to the specified event log.
+func Open(source string) (*Log, error) {
+	return OpenRemote("", source)
+}
+
+// OpenRemote does the same as Open, but on different computer host.
+func OpenRemote(host, source string) (*Log, error) {
+	if source == "" {
+		return nil, errors.New("Specify event log source")
+	}
+	var s *uint16
+	if host != "" {
+		s = syscall.StringToUTF16Ptr(host)
+	}
+	h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source))
+	if err != nil {
+		return nil, err
+	}
+	return &Log{Handle: h}, nil
+}
+
+// Close closes event log l.
+func (l *Log) Close() error {
+	return windows.DeregisterEventSource(l.Handle)
+}
+
+func (l *Log) report(etype uint16, eid uint32, msg string) error {
+	ss := []*uint16{syscall.StringToUTF16Ptr(msg)}
+	return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
+}
+
+// Info writes an information event msg with event id eid to the end of event log l.
+// When EventCreate.exe is used, eid must be between 1 and 1000.
+func (l *Log) Info(eid uint32, msg string) error {
+	return l.report(windows.EVENTLOG_INFORMATION_TYPE, eid, msg)
+}
+
+// Warning writes an warning event msg with event id eid to the end of event log l.
+// When EventCreate.exe is used, eid must be between 1 and 1000.
+func (l *Log) Warning(eid uint32, msg string) error {
+	return l.report(windows.EVENTLOG_WARNING_TYPE, eid, msg)
+}
+
+// Error writes an error event msg with event id eid to the end of event log l.
+// When EventCreate.exe is used, eid must be between 1 and 1000.
+func (l *Log) Error(eid uint32, msg string) error {
+	return l.report(windows.EVENTLOG_ERROR_TYPE, eid, msg)
+}

+ 22 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/beep.go

@@ -0,0 +1,22 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"syscall"
+)
+
+// BUG(brainman): MessageBeep Windows api is broken on Windows 7,
+// so this example does not beep when runs as service on Windows 7.
+
+var (
+	beepFunc = syscall.MustLoadDLL("user32.dll").MustFindProc("MessageBeep")
+)
+
+func beep() {
+	beepFunc.Call(0xffffffff)
+}

+ 92 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/install.go

@@ -0,0 +1,92 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+
+	"golang.org/x/sys/windows/svc/eventlog"
+	"golang.org/x/sys/windows/svc/mgr"
+)
+
+func exePath() (string, error) {
+	prog := os.Args[0]
+	p, err := filepath.Abs(prog)
+	if err != nil {
+		return "", err
+	}
+	fi, err := os.Stat(p)
+	if err == nil {
+		if !fi.Mode().IsDir() {
+			return p, nil
+		}
+		err = fmt.Errorf("%s is directory", p)
+	}
+	if filepath.Ext(p) == "" {
+		p += ".exe"
+		fi, err := os.Stat(p)
+		if err == nil {
+			if !fi.Mode().IsDir() {
+				return p, nil
+			}
+			err = fmt.Errorf("%s is directory", p)
+		}
+	}
+	return "", err
+}
+
+func installService(name, desc string) error {
+	exepath, err := exePath()
+	if err != nil {
+		return err
+	}
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err == nil {
+		s.Close()
+		return fmt.Errorf("service %s already exists", name)
+	}
+	s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc}, "is", "auto-started")
+	if err != nil {
+		return err
+	}
+	defer s.Close()
+	err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
+	if err != nil {
+		s.Delete()
+		return fmt.Errorf("SetupEventLogSource() failed: %s", err)
+	}
+	return nil
+}
+
+func removeService(name string) error {
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err != nil {
+		return fmt.Errorf("service %s is not installed", name)
+	}
+	defer s.Close()
+	err = s.Delete()
+	if err != nil {
+		return err
+	}
+	err = eventlog.Remove(name)
+	if err != nil {
+		return fmt.Errorf("RemoveEventLogSource() failed: %s", err)
+	}
+	return nil
+}

+ 76 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/main.go

@@ -0,0 +1,76 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Example service program that beeps.
+//
+// The program demonstrates how to create Windows service and
+// install / remove it on a computer. It also shows how to
+// stop / start / pause / continue any service, and how to
+// write to event log. It also shows how to use debug
+// facilities available in debug package.
+//
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"strings"
+
+	"golang.org/x/sys/windows/svc"
+)
+
+func usage(errmsg string) {
+	fmt.Fprintf(os.Stderr,
+		"%s\n\n"+
+			"usage: %s <command>\n"+
+			"       where <command> is one of\n"+
+			"       install, remove, debug, start, stop, pause or continue.\n",
+		errmsg, os.Args[0])
+	os.Exit(2)
+}
+
+func main() {
+	const svcName = "myservice"
+
+	isIntSess, err := svc.IsAnInteractiveSession()
+	if err != nil {
+		log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
+	}
+	if !isIntSess {
+		runService(svcName, false)
+		return
+	}
+
+	if len(os.Args) < 2 {
+		usage("no command specified")
+	}
+
+	cmd := strings.ToLower(os.Args[1])
+	switch cmd {
+	case "debug":
+		runService(svcName, true)
+		return
+	case "install":
+		err = installService(svcName, "my service")
+	case "remove":
+		err = removeService(svcName)
+	case "start":
+		err = startService(svcName)
+	case "stop":
+		err = controlService(svcName, svc.Stop, svc.Stopped)
+	case "pause":
+		err = controlService(svcName, svc.Pause, svc.Paused)
+	case "continue":
+		err = controlService(svcName, svc.Continue, svc.Running)
+	default:
+		usage(fmt.Sprintf("invalid command %s", cmd))
+	}
+	if err != nil {
+		log.Fatalf("failed to %s %s: %v", cmd, svcName, err)
+	}
+	return
+}

+ 62 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/manage.go

@@ -0,0 +1,62 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"fmt"
+	"time"
+
+	"golang.org/x/sys/windows/svc"
+	"golang.org/x/sys/windows/svc/mgr"
+)
+
+func startService(name string) error {
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err != nil {
+		return fmt.Errorf("could not access service: %v", err)
+	}
+	defer s.Close()
+	err = s.Start("is", "manual-started")
+	if err != nil {
+		return fmt.Errorf("could not start service: %v", err)
+	}
+	return nil
+}
+
+func controlService(name string, c svc.Cmd, to svc.State) error {
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err != nil {
+		return fmt.Errorf("could not access service: %v", err)
+	}
+	defer s.Close()
+	status, err := s.Control(c)
+	if err != nil {
+		return fmt.Errorf("could not send control=%d: %v", c, err)
+	}
+	timeout := time.Now().Add(10 * time.Second)
+	for status.State != to {
+		if timeout.Before(time.Now()) {
+			return fmt.Errorf("timeout waiting for service to go to state=%d", to)
+		}
+		time.Sleep(300 * time.Millisecond)
+		status, err = s.Query()
+		if err != nil {
+			return fmt.Errorf("could not retrieve service status: %v", err)
+		}
+	}
+	return nil
+}

+ 82 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/example/service.go

@@ -0,0 +1,82 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"fmt"
+	"time"
+
+	"golang.org/x/sys/windows/svc"
+	"golang.org/x/sys/windows/svc/debug"
+	"golang.org/x/sys/windows/svc/eventlog"
+)
+
+var elog debug.Log
+
+type myservice struct{}
+
+func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
+	const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
+	changes <- svc.Status{State: svc.StartPending}
+	fasttick := time.Tick(500 * time.Millisecond)
+	slowtick := time.Tick(2 * time.Second)
+	tick := fasttick
+	changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
+loop:
+	for {
+		select {
+		case <-tick:
+			beep()
+			elog.Info(1, "beep")
+		case c := <-r:
+			switch c.Cmd {
+			case svc.Interrogate:
+				changes <- c.CurrentStatus
+				// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
+				time.Sleep(100 * time.Millisecond)
+				changes <- c.CurrentStatus
+			case svc.Stop, svc.Shutdown:
+				break loop
+			case svc.Pause:
+				changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
+				tick = slowtick
+			case svc.Continue:
+				changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
+				tick = fasttick
+			default:
+				elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
+			}
+		}
+	}
+	changes <- svc.Status{State: svc.StopPending}
+	return
+}
+
+func runService(name string, isDebug bool) {
+	var err error
+	if isDebug {
+		elog = debug.New(name)
+	} else {
+		elog, err = eventlog.Open(name)
+		if err != nil {
+			return
+		}
+	}
+	defer elog.Close()
+
+	elog.Info(1, fmt.Sprintf("starting %s service", name))
+	run := svc.Run
+	if isDebug {
+		run = debug.Run
+	}
+	err = run(name, &myservice{})
+	if err != nil {
+		elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
+		return
+	}
+	elog.Info(1, fmt.Sprintf("%s service stopped", name))
+}

+ 24 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/go12.c

@@ -0,0 +1,24 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+// +build !go1.3
+
+// copied from pkg/runtime
+typedef	unsigned int	uint32;
+typedef	unsigned long long int	uint64;
+#ifdef _64BIT
+typedef	uint64		uintptr;
+#else
+typedef	uint32		uintptr;
+#endif
+
+// from sys_386.s or sys_amd64.s
+void ·servicemain(void);
+
+void
+·getServiceMain(uintptr *r)
+{
+	*r = (uintptr)·servicemain;
+}

+ 11 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/go12.go

@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+// +build !go1.3
+
+package svc
+
+// from go12.c
+func getServiceMain(r *uintptr)

+ 31 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/go13.go

@@ -0,0 +1,31 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+// +build go1.3
+
+package svc
+
+import "unsafe"
+
+const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
+
+// Should be a built-in for unsafe.Pointer?
+func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
+	return unsafe.Pointer(uintptr(p) + x)
+}
+
+// funcPC returns the entry PC of the function f.
+// It assumes that f is a func value. Otherwise the behavior is undefined.
+func funcPC(f interface{}) uintptr {
+	return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
+}
+
+// from sys_386.s and sys_amd64.s
+func servicectlhandler(ctl uint32) uintptr
+func servicemain(argc uint32, argv **uint16)
+
+func getServiceMain(r *uintptr) {
+	*r = funcPC(servicemain)
+}

+ 139 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/mgr/config.go

@@ -0,0 +1,139 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package mgr
+
+import (
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+const (
+	// Service start types.
+	StartManual    = windows.SERVICE_DEMAND_START // the service must be started manually
+	StartAutomatic = windows.SERVICE_AUTO_START   // the service will start by itself whenever the computer reboots
+	StartDisabled  = windows.SERVICE_DISABLED     // the service cannot be started
+
+	// The severity of the error, and action taken,
+	// if this service fails to start.
+	ErrorCritical = windows.SERVICE_ERROR_CRITICAL
+	ErrorIgnore   = windows.SERVICE_ERROR_IGNORE
+	ErrorNormal   = windows.SERVICE_ERROR_NORMAL
+	ErrorSevere   = windows.SERVICE_ERROR_SEVERE
+)
+
+// TODO(brainman): Password is not returned by windows.QueryServiceConfig, not sure how to get it.
+
+type Config struct {
+	ServiceType      uint32
+	StartType        uint32
+	ErrorControl     uint32
+	BinaryPathName   string // fully qualified path to the service binary file, can also include arguments for an auto-start service
+	LoadOrderGroup   string
+	TagId            uint32
+	Dependencies     []string
+	ServiceStartName string // name of the account under which the service should run
+	DisplayName      string
+	Password         string
+	Description      string
+}
+
+func toString(p *uint16) string {
+	if p == nil {
+		return ""
+	}
+	return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
+}
+
+func toStringSlice(ps *uint16) []string {
+	if ps == nil {
+		return nil
+	}
+	r := make([]string, 0)
+	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(ps)); true; i++ {
+		if p[i] == 0 {
+			// empty string marks the end
+			if i <= from {
+				break
+			}
+			r = append(r, string(utf16.Decode(p[from:i])))
+			from = i + 1
+		}
+	}
+	return r
+}
+
+// Config retrieves service s configuration paramteres.
+func (s *Service) Config() (Config, error) {
+	var p *windows.QUERY_SERVICE_CONFIG
+	n := uint32(1024)
+	for {
+		b := make([]byte, n)
+		p = (*windows.QUERY_SERVICE_CONFIG)(unsafe.Pointer(&b[0]))
+		err := windows.QueryServiceConfig(s.Handle, p, n, &n)
+		if err == nil {
+			break
+		}
+		if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
+			return Config{}, err
+		}
+		if n <= uint32(len(b)) {
+			return Config{}, err
+		}
+	}
+
+	var p2 *windows.SERVICE_DESCRIPTION
+	n = uint32(1024)
+	for {
+		b := make([]byte, n)
+		p2 = (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0]))
+		err := windows.QueryServiceConfig2(s.Handle,
+			windows.SERVICE_CONFIG_DESCRIPTION, &b[0], n, &n)
+		if err == nil {
+			break
+		}
+		if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
+			return Config{}, err
+		}
+		if n <= uint32(len(b)) {
+			return Config{}, err
+		}
+	}
+
+	return Config{
+		ServiceType:      p.ServiceType,
+		StartType:        p.StartType,
+		ErrorControl:     p.ErrorControl,
+		BinaryPathName:   toString(p.BinaryPathName),
+		LoadOrderGroup:   toString(p.LoadOrderGroup),
+		TagId:            p.TagId,
+		Dependencies:     toStringSlice(p.Dependencies),
+		ServiceStartName: toString(p.ServiceStartName),
+		DisplayName:      toString(p.DisplayName),
+		Description:      toString(p2.Description),
+	}, nil
+}
+
+func updateDescription(handle windows.Handle, desc string) error {
+	d := windows.SERVICE_DESCRIPTION{toPtr(desc)}
+	return windows.ChangeServiceConfig2(handle,
+		windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
+}
+
+// UpdateConfig updates service s configuration parameters.
+func (s *Service) UpdateConfig(c Config) error {
+	err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
+		c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup),
+		nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName),
+		toPtr(c.Password), toPtr(c.DisplayName))
+	if err != nil {
+		return err
+	}
+	return updateDescription(s.Handle, c.Description)
+}

+ 119 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/mgr/mgr.go

@@ -0,0 +1,119 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package mgr can be used to manage Windows service programs.
+// It can be used to install and remove them. It can also start,
+// stop and pause them. The package can query / change current
+// service state and config parameters.
+//
+package mgr
+
+import (
+	"syscall"
+	"unicode/utf16"
+
+	"golang.org/x/sys/windows"
+)
+
+// Mgr is used to manage Windows service.
+type Mgr struct {
+	Handle windows.Handle
+}
+
+// Connect establishes a connection to the service control manager.
+func Connect() (*Mgr, error) {
+	return ConnectRemote("")
+}
+
+// ConnectRemote establishes a connection to the
+// service control manager on computer named host.
+func ConnectRemote(host string) (*Mgr, error) {
+	var s *uint16
+	if host != "" {
+		s = syscall.StringToUTF16Ptr(host)
+	}
+	h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
+	if err != nil {
+		return nil, err
+	}
+	return &Mgr{Handle: h}, nil
+}
+
+// Disconnect closes connection to the service control manager m.
+func (m *Mgr) Disconnect() error {
+	return windows.CloseServiceHandle(m.Handle)
+}
+
+func toPtr(s string) *uint16 {
+	if len(s) == 0 {
+		return nil
+	}
+	return syscall.StringToUTF16Ptr(s)
+}
+
+// toStringBlock terminates strings in ss with 0, and then
+// concatenates them together. It also adds extra 0 at the end.
+func toStringBlock(ss []string) *uint16 {
+	if len(ss) == 0 {
+		return nil
+	}
+	t := ""
+	for _, s := range ss {
+		if s != "" {
+			t += s + "\x00"
+		}
+	}
+	if t == "" {
+		return nil
+	}
+	t += "\x00"
+	return &utf16.Encode([]rune(t))[0]
+}
+
+// CreateService installs new service name on the system.
+// The service will be executed by running exepath binary.
+// Use config c to specify service parameters.
+// If service StartType is set to StartAutomatic,
+// args will be passed to svc.Handle.Execute.
+func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) {
+	if c.StartType == 0 {
+		c.StartType = StartManual
+	}
+	if c.ErrorControl == 0 {
+		c.ErrorControl = ErrorNormal
+	}
+	if c.ServiceType == 0 {
+		c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
+	}
+	s := syscall.EscapeArg(exepath)
+	for _, v := range args {
+		s += " " + syscall.EscapeArg(v)
+	}
+	h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
+		windows.SERVICE_ALL_ACCESS, c.ServiceType,
+		c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup),
+		nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
+	if err != nil {
+		return nil, err
+	}
+	if c.Description != "" {
+		err = updateDescription(h, c.Description)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return &Service{Name: name, Handle: h}, nil
+}
+
+// OpenService retrieves access to service name, so it can
+// be interrogated and controlled.
+func (m *Mgr) OpenService(name string) (*Service, error) {
+	h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS)
+	if err != nil {
+		return nil, err
+	}
+	return &Service{Name: name, Handle: h}, nil
+}

+ 74 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/mgr/service.go

@@ -0,0 +1,74 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package mgr
+
+import (
+	"syscall"
+
+	"golang.org/x/sys/windows"
+	"golang.org/x/sys/windows/svc"
+)
+
+// TODO(brainman): Use EnumDependentServices to enumerate dependent services.
+
+// TODO(brainman): Use EnumServicesStatus to enumerate services in the specified service control manager database.
+
+// Service is used to access Windows service.
+type Service struct {
+	Name   string
+	Handle windows.Handle
+}
+
+// Delete marks service s for deletion from the service control manager database.
+func (s *Service) Delete() error {
+	return windows.DeleteService(s.Handle)
+}
+
+// Close relinquish access to the service s.
+func (s *Service) Close() error {
+	return windows.CloseServiceHandle(s.Handle)
+}
+
+// Start starts service s.
+// args will be passed to svc.Handler.Execute.
+func (s *Service) Start(args ...string) error {
+	var p **uint16
+	if len(args) > 0 {
+		vs := make([]*uint16, len(args))
+		for i, _ := range vs {
+			vs[i] = syscall.StringToUTF16Ptr(args[i])
+		}
+		p = &vs[0]
+	}
+	return windows.StartService(s.Handle, uint32(len(args)), p)
+}
+
+// Control sends state change request c to the servce s.
+func (s *Service) Control(c svc.Cmd) (svc.Status, error) {
+	var t windows.SERVICE_STATUS
+	err := windows.ControlService(s.Handle, uint32(c), &t)
+	if err != nil {
+		return svc.Status{}, err
+	}
+	return svc.Status{
+		State:   svc.State(t.CurrentState),
+		Accepts: svc.Accepted(t.ControlsAccepted),
+	}, nil
+}
+
+// Query returns current status of service s.
+func (s *Service) Query() (svc.Status, error) {
+	var t windows.SERVICE_STATUS
+	err := windows.QueryServiceStatus(s.Handle, &t)
+	if err != nil {
+		return svc.Status{}, err
+	}
+	return svc.Status{
+		State:   svc.State(t.CurrentState),
+		Accepts: svc.Accepted(t.ControlsAccepted),
+	}, nil
+}

+ 62 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/security.go

@@ -0,0 +1,62 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package svc
+
+import (
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+func allocSid(subAuth0 uint32) (*windows.SID, error) {
+	var sid *windows.SID
+	err := windows.AllocateAndInitializeSid(&windows.SECURITY_NT_AUTHORITY,
+		1, subAuth0, 0, 0, 0, 0, 0, 0, 0, &sid)
+	if err != nil {
+		return nil, err
+	}
+	return sid, nil
+}
+
+// IsAnInteractiveSession determines if calling process is running interactively.
+// It queries the process token for membership in the Interactive group.
+// http://stackoverflow.com/questions/2668851/how-do-i-detect-that-my-application-is-running-as-service-or-in-an-interactive-s
+func IsAnInteractiveSession() (bool, error) {
+	interSid, err := allocSid(windows.SECURITY_INTERACTIVE_RID)
+	if err != nil {
+		return false, err
+	}
+	defer windows.FreeSid(interSid)
+
+	serviceSid, err := allocSid(windows.SECURITY_SERVICE_RID)
+	if err != nil {
+		return false, err
+	}
+	defer windows.FreeSid(serviceSid)
+
+	t, err := windows.OpenCurrentProcessToken()
+	if err != nil {
+		return false, err
+	}
+	defer t.Close()
+
+	gs, err := t.GetTokenGroups()
+	if err != nil {
+		return false, err
+	}
+	p := unsafe.Pointer(&gs.Groups[0])
+	groups := (*[2 << 20]windows.SIDAndAttributes)(p)[:gs.GroupCount]
+	for _, g := range groups {
+		if windows.EqualSid(g.Sid, interSid) {
+			return true, nil
+		}
+		if windows.EqualSid(g.Sid, serviceSid) {
+			return false, nil
+		}
+	}
+	return false, nil
+}

+ 316 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/service.go

@@ -0,0 +1,316 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package svc provides everything required to build Windows service.
+//
+package svc
+
+import (
+	"errors"
+	"runtime"
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+// State describes service execution state (Stopped, Running and so on).
+type State uint32
+
+const (
+	Stopped         = State(windows.SERVICE_STOPPED)
+	StartPending    = State(windows.SERVICE_START_PENDING)
+	StopPending     = State(windows.SERVICE_STOP_PENDING)
+	Running         = State(windows.SERVICE_RUNNING)
+	ContinuePending = State(windows.SERVICE_CONTINUE_PENDING)
+	PausePending    = State(windows.SERVICE_PAUSE_PENDING)
+	Paused          = State(windows.SERVICE_PAUSED)
+)
+
+// Cmd represents service state change request. It is sent to a service
+// by the service manager, and should be actioned upon by the service.
+type Cmd uint32
+
+const (
+	Stop        = Cmd(windows.SERVICE_CONTROL_STOP)
+	Pause       = Cmd(windows.SERVICE_CONTROL_PAUSE)
+	Continue    = Cmd(windows.SERVICE_CONTROL_CONTINUE)
+	Interrogate = Cmd(windows.SERVICE_CONTROL_INTERROGATE)
+	Shutdown    = Cmd(windows.SERVICE_CONTROL_SHUTDOWN)
+)
+
+// Accepted is used to describe commands accepted by the service.
+// Note that Interrogate is always accepted.
+type Accepted uint32
+
+const (
+	AcceptStop             = Accepted(windows.SERVICE_ACCEPT_STOP)
+	AcceptShutdown         = Accepted(windows.SERVICE_ACCEPT_SHUTDOWN)
+	AcceptPauseAndContinue = Accepted(windows.SERVICE_ACCEPT_PAUSE_CONTINUE)
+)
+
+// Status combines State and Accepted commands to fully describe running service.
+type Status struct {
+	State      State
+	Accepts    Accepted
+	CheckPoint uint32 // used to report progress during a lengthy operation
+	WaitHint   uint32 // estimated time required for a pending operation, in milliseconds
+}
+
+// ChangeRequest is sent to the service Handler to request service status change.
+type ChangeRequest struct {
+	Cmd           Cmd
+	CurrentStatus Status
+}
+
+// Handler is the interface that must be implemented to build Windows service.
+type Handler interface {
+
+	// Execute will be called by the package code at the start of
+	// the service, and the service will exit once Execute completes.
+	// Inside Execute you must read service change requests from r and
+	// act accordingly. You must keep service control manager up to date
+	// about state of your service by writing into s as required.
+	// args contains service name followed by argument strings passed
+	// to the service.
+	// You can provide service exit code in exitCode return parameter,
+	// with 0 being "no error". You can also indicate if exit code,
+	// if any, is service specific or not by using svcSpecificEC
+	// parameter.
+	Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32)
+}
+
+var (
+	// These are used by asm code.
+	goWaitsH                     uintptr
+	cWaitsH                      uintptr
+	ssHandle                     uintptr
+	sName                        *uint16
+	sArgc                        uintptr
+	sArgv                        **uint16
+	ctlHandlerProc               uintptr
+	cSetEvent                    uintptr
+	cWaitForSingleObject         uintptr
+	cRegisterServiceCtrlHandlerW uintptr
+)
+
+func init() {
+	k := syscall.MustLoadDLL("kernel32.dll")
+	cSetEvent = k.MustFindProc("SetEvent").Addr()
+	cWaitForSingleObject = k.MustFindProc("WaitForSingleObject").Addr()
+	a := syscall.MustLoadDLL("advapi32.dll")
+	cRegisterServiceCtrlHandlerW = a.MustFindProc("RegisterServiceCtrlHandlerW").Addr()
+}
+
+type ctlEvent struct {
+	cmd   Cmd
+	errno uint32
+}
+
+// service provides access to windows service api.
+type service struct {
+	name    string
+	h       windows.Handle
+	cWaits  *event
+	goWaits *event
+	c       chan ctlEvent
+	handler Handler
+}
+
+func newService(name string, handler Handler) (*service, error) {
+	var s service
+	var err error
+	s.name = name
+	s.c = make(chan ctlEvent)
+	s.handler = handler
+	s.cWaits, err = newEvent()
+	if err != nil {
+		return nil, err
+	}
+	s.goWaits, err = newEvent()
+	if err != nil {
+		s.cWaits.Close()
+		return nil, err
+	}
+	return &s, nil
+}
+
+func (s *service) close() error {
+	s.cWaits.Close()
+	s.goWaits.Close()
+	return nil
+}
+
+type exitCode struct {
+	isSvcSpecific bool
+	errno         uint32
+}
+
+func (s *service) updateStatus(status *Status, ec *exitCode) error {
+	if s.h == 0 {
+		return errors.New("updateStatus with no service status handle")
+	}
+	var t windows.SERVICE_STATUS
+	t.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
+	t.CurrentState = uint32(status.State)
+	if status.Accepts&AcceptStop != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_STOP
+	}
+	if status.Accepts&AcceptShutdown != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_SHUTDOWN
+	}
+	if status.Accepts&AcceptPauseAndContinue != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_PAUSE_CONTINUE
+	}
+	if ec.errno == 0 {
+		t.Win32ExitCode = windows.NO_ERROR
+		t.ServiceSpecificExitCode = windows.NO_ERROR
+	} else if ec.isSvcSpecific {
+		t.Win32ExitCode = uint32(windows.ERROR_SERVICE_SPECIFIC_ERROR)
+		t.ServiceSpecificExitCode = ec.errno
+	} else {
+		t.Win32ExitCode = ec.errno
+		t.ServiceSpecificExitCode = windows.NO_ERROR
+	}
+	t.CheckPoint = status.CheckPoint
+	t.WaitHint = status.WaitHint
+	return windows.SetServiceStatus(s.h, &t)
+}
+
+const (
+	sysErrSetServiceStatusFailed = uint32(syscall.APPLICATION_ERROR) + iota
+	sysErrNewThreadInCallback
+)
+
+func (s *service) run() {
+	s.goWaits.Wait()
+	s.h = windows.Handle(ssHandle)
+	argv := (*[100]*int16)(unsafe.Pointer(sArgv))[:sArgc]
+	args := make([]string, len(argv))
+	for i, a := range argv {
+		args[i] = syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(a))[:])
+	}
+
+	cmdsToHandler := make(chan ChangeRequest)
+	changesFromHandler := make(chan Status)
+	exitFromHandler := make(chan exitCode)
+
+	go func() {
+		ss, errno := s.handler.Execute(args, cmdsToHandler, changesFromHandler)
+		exitFromHandler <- exitCode{ss, errno}
+	}()
+
+	status := Status{State: Stopped}
+	ec := exitCode{isSvcSpecific: true, errno: 0}
+	var outch chan ChangeRequest
+	inch := s.c
+	var cmd Cmd
+loop:
+	for {
+		select {
+		case r := <-inch:
+			if r.errno != 0 {
+				ec.errno = r.errno
+				break loop
+			}
+			inch = nil
+			outch = cmdsToHandler
+			cmd = r.cmd
+		case outch <- ChangeRequest{cmd, status}:
+			inch = s.c
+			outch = nil
+		case c := <-changesFromHandler:
+			err := s.updateStatus(&c, &ec)
+			if err != nil {
+				// best suitable error number
+				ec.errno = sysErrSetServiceStatusFailed
+				if err2, ok := err.(syscall.Errno); ok {
+					ec.errno = uint32(err2)
+				}
+				break loop
+			}
+			status = c
+		case ec = <-exitFromHandler:
+			break loop
+		}
+	}
+
+	s.updateStatus(&Status{State: Stopped}, &ec)
+	s.cWaits.Set()
+}
+
+func newCallback(fn interface{}) (cb uintptr, err error) {
+	defer func() {
+		r := recover()
+		if r == nil {
+			return
+		}
+		cb = 0
+		switch v := r.(type) {
+		case string:
+			err = errors.New(v)
+		case error:
+			err = v
+		default:
+			err = errors.New("unexpected panic in syscall.NewCallback")
+		}
+	}()
+	return syscall.NewCallback(fn), nil
+}
+
+// BUG(brainman): There is no mechanism to run multiple services
+// inside one single executable. Perhaps, it can be overcome by
+// using RegisterServiceCtrlHandlerEx Windows api.
+
+// Run executes service name by calling appropriate handler function.
+func Run(name string, handler Handler) error {
+	runtime.LockOSThread()
+
+	tid := windows.GetCurrentThreadId()
+
+	s, err := newService(name, handler)
+	if err != nil {
+		return err
+	}
+
+	ctlHandler := func(ctl uint32) uintptr {
+		e := ctlEvent{cmd: Cmd(ctl)}
+		// We assume that this callback function is running on
+		// the same thread as Run. Nowhere in MS documentation
+		// I could find statement to guarantee that. So putting
+		// check here to verify, otherwise things will go bad
+		// quickly, if ignored.
+		i := windows.GetCurrentThreadId()
+		if i != tid {
+			e.errno = sysErrNewThreadInCallback
+		}
+		s.c <- e
+		return 0
+	}
+
+	var svcmain uintptr
+	getServiceMain(&svcmain)
+	t := []windows.SERVICE_TABLE_ENTRY{
+		{syscall.StringToUTF16Ptr(s.name), svcmain},
+		{nil, 0},
+	}
+
+	goWaitsH = uintptr(s.goWaits.h)
+	cWaitsH = uintptr(s.cWaits.h)
+	sName = t[0].ServiceName
+	ctlHandlerProc, err = newCallback(ctlHandler)
+	if err != nil {
+		return err
+	}
+
+	go s.run()
+
+	err = windows.StartServiceCtrlDispatcher(&t[0])
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 67 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/sys_386.s

@@ -0,0 +1,67 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// func servicemain(argc uint32, argv **uint16)
+TEXT ·servicemain(SB),7,$0
+	MOVL	argc+0(FP), AX
+	MOVL	AX, ·sArgc(SB)
+	MOVL	argv+4(FP), AX
+	MOVL	AX, ·sArgv(SB)
+
+	PUSHL	BP
+	PUSHL	BX
+	PUSHL	SI
+	PUSHL	DI
+
+	SUBL	$12, SP
+
+	MOVL	·sName(SB), AX
+	MOVL	AX, (SP)
+	MOVL	$·servicectlhandler(SB), AX
+	MOVL	AX, 4(SP)
+	MOVL	·cRegisterServiceCtrlHandlerW(SB), AX
+	MOVL	SP, BP
+	CALL	AX
+	MOVL	BP, SP
+	CMPL	AX, $0
+	JE	exit
+	MOVL	AX, ·ssHandle(SB)
+
+	MOVL	·goWaitsH(SB), AX
+	MOVL	AX, (SP)
+	MOVL	·cSetEvent(SB), AX
+	MOVL	SP, BP
+	CALL	AX
+	MOVL	BP, SP
+
+	MOVL	·cWaitsH(SB), AX
+	MOVL	AX, (SP)
+	MOVL	$-1, AX
+	MOVL	AX, 4(SP)
+	MOVL	·cWaitForSingleObject(SB), AX
+	MOVL	SP, BP
+	CALL	AX
+	MOVL	BP, SP
+
+exit:
+	ADDL	$12, SP
+
+	POPL	DI
+	POPL	SI
+	POPL	BX
+	POPL	BP
+
+	MOVL	0(SP), CX
+	ADDL	$12, SP
+	JMP	CX
+
+// I do not know why, but this seems to be the only way to call
+// ctlHandlerProc on Windows 7.
+
+// func servicectlhandler(ctl uint32) uintptr
+TEXT ·servicectlhandler(SB),7,$0
+	MOVL	·ctlHandlerProc(SB), CX
+	JMP	CX

+ 41 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/svc/sys_amd64.s

@@ -0,0 +1,41 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// func servicemain(argc uint32, argv **uint16)
+TEXT ·servicemain(SB),7,$0
+	MOVL	CX, ·sArgc(SB)
+	MOVL	DX, ·sArgv(SB)
+
+	SUBQ	$32, SP		// stack for the first 4 syscall params
+
+	MOVQ	·sName(SB), CX
+	MOVQ	$·servicectlhandler(SB), DX
+	MOVQ	·cRegisterServiceCtrlHandlerW(SB), AX
+	CALL	AX
+	CMPQ	AX, $0
+	JE	exit
+	MOVQ	AX, ·ssHandle(SB)
+
+	MOVQ	·goWaitsH(SB), CX
+	MOVQ	·cSetEvent(SB), AX
+	CALL	AX
+
+	MOVQ	·cWaitsH(SB), CX
+	MOVQ	$4294967295, DX
+	MOVQ	·cWaitForSingleObject(SB), AX
+	CALL	AX
+
+exit:
+	ADDQ	$32, SP
+	RET
+
+// I do not know why, but this seems to be the only way to call
+// ctlHandlerProc on Windows 7.
+
+// func servicectlhandler(ctl uint32) uintptr
+TEXT ·servicectlhandler(SB),7,$0
+	MOVQ	·ctlHandlerProc(SB), AX
+	JMP	AX

+ 77 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/syscall.go

@@ -0,0 +1,77 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package windows contains an interface to the low-level operating system
+// primitives.  OS details vary depending on the underlying system, and
+// by default, godoc will display the OS-specific documentation for the current
+// system.  If you want godoc to display syscall documentation for another
+// system, set $GOOS and $GOARCH to the desired system.  For example, if
+// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
+// to freebsd and $GOARCH to arm.
+// The primary use of this package is inside other packages that provide a more
+// portable interface to the system, such as "os", "time" and "net".  Use
+// those packages rather than this one if you can.
+// For details of the functions and data types in this package consult
+// the manuals for the appropriate operating system.
+// These calls return err == nil to indicate success; otherwise
+// err represents an operating system error describing the failure and
+// holds a value of type syscall.Errno.
+package windows // import "golang.org/x/sys/windows"
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// ByteSliceFromString returns a NUL-terminated slice of bytes
+// containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, syscall.EINVAL).
+func ByteSliceFromString(s string) ([]byte, error) {
+	for i := 0; i < len(s); i++ {
+		if s[i] == 0 {
+			return nil, syscall.EINVAL
+		}
+	}
+	a := make([]byte, len(s)+1)
+	copy(a, s)
+	return a, nil
+}
+
+// BytePtrFromString returns a pointer to a NUL-terminated array of
+// bytes containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, syscall.EINVAL).
+func BytePtrFromString(s string) (*byte, error) {
+	a, err := ByteSliceFromString(s)
+	if err != nil {
+		return nil, err
+	}
+	return &a[0], nil
+}
+
+// Single-word zero for use when we need a valid pointer to 0 bytes.
+// See mksyscall.pl.
+var _zero uintptr
+
+func (ts *Timespec) Unix() (sec int64, nsec int64) {
+	return int64(ts.Sec), int64(ts.Nsec)
+}
+
+func (tv *Timeval) Unix() (sec int64, nsec int64) {
+	return int64(tv.Sec), int64(tv.Usec) * 1000
+}
+
+func (ts *Timespec) Nano() int64 {
+	return int64(ts.Sec)*1e9 + int64(ts.Nsec)
+}
+
+func (tv *Timeval) Nano() int64 {
+	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
+}
+
+// use is a no-op, but the compiler cannot see that it is.
+// Calling use(p) ensures that p is kept live until that point.
+//go:noescape
+func use(p unsafe.Pointer)

+ 990 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/syscall_windows.go

@@ -0,0 +1,990 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Windows system calls.
+
+package windows
+
+import (
+	errorspkg "errors"
+	"sync"
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+)
+
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go
+
+type Handle uintptr
+
+const InvalidHandle = ^Handle(0)
+
+// StringToUTF16 is deprecated. Use UTF16FromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringToUTF16(s string) []uint16 {
+	a, err := UTF16FromString(s)
+	if err != nil {
+		panic("windows: string with NUL passed to StringToUTF16")
+	}
+	return a
+}
+
+// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
+// s, with a terminating NUL added. If s contains a NUL byte at any
+// location, it returns (nil, syscall.EINVAL).
+func UTF16FromString(s string) ([]uint16, error) {
+	for i := 0; i < len(s); i++ {
+		if s[i] == 0 {
+			return nil, syscall.EINVAL
+		}
+	}
+	return utf16.Encode([]rune(s + "\x00")), nil
+}
+
+// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
+// with a terminating NUL removed.
+func UTF16ToString(s []uint16) string {
+	for i, v := range s {
+		if v == 0 {
+			s = s[0:i]
+			break
+		}
+	}
+	return string(utf16.Decode(s))
+}
+
+// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
+
+// UTF16PtrFromString returns pointer to the UTF-16 encoding of
+// the UTF-8 string s, with a terminating NUL added. If s
+// contains a NUL byte at any location, it returns (nil, syscall.EINVAL).
+func UTF16PtrFromString(s string) (*uint16, error) {
+	a, err := UTF16FromString(s)
+	if err != nil {
+		return nil, err
+	}
+	return &a[0], nil
+}
+
+func Getpagesize() int { return 4096 }
+
+// Converts a Go function to a function pointer conforming
+// to the stdcall or cdecl calling convention.  This is useful when
+// interoperating with Windows code requiring callbacks.
+// Implemented in runtime/syscall_windows.goc
+func NewCallback(fn interface{}) uintptr
+func NewCallbackCDecl(fn interface{}) uintptr
+
+// windows api calls
+
+//sys	GetLastError() (lasterr error)
+//sys	LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
+//sys	FreeLibrary(handle Handle) (err error)
+//sys	GetProcAddress(module Handle, procname string) (proc uintptr, err error)
+//sys	GetVersion() (ver uint32, err error)
+//sys	FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
+//sys	ExitProcess(exitcode uint32)
+//sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
+//sys	ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
+//sys	WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
+//sys	SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
+//sys	CloseHandle(handle Handle) (err error)
+//sys	GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle]
+//sys	findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
+//sys	findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
+//sys	FindClose(handle Handle) (err error)
+//sys	GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
+//sys	GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
+//sys	SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
+//sys	CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
+//sys	RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
+//sys	DeleteFile(path *uint16) (err error) = DeleteFileW
+//sys	MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
+//sys	MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
+//sys	GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
+//sys	GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
+//sys	SetEndOfFile(handle Handle) (err error)
+//sys	GetSystemTimeAsFileTime(time *Filetime)
+//sys	GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
+//sys	CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
+//sys	GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
+//sys	PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
+//sys	CancelIo(s Handle) (err error)
+//sys	CancelIoEx(s Handle, o *Overlapped) (err error)
+//sys	CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
+//sys	OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
+//sys	TerminateProcess(handle Handle, exitcode uint32) (err error)
+//sys	GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
+//sys	GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
+//sys	GetCurrentProcess() (pseudoHandle Handle, err error)
+//sys	GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
+//sys	DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
+//sys	WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
+//sys	GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
+//sys	CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
+//sys	GetFileType(filehandle Handle) (n uint32, err error)
+//sys	CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
+//sys	CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
+//sys	CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
+//sys	GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
+//sys	FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
+//sys	GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
+//sys	SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
+//sys	SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
+//sys	GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
+//sys	SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
+//sys	GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
+//sys	GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
+//sys	CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
+//sys	LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
+//sys	SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
+//sys	FlushFileBuffers(handle Handle) (err error)
+//sys	GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
+//sys	GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
+//sys	GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
+//sys	CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
+//sys	MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
+//sys	UnmapViewOfFile(addr uintptr) (err error)
+//sys	FlushViewOfFile(addr uintptr, length uintptr) (err error)
+//sys	VirtualLock(addr uintptr, length uintptr) (err error)
+//sys	VirtualUnlock(addr uintptr, length uintptr) (err error)
+//sys	TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
+//sys	ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
+//sys	CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
+//sys   CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore
+//sys	CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
+//sys   CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
+//sys	CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
+//sys   CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
+//sys   CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
+//sys   CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
+//sys   CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
+//sys   CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
+//sys	RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
+//sys	RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
+//sys	RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
+//sys	RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
+//sys	RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
+//sys	getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
+//sys	GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
+//sys	WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
+//sys	ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
+//sys	CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
+//sys	Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW
+//sys	Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW
+//sys	DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error)
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+//sys	CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
+//sys	CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
+//sys	GetCurrentThreadId() (id uint32)
+//sys	CreateEvent(eventAttrs *syscall.SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW
+//sys	SetEvent(event Handle) (err error) = kernel32.SetEvent
+
+// syscall interface implementation for other packages
+
+func Exit(code int) { ExitProcess(uint32(code)) }
+
+func makeInheritSa() *SecurityAttributes {
+	var sa SecurityAttributes
+	sa.Length = uint32(unsafe.Sizeof(sa))
+	sa.InheritHandle = 1
+	return &sa
+}
+
+func Open(path string, mode int, perm uint32) (fd Handle, err error) {
+	if len(path) == 0 {
+		return InvalidHandle, ERROR_FILE_NOT_FOUND
+	}
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return InvalidHandle, err
+	}
+	var access uint32
+	switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
+	case O_RDONLY:
+		access = GENERIC_READ
+	case O_WRONLY:
+		access = GENERIC_WRITE
+	case O_RDWR:
+		access = GENERIC_READ | GENERIC_WRITE
+	}
+	if mode&O_CREAT != 0 {
+		access |= GENERIC_WRITE
+	}
+	if mode&O_APPEND != 0 {
+		access &^= GENERIC_WRITE
+		access |= FILE_APPEND_DATA
+	}
+	sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
+	var sa *SecurityAttributes
+	if mode&O_CLOEXEC == 0 {
+		sa = makeInheritSa()
+	}
+	var createmode uint32
+	switch {
+	case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
+		createmode = CREATE_NEW
+	case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
+		createmode = CREATE_ALWAYS
+	case mode&O_CREAT == O_CREAT:
+		createmode = OPEN_ALWAYS
+	case mode&O_TRUNC == O_TRUNC:
+		createmode = TRUNCATE_EXISTING
+	default:
+		createmode = OPEN_EXISTING
+	}
+	h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
+	return h, e
+}
+
+func Read(fd Handle, p []byte) (n int, err error) {
+	var done uint32
+	e := ReadFile(fd, p, &done, nil)
+	if e != nil {
+		if e == ERROR_BROKEN_PIPE {
+			// NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
+			return 0, nil
+		}
+		return 0, e
+	}
+	if raceenabled {
+		if done > 0 {
+			raceWriteRange(unsafe.Pointer(&p[0]), int(done))
+		}
+		raceAcquire(unsafe.Pointer(&ioSync))
+	}
+	return int(done), nil
+}
+
+func Write(fd Handle, p []byte) (n int, err error) {
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	var done uint32
+	e := WriteFile(fd, p, &done, nil)
+	if e != nil {
+		return 0, e
+	}
+	if raceenabled && done > 0 {
+		raceReadRange(unsafe.Pointer(&p[0]), int(done))
+	}
+	return int(done), nil
+}
+
+var ioSync int64
+
+func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
+	var w uint32
+	switch whence {
+	case 0:
+		w = FILE_BEGIN
+	case 1:
+		w = FILE_CURRENT
+	case 2:
+		w = FILE_END
+	}
+	hi := int32(offset >> 32)
+	lo := int32(offset)
+	// use GetFileType to check pipe, pipe can't do seek
+	ft, _ := GetFileType(fd)
+	if ft == FILE_TYPE_PIPE {
+		return 0, syscall.EPIPE
+	}
+	rlo, e := SetFilePointer(fd, lo, &hi, w)
+	if e != nil {
+		return 0, e
+	}
+	return int64(hi)<<32 + int64(rlo), nil
+}
+
+func Close(fd Handle) (err error) {
+	return CloseHandle(fd)
+}
+
+var (
+	Stdin  = getStdHandle(STD_INPUT_HANDLE)
+	Stdout = getStdHandle(STD_OUTPUT_HANDLE)
+	Stderr = getStdHandle(STD_ERROR_HANDLE)
+)
+
+func getStdHandle(h int) (fd Handle) {
+	r, _ := GetStdHandle(h)
+	CloseOnExec(r)
+	return r
+}
+
+const ImplementsGetwd = true
+
+func Getwd() (wd string, err error) {
+	b := make([]uint16, 300)
+	n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
+	if e != nil {
+		return "", e
+	}
+	return string(utf16.Decode(b[0:n])), nil
+}
+
+func Chdir(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return SetCurrentDirectory(pathp)
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return CreateDirectory(pathp, nil)
+}
+
+func Rmdir(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return RemoveDirectory(pathp)
+}
+
+func Unlink(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return DeleteFile(pathp)
+}
+
+func Rename(oldpath, newpath string) (err error) {
+	from, err := UTF16PtrFromString(oldpath)
+	if err != nil {
+		return err
+	}
+	to, err := UTF16PtrFromString(newpath)
+	if err != nil {
+		return err
+	}
+	return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
+}
+
+func ComputerName() (name string, err error) {
+	var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
+	b := make([]uint16, n)
+	e := GetComputerName(&b[0], &n)
+	if e != nil {
+		return "", e
+	}
+	return string(utf16.Decode(b[0:n])), nil
+}
+
+func Ftruncate(fd Handle, length int64) (err error) {
+	curoffset, e := Seek(fd, 0, 1)
+	if e != nil {
+		return e
+	}
+	defer Seek(fd, curoffset, 0)
+	_, e = Seek(fd, length, 0)
+	if e != nil {
+		return e
+	}
+	e = SetEndOfFile(fd)
+	if e != nil {
+		return e
+	}
+	return nil
+}
+
+func Gettimeofday(tv *Timeval) (err error) {
+	var ft Filetime
+	GetSystemTimeAsFileTime(&ft)
+	*tv = NsecToTimeval(ft.Nanoseconds())
+	return nil
+}
+
+func Pipe(p []Handle) (err error) {
+	if len(p) != 2 {
+		return syscall.EINVAL
+	}
+	var r, w Handle
+	e := CreatePipe(&r, &w, makeInheritSa(), 0)
+	if e != nil {
+		return e
+	}
+	p[0] = r
+	p[1] = w
+	return nil
+}
+
+func Utimes(path string, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return syscall.EINVAL
+	}
+	pathp, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	h, e := CreateFile(pathp,
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if e != nil {
+		return e
+	}
+	defer Close(h)
+	a := NsecToFiletime(tv[0].Nanoseconds())
+	w := NsecToFiletime(tv[1].Nanoseconds())
+	return SetFileTime(h, nil, &a, &w)
+}
+
+func UtimesNano(path string, ts []Timespec) (err error) {
+	if len(ts) != 2 {
+		return syscall.EINVAL
+	}
+	pathp, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	h, e := CreateFile(pathp,
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if e != nil {
+		return e
+	}
+	defer Close(h)
+	a := NsecToFiletime(TimespecToNsec(ts[0]))
+	w := NsecToFiletime(TimespecToNsec(ts[1]))
+	return SetFileTime(h, nil, &a, &w)
+}
+
+func Fsync(fd Handle) (err error) {
+	return FlushFileBuffers(fd)
+}
+
+func Chmod(path string, mode uint32) (err error) {
+	if mode == 0 {
+		return syscall.EINVAL
+	}
+	p, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	attrs, e := GetFileAttributes(p)
+	if e != nil {
+		return e
+	}
+	if mode&S_IWRITE != 0 {
+		attrs &^= FILE_ATTRIBUTE_READONLY
+	} else {
+		attrs |= FILE_ATTRIBUTE_READONLY
+	}
+	return SetFileAttributes(p, attrs)
+}
+
+func LoadCancelIoEx() error {
+	return procCancelIoEx.Find()
+}
+
+func LoadSetFileCompletionNotificationModes() error {
+	return procSetFileCompletionNotificationModes.Find()
+}
+
+// net api calls
+
+const socket_error = uintptr(^uint32(0))
+
+//sys	WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
+//sys	WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
+//sys	WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl
+//sys	socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
+//sys	Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
+//sys	Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
+//sys	bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
+//sys	connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
+//sys	getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
+//sys	getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
+//sys	listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
+//sys	shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
+//sys	Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
+//sys	AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
+//sys	GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
+//sys	WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
+//sys	WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
+//sys	WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32,  from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
+//sys	WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32,  overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
+//sys	GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
+//sys	GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
+//sys	Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
+//sys	GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
+//sys	DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
+//sys	DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
+//sys	DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W
+//sys	GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
+//sys	FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
+//sys	GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
+//sys	GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
+//sys	SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
+//sys	WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
+//sys	GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
+//sys	GetACP() (acp uint32) = kernel32.GetACP
+//sys	MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+type RawSockaddrInet4 struct {
+	Family uint16
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]uint8
+}
+
+type RawSockaddrInet6 struct {
+	Family   uint16
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddr struct {
+	Family uint16
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [96]int8
+}
+
+type Sockaddr interface {
+	sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
+}
+
+type SockaddrInet4 struct {
+	Port int
+	Addr [4]byte
+	raw  RawSockaddrInet4
+}
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, syscall.EINVAL
+	}
+	sa.raw.Family = AF_INET
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type SockaddrInet6 struct {
+	Port   int
+	ZoneId uint32
+	Addr   [16]byte
+	raw    RawSockaddrInet6
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, syscall.EINVAL
+	}
+	sa.raw.Family = AF_INET6
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	sa.raw.Scope_id = sa.ZoneId
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type SockaddrUnix struct {
+	Name string
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
+	// TODO(brainman): implement SockaddrUnix.sockaddr()
+	return nil, 0, syscall.EWINDOWS
+}
+
+func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
+	switch rsa.Addr.Family {
+	case AF_UNIX:
+		return nil, syscall.EWINDOWS
+
+	case AF_INET:
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet4)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+
+	case AF_INET6:
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet6)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		sa.ZoneId = pp.Scope_id
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+	}
+	return nil, syscall.EAFNOSUPPORT
+}
+
+func Socket(domain, typ, proto int) (fd Handle, err error) {
+	if domain == AF_INET6 && SocketDisableIPv6 {
+		return InvalidHandle, syscall.EAFNOSUPPORT
+	}
+	return socket(int32(domain), int32(typ), int32(proto))
+}
+
+func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
+	v := int32(value)
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
+}
+
+func Bind(fd Handle, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return bind(fd, ptr, n)
+}
+
+func Connect(fd Handle, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connect(fd, ptr, n)
+}
+
+func Getsockname(fd Handle) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	l := int32(unsafe.Sizeof(rsa))
+	if err = getsockname(fd, &rsa, &l); err != nil {
+		return
+	}
+	return rsa.Sockaddr()
+}
+
+func Getpeername(fd Handle) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	l := int32(unsafe.Sizeof(rsa))
+	if err = getpeername(fd, &rsa, &l); err != nil {
+		return
+	}
+	return rsa.Sockaddr()
+}
+
+func Listen(s Handle, n int) (err error) {
+	return listen(s, int32(n))
+}
+
+func Shutdown(fd Handle, how int) (err error) {
+	return shutdown(fd, int32(how))
+}
+
+func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
+	rsa, l, err := to.sockaddr()
+	if err != nil {
+		return err
+	}
+	return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
+}
+
+func LoadGetAddrInfo() error {
+	return procGetAddrInfoW.Find()
+}
+
+var connectExFunc struct {
+	once sync.Once
+	addr uintptr
+	err  error
+}
+
+func LoadConnectEx() error {
+	connectExFunc.once.Do(func() {
+		var s Handle
+		s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
+		if connectExFunc.err != nil {
+			return
+		}
+		defer CloseHandle(s)
+		var n uint32
+		connectExFunc.err = WSAIoctl(s,
+			SIO_GET_EXTENSION_FUNCTION_POINTER,
+			(*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
+			uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
+			(*byte)(unsafe.Pointer(&connectExFunc.addr)),
+			uint32(unsafe.Sizeof(connectExFunc.addr)),
+			&n, nil, 0)
+	})
+	return connectExFunc.err
+}
+
+func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
+	err := LoadConnectEx()
+	if err != nil {
+		return errorspkg.New("failed to find ConnectEx: " + err.Error())
+	}
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
+}
+
+// Invented structures to support what package os expects.
+type Rusage struct {
+	CreationTime Filetime
+	ExitTime     Filetime
+	KernelTime   Filetime
+	UserTime     Filetime
+}
+
+type WaitStatus struct {
+	ExitCode uint32
+}
+
+func (w WaitStatus) Exited() bool { return true }
+
+func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
+
+func (w WaitStatus) Signal() Signal { return -1 }
+
+func (w WaitStatus) CoreDump() bool { return false }
+
+func (w WaitStatus) Stopped() bool { return false }
+
+func (w WaitStatus) Continued() bool { return false }
+
+func (w WaitStatus) StopSignal() Signal { return -1 }
+
+func (w WaitStatus) Signaled() bool { return false }
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
+// Timespec is an invented structure on Windows, but here for
+// consistency with the corresponding package for other operating systems.
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = nsec / 1e9
+	ts.Nsec = nsec % 1e9
+	return
+}
+
+// TODO(brainman): fix all needed for net
+
+func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS }
+func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
+	return 0, nil, syscall.EWINDOWS
+}
+func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error)       { return syscall.EWINDOWS }
+func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS }
+
+// The Linger struct is wrong but we only noticed after Go 1.
+// sysLinger is the real system call structure.
+
+// BUG(brainman): The definition of Linger is not appropriate for direct use
+// with Setsockopt and Getsockopt.
+// Use SetsockoptLinger instead.
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type sysLinger struct {
+	Onoff  uint16
+	Linger uint16
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS }
+
+func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
+	sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
+}
+
+func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
+}
+func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
+}
+func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
+	return syscall.EWINDOWS
+}
+
+func Getpid() (pid int) { return int(getCurrentProcessId()) }
+
+func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
+	// NOTE(rsc): The Win32finddata struct is wrong for the system call:
+	// the two paths are each one uint16 short. Use the correct struct,
+	// a win32finddata1, and then copy the results out.
+	// There is no loss of expressivity here, because the final
+	// uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
+	// For Go 1.1, we might avoid the allocation of win32finddata1 here
+	// by adding a final Bug [2]uint16 field to the struct and then
+	// adjusting the fields in the result directly.
+	var data1 win32finddata1
+	handle, err = findFirstFile1(name, &data1)
+	if err == nil {
+		copyFindData(data, &data1)
+	}
+	return
+}
+
+func FindNextFile(handle Handle, data *Win32finddata) (err error) {
+	var data1 win32finddata1
+	err = findNextFile1(handle, &data1)
+	if err == nil {
+		copyFindData(data, &data1)
+	}
+	return
+}
+
+func getProcessEntry(pid int) (*ProcessEntry32, error) {
+	snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
+	if err != nil {
+		return nil, err
+	}
+	defer CloseHandle(snapshot)
+	var procEntry ProcessEntry32
+	procEntry.Size = uint32(unsafe.Sizeof(procEntry))
+	if err = Process32First(snapshot, &procEntry); err != nil {
+		return nil, err
+	}
+	for {
+		if procEntry.ProcessID == uint32(pid) {
+			return &procEntry, nil
+		}
+		err = Process32Next(snapshot, &procEntry)
+		if err != nil {
+			return nil, err
+		}
+	}
+}
+
+func Getppid() (ppid int) {
+	pe, err := getProcessEntry(Getpid())
+	if err != nil {
+		return -1
+	}
+	return int(pe.ParentProcessID)
+}
+
+// TODO(brainman): fix all needed for os
+func Fchdir(fd Handle) (err error)             { return syscall.EWINDOWS }
+func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS }
+func Symlink(path, link string) (err error)    { return syscall.EWINDOWS }
+
+func Fchmod(fd Handle, mode uint32) (err error)        { return syscall.EWINDOWS }
+func Chown(path string, uid int, gid int) (err error)  { return syscall.EWINDOWS }
+func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS }
+func Fchown(fd Handle, uid int, gid int) (err error)   { return syscall.EWINDOWS }
+
+func Getuid() (uid int)                  { return -1 }
+func Geteuid() (euid int)                { return -1 }
+func Getgid() (gid int)                  { return -1 }
+func Getegid() (egid int)                { return -1 }
+func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS }
+
+type Signal int
+
+func (s Signal) Signal() {}
+
+func (s Signal) String() string {
+	if 0 <= s && int(s) < len(signals) {
+		str := signals[s]
+		if str != "" {
+			return str
+		}
+	}
+	return "signal " + itoa(int(s))
+}
+
+func LoadCreateSymbolicLink() error {
+	return procCreateSymbolicLinkW.Find()
+}
+
+// Readlink returns the destination of the named symbolic link.
+func Readlink(path string, buf []byte) (n int, err error) {
+	fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
+		FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if err != nil {
+		return -1, err
+	}
+	defer CloseHandle(fd)
+
+	rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
+	var bytesReturned uint32
+	err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
+	if err != nil {
+		return -1, err
+	}
+
+	rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
+	var s string
+	switch rdb.ReparseTag {
+	case IO_REPARSE_TAG_SYMLINK:
+		data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
+		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
+		s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
+	case IO_REPARSE_TAG_MOUNT_POINT:
+		data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
+		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
+		s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
+	default:
+		// the path is not a symlink or junction but another type of reparse
+		// point
+		return -1, syscall.ENOENT
+	}
+	n = copy(buf, []byte(s))
+
+	return n, nil
+}

+ 2220 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/zsyscall_windows.go

@@ -0,0 +1,2220 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package windows
+
+import "unsafe"
+import "syscall"
+
+var _ unsafe.Pointer
+
+var (
+	modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
+	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+	modshell32  = syscall.NewLazyDLL("shell32.dll")
+	modmswsock  = syscall.NewLazyDLL("mswsock.dll")
+	modcrypt32  = syscall.NewLazyDLL("crypt32.dll")
+	modws2_32   = syscall.NewLazyDLL("ws2_32.dll")
+	moddnsapi   = syscall.NewLazyDLL("dnsapi.dll")
+	modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
+	modsecur32  = syscall.NewLazyDLL("secur32.dll")
+	modnetapi32 = syscall.NewLazyDLL("netapi32.dll")
+	moduserenv  = syscall.NewLazyDLL("userenv.dll")
+
+	procRegisterEventSourceW               = modadvapi32.NewProc("RegisterEventSourceW")
+	procDeregisterEventSource              = modadvapi32.NewProc("DeregisterEventSource")
+	procReportEventW                       = modadvapi32.NewProc("ReportEventW")
+	procOpenSCManagerW                     = modadvapi32.NewProc("OpenSCManagerW")
+	procCloseServiceHandle                 = modadvapi32.NewProc("CloseServiceHandle")
+	procCreateServiceW                     = modadvapi32.NewProc("CreateServiceW")
+	procOpenServiceW                       = modadvapi32.NewProc("OpenServiceW")
+	procDeleteService                      = modadvapi32.NewProc("DeleteService")
+	procStartServiceW                      = modadvapi32.NewProc("StartServiceW")
+	procQueryServiceStatus                 = modadvapi32.NewProc("QueryServiceStatus")
+	procControlService                     = modadvapi32.NewProc("ControlService")
+	procStartServiceCtrlDispatcherW        = modadvapi32.NewProc("StartServiceCtrlDispatcherW")
+	procSetServiceStatus                   = modadvapi32.NewProc("SetServiceStatus")
+	procChangeServiceConfigW               = modadvapi32.NewProc("ChangeServiceConfigW")
+	procQueryServiceConfigW                = modadvapi32.NewProc("QueryServiceConfigW")
+	procChangeServiceConfig2W              = modadvapi32.NewProc("ChangeServiceConfig2W")
+	procQueryServiceConfig2W               = modadvapi32.NewProc("QueryServiceConfig2W")
+	procGetLastError                       = modkernel32.NewProc("GetLastError")
+	procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
+	procFreeLibrary                        = modkernel32.NewProc("FreeLibrary")
+	procGetProcAddress                     = modkernel32.NewProc("GetProcAddress")
+	procGetVersion                         = modkernel32.NewProc("GetVersion")
+	procFormatMessageW                     = modkernel32.NewProc("FormatMessageW")
+	procExitProcess                        = modkernel32.NewProc("ExitProcess")
+	procCreateFileW                        = modkernel32.NewProc("CreateFileW")
+	procReadFile                           = modkernel32.NewProc("ReadFile")
+	procWriteFile                          = modkernel32.NewProc("WriteFile")
+	procSetFilePointer                     = modkernel32.NewProc("SetFilePointer")
+	procCloseHandle                        = modkernel32.NewProc("CloseHandle")
+	procGetStdHandle                       = modkernel32.NewProc("GetStdHandle")
+	procFindFirstFileW                     = modkernel32.NewProc("FindFirstFileW")
+	procFindNextFileW                      = modkernel32.NewProc("FindNextFileW")
+	procFindClose                          = modkernel32.NewProc("FindClose")
+	procGetFileInformationByHandle         = modkernel32.NewProc("GetFileInformationByHandle")
+	procGetCurrentDirectoryW               = modkernel32.NewProc("GetCurrentDirectoryW")
+	procSetCurrentDirectoryW               = modkernel32.NewProc("SetCurrentDirectoryW")
+	procCreateDirectoryW                   = modkernel32.NewProc("CreateDirectoryW")
+	procRemoveDirectoryW                   = modkernel32.NewProc("RemoveDirectoryW")
+	procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
+	procMoveFileW                          = modkernel32.NewProc("MoveFileW")
+	procMoveFileExW                        = modkernel32.NewProc("MoveFileExW")
+	procGetComputerNameW                   = modkernel32.NewProc("GetComputerNameW")
+	procGetComputerNameExW                 = modkernel32.NewProc("GetComputerNameExW")
+	procSetEndOfFile                       = modkernel32.NewProc("SetEndOfFile")
+	procGetSystemTimeAsFileTime            = modkernel32.NewProc("GetSystemTimeAsFileTime")
+	procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
+	procCreateIoCompletionPort             = modkernel32.NewProc("CreateIoCompletionPort")
+	procGetQueuedCompletionStatus          = modkernel32.NewProc("GetQueuedCompletionStatus")
+	procPostQueuedCompletionStatus         = modkernel32.NewProc("PostQueuedCompletionStatus")
+	procCancelIo                           = modkernel32.NewProc("CancelIo")
+	procCancelIoEx                         = modkernel32.NewProc("CancelIoEx")
+	procCreateProcessW                     = modkernel32.NewProc("CreateProcessW")
+	procOpenProcess                        = modkernel32.NewProc("OpenProcess")
+	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
+	procGetExitCodeProcess                 = modkernel32.NewProc("GetExitCodeProcess")
+	procGetStartupInfoW                    = modkernel32.NewProc("GetStartupInfoW")
+	procGetCurrentProcess                  = modkernel32.NewProc("GetCurrentProcess")
+	procGetProcessTimes                    = modkernel32.NewProc("GetProcessTimes")
+	procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
+	procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
+	procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
+	procCreatePipe                         = modkernel32.NewProc("CreatePipe")
+	procGetFileType                        = modkernel32.NewProc("GetFileType")
+	procCryptAcquireContextW               = modadvapi32.NewProc("CryptAcquireContextW")
+	procCryptReleaseContext                = modadvapi32.NewProc("CryptReleaseContext")
+	procCryptGenRandom                     = modadvapi32.NewProc("CryptGenRandom")
+	procGetEnvironmentStringsW             = modkernel32.NewProc("GetEnvironmentStringsW")
+	procFreeEnvironmentStringsW            = modkernel32.NewProc("FreeEnvironmentStringsW")
+	procGetEnvironmentVariableW            = modkernel32.NewProc("GetEnvironmentVariableW")
+	procSetEnvironmentVariableW            = modkernel32.NewProc("SetEnvironmentVariableW")
+	procSetFileTime                        = modkernel32.NewProc("SetFileTime")
+	procGetFileAttributesW                 = modkernel32.NewProc("GetFileAttributesW")
+	procSetFileAttributesW                 = modkernel32.NewProc("SetFileAttributesW")
+	procGetFileAttributesExW               = modkernel32.NewProc("GetFileAttributesExW")
+	procGetCommandLineW                    = modkernel32.NewProc("GetCommandLineW")
+	procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
+	procLocalFree                          = modkernel32.NewProc("LocalFree")
+	procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
+	procFlushFileBuffers                   = modkernel32.NewProc("FlushFileBuffers")
+	procGetFullPathNameW                   = modkernel32.NewProc("GetFullPathNameW")
+	procGetLongPathNameW                   = modkernel32.NewProc("GetLongPathNameW")
+	procGetShortPathNameW                  = modkernel32.NewProc("GetShortPathNameW")
+	procCreateFileMappingW                 = modkernel32.NewProc("CreateFileMappingW")
+	procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
+	procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
+	procFlushViewOfFile                    = modkernel32.NewProc("FlushViewOfFile")
+	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
+	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
+	procTransmitFile                       = modmswsock.NewProc("TransmitFile")
+	procReadDirectoryChangesW              = modkernel32.NewProc("ReadDirectoryChangesW")
+	procCertOpenSystemStoreW               = modcrypt32.NewProc("CertOpenSystemStoreW")
+	procCertOpenStore                      = modcrypt32.NewProc("CertOpenStore")
+	procCertEnumCertificatesInStore        = modcrypt32.NewProc("CertEnumCertificatesInStore")
+	procCertAddCertificateContextToStore   = modcrypt32.NewProc("CertAddCertificateContextToStore")
+	procCertCloseStore                     = modcrypt32.NewProc("CertCloseStore")
+	procCertGetCertificateChain            = modcrypt32.NewProc("CertGetCertificateChain")
+	procCertFreeCertificateChain           = modcrypt32.NewProc("CertFreeCertificateChain")
+	procCertCreateCertificateContext       = modcrypt32.NewProc("CertCreateCertificateContext")
+	procCertFreeCertificateContext         = modcrypt32.NewProc("CertFreeCertificateContext")
+	procCertVerifyCertificateChainPolicy   = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
+	procRegOpenKeyExW                      = modadvapi32.NewProc("RegOpenKeyExW")
+	procRegCloseKey                        = modadvapi32.NewProc("RegCloseKey")
+	procRegQueryInfoKeyW                   = modadvapi32.NewProc("RegQueryInfoKeyW")
+	procRegEnumKeyExW                      = modadvapi32.NewProc("RegEnumKeyExW")
+	procRegQueryValueExW                   = modadvapi32.NewProc("RegQueryValueExW")
+	procGetCurrentProcessId                = modkernel32.NewProc("GetCurrentProcessId")
+	procGetConsoleMode                     = modkernel32.NewProc("GetConsoleMode")
+	procWriteConsoleW                      = modkernel32.NewProc("WriteConsoleW")
+	procReadConsoleW                       = modkernel32.NewProc("ReadConsoleW")
+	procCreateToolhelp32Snapshot           = modkernel32.NewProc("CreateToolhelp32Snapshot")
+	procProcess32FirstW                    = modkernel32.NewProc("Process32FirstW")
+	procProcess32NextW                     = modkernel32.NewProc("Process32NextW")
+	procDeviceIoControl                    = modkernel32.NewProc("DeviceIoControl")
+	procCreateSymbolicLinkW                = modkernel32.NewProc("CreateSymbolicLinkW")
+	procCreateHardLinkW                    = modkernel32.NewProc("CreateHardLinkW")
+	procGetCurrentThreadId                 = modkernel32.NewProc("GetCurrentThreadId")
+	procCreateEventW                       = modkernel32.NewProc("CreateEventW")
+	procSetEvent                           = modkernel32.NewProc("SetEvent")
+	procWSAStartup                         = modws2_32.NewProc("WSAStartup")
+	procWSACleanup                         = modws2_32.NewProc("WSACleanup")
+	procWSAIoctl                           = modws2_32.NewProc("WSAIoctl")
+	procsocket                             = modws2_32.NewProc("socket")
+	procsetsockopt                         = modws2_32.NewProc("setsockopt")
+	procgetsockopt                         = modws2_32.NewProc("getsockopt")
+	procbind                               = modws2_32.NewProc("bind")
+	procconnect                            = modws2_32.NewProc("connect")
+	procgetsockname                        = modws2_32.NewProc("getsockname")
+	procgetpeername                        = modws2_32.NewProc("getpeername")
+	proclisten                             = modws2_32.NewProc("listen")
+	procshutdown                           = modws2_32.NewProc("shutdown")
+	procclosesocket                        = modws2_32.NewProc("closesocket")
+	procAcceptEx                           = modmswsock.NewProc("AcceptEx")
+	procGetAcceptExSockaddrs               = modmswsock.NewProc("GetAcceptExSockaddrs")
+	procWSARecv                            = modws2_32.NewProc("WSARecv")
+	procWSASend                            = modws2_32.NewProc("WSASend")
+	procWSARecvFrom                        = modws2_32.NewProc("WSARecvFrom")
+	procWSASendTo                          = modws2_32.NewProc("WSASendTo")
+	procgethostbyname                      = modws2_32.NewProc("gethostbyname")
+	procgetservbyname                      = modws2_32.NewProc("getservbyname")
+	procntohs                              = modws2_32.NewProc("ntohs")
+	procgetprotobyname                     = modws2_32.NewProc("getprotobyname")
+	procDnsQuery_W                         = moddnsapi.NewProc("DnsQuery_W")
+	procDnsRecordListFree                  = moddnsapi.NewProc("DnsRecordListFree")
+	procDnsNameCompare_W                   = moddnsapi.NewProc("DnsNameCompare_W")
+	procGetAddrInfoW                       = modws2_32.NewProc("GetAddrInfoW")
+	procFreeAddrInfoW                      = modws2_32.NewProc("FreeAddrInfoW")
+	procGetIfEntry                         = modiphlpapi.NewProc("GetIfEntry")
+	procGetAdaptersInfo                    = modiphlpapi.NewProc("GetAdaptersInfo")
+	procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
+	procWSAEnumProtocolsW                  = modws2_32.NewProc("WSAEnumProtocolsW")
+	procGetAdaptersAddresses               = modiphlpapi.NewProc("GetAdaptersAddresses")
+	procGetACP                             = modkernel32.NewProc("GetACP")
+	procMultiByteToWideChar                = modkernel32.NewProc("MultiByteToWideChar")
+	procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
+	procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
+	procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
+	procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
+	procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
+	procLookupAccountSidW                  = modadvapi32.NewProc("LookupAccountSidW")
+	procLookupAccountNameW                 = modadvapi32.NewProc("LookupAccountNameW")
+	procConvertSidToStringSidW             = modadvapi32.NewProc("ConvertSidToStringSidW")
+	procConvertStringSidToSidW             = modadvapi32.NewProc("ConvertStringSidToSidW")
+	procGetLengthSid                       = modadvapi32.NewProc("GetLengthSid")
+	procCopySid                            = modadvapi32.NewProc("CopySid")
+	procAllocateAndInitializeSid           = modadvapi32.NewProc("AllocateAndInitializeSid")
+	procFreeSid                            = modadvapi32.NewProc("FreeSid")
+	procEqualSid                           = modadvapi32.NewProc("EqualSid")
+	procOpenProcessToken                   = modadvapi32.NewProc("OpenProcessToken")
+	procGetTokenInformation                = modadvapi32.NewProc("GetTokenInformation")
+	procGetUserProfileDirectoryW           = moduserenv.NewProc("GetUserProfileDirectoryW")
+)
+
+func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeregisterEventSource(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CloseServiceHandle(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeleteService(service Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) {
+	r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) {
+	r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) {
+	r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) {
+	r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetLastError() (lasterr error) {
+	r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
+	if r0 != 0 {
+		lasterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func LoadLibrary(libname string) (handle Handle, err error) {
+	var _p0 *uint16
+	_p0, err = syscall.UTF16PtrFromString(libname)
+	if err != nil {
+		return
+	}
+	return _LoadLibrary(_p0)
+}
+
+func _LoadLibrary(libname *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FreeLibrary(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(procname)
+	if err != nil {
+		return
+	}
+	return _GetProcAddress(module, _p0)
+}
+
+func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
+	r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
+	proc = uintptr(r0)
+	if proc == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetVersion() (ver uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
+	ver = uint32(r0)
+	if ver == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
+	var _p0 *uint16
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ExitProcess(exitcode uint32) {
+	syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
+	return
+}
+
+func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
+	r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
+	newlowoffset = uint32(r0)
+	if newlowoffset == 0xffffffff {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CloseHandle(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetStdHandle(stdhandle int) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func findNextFile1(handle Handle, data *win32finddata1) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FindClose(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetCurrentDirectory(path *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
+	r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func RemoveDirectory(path *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeleteFile(path *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func MoveFile(from *uint16, to *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetComputerName(buf *uint16, n *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetEndOfFile(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetSystemTimeAsFileTime(time *Filetime) {
+	syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
+	return
+}
+
+func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
+	rc = uint32(r0)
+	if rc == 0xffffffff {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CancelIo(s Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CancelIoEx(s Handle, o *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
+	var _p0 uint32
+	if inheritHandles {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
+	var _p0 uint32
+	if inheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func TerminateProcess(handle Handle, exitcode uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetStartupInfo(startupInfo *StartupInfo) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentProcess() (pseudoHandle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
+	pseudoHandle = Handle(r0)
+	if pseudoHandle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
+	var _p0 uint32
+	if bInheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
+	event = uint32(r0)
+	if event == 0xffffffff {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileType(filehandle Handle) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
+	r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetEnvironmentStrings() (envs *uint16, err error) {
+	r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
+	envs = (*uint16)(unsafe.Pointer(r0))
+	if envs == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FreeEnvironmentStrings(envs *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
+	r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileAttributes(name *uint16) (attrs uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	attrs = uint32(r0)
+	if attrs == INVALID_FILE_ATTRIBUTES {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetFileAttributes(name *uint16, attrs uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCommandLine() (cmd *uint16) {
+	r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
+	cmd = (*uint16)(unsafe.Pointer(r0))
+	return
+}
+
+func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
+	r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
+	argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
+	if argv == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func LocalFree(hmem Handle) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
+	handle = Handle(r0)
+	if handle != 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FlushFileBuffers(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
+	r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
+	addr = uintptr(r0)
+	if addr == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func UnmapViewOfFile(addr uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualLock(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func VirtualUnlock(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+	var _p0 uint32
+	if watchSubTree {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
+	store = Handle(r0)
+	if store == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
+	r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
+	context = (*CertContext)(unsafe.Pointer(r0))
+	if context == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertCloseStore(store Handle, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
+	r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertFreeCertificateChain(ctx *CertChainContext) {
+	syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+	return
+}
+
+func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
+	r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
+	context = (*CertContext)(unsafe.Pointer(r0))
+	if context == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertFreeCertificateContext(ctx *CertContext) (err error) {
+	r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
+	r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegCloseKey(key Handle) (regerrno error) {
+	r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+	r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+	r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
+	r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
+	if r0 != 0 {
+		regerrno = syscall.Errno(r0)
+	}
+	return
+}
+
+func getCurrentProcessId() (pid uint32) {
+	r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
+	pid = uint32(r0)
+	return
+}
+
+func GetConsoleMode(console Handle, mode *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
+	r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
+	r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+	r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+	r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentThreadId() (id uint32) {
+	r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0)
+	id = uint32(r0)
+	return
+}
+
+func CreateEvent(eventAttrs *syscall.SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func SetEvent(event Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
+	r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
+	if r0 != 0 {
+		sockerr = syscall.Errno(r0)
+	}
+	return
+}
+
+func WSACleanup() (err error) {
+	r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func listen(s Handle, backlog int32) (err error) {
+	r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func shutdown(s Handle, how int32) (err error) {
+	r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Closesocket(s Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
+	syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
+	return
+}
+
+func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetHostByName(name string) (h *Hostent, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	return _GetHostByName(_p0)
+}
+
+func _GetHostByName(name *byte) (h *Hostent, err error) {
+	r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	h = (*Hostent)(unsafe.Pointer(r0))
+	if h == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetServByName(name string, proto string) (s *Servent, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = syscall.BytePtrFromString(proto)
+	if err != nil {
+		return
+	}
+	return _GetServByName(_p0, _p1)
+}
+
+func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
+	r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
+	s = (*Servent)(unsafe.Pointer(r0))
+	if s == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func Ntohs(netshort uint16) (u uint16) {
+	r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
+	u = uint16(r0)
+	return
+}
+
+func GetProtoByName(name string) (p *Protoent, err error) {
+	var _p0 *byte
+	_p0, err = syscall.BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	return _GetProtoByName(_p0)
+}
+
+func _GetProtoByName(name *byte) (p *Protoent, err error) {
+	r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	p = (*Protoent)(unsafe.Pointer(r0))
+	if p == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+	var _p0 *uint16
+	_p0, status = syscall.UTF16PtrFromString(name)
+	if status != nil {
+		return
+	}
+	return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
+}
+
+func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+	r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
+	if r0 != 0 {
+		status = syscall.Errno(r0)
+	}
+	return
+}
+
+func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
+	syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
+	return
+}
+
+func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) {
+	r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0)
+	same = r0 != 0
+	return
+}
+
+func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
+	r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if r0 != 0 {
+		sockerr = syscall.Errno(r0)
+	}
+	return
+}
+
+func FreeAddrInfoW(addrinfo *AddrinfoW) {
+	syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
+	return
+}
+
+func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
+	r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
+func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
+	r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
+func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
+	r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
+	n = int32(r0)
+	if n == -1 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
+	r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
+func GetACP() (acp uint32) {
+	r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0)
+	acp = uint32(r0)
+	return
+}
+
+func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) {
+	r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar))
+	nwrite = int32(r0)
+	if nwrite == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
+	r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
+	if r0 != 0 {
+		neterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
+	r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
+	if r0 != 0 {
+		neterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func NetApiBufferFree(buf *byte) (neterr error) {
+	r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
+	if r0 != 0 {
+		neterr = syscall.Errno(r0)
+	}
+	return
+}
+
+func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
+	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
+	r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetLengthSid(sid *SID) (len uint32) {
+	r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+	len = uint32(r0)
+	return
+}
+
+func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
+	r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) {
+	r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func FreeSid(sid *SID) (err error) {
+	r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+	if r1 != 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) {
+	r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0)
+	isEqual = r0 != 0
+	return
+}
+
+func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
+	r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}

+ 1242 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/ztypes_windows.go

@@ -0,0 +1,1242 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+import "syscall"
+
+const (
+	// Windows errors.
+	ERROR_FILE_NOT_FOUND         syscall.Errno = 2
+	ERROR_PATH_NOT_FOUND         syscall.Errno = 3
+	ERROR_ACCESS_DENIED          syscall.Errno = 5
+	ERROR_NO_MORE_FILES          syscall.Errno = 18
+	ERROR_HANDLE_EOF             syscall.Errno = 38
+	ERROR_NETNAME_DELETED        syscall.Errno = 64
+	ERROR_FILE_EXISTS            syscall.Errno = 80
+	ERROR_BROKEN_PIPE            syscall.Errno = 109
+	ERROR_BUFFER_OVERFLOW        syscall.Errno = 111
+	ERROR_INSUFFICIENT_BUFFER    syscall.Errno = 122
+	ERROR_MOD_NOT_FOUND          syscall.Errno = 126
+	ERROR_PROC_NOT_FOUND         syscall.Errno = 127
+	ERROR_ALREADY_EXISTS         syscall.Errno = 183
+	ERROR_ENVVAR_NOT_FOUND       syscall.Errno = 203
+	ERROR_MORE_DATA              syscall.Errno = 234
+	ERROR_OPERATION_ABORTED      syscall.Errno = 995
+	ERROR_IO_PENDING             syscall.Errno = 997
+	ERROR_SERVICE_SPECIFIC_ERROR syscall.Errno = 1066
+	ERROR_NOT_FOUND              syscall.Errno = 1168
+	ERROR_PRIVILEGE_NOT_HELD     syscall.Errno = 1314
+	WSAEACCES                    syscall.Errno = 10013
+	WSAECONNRESET                syscall.Errno = 10054
+)
+
+const (
+	// Invented values to support what package os expects.
+	O_RDONLY   = 0x00000
+	O_WRONLY   = 0x00001
+	O_RDWR     = 0x00002
+	O_CREAT    = 0x00040
+	O_EXCL     = 0x00080
+	O_NOCTTY   = 0x00100
+	O_TRUNC    = 0x00200
+	O_NONBLOCK = 0x00800
+	O_APPEND   = 0x00400
+	O_SYNC     = 0x01000
+	O_ASYNC    = 0x02000
+	O_CLOEXEC  = 0x80000
+)
+
+const (
+	// More invented values for signals
+	SIGHUP  = Signal(0x1)
+	SIGINT  = Signal(0x2)
+	SIGQUIT = Signal(0x3)
+	SIGILL  = Signal(0x4)
+	SIGTRAP = Signal(0x5)
+	SIGABRT = Signal(0x6)
+	SIGBUS  = Signal(0x7)
+	SIGFPE  = Signal(0x8)
+	SIGKILL = Signal(0x9)
+	SIGSEGV = Signal(0xb)
+	SIGPIPE = Signal(0xd)
+	SIGALRM = Signal(0xe)
+	SIGTERM = Signal(0xf)
+)
+
+var signals = [...]string{
+	1:  "hangup",
+	2:  "interrupt",
+	3:  "quit",
+	4:  "illegal instruction",
+	5:  "trace/breakpoint trap",
+	6:  "aborted",
+	7:  "bus error",
+	8:  "floating point exception",
+	9:  "killed",
+	10: "user defined signal 1",
+	11: "segmentation fault",
+	12: "user defined signal 2",
+	13: "broken pipe",
+	14: "alarm clock",
+	15: "terminated",
+}
+
+const (
+	GENERIC_READ    = 0x80000000
+	GENERIC_WRITE   = 0x40000000
+	GENERIC_EXECUTE = 0x20000000
+	GENERIC_ALL     = 0x10000000
+
+	FILE_LIST_DIRECTORY   = 0x00000001
+	FILE_APPEND_DATA      = 0x00000004
+	FILE_WRITE_ATTRIBUTES = 0x00000100
+
+	FILE_SHARE_READ              = 0x00000001
+	FILE_SHARE_WRITE             = 0x00000002
+	FILE_SHARE_DELETE            = 0x00000004
+	FILE_ATTRIBUTE_READONLY      = 0x00000001
+	FILE_ATTRIBUTE_HIDDEN        = 0x00000002
+	FILE_ATTRIBUTE_SYSTEM        = 0x00000004
+	FILE_ATTRIBUTE_DIRECTORY     = 0x00000010
+	FILE_ATTRIBUTE_ARCHIVE       = 0x00000020
+	FILE_ATTRIBUTE_NORMAL        = 0x00000080
+	FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
+
+	INVALID_FILE_ATTRIBUTES = 0xffffffff
+
+	CREATE_NEW        = 1
+	CREATE_ALWAYS     = 2
+	OPEN_EXISTING     = 3
+	OPEN_ALWAYS       = 4
+	TRUNCATE_EXISTING = 5
+
+	FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
+	FILE_FLAG_BACKUP_SEMANTICS   = 0x02000000
+	FILE_FLAG_OVERLAPPED         = 0x40000000
+
+	HANDLE_FLAG_INHERIT    = 0x00000001
+	STARTF_USESTDHANDLES   = 0x00000100
+	STARTF_USESHOWWINDOW   = 0x00000001
+	DUPLICATE_CLOSE_SOURCE = 0x00000001
+	DUPLICATE_SAME_ACCESS  = 0x00000002
+
+	STD_INPUT_HANDLE  = -10
+	STD_OUTPUT_HANDLE = -11
+	STD_ERROR_HANDLE  = -12
+
+	FILE_BEGIN   = 0
+	FILE_CURRENT = 1
+	FILE_END     = 2
+
+	LANG_ENGLISH       = 0x09
+	SUBLANG_ENGLISH_US = 0x01
+
+	FORMAT_MESSAGE_ALLOCATE_BUFFER = 256
+	FORMAT_MESSAGE_IGNORE_INSERTS  = 512
+	FORMAT_MESSAGE_FROM_STRING     = 1024
+	FORMAT_MESSAGE_FROM_HMODULE    = 2048
+	FORMAT_MESSAGE_FROM_SYSTEM     = 4096
+	FORMAT_MESSAGE_ARGUMENT_ARRAY  = 8192
+	FORMAT_MESSAGE_MAX_WIDTH_MASK  = 255
+
+	MAX_PATH      = 260
+	MAX_LONG_PATH = 32768
+
+	MAX_COMPUTERNAME_LENGTH = 15
+
+	TIME_ZONE_ID_UNKNOWN  = 0
+	TIME_ZONE_ID_STANDARD = 1
+
+	TIME_ZONE_ID_DAYLIGHT = 2
+	IGNORE                = 0
+	INFINITE              = 0xffffffff
+
+	WAIT_TIMEOUT   = 258
+	WAIT_ABANDONED = 0x00000080
+	WAIT_OBJECT_0  = 0x00000000
+	WAIT_FAILED    = 0xFFFFFFFF
+
+	CREATE_NEW_PROCESS_GROUP   = 0x00000200
+	CREATE_UNICODE_ENVIRONMENT = 0x00000400
+
+	PROCESS_TERMINATE         = 1
+	PROCESS_QUERY_INFORMATION = 0x00000400
+	SYNCHRONIZE               = 0x00100000
+
+	PAGE_READONLY          = 0x02
+	PAGE_READWRITE         = 0x04
+	PAGE_WRITECOPY         = 0x08
+	PAGE_EXECUTE_READ      = 0x20
+	PAGE_EXECUTE_READWRITE = 0x40
+	PAGE_EXECUTE_WRITECOPY = 0x80
+
+	FILE_MAP_COPY    = 0x01
+	FILE_MAP_WRITE   = 0x02
+	FILE_MAP_READ    = 0x04
+	FILE_MAP_EXECUTE = 0x20
+
+	CTRL_C_EVENT     = 0
+	CTRL_BREAK_EVENT = 1
+
+	// Windows reserves errors >= 1<<29 for application use.
+	APPLICATION_ERROR = 1 << 29
+)
+
+const (
+	// flags for CreateToolhelp32Snapshot
+	TH32CS_SNAPHEAPLIST = 0x01
+	TH32CS_SNAPPROCESS  = 0x02
+	TH32CS_SNAPTHREAD   = 0x04
+	TH32CS_SNAPMODULE   = 0x08
+	TH32CS_SNAPMODULE32 = 0x10
+	TH32CS_SNAPALL      = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD
+	TH32CS_INHERIT      = 0x80000000
+)
+
+const (
+	// filters for ReadDirectoryChangesW
+	FILE_NOTIFY_CHANGE_FILE_NAME   = 0x001
+	FILE_NOTIFY_CHANGE_DIR_NAME    = 0x002
+	FILE_NOTIFY_CHANGE_ATTRIBUTES  = 0x004
+	FILE_NOTIFY_CHANGE_SIZE        = 0x008
+	FILE_NOTIFY_CHANGE_LAST_WRITE  = 0x010
+	FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020
+	FILE_NOTIFY_CHANGE_CREATION    = 0x040
+	FILE_NOTIFY_CHANGE_SECURITY    = 0x100
+)
+
+const (
+	// do not reorder
+	FILE_ACTION_ADDED = iota + 1
+	FILE_ACTION_REMOVED
+	FILE_ACTION_MODIFIED
+	FILE_ACTION_RENAMED_OLD_NAME
+	FILE_ACTION_RENAMED_NEW_NAME
+)
+
+const (
+	// wincrypt.h
+	PROV_RSA_FULL                    = 1
+	PROV_RSA_SIG                     = 2
+	PROV_DSS                         = 3
+	PROV_FORTEZZA                    = 4
+	PROV_MS_EXCHANGE                 = 5
+	PROV_SSL                         = 6
+	PROV_RSA_SCHANNEL                = 12
+	PROV_DSS_DH                      = 13
+	PROV_EC_ECDSA_SIG                = 14
+	PROV_EC_ECNRA_SIG                = 15
+	PROV_EC_ECDSA_FULL               = 16
+	PROV_EC_ECNRA_FULL               = 17
+	PROV_DH_SCHANNEL                 = 18
+	PROV_SPYRUS_LYNKS                = 20
+	PROV_RNG                         = 21
+	PROV_INTEL_SEC                   = 22
+	PROV_REPLACE_OWF                 = 23
+	PROV_RSA_AES                     = 24
+	CRYPT_VERIFYCONTEXT              = 0xF0000000
+	CRYPT_NEWKEYSET                  = 0x00000008
+	CRYPT_DELETEKEYSET               = 0x00000010
+	CRYPT_MACHINE_KEYSET             = 0x00000020
+	CRYPT_SILENT                     = 0x00000040
+	CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080
+
+	USAGE_MATCH_TYPE_AND = 0
+	USAGE_MATCH_TYPE_OR  = 1
+
+	X509_ASN_ENCODING   = 0x00000001
+	PKCS_7_ASN_ENCODING = 0x00010000
+
+	CERT_STORE_PROV_MEMORY = 2
+
+	CERT_STORE_ADD_ALWAYS = 4
+
+	CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004
+
+	CERT_TRUST_NO_ERROR                          = 0x00000000
+	CERT_TRUST_IS_NOT_TIME_VALID                 = 0x00000001
+	CERT_TRUST_IS_REVOKED                        = 0x00000004
+	CERT_TRUST_IS_NOT_SIGNATURE_VALID            = 0x00000008
+	CERT_TRUST_IS_NOT_VALID_FOR_USAGE            = 0x00000010
+	CERT_TRUST_IS_UNTRUSTED_ROOT                 = 0x00000020
+	CERT_TRUST_REVOCATION_STATUS_UNKNOWN         = 0x00000040
+	CERT_TRUST_IS_CYCLIC                         = 0x00000080
+	CERT_TRUST_INVALID_EXTENSION                 = 0x00000100
+	CERT_TRUST_INVALID_POLICY_CONSTRAINTS        = 0x00000200
+	CERT_TRUST_INVALID_BASIC_CONSTRAINTS         = 0x00000400
+	CERT_TRUST_INVALID_NAME_CONSTRAINTS          = 0x00000800
+	CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000
+	CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT   = 0x00002000
+	CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000
+	CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT      = 0x00008000
+	CERT_TRUST_IS_OFFLINE_REVOCATION             = 0x01000000
+	CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY          = 0x02000000
+	CERT_TRUST_IS_EXPLICIT_DISTRUST              = 0x04000000
+	CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT    = 0x08000000
+
+	CERT_CHAIN_POLICY_BASE              = 1
+	CERT_CHAIN_POLICY_AUTHENTICODE      = 2
+	CERT_CHAIN_POLICY_AUTHENTICODE_TS   = 3
+	CERT_CHAIN_POLICY_SSL               = 4
+	CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5
+	CERT_CHAIN_POLICY_NT_AUTH           = 6
+	CERT_CHAIN_POLICY_MICROSOFT_ROOT    = 7
+	CERT_CHAIN_POLICY_EV                = 8
+
+	CERT_E_EXPIRED       = 0x800B0101
+	CERT_E_ROLE          = 0x800B0103
+	CERT_E_PURPOSE       = 0x800B0106
+	CERT_E_UNTRUSTEDROOT = 0x800B0109
+	CERT_E_CN_NO_MATCH   = 0x800B010F
+
+	AUTHTYPE_CLIENT = 1
+	AUTHTYPE_SERVER = 2
+)
+
+var (
+	OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00")
+	OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00")
+	OID_SGC_NETSCAPE        = []byte("2.16.840.1.113730.4.1\x00")
+)
+
+// Invented values to support what package os expects.
+type Timeval struct {
+	Sec  int32
+	Usec int32
+}
+
+func (tv *Timeval) Nanoseconds() int64 {
+	return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	tv.Sec = int32(nsec / 1e9)
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	return
+}
+
+type SecurityAttributes struct {
+	Length             uint32
+	SecurityDescriptor uintptr
+	InheritHandle      uint32
+}
+
+type Overlapped struct {
+	Internal     uintptr
+	InternalHigh uintptr
+	Offset       uint32
+	OffsetHigh   uint32
+	HEvent       Handle
+}
+
+type FileNotifyInformation struct {
+	NextEntryOffset uint32
+	Action          uint32
+	FileNameLength  uint32
+	FileName        uint16
+}
+
+type Filetime struct {
+	LowDateTime  uint32
+	HighDateTime uint32
+}
+
+// Nanoseconds returns Filetime ft in nanoseconds
+// since Epoch (00:00:00 UTC, January 1, 1970).
+func (ft *Filetime) Nanoseconds() int64 {
+	// 100-nanosecond intervals since January 1, 1601
+	nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
+	// change starting time to the Epoch (00:00:00 UTC, January 1, 1970)
+	nsec -= 116444736000000000
+	// convert into nanoseconds
+	nsec *= 100
+	return nsec
+}
+
+func NsecToFiletime(nsec int64) (ft Filetime) {
+	// convert into 100-nanosecond
+	nsec /= 100
+	// change starting time to January 1, 1601
+	nsec += 116444736000000000
+	// split into high / low
+	ft.LowDateTime = uint32(nsec & 0xffffffff)
+	ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff)
+	return ft
+}
+
+type Win32finddata struct {
+	FileAttributes    uint32
+	CreationTime      Filetime
+	LastAccessTime    Filetime
+	LastWriteTime     Filetime
+	FileSizeHigh      uint32
+	FileSizeLow       uint32
+	Reserved0         uint32
+	Reserved1         uint32
+	FileName          [MAX_PATH - 1]uint16
+	AlternateFileName [13]uint16
+}
+
+// This is the actual system call structure.
+// Win32finddata is what we committed to in Go 1.
+type win32finddata1 struct {
+	FileAttributes    uint32
+	CreationTime      Filetime
+	LastAccessTime    Filetime
+	LastWriteTime     Filetime
+	FileSizeHigh      uint32
+	FileSizeLow       uint32
+	Reserved0         uint32
+	Reserved1         uint32
+	FileName          [MAX_PATH]uint16
+	AlternateFileName [14]uint16
+}
+
+func copyFindData(dst *Win32finddata, src *win32finddata1) {
+	dst.FileAttributes = src.FileAttributes
+	dst.CreationTime = src.CreationTime
+	dst.LastAccessTime = src.LastAccessTime
+	dst.LastWriteTime = src.LastWriteTime
+	dst.FileSizeHigh = src.FileSizeHigh
+	dst.FileSizeLow = src.FileSizeLow
+	dst.Reserved0 = src.Reserved0
+	dst.Reserved1 = src.Reserved1
+
+	// The src is 1 element bigger than dst, but it must be NUL.
+	copy(dst.FileName[:], src.FileName[:])
+	copy(dst.AlternateFileName[:], src.AlternateFileName[:])
+}
+
+type ByHandleFileInformation struct {
+	FileAttributes     uint32
+	CreationTime       Filetime
+	LastAccessTime     Filetime
+	LastWriteTime      Filetime
+	VolumeSerialNumber uint32
+	FileSizeHigh       uint32
+	FileSizeLow        uint32
+	NumberOfLinks      uint32
+	FileIndexHigh      uint32
+	FileIndexLow       uint32
+}
+
+const (
+	GetFileExInfoStandard = 0
+	GetFileExMaxInfoLevel = 1
+)
+
+type Win32FileAttributeData struct {
+	FileAttributes uint32
+	CreationTime   Filetime
+	LastAccessTime Filetime
+	LastWriteTime  Filetime
+	FileSizeHigh   uint32
+	FileSizeLow    uint32
+}
+
+// ShowWindow constants
+const (
+	// winuser.h
+	SW_HIDE            = 0
+	SW_NORMAL          = 1
+	SW_SHOWNORMAL      = 1
+	SW_SHOWMINIMIZED   = 2
+	SW_SHOWMAXIMIZED   = 3
+	SW_MAXIMIZE        = 3
+	SW_SHOWNOACTIVATE  = 4
+	SW_SHOW            = 5
+	SW_MINIMIZE        = 6
+	SW_SHOWMINNOACTIVE = 7
+	SW_SHOWNA          = 8
+	SW_RESTORE         = 9
+	SW_SHOWDEFAULT     = 10
+	SW_FORCEMINIMIZE   = 11
+)
+
+type StartupInfo struct {
+	Cb            uint32
+	_             *uint16
+	Desktop       *uint16
+	Title         *uint16
+	X             uint32
+	Y             uint32
+	XSize         uint32
+	YSize         uint32
+	XCountChars   uint32
+	YCountChars   uint32
+	FillAttribute uint32
+	Flags         uint32
+	ShowWindow    uint16
+	_             uint16
+	_             *byte
+	StdInput      Handle
+	StdOutput     Handle
+	StdErr        Handle
+}
+
+type ProcessInformation struct {
+	Process   Handle
+	Thread    Handle
+	ProcessId uint32
+	ThreadId  uint32
+}
+
+type ProcessEntry32 struct {
+	Size            uint32
+	Usage           uint32
+	ProcessID       uint32
+	DefaultHeapID   uintptr
+	ModuleID        uint32
+	Threads         uint32
+	ParentProcessID uint32
+	PriClassBase    int32
+	Flags           uint32
+	ExeFile         [MAX_PATH]uint16
+}
+
+type Systemtime struct {
+	Year         uint16
+	Month        uint16
+	DayOfWeek    uint16
+	Day          uint16
+	Hour         uint16
+	Minute       uint16
+	Second       uint16
+	Milliseconds uint16
+}
+
+type Timezoneinformation struct {
+	Bias         int32
+	StandardName [32]uint16
+	StandardDate Systemtime
+	StandardBias int32
+	DaylightName [32]uint16
+	DaylightDate Systemtime
+	DaylightBias int32
+}
+
+// Socket related.
+
+const (
+	AF_UNSPEC  = 0
+	AF_UNIX    = 1
+	AF_INET    = 2
+	AF_INET6   = 23
+	AF_NETBIOS = 17
+
+	SOCK_STREAM    = 1
+	SOCK_DGRAM     = 2
+	SOCK_RAW       = 3
+	SOCK_SEQPACKET = 5
+
+	IPPROTO_IP   = 0
+	IPPROTO_IPV6 = 0x29
+	IPPROTO_TCP  = 6
+	IPPROTO_UDP  = 17
+
+	SOL_SOCKET                = 0xffff
+	SO_REUSEADDR              = 4
+	SO_KEEPALIVE              = 8
+	SO_DONTROUTE              = 16
+	SO_BROADCAST              = 32
+	SO_LINGER                 = 128
+	SO_RCVBUF                 = 0x1002
+	SO_SNDBUF                 = 0x1001
+	SO_UPDATE_ACCEPT_CONTEXT  = 0x700b
+	SO_UPDATE_CONNECT_CONTEXT = 0x7010
+
+	IOC_OUT                            = 0x40000000
+	IOC_IN                             = 0x80000000
+	IOC_VENDOR                         = 0x18000000
+	IOC_INOUT                          = IOC_IN | IOC_OUT
+	IOC_WS2                            = 0x08000000
+	SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
+	SIO_KEEPALIVE_VALS                 = IOC_IN | IOC_VENDOR | 4
+	SIO_UDP_CONNRESET                  = IOC_IN | IOC_VENDOR | 12
+
+	// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
+
+	IP_TOS             = 0x3
+	IP_TTL             = 0x4
+	IP_MULTICAST_IF    = 0x9
+	IP_MULTICAST_TTL   = 0xa
+	IP_MULTICAST_LOOP  = 0xb
+	IP_ADD_MEMBERSHIP  = 0xc
+	IP_DROP_MEMBERSHIP = 0xd
+
+	IPV6_V6ONLY         = 0x1b
+	IPV6_UNICAST_HOPS   = 0x4
+	IPV6_MULTICAST_IF   = 0x9
+	IPV6_MULTICAST_HOPS = 0xa
+	IPV6_MULTICAST_LOOP = 0xb
+	IPV6_JOIN_GROUP     = 0xc
+	IPV6_LEAVE_GROUP    = 0xd
+
+	SOMAXCONN = 0x7fffffff
+
+	TCP_NODELAY = 1
+
+	SHUT_RD   = 0
+	SHUT_WR   = 1
+	SHUT_RDWR = 2
+
+	WSADESCRIPTION_LEN = 256
+	WSASYS_STATUS_LEN  = 128
+)
+
+type WSABuf struct {
+	Len uint32
+	Buf *byte
+}
+
+// Invented values to support what package os expects.
+const (
+	S_IFMT   = 0x1f000
+	S_IFIFO  = 0x1000
+	S_IFCHR  = 0x2000
+	S_IFDIR  = 0x4000
+	S_IFBLK  = 0x6000
+	S_IFREG  = 0x8000
+	S_IFLNK  = 0xa000
+	S_IFSOCK = 0xc000
+	S_ISUID  = 0x800
+	S_ISGID  = 0x400
+	S_ISVTX  = 0x200
+	S_IRUSR  = 0x100
+	S_IWRITE = 0x80
+	S_IWUSR  = 0x80
+	S_IXUSR  = 0x40
+)
+
+const (
+	FILE_TYPE_CHAR    = 0x0002
+	FILE_TYPE_DISK    = 0x0001
+	FILE_TYPE_PIPE    = 0x0003
+	FILE_TYPE_REMOTE  = 0x8000
+	FILE_TYPE_UNKNOWN = 0x0000
+)
+
+type Hostent struct {
+	Name     *byte
+	Aliases  **byte
+	AddrType uint16
+	Length   uint16
+	AddrList **byte
+}
+
+type Protoent struct {
+	Name    *byte
+	Aliases **byte
+	Proto   uint16
+}
+
+const (
+	DNS_TYPE_A       = 0x0001
+	DNS_TYPE_NS      = 0x0002
+	DNS_TYPE_MD      = 0x0003
+	DNS_TYPE_MF      = 0x0004
+	DNS_TYPE_CNAME   = 0x0005
+	DNS_TYPE_SOA     = 0x0006
+	DNS_TYPE_MB      = 0x0007
+	DNS_TYPE_MG      = 0x0008
+	DNS_TYPE_MR      = 0x0009
+	DNS_TYPE_NULL    = 0x000a
+	DNS_TYPE_WKS     = 0x000b
+	DNS_TYPE_PTR     = 0x000c
+	DNS_TYPE_HINFO   = 0x000d
+	DNS_TYPE_MINFO   = 0x000e
+	DNS_TYPE_MX      = 0x000f
+	DNS_TYPE_TEXT    = 0x0010
+	DNS_TYPE_RP      = 0x0011
+	DNS_TYPE_AFSDB   = 0x0012
+	DNS_TYPE_X25     = 0x0013
+	DNS_TYPE_ISDN    = 0x0014
+	DNS_TYPE_RT      = 0x0015
+	DNS_TYPE_NSAP    = 0x0016
+	DNS_TYPE_NSAPPTR = 0x0017
+	DNS_TYPE_SIG     = 0x0018
+	DNS_TYPE_KEY     = 0x0019
+	DNS_TYPE_PX      = 0x001a
+	DNS_TYPE_GPOS    = 0x001b
+	DNS_TYPE_AAAA    = 0x001c
+	DNS_TYPE_LOC     = 0x001d
+	DNS_TYPE_NXT     = 0x001e
+	DNS_TYPE_EID     = 0x001f
+	DNS_TYPE_NIMLOC  = 0x0020
+	DNS_TYPE_SRV     = 0x0021
+	DNS_TYPE_ATMA    = 0x0022
+	DNS_TYPE_NAPTR   = 0x0023
+	DNS_TYPE_KX      = 0x0024
+	DNS_TYPE_CERT    = 0x0025
+	DNS_TYPE_A6      = 0x0026
+	DNS_TYPE_DNAME   = 0x0027
+	DNS_TYPE_SINK    = 0x0028
+	DNS_TYPE_OPT     = 0x0029
+	DNS_TYPE_DS      = 0x002B
+	DNS_TYPE_RRSIG   = 0x002E
+	DNS_TYPE_NSEC    = 0x002F
+	DNS_TYPE_DNSKEY  = 0x0030
+	DNS_TYPE_DHCID   = 0x0031
+	DNS_TYPE_UINFO   = 0x0064
+	DNS_TYPE_UID     = 0x0065
+	DNS_TYPE_GID     = 0x0066
+	DNS_TYPE_UNSPEC  = 0x0067
+	DNS_TYPE_ADDRS   = 0x00f8
+	DNS_TYPE_TKEY    = 0x00f9
+	DNS_TYPE_TSIG    = 0x00fa
+	DNS_TYPE_IXFR    = 0x00fb
+	DNS_TYPE_AXFR    = 0x00fc
+	DNS_TYPE_MAILB   = 0x00fd
+	DNS_TYPE_MAILA   = 0x00fe
+	DNS_TYPE_ALL     = 0x00ff
+	DNS_TYPE_ANY     = 0x00ff
+	DNS_TYPE_WINS    = 0xff01
+	DNS_TYPE_WINSR   = 0xff02
+	DNS_TYPE_NBSTAT  = 0xff01
+)
+
+const (
+	DNS_INFO_NO_RECORDS = 0x251D
+)
+
+const (
+	// flags inside DNSRecord.Dw
+	DnsSectionQuestion   = 0x0000
+	DnsSectionAnswer     = 0x0001
+	DnsSectionAuthority  = 0x0002
+	DnsSectionAdditional = 0x0003
+)
+
+type DNSSRVData struct {
+	Target   *uint16
+	Priority uint16
+	Weight   uint16
+	Port     uint16
+	Pad      uint16
+}
+
+type DNSPTRData struct {
+	Host *uint16
+}
+
+type DNSMXData struct {
+	NameExchange *uint16
+	Preference   uint16
+	Pad          uint16
+}
+
+type DNSTXTData struct {
+	StringCount uint16
+	StringArray [1]*uint16
+}
+
+type DNSRecord struct {
+	Next     *DNSRecord
+	Name     *uint16
+	Type     uint16
+	Length   uint16
+	Dw       uint32
+	Ttl      uint32
+	Reserved uint32
+	Data     [40]byte
+}
+
+const (
+	TF_DISCONNECT         = 1
+	TF_REUSE_SOCKET       = 2
+	TF_WRITE_BEHIND       = 4
+	TF_USE_DEFAULT_WORKER = 0
+	TF_USE_SYSTEM_THREAD  = 16
+	TF_USE_KERNEL_APC     = 32
+)
+
+type TransmitFileBuffers struct {
+	Head       uintptr
+	HeadLength uint32
+	Tail       uintptr
+	TailLength uint32
+}
+
+const (
+	IFF_UP           = 1
+	IFF_BROADCAST    = 2
+	IFF_LOOPBACK     = 4
+	IFF_POINTTOPOINT = 8
+	IFF_MULTICAST    = 16
+)
+
+const SIO_GET_INTERFACE_LIST = 0x4004747F
+
+// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old.
+// will be fixed to change variable type as suitable.
+
+type SockaddrGen [24]byte
+
+type InterfaceInfo struct {
+	Flags            uint32
+	Address          SockaddrGen
+	BroadcastAddress SockaddrGen
+	Netmask          SockaddrGen
+}
+
+type IpAddressString struct {
+	String [16]byte
+}
+
+type IpMaskString IpAddressString
+
+type IpAddrString struct {
+	Next      *IpAddrString
+	IpAddress IpAddressString
+	IpMask    IpMaskString
+	Context   uint32
+}
+
+const MAX_ADAPTER_NAME_LENGTH = 256
+const MAX_ADAPTER_DESCRIPTION_LENGTH = 128
+const MAX_ADAPTER_ADDRESS_LENGTH = 8
+
+type IpAdapterInfo struct {
+	Next                *IpAdapterInfo
+	ComboIndex          uint32
+	AdapterName         [MAX_ADAPTER_NAME_LENGTH + 4]byte
+	Description         [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte
+	AddressLength       uint32
+	Address             [MAX_ADAPTER_ADDRESS_LENGTH]byte
+	Index               uint32
+	Type                uint32
+	DhcpEnabled         uint32
+	CurrentIpAddress    *IpAddrString
+	IpAddressList       IpAddrString
+	GatewayList         IpAddrString
+	DhcpServer          IpAddrString
+	HaveWins            bool
+	PrimaryWinsServer   IpAddrString
+	SecondaryWinsServer IpAddrString
+	LeaseObtained       int64
+	LeaseExpires        int64
+}
+
+const MAXLEN_PHYSADDR = 8
+const MAX_INTERFACE_NAME_LEN = 256
+const MAXLEN_IFDESCR = 256
+
+type MibIfRow struct {
+	Name            [MAX_INTERFACE_NAME_LEN]uint16
+	Index           uint32
+	Type            uint32
+	Mtu             uint32
+	Speed           uint32
+	PhysAddrLen     uint32
+	PhysAddr        [MAXLEN_PHYSADDR]byte
+	AdminStatus     uint32
+	OperStatus      uint32
+	LastChange      uint32
+	InOctets        uint32
+	InUcastPkts     uint32
+	InNUcastPkts    uint32
+	InDiscards      uint32
+	InErrors        uint32
+	InUnknownProtos uint32
+	OutOctets       uint32
+	OutUcastPkts    uint32
+	OutNUcastPkts   uint32
+	OutDiscards     uint32
+	OutErrors       uint32
+	OutQLen         uint32
+	DescrLen        uint32
+	Descr           [MAXLEN_IFDESCR]byte
+}
+
+type CertContext struct {
+	EncodingType uint32
+	EncodedCert  *byte
+	Length       uint32
+	CertInfo     uintptr
+	Store        Handle
+}
+
+type CertChainContext struct {
+	Size                       uint32
+	TrustStatus                CertTrustStatus
+	ChainCount                 uint32
+	Chains                     **CertSimpleChain
+	LowerQualityChainCount     uint32
+	LowerQualityChains         **CertChainContext
+	HasRevocationFreshnessTime uint32
+	RevocationFreshnessTime    uint32
+}
+
+type CertSimpleChain struct {
+	Size                       uint32
+	TrustStatus                CertTrustStatus
+	NumElements                uint32
+	Elements                   **CertChainElement
+	TrustListInfo              uintptr
+	HasRevocationFreshnessTime uint32
+	RevocationFreshnessTime    uint32
+}
+
+type CertChainElement struct {
+	Size              uint32
+	CertContext       *CertContext
+	TrustStatus       CertTrustStatus
+	RevocationInfo    *CertRevocationInfo
+	IssuanceUsage     *CertEnhKeyUsage
+	ApplicationUsage  *CertEnhKeyUsage
+	ExtendedErrorInfo *uint16
+}
+
+type CertRevocationInfo struct {
+	Size             uint32
+	RevocationResult uint32
+	RevocationOid    *byte
+	OidSpecificInfo  uintptr
+	HasFreshnessTime uint32
+	FreshnessTime    uint32
+	CrlInfo          uintptr // *CertRevocationCrlInfo
+}
+
+type CertTrustStatus struct {
+	ErrorStatus uint32
+	InfoStatus  uint32
+}
+
+type CertUsageMatch struct {
+	Type  uint32
+	Usage CertEnhKeyUsage
+}
+
+type CertEnhKeyUsage struct {
+	Length           uint32
+	UsageIdentifiers **byte
+}
+
+type CertChainPara struct {
+	Size                         uint32
+	RequestedUsage               CertUsageMatch
+	RequstedIssuancePolicy       CertUsageMatch
+	URLRetrievalTimeout          uint32
+	CheckRevocationFreshnessTime uint32
+	RevocationFreshnessTime      uint32
+	CacheResync                  *Filetime
+}
+
+type CertChainPolicyPara struct {
+	Size            uint32
+	Flags           uint32
+	ExtraPolicyPara uintptr
+}
+
+type SSLExtraCertChainPolicyPara struct {
+	Size       uint32
+	AuthType   uint32
+	Checks     uint32
+	ServerName *uint16
+}
+
+type CertChainPolicyStatus struct {
+	Size              uint32
+	Error             uint32
+	ChainIndex        uint32
+	ElementIndex      uint32
+	ExtraPolicyStatus uintptr
+}
+
+const (
+	// do not reorder
+	HKEY_CLASSES_ROOT = 0x80000000 + iota
+	HKEY_CURRENT_USER
+	HKEY_LOCAL_MACHINE
+	HKEY_USERS
+	HKEY_PERFORMANCE_DATA
+	HKEY_CURRENT_CONFIG
+	HKEY_DYN_DATA
+
+	KEY_QUERY_VALUE        = 1
+	KEY_SET_VALUE          = 2
+	KEY_CREATE_SUB_KEY     = 4
+	KEY_ENUMERATE_SUB_KEYS = 8
+	KEY_NOTIFY             = 16
+	KEY_CREATE_LINK        = 32
+	KEY_WRITE              = 0x20006
+	KEY_EXECUTE            = 0x20019
+	KEY_READ               = 0x20019
+	KEY_WOW64_64KEY        = 0x0100
+	KEY_WOW64_32KEY        = 0x0200
+	KEY_ALL_ACCESS         = 0xf003f
+)
+
+const (
+	// do not reorder
+	REG_NONE = iota
+	REG_SZ
+	REG_EXPAND_SZ
+	REG_BINARY
+	REG_DWORD_LITTLE_ENDIAN
+	REG_DWORD_BIG_ENDIAN
+	REG_LINK
+	REG_MULTI_SZ
+	REG_RESOURCE_LIST
+	REG_FULL_RESOURCE_DESCRIPTOR
+	REG_RESOURCE_REQUIREMENTS_LIST
+	REG_QWORD_LITTLE_ENDIAN
+	REG_DWORD = REG_DWORD_LITTLE_ENDIAN
+	REG_QWORD = REG_QWORD_LITTLE_ENDIAN
+)
+
+type AddrinfoW struct {
+	Flags     int32
+	Family    int32
+	Socktype  int32
+	Protocol  int32
+	Addrlen   uintptr
+	Canonname *uint16
+	Addr      uintptr
+	Next      *AddrinfoW
+}
+
+const (
+	AI_PASSIVE     = 1
+	AI_CANONNAME   = 2
+	AI_NUMERICHOST = 4
+)
+
+type GUID struct {
+	Data1 uint32
+	Data2 uint16
+	Data3 uint16
+	Data4 [8]byte
+}
+
+var WSAID_CONNECTEX = GUID{
+	0x25a207b9,
+	0xddf3,
+	0x4660,
+	[8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
+}
+
+const (
+	FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
+	FILE_SKIP_SET_EVENT_ON_HANDLE        = 2
+)
+
+const (
+	WSAPROTOCOL_LEN    = 255
+	MAX_PROTOCOL_CHAIN = 7
+	BASE_PROTOCOL      = 1
+	LAYERED_PROTOCOL   = 0
+
+	XP1_CONNECTIONLESS           = 0x00000001
+	XP1_GUARANTEED_DELIVERY      = 0x00000002
+	XP1_GUARANTEED_ORDER         = 0x00000004
+	XP1_MESSAGE_ORIENTED         = 0x00000008
+	XP1_PSEUDO_STREAM            = 0x00000010
+	XP1_GRACEFUL_CLOSE           = 0x00000020
+	XP1_EXPEDITED_DATA           = 0x00000040
+	XP1_CONNECT_DATA             = 0x00000080
+	XP1_DISCONNECT_DATA          = 0x00000100
+	XP1_SUPPORT_BROADCAST        = 0x00000200
+	XP1_SUPPORT_MULTIPOINT       = 0x00000400
+	XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800
+	XP1_MULTIPOINT_DATA_PLANE    = 0x00001000
+	XP1_QOS_SUPPORTED            = 0x00002000
+	XP1_UNI_SEND                 = 0x00008000
+	XP1_UNI_RECV                 = 0x00010000
+	XP1_IFS_HANDLES              = 0x00020000
+	XP1_PARTIAL_MESSAGE          = 0x00040000
+	XP1_SAN_SUPPORT_SDP          = 0x00080000
+
+	PFL_MULTIPLE_PROTO_ENTRIES  = 0x00000001
+	PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002
+	PFL_HIDDEN                  = 0x00000004
+	PFL_MATCHES_PROTOCOL_ZERO   = 0x00000008
+	PFL_NETWORKDIRECT_PROVIDER  = 0x00000010
+)
+
+type WSAProtocolInfo struct {
+	ServiceFlags1     uint32
+	ServiceFlags2     uint32
+	ServiceFlags3     uint32
+	ServiceFlags4     uint32
+	ProviderFlags     uint32
+	ProviderId        GUID
+	CatalogEntryId    uint32
+	ProtocolChain     WSAProtocolChain
+	Version           int32
+	AddressFamily     int32
+	MaxSockAddr       int32
+	MinSockAddr       int32
+	SocketType        int32
+	Protocol          int32
+	ProtocolMaxOffset int32
+	NetworkByteOrder  int32
+	SecurityScheme    int32
+	MessageSize       uint32
+	ProviderReserved  uint32
+	ProtocolName      [WSAPROTOCOL_LEN + 1]uint16
+}
+
+type WSAProtocolChain struct {
+	ChainLen     int32
+	ChainEntries [MAX_PROTOCOL_CHAIN]uint32
+}
+
+type TCPKeepalive struct {
+	OnOff    uint32
+	Time     uint32
+	Interval uint32
+}
+
+type symbolicLinkReparseBuffer struct {
+	SubstituteNameOffset uint16
+	SubstituteNameLength uint16
+	PrintNameOffset      uint16
+	PrintNameLength      uint16
+	Flags                uint32
+	PathBuffer           [1]uint16
+}
+
+type mountPointReparseBuffer struct {
+	SubstituteNameOffset uint16
+	SubstituteNameLength uint16
+	PrintNameOffset      uint16
+	PrintNameLength      uint16
+	PathBuffer           [1]uint16
+}
+
+type reparseDataBuffer struct {
+	ReparseTag        uint32
+	ReparseDataLength uint16
+	Reserved          uint16
+
+	// GenericReparseBuffer
+	reparseBuffer byte
+}
+
+const (
+	FSCTL_GET_REPARSE_POINT          = 0x900A8
+	MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
+	IO_REPARSE_TAG_MOUNT_POINT       = 0xA0000003
+	IO_REPARSE_TAG_SYMLINK           = 0xA000000C
+	SYMBOLIC_LINK_FLAG_DIRECTORY     = 0x1
+)
+
+const (
+	ComputerNameNetBIOS                   = 0
+	ComputerNameDnsHostname               = 1
+	ComputerNameDnsDomain                 = 2
+	ComputerNameDnsFullyQualified         = 3
+	ComputerNamePhysicalNetBIOS           = 4
+	ComputerNamePhysicalDnsHostname       = 5
+	ComputerNamePhysicalDnsDomain         = 6
+	ComputerNamePhysicalDnsFullyQualified = 7
+	ComputerNameMax                       = 8
+)
+
+const (
+	MOVEFILE_REPLACE_EXISTING      = 0x1
+	MOVEFILE_COPY_ALLOWED          = 0x2
+	MOVEFILE_DELAY_UNTIL_REBOOT    = 0x4
+	MOVEFILE_WRITE_THROUGH         = 0x8
+	MOVEFILE_CREATE_HARDLINK       = 0x10
+	MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
+)
+
+const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
+
+const (
+	IF_TYPE_OTHER              = 1
+	IF_TYPE_ETHERNET_CSMACD    = 6
+	IF_TYPE_ISO88025_TOKENRING = 9
+	IF_TYPE_PPP                = 23
+	IF_TYPE_SOFTWARE_LOOPBACK  = 24
+	IF_TYPE_ATM                = 37
+	IF_TYPE_IEEE80211          = 71
+	IF_TYPE_TUNNEL             = 131
+	IF_TYPE_IEEE1394           = 144
+)
+
+type SocketAddress struct {
+	Sockaddr       *syscall.RawSockaddrAny
+	SockaddrLength int32
+}
+
+type IpAdapterUnicastAddress struct {
+	Length             uint32
+	Flags              uint32
+	Next               *IpAdapterUnicastAddress
+	Address            SocketAddress
+	PrefixOrigin       int32
+	SuffixOrigin       int32
+	DadState           int32
+	ValidLifetime      uint32
+	PreferredLifetime  uint32
+	LeaseLifetime      uint32
+	OnLinkPrefixLength uint8
+}
+
+type IpAdapterAnycastAddress struct {
+	Length  uint32
+	Flags   uint32
+	Next    *IpAdapterAnycastAddress
+	Address SocketAddress
+}
+
+type IpAdapterMulticastAddress struct {
+	Length  uint32
+	Flags   uint32
+	Next    *IpAdapterMulticastAddress
+	Address SocketAddress
+}
+
+type IpAdapterDnsServerAdapter struct {
+	Length   uint32
+	Reserved uint32
+	Next     *IpAdapterDnsServerAdapter
+	Address  SocketAddress
+}
+
+type IpAdapterPrefix struct {
+	Length       uint32
+	Flags        uint32
+	Next         *IpAdapterPrefix
+	Address      SocketAddress
+	PrefixLength uint32
+}
+
+type IpAdapterAddresses struct {
+	Length                uint32
+	IfIndex               uint32
+	Next                  *IpAdapterAddresses
+	AdapterName           *byte
+	FirstUnicastAddress   *IpAdapterUnicastAddress
+	FirstAnycastAddress   *IpAdapterAnycastAddress
+	FirstMulticastAddress *IpAdapterMulticastAddress
+	FirstDnsServerAddress *IpAdapterDnsServerAdapter
+	DnsSuffix             *uint16
+	Description           *uint16
+	FriendlyName          *uint16
+	PhysicalAddress       [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
+	PhysicalAddressLength uint32
+	Flags                 uint32
+	Mtu                   uint32
+	IfType                uint32
+	OperStatus            uint32
+	Ipv6IfIndex           uint32
+	ZoneIndices           [16]uint32
+	FirstPrefix           *IpAdapterPrefix
+	/* more fields might be present here. */
+}
+
+const (
+	IfOperStatusUp             = 1
+	IfOperStatusDown           = 2
+	IfOperStatusTesting        = 3
+	IfOperStatusUnknown        = 4
+	IfOperStatusDormant        = 5
+	IfOperStatusNotPresent     = 6
+	IfOperStatusLowerLayerDown = 7
+)

+ 22 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/ztypes_windows_386.go

@@ -0,0 +1,22 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+type WSAData struct {
+	Version      uint16
+	HighVersion  uint16
+	Description  [WSADESCRIPTION_LEN + 1]byte
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
+	MaxSockets   uint16
+	MaxUdpDg     uint16
+	VendorInfo   *byte
+}
+
+type Servent struct {
+	Name    *byte
+	Aliases **byte
+	Port    uint16
+	Proto   *byte
+}

+ 22 - 0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/windows/ztypes_windows_amd64.go

@@ -0,0 +1,22 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+type WSAData struct {
+	Version      uint16
+	HighVersion  uint16
+	MaxSockets   uint16
+	MaxUdpDg     uint16
+	VendorInfo   *byte
+	Description  [WSADESCRIPTION_LEN + 1]byte
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
+}
+
+type Servent struct {
+	Name    *byte
+	Aliases **byte
+	Proto   *byte
+	Port    uint16
+}

+ 2 - 0
libnetwork/controller.go

@@ -804,6 +804,8 @@ func (c *controller) addNetwork(n *network) error {
 		return err
 	}
 
+	n.startResolver()
+
 	return nil
 }
 

+ 15 - 0
libnetwork/drivers/windows/labels.go

@@ -15,4 +15,19 @@ const (
 
 	// QosPolicies of the endpoint
 	QosPolicies = "com.docker.endpoint.windowsshim.qospolicies"
+
+	// VLAN of the network
+	VLAN = "com.docker.network.windowsshim.vlanid"
+
+	// VSID of the network
+	VSID = "com.docker.network.windowsshim.vsid"
+
+	// DNSSuffix of the network
+	DNSSuffix = "com.docker.network.windowsshim.dnssuffix"
+
+	// DNSServers of the network
+	DNSServers = "com.docker.network.windowsshim.dnsservers"
+
+	// SourceMac of the network
+	SourceMac = "com.docker.network.windowsshim.sourcemac"
 )

+ 69 - 1
libnetwork/drivers/windows/windows.go

@@ -15,6 +15,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"net"
+	"strconv"
 	"strings"
 	"sync"
 
@@ -34,6 +35,11 @@ type networkConfiguration struct {
 	Name               string
 	HnsID              string
 	RDID               string
+	VLAN               uint
+	VSID               uint
+	DNSServers         string
+	DNSSuffix          string
+	SourceMac          string
 	NetworkAdapterName string
 }
 
@@ -43,6 +49,7 @@ type endpointConfiguration struct {
 	PortBindings []types.PortBinding
 	ExposedPorts []types.TransportPort
 	QosPolicies  []types.QosPolicy
+	DNSServers   []string
 }
 
 type hnsEndpoint struct {
@@ -69,7 +76,7 @@ type driver struct {
 }
 
 func isValidNetworkType(networkType string) bool {
-	if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "transparent" == networkType {
+	if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "ics" == networkType || "transparent" == networkType {
 		return true
 	}
 
@@ -129,6 +136,22 @@ func (d *driver) parseNetworkOptions(id string, genericOptions map[string]string
 			config.RDID = value
 		case Interface:
 			config.NetworkAdapterName = value
+		case DNSSuffix:
+			config.DNSSuffix = value
+		case DNSServers:
+			config.DNSServers = value
+		case VLAN:
+			vlan, err := strconv.ParseUint(value, 10, 32)
+			if err != nil {
+				return nil, err
+			}
+			config.VLAN = uint(vlan)
+		case VSID:
+			vsid, err := strconv.ParseUint(value, 10, 32)
+			if err != nil {
+				return nil, err
+			}
+			config.VSID = uint(vsid)
 		}
 	}
 
@@ -207,9 +230,36 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
 			Name:               config.Name,
 			Type:               d.name,
 			Subnets:            subnets,
+			DNSServerList:      config.DNSServers,
+			DNSSuffix:          config.DNSSuffix,
+			SourceMac:          config.SourceMac,
 			NetworkAdapterName: config.NetworkAdapterName,
 		}
 
+		if config.VLAN != 0 {
+			vlanPolicy, err := json.Marshal(hcsshim.VlanPolicy{
+				Type: "VLAN",
+				VLAN: config.VLAN,
+			})
+
+			if err != nil {
+				return err
+			}
+			network.Policies = append(network.Policies, vlanPolicy)
+		}
+
+		if config.VSID != 0 {
+			vsidPolicy, err := json.Marshal(hcsshim.VsidPolicy{
+				Type: "VSID",
+				VSID: config.VSID,
+			})
+
+			if err != nil {
+				return err
+			}
+			network.Policies = append(network.Policies, vsidPolicy)
+		}
+
 		if network.Name == "" {
 			network.Name = id
 		}
@@ -379,6 +429,14 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfigurat
 		}
 	}
 
+	if opt, ok := epOptions[netlabel.DNSServers]; ok {
+		if dns, ok := opt.([]string); ok {
+			ec.DNSServers = dns
+		} else {
+			return nil, fmt.Errorf("Invalid endpoint configuration")
+		}
+	}
+
 	return ec, nil
 }
 
@@ -421,6 +479,12 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
 		endpointStruct.IPAddress = ifInfo.Address().IP
 	}
 
+	endpointStruct.DNSServerList = strings.Join(ec.DNSServers, ",")
+
+	if n.driver.name == "nat" {
+		endpointStruct.EnableInternalDNS = true
+	}
+
 	configurationb, err := json.Marshal(endpointStruct)
 	if err != nil {
 		return err
@@ -502,6 +566,10 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro
 	}
 
 	data := make(map[string]interface{}, 1)
+	if network.driver.name == "nat" {
+		data["AllowUnqualifiedDNSQuery"] = true
+	}
+
 	data["hnsid"] = ep.profileID
 	if ep.config.ExposedPorts != nil {
 		// Return a copy of the config data

+ 1 - 1
libnetwork/drivers/windows/windows_test.go

@@ -29,7 +29,7 @@ func testNetwork(networkType string, t *testing.T) {
 		},
 	}
 
-	err := d.CreateNetwork("dummy", netOption, ipdList, nil)
+	err := d.CreateNetwork("dummy", netOption, nil, ipdList, nil)
 	if err != nil {
 		t.Fatalf("Failed to create bridge: %v", err)
 	}

+ 8 - 0
libnetwork/endpoint.go

@@ -883,6 +883,14 @@ func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption {
 	}
 }
 
+// CreateOptionDNS function returns an option setter for dns entry option to
+// be passed to container Create method.
+func CreateOptionDNS(dns []string) EndpointOption {
+	return func(ep *endpoint) {
+		ep.generic[netlabel.DNSServers] = dns
+	}
+}
+
 // CreateOptionAnonymous function returns an option setter for setting
 // this endpoint as anonymous
 func CreateOptionAnonymous() EndpointOption {

+ 5 - 9
libnetwork/libnetwork_internal_test.go

@@ -389,10 +389,8 @@ func TestSRVServiceQuery(t *testing.T) {
 
 	c.(*controller).svcRecords[n.ID()] = sr
 
-	_, ip, err := ep.Info().Sandbox().ResolveService("_http._tcp.web.swarm")
-	if err != nil {
-		t.Fatal(err)
-	}
+	_, ip := ep.Info().Sandbox().ResolveService("_http._tcp.web.swarm")
+
 	if len(ip) == 0 {
 		t.Fatal(err)
 	}
@@ -400,10 +398,8 @@ func TestSRVServiceQuery(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	_, ip, err = ep.Info().Sandbox().ResolveService("_host_http._tcp.web.swarm")
-	if err != nil {
-		t.Fatal(err)
-	}
+	_, ip = ep.Info().Sandbox().ResolveService("_host_http._tcp.web.swarm")
+
 	if len(ip) == 0 {
 		t.Fatal(err)
 	}
@@ -412,7 +408,7 @@ func TestSRVServiceQuery(t *testing.T) {
 	}
 
 	// Service name with invalid protocol name. Should fail without error
-	_, ip, err = ep.Info().Sandbox().ResolveService("_http._icmp.web.swarm")
+	_, ip = ep.Info().Sandbox().ResolveService("_http._icmp.web.swarm")
 	if len(ip) != 0 {
 		t.Fatal("Valid response for invalid service name")
 	}

+ 2 - 2
libnetwork/libnetwork_test.go

@@ -1208,8 +1208,8 @@ func (f *fakeSandbox) ResolveIP(ip string) string {
 	return ""
 }
 
-func (f *fakeSandbox) ResolveService(name string) ([]*net.SRV, []net.IP, error) {
-	return nil, nil, nil
+func (f *fakeSandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
+	return nil, nil
 }
 
 func (f *fakeSandbox) Endpoints() []libnetwork.Endpoint {

+ 3 - 0
libnetwork/netlabel/labels.go

@@ -27,6 +27,9 @@ const (
 	// ExposedPorts constant represents the container's Exposed Ports
 	ExposedPorts = Prefix + ".endpoint.exposedports"
 
+	// DNSServers A list of DNS servers associated with the endpoint
+	DNSServers = Prefix + ".endpoint.dnsservers"
+
 	//EnableIPv6 constant represents enabling IPV6 at network level
 	EnableIPv6 = Prefix + ".enable_ipv6"
 

+ 128 - 0
libnetwork/network.go

@@ -184,6 +184,8 @@ type network struct {
 	persist      bool
 	stopWatchCh  chan struct{}
 	drvOnce      *sync.Once
+	resolverOnce sync.Once
+	resolver     []Resolver
 	internal     bool
 	inDelete     bool
 	ingress      bool
@@ -803,6 +805,9 @@ func (n *network) deleteNetwork() error {
 		}
 	}
 
+	for _, resolver := range n.resolver {
+		resolver.Stop()
+	}
 	return nil
 }
 
@@ -1528,3 +1533,126 @@ func (n *network) TableEventRegister(tableName string) error {
 func (n *network) hasSpecialDriver() bool {
 	return n.Type() == "host" || n.Type() == "null"
 }
+
+func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) {
+	var ipv6Miss bool
+
+	c := n.getController()
+	c.Lock()
+	sr, ok := c.svcRecords[n.ID()]
+	c.Unlock()
+
+	if !ok {
+		return nil, false
+	}
+
+	req = strings.TrimSuffix(req, ".")
+	var ip []net.IP
+	n.Lock()
+	ip, ok = sr.svcMap[req]
+
+	if ipType == types.IPv6 {
+		// If the name resolved to v4 address then its a valid name in
+		// the docker network domain. If the network is not v6 enabled
+		// set ipv6Miss to filter the DNS query from going to external
+		// resolvers.
+		if ok && n.enableIPv6 == false {
+			ipv6Miss = true
+		}
+		ip = sr.svcIPv6Map[req]
+	}
+	n.Unlock()
+
+	if ip != nil {
+		return ip, false
+	}
+
+	return nil, ipv6Miss
+}
+
+func (n *network) ResolveIP(ip string) string {
+	var svc string
+
+	c := n.getController()
+	c.Lock()
+	sr, ok := c.svcRecords[n.ID()]
+	c.Unlock()
+
+	if !ok {
+		return ""
+	}
+
+	nwName := n.Name()
+
+	n.Lock()
+	defer n.Unlock()
+	svc, ok = sr.ipMap[ip]
+
+	if ok {
+		return svc + "." + nwName
+	}
+
+	return svc
+}
+
+func (n *network) ResolveService(name string) ([]*net.SRV, []net.IP) {
+	c := n.getController()
+
+	srv := []*net.SRV{}
+	ip := []net.IP{}
+
+	log.Debugf("Service name To resolve: %v", name)
+
+	// There are DNS implementaions that allow SRV queries for names not in
+	// the format defined by RFC 2782. Hence specific validations checks are
+	// not done
+	parts := strings.Split(name, ".")
+	if len(parts) < 3 {
+		return nil, nil
+	}
+
+	portName := parts[0]
+	proto := parts[1]
+	svcName := strings.Join(parts[2:], ".")
+
+	c.Lock()
+	sr, ok := c.svcRecords[n.ID()]
+	c.Unlock()
+
+	if !ok {
+		return nil, nil
+	}
+
+	svcs, ok := sr.service[svcName]
+	if !ok {
+		return nil, nil
+	}
+
+	for _, svc := range svcs {
+		if svc.portName != portName {
+			continue
+		}
+		if svc.proto != proto {
+			continue
+		}
+		for _, t := range svc.target {
+			srv = append(srv,
+				&net.SRV{
+					Target: t.name,
+					Port:   t.port,
+				})
+
+			ip = append(ip, t.ip)
+		}
+	}
+
+	return srv, ip
+}
+
+func (n *network) ExecFunc(f func()) error {
+	return types.NotImplementedErrorf("ExecFunc not supported by network")
+}
+
+func (n *network) NdotsSet() bool {
+	return false
+}

+ 8 - 0
libnetwork/network_unix.go

@@ -0,0 +1,8 @@
+// +build !windows
+
+package libnetwork
+
+// Stub implementations for DNS related functions
+
+func (n *network) startResolver() {
+}

+ 52 - 0
libnetwork/network_windows.go

@@ -0,0 +1,52 @@
+// +build windows
+
+package libnetwork
+
+import (
+	"runtime"
+
+	"github.com/Microsoft/hcsshim"
+	log "github.com/Sirupsen/logrus"
+	"github.com/docker/libnetwork/drivers/windows"
+)
+
+func executeInCompartment(compartmentID uint32, x func()) {
+	runtime.LockOSThread()
+
+	if err := hcsshim.SetCurrentThreadCompartmentId(compartmentID); err != nil {
+		log.Error(err)
+	}
+	defer func() {
+		hcsshim.SetCurrentThreadCompartmentId(0)
+		runtime.UnlockOSThread()
+	}()
+
+	x()
+}
+
+func (n *network) startResolver() {
+	n.resolverOnce.Do(func() {
+		log.Debugf("Launching DNS server for network", n.Name())
+		options := n.Info().DriverOptions()
+		hnsid := options[windows.HNSID]
+
+		hnsresponse, err := hcsshim.HNSNetworkRequest("GET", hnsid, "")
+		if err != nil {
+			log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
+			return
+		}
+
+		for _, subnet := range hnsresponse.Subnets {
+			if subnet.GatewayAddress != "" {
+				resolver := NewResolver(subnet.GatewayAddress, false, "", n)
+				log.Debugf("Binding a resolver on network %s gateway %s", n.Name(), subnet.GatewayAddress)
+				executeInCompartment(hnsresponse.DNSServerCompartment, resolver.SetupFunc(53))
+				if err = resolver.Start(); err != nil {
+					log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
+				} else {
+					n.resolver = append(n.resolver, resolver)
+				}
+			}
+		}
+	})
+}

+ 72 - 32
libnetwork/resolver.go

@@ -23,7 +23,7 @@ type Resolver interface {
 	Stop()
 	// SetupFunc() provides the setup function that should be run
 	// in the container's network namespace.
-	SetupFunc() func()
+	SetupFunc(int) func()
 	// NameServer() returns the IP of the DNS resolver for the
 	// containers.
 	NameServer() string
@@ -34,8 +34,29 @@ type Resolver interface {
 	ResolverOptions() []string
 }
 
+// DNSBackend represents a backend DNS resolver used for DNS name
+// resolution. All the queries to the resolver are forwared to the
+// backend resolver.
+type DNSBackend interface {
+	// ResolveName resolves a service name to an IPv4 or IPv6 address by searching
+	// the networks the sandbox is connected to. For IPv6 queries, second return
+	// value will be true if the name exists in docker domain but doesn't have an
+	// IPv6 address. Such queries shouldn't be forwarded to external nameservers.
+	ResolveName(name string, iplen int) ([]net.IP, bool)
+	// ResolveIP returns the service name for the passed in IP. IP is in reverse dotted
+	// notation; the format used for DNS PTR records
+	ResolveIP(name string) string
+	// ResolveService returns all the backend details about the containers or hosts
+	// backing a service. Its purpose is to satisfy an SRV query
+	ResolveService(name string) ([]*net.SRV, []net.IP)
+	// ExecFunc allows a function to be executed in the context of the backend
+	// on behalf of the resolver.
+	ExecFunc(f func()) error
+	//NdotsSet queries the backends ndots dns option settings
+	NdotsSet() bool
+}
+
 const (
-	resolverIP      = "127.0.0.11"
 	dnsPort         = "53"
 	ptrIPv4domain   = ".in-addr.arpa."
 	ptrIPv6domain   = ".ip6.arpa."
@@ -53,16 +74,19 @@ type extDNSEntry struct {
 
 // resolver implements the Resolver interface
 type resolver struct {
-	sb         *sandbox
-	extDNSList [maxExtDNS]extDNSEntry
-	server     *dns.Server
-	conn       *net.UDPConn
-	tcpServer  *dns.Server
-	tcpListen  *net.TCPListener
-	err        error
-	count      int32
-	tStamp     time.Time
-	queryLock  sync.Mutex
+	backend       DNSBackend
+	extDNSList    [maxExtDNS]extDNSEntry
+	server        *dns.Server
+	conn          *net.UDPConn
+	tcpServer     *dns.Server
+	tcpListen     *net.TCPListener
+	err           error
+	count         int32
+	tStamp        time.Time
+	queryLock     sync.Mutex
+	listenAddress string
+	proxyDNS      bool
+	resolverKey   string
 }
 
 func init() {
@@ -70,20 +94,24 @@ func init() {
 }
 
 // NewResolver creates a new instance of the Resolver
-func NewResolver(sb *sandbox) Resolver {
+func NewResolver(address string, proxyDNS bool, resolverKey string, backend DNSBackend) Resolver {
 	return &resolver{
-		sb:  sb,
-		err: fmt.Errorf("setup not done yet"),
+		backend:       backend,
+		proxyDNS:      proxyDNS,
+		listenAddress: address,
+		resolverKey:   resolverKey,
+		err:           fmt.Errorf("setup not done yet"),
 	}
 }
 
-func (r *resolver) SetupFunc() func() {
+func (r *resolver) SetupFunc(port int) func() {
 	return (func() {
 		var err error
 
 		// DNS operates primarily on UDP
 		addr := &net.UDPAddr{
-			IP: net.ParseIP(resolverIP),
+			IP:   net.ParseIP(r.listenAddress),
+			Port: port,
 		}
 
 		r.conn, err = net.ListenUDP("udp", addr)
@@ -94,7 +122,8 @@ func (r *resolver) SetupFunc() func() {
 
 		// Listen on a TCP as well
 		tcpaddr := &net.TCPAddr{
-			IP: net.ParseIP(resolverIP),
+			IP:   net.ParseIP(r.listenAddress),
+			Port: port,
 		}
 
 		r.tcpListen, err = net.ListenTCP("tcp", tcpaddr)
@@ -156,7 +185,7 @@ func (r *resolver) SetExtServers(dns []string) {
 }
 
 func (r *resolver) NameServer() string {
-	return resolverIP
+	return r.listenAddress
 }
 
 func (r *resolver) ResolverOptions() []string {
@@ -184,7 +213,10 @@ func createRespMsg(query *dns.Msg) *dns.Msg {
 }
 
 func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns.Msg, error) {
-	addr, ipv6Miss := r.sb.ResolveName(name, ipType)
+	var addr []net.IP
+	var ipv6Miss bool
+	addr, ipv6Miss = r.backend.ResolveName(name, ipType)
+
 	if addr == nil && ipv6Miss {
 		// Send a reply without any Answer sections
 		log.Debugf("Lookup name %s present without IPv6 address", name)
@@ -230,7 +262,8 @@ func (r *resolver) handlePTRQuery(ptr string, query *dns.Msg) (*dns.Msg, error)
 		return nil, fmt.Errorf("invalid PTR query, %v", ptr)
 	}
 
-	host := r.sb.ResolveIP(parts[0])
+	host := r.backend.ResolveIP(parts[0])
+
 	if len(host) == 0 {
 		return nil, nil
 	}
@@ -250,11 +283,9 @@ func (r *resolver) handlePTRQuery(ptr string, query *dns.Msg) (*dns.Msg, error)
 }
 
 func (r *resolver) handleSRVQuery(svc string, query *dns.Msg) (*dns.Msg, error) {
-	srv, ip, err := r.sb.ResolveService(svc)
 
-	if err != nil {
-		return nil, err
-	}
+	srv, ip := r.backend.ResolveService(svc)
+
 	if len(srv) == 0 {
 		return nil, nil
 	}
@@ -325,16 +356,25 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
 		return
 	}
 
-	// If the user sets ndots > 0 explicitly and the query is
-	// in the root domain don't forward it out. We will return
-	// failure and let the client retry with the search domain
-	// attached
 	if resp == nil {
+		// If the backend doesn't support proxying dns request
+		// fail the response
+		if !r.proxyDNS {
+			resp = new(dns.Msg)
+			resp.SetRcode(query, dns.RcodeServerFailure)
+			w.WriteMsg(resp)
+			return
+		}
+
+		// If the user sets ndots > 0 explicitly and the query is
+		// in the root domain don't forward it out. We will return
+		// failure and let the client retry with the search domain
+		// attached
 		switch query.Question[0].Qtype {
 		case dns.TypeA:
 			fallthrough
 		case dns.TypeAAAA:
-			if r.sb.ndotsSet && !strings.Contains(strings.TrimSuffix(name, "."), ".") {
+			if r.backend.NdotsSet() && !strings.Contains(strings.TrimSuffix(name, "."), ".") {
 				resp = createRespMsg(query)
 			}
 		}
@@ -369,8 +409,8 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
 				extConn, err = net.DialTimeout(proto, addr, extIOTimeout)
 			}
 
-			r.sb.execFunc(extConnect)
-			if err != nil {
+			execErr := r.backend.ExecFunc(extConnect)
+			if execErr != nil || err != nil {
 				log.Debugf("Connect failed, %s", err)
 				continue
 			}

+ 2 - 2
libnetwork/resolver_unix.go

@@ -35,7 +35,7 @@ func reexecSetupResolver() {
 		os.Exit(1)
 	}
 
-	_, ipPort, _ := net.SplitHostPort(os.Args[2])
+	resolverIP, ipPort, _ := net.SplitHostPort(os.Args[2])
 	_, tcpPort, _ := net.SplitHostPort(os.Args[3])
 	rules := [][]string{
 		{"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[2]},
@@ -90,7 +90,7 @@ func (r *resolver) setupIPTable() error {
 
 	cmd := &exec.Cmd{
 		Path:   reexec.Self(),
-		Args:   append([]string{"setup-resolver"}, r.sb.Key(), laddr, ltcpaddr),
+		Args:   append([]string{"setup-resolver"}, r.resolverKey, laddr, ltcpaddr),
 		Stdout: os.Stdout,
 		Stderr: os.Stderr,
 	}

+ 27 - 92
libnetwork/sandbox.go

@@ -37,19 +37,11 @@ type Sandbox interface {
 	Rename(name string) error
 	// Delete destroys this container after detaching it from all connected endpoints.
 	Delete() error
-	// ResolveName resolves a service name to an IPv4 or IPv6 address by searching
-	// the networks the sandbox is connected to. For IPv6 queries, second return
-	// value will be true if the name exists in docker domain but doesn't have an
-	// IPv6 address. Such queries shouldn't be forwarded to external nameservers.
-	ResolveName(name string, iplen int) ([]net.IP, bool)
-	// ResolveIP returns the service name for the passed in IP. IP is in reverse dotted
-	// notation; the format used for DNS PTR records
-	ResolveIP(name string) string
-	// ResolveService returns all the backend details about the containers or hosts
-	// backing a service. Its purpose is to satisfy an SRV query
-	ResolveService(name string) ([]*net.SRV, []net.IP, error)
 	// Endpoints returns all the endpoints connected to the sandbox
 	Endpoints() []Endpoint
+	// ResolveService returns all the backend details about the containers or hosts
+	// backing a service. Its purpose is to satisfy an SRV query
+	ResolveService(name string) ([]*net.SRV, []net.IP)
 }
 
 // SandboxOption is an option setter function type used to pass various options to
@@ -131,6 +123,10 @@ type containerConfig struct {
 	exposedPorts      []types.TransportPort
 }
 
+const (
+	resolverIPSandbox = "127.0.0.11"
+)
+
 func (sb *sandbox) ID() string {
 	return sb.id
 }
@@ -415,33 +411,21 @@ func (sb *sandbox) ResolveIP(ip string) string {
 
 	for _, ep := range sb.getConnectedEndpoints() {
 		n := ep.getNetwork()
-
-		c := n.getController()
-
-		c.Lock()
-		sr, ok := c.svcRecords[n.ID()]
-		c.Unlock()
-
-		if !ok {
-			continue
-		}
-
-		nwName := n.Name()
-		n.Lock()
-		svc, ok = sr.ipMap[ip]
-		n.Unlock()
-		if ok {
-			return svc + "." + nwName
+		svc = n.ResolveIP(ip)
+		if len(svc) != 0 {
+			return svc
 		}
 	}
+
 	return svc
 }
 
-func (sb *sandbox) execFunc(f func()) {
+func (sb *sandbox) ExecFunc(f func()) error {
 	sb.osSbox.InvokeFunc(f)
+	return nil
 }
 
-func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP, error) {
+func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
 	srv := []*net.SRV{}
 	ip := []net.IP{}
 
@@ -452,53 +436,18 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP, error) {
 	// not done
 	parts := strings.Split(name, ".")
 	if len(parts) < 3 {
-		return nil, nil, nil
+		return nil, nil
 	}
 
-	portName := parts[0]
-	proto := parts[1]
-	svcName := strings.Join(parts[2:], ".")
-
 	for _, ep := range sb.getConnectedEndpoints() {
 		n := ep.getNetwork()
 
-		c := n.getController()
-
-		c.Lock()
-		sr, ok := c.svcRecords[n.ID()]
-		c.Unlock()
-
-		if !ok {
-			continue
-		}
-
-		svcs, ok := sr.service[svcName]
-		if !ok {
-			continue
-		}
-
-		for _, svc := range svcs {
-			if svc.portName != portName {
-				continue
-			}
-			if svc.proto != proto {
-				continue
-			}
-			for _, t := range svc.target {
-				srv = append(srv,
-					&net.SRV{
-						Target: t.name,
-						Port:   t.port,
-					})
-
-				ip = append(ip, t.ip)
-			}
-		}
+		srv, ip = n.ResolveService(name)
 		if len(srv) > 0 {
 			break
 		}
 	}
-	return srv, ip, nil
+	return srv, ip
 }
 
 func getDynamicNwEndpoints(epList []*endpoint) []*endpoint {
@@ -635,33 +584,15 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
 			ep.Unlock()
 		}
 
-		c := n.getController()
-		c.Lock()
-		sr, ok := c.svcRecords[n.ID()]
-		c.Unlock()
+		ip, miss := n.ResolveName(name, ipType)
 
-		if !ok {
-			continue
-		}
-
-		var ip []net.IP
-		n.Lock()
-		ip, ok = sr.svcMap[name]
-
-		if ipType == types.IPv6 {
-			// If the name resolved to v4 address then its a valid name in
-			// the docker network domain. If the network is not v6 enabled
-			// set ipv6Miss to filter the DNS query from going to external
-			// resolvers.
-			if ok && n.enableIPv6 == false {
-				ipv6Miss = true
-			}
-			ip = sr.svcIPv6Map[name]
-		}
-		n.Unlock()
 		if ip != nil {
 			return ip, false
 		}
+
+		if miss {
+			ipv6Miss = miss
+		}
 	}
 	return nil, ipv6Miss
 }
@@ -708,7 +639,7 @@ func (sb *sandbox) SetKey(basePath string) error {
 	if oldosSbox != nil && sb.resolver != nil {
 		sb.resolver.Stop()
 
-		sb.osSbox.InvokeFunc(sb.resolver.SetupFunc())
+		sb.osSbox.InvokeFunc(sb.resolver.SetupFunc(0))
 		if err := sb.resolver.Start(); err != nil {
 			log.Errorf("Resolver Setup/Start failed for container %s, %q", sb.ContainerID(), err)
 		}
@@ -1231,3 +1162,7 @@ func (eh *epHeap) Pop() interface{} {
 	*eh = old[0 : n-1]
 	return x
 }
+
+func (sb *sandbox) NdotsSet() bool {
+	return sb.ndotsSet
+}

+ 2 - 2
libnetwork/sandbox_dns_unix.go

@@ -26,7 +26,7 @@ const (
 func (sb *sandbox) startResolver(restore bool) {
 	sb.resolverOnce.Do(func() {
 		var err error
-		sb.resolver = NewResolver(sb)
+		sb.resolver = NewResolver(resolverIPSandbox, true, sb.Key(), sb)
 		defer func() {
 			if err != nil {
 				sb.resolver = nil
@@ -46,7 +46,7 @@ func (sb *sandbox) startResolver(restore bool) {
 		}
 		sb.resolver.SetExtServers(sb.extDNS)
 
-		sb.osSbox.InvokeFunc(sb.resolver.SetupFunc())
+		sb.osSbox.InvokeFunc(sb.resolver.SetupFunc(0))
 		if err = sb.resolver.Start(); err != nil {
 			log.Errorf("Resolver Setup/Start failed for container %s, %q", sb.ContainerID(), err)
 		}