github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/pkg/system/syscall_windows.go (about) 1 package system // import "github.com/docker/docker/pkg/system" 2 3 import ( 4 "fmt" 5 "syscall" 6 "unsafe" 7 8 "github.com/sirupsen/logrus" 9 "golang.org/x/sys/windows" 10 ) 11 12 const ( 13 OWNER_SECURITY_INFORMATION = 0x00000001 14 GROUP_SECURITY_INFORMATION = 0x00000002 15 DACL_SECURITY_INFORMATION = 0x00000004 16 SACL_SECURITY_INFORMATION = 0x00000008 17 LABEL_SECURITY_INFORMATION = 0x00000010 18 ATTRIBUTE_SECURITY_INFORMATION = 0x00000020 19 SCOPE_SECURITY_INFORMATION = 0x00000040 20 PROCESS_TRUST_LABEL_SECURITY_INFORMATION = 0x00000080 21 ACCESS_FILTER_SECURITY_INFORMATION = 0x00000100 22 BACKUP_SECURITY_INFORMATION = 0x00010000 23 PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000 24 PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000 25 UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000 26 UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000 27 ) 28 29 const ( 30 SE_UNKNOWN_OBJECT_TYPE = iota 31 SE_FILE_OBJECT 32 SE_SERVICE 33 SE_PRINTER 34 SE_REGISTRY_KEY 35 SE_LMSHARE 36 SE_KERNEL_OBJECT 37 SE_WINDOW_OBJECT 38 SE_DS_OBJECT 39 SE_DS_OBJECT_ALL 40 SE_PROVIDER_DEFINED_OBJECT 41 SE_WMIGUID_OBJECT 42 SE_REGISTRY_WOW64_32KEY 43 ) 44 45 const ( 46 SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege" 47 ) 48 49 const ( 50 ContainerAdministratorSidString = "S-1-5-93-2-1" 51 ContainerUserSidString = "S-1-5-93-2-2" 52 ) 53 54 var ( 55 ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0") 56 modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") 57 procGetVersionExW = modkernel32.NewProc("GetVersionExW") 58 procGetProductInfo = modkernel32.NewProc("GetProductInfo") 59 procSetNamedSecurityInfo = modadvapi32.NewProc("SetNamedSecurityInfoW") 60 procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl") 61 ) 62 63 // OSVersion is a wrapper for Windows version information 64 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx 65 type OSVersion struct { 66 Version uint32 67 MajorVersion uint8 68 MinorVersion uint8 69 Build uint16 70 } 71 72 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx 73 type osVersionInfoEx struct { 74 OSVersionInfoSize uint32 75 MajorVersion uint32 76 MinorVersion uint32 77 BuildNumber uint32 78 PlatformID uint32 79 CSDVersion [128]uint16 80 ServicePackMajor uint16 81 ServicePackMinor uint16 82 SuiteMask uint16 83 ProductType byte 84 Reserve byte 85 } 86 87 // GetOSVersion gets the operating system version on Windows. Note that 88 // docker.exe must be manifested to get the correct version information. 89 func GetOSVersion() OSVersion { 90 var err error 91 osv := OSVersion{} 92 osv.Version, err = windows.GetVersion() 93 if err != nil { 94 // GetVersion never fails. 95 panic(err) 96 } 97 osv.MajorVersion = uint8(osv.Version & 0xFF) 98 osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) 99 osv.Build = uint16(osv.Version >> 16) 100 return osv 101 } 102 103 func (osv OSVersion) ToString() string { 104 return fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.Build) 105 } 106 107 // IsWindowsClient returns true if the SKU is client 108 // @engine maintainers - this function should not be removed or modified as it 109 // is used to enforce licensing restrictions on Windows. 110 func IsWindowsClient() bool { 111 osviex := &osVersionInfoEx{OSVersionInfoSize: 284} 112 r1, _, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(osviex))) 113 if r1 == 0 { 114 logrus.Warnf("GetVersionExW failed - assuming server SKU: %v", err) 115 return false 116 } 117 const verNTWorkstation = 0x00000001 118 return osviex.ProductType == verNTWorkstation 119 } 120 121 // IsIoTCore returns true if the currently running image is based off of 122 // Windows 10 IoT Core. 123 // @engine maintainers - this function should not be removed or modified as it 124 // is used to enforce licensing restrictions on Windows. 125 func IsIoTCore() bool { 126 var returnedProductType uint32 127 r1, _, err := procGetProductInfo.Call(6, 1, 0, 0, uintptr(unsafe.Pointer(&returnedProductType))) 128 if r1 == 0 { 129 logrus.Warnf("GetProductInfo failed - assuming this is not IoT: %v", err) 130 return false 131 } 132 const productIoTUAP = 0x0000007B 133 const productIoTUAPCommercial = 0x00000083 134 return returnedProductType == productIoTUAP || returnedProductType == productIoTUAPCommercial 135 } 136 137 // Unmount is a platform-specific helper function to call 138 // the unmount syscall. Not supported on Windows 139 func Unmount(dest string) error { 140 return nil 141 } 142 143 // CommandLineToArgv wraps the Windows syscall to turn a commandline into an argument array. 144 func CommandLineToArgv(commandLine string) ([]string, error) { 145 var argc int32 146 147 argsPtr, err := windows.UTF16PtrFromString(commandLine) 148 if err != nil { 149 return nil, err 150 } 151 152 argv, err := windows.CommandLineToArgv(argsPtr, &argc) 153 if err != nil { 154 return nil, err 155 } 156 defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(argv)))) 157 158 newArgs := make([]string, argc) 159 for i, v := range (*argv)[:argc] { 160 newArgs[i] = string(windows.UTF16ToString((*v)[:])) 161 } 162 163 return newArgs, nil 164 } 165 166 // HasWin32KSupport determines whether containers that depend on win32k can 167 // run on this machine. Win32k is the driver used to implement windowing. 168 func HasWin32KSupport() bool { 169 // For now, check for ntuser API support on the host. In the future, a host 170 // may support win32k in containers even if the host does not support ntuser 171 // APIs. 172 return ntuserApiset.Load() == nil 173 } 174 175 func SetNamedSecurityInfo(objectName *uint16, objectType uint32, securityInformation uint32, sidOwner *windows.SID, sidGroup *windows.SID, dacl *byte, sacl *byte) (result error) { 176 r0, _, _ := syscall.Syscall9(procSetNamedSecurityInfo.Addr(), 7, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(sidOwner)), uintptr(unsafe.Pointer(sidGroup)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) 177 if r0 != 0 { 178 result = syscall.Errno(r0) 179 } 180 return 181 } 182 183 func GetSecurityDescriptorDacl(securityDescriptor *byte, daclPresent *uint32, dacl **byte, daclDefaulted *uint32) (result error) { 184 r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(securityDescriptor)), uintptr(unsafe.Pointer(daclPresent)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclDefaulted)), 0, 0) 185 if r1 == 0 { 186 if e1 != 0 { 187 result = syscall.Errno(e1) 188 } else { 189 result = syscall.EINVAL 190 } 191 } 192 return 193 }