github.com/dorkamotorka/go/src@v0.0.0-20230614113921-187095f0e316/syscall/syscall_windows.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Windows system calls. 6 7 package syscall 8 9 import ( 10 errorspkg "errors" 11 "internal/bytealg" 12 "internal/itoa" 13 "internal/oserror" 14 "internal/race" 15 "runtime" 16 "sync" 17 "unsafe" 18 ) 19 20 type Handle uintptr 21 22 const InvalidHandle = ^Handle(0) 23 24 // StringToUTF16 returns the UTF-16 encoding of the UTF-8 string s, 25 // with a terminating NUL added. If s contains a NUL byte this 26 // function panics instead of returning an error. 27 // 28 // Deprecated: Use UTF16FromString instead. 29 func StringToUTF16(s string) []uint16 { 30 a, err := UTF16FromString(s) 31 if err != nil { 32 panic("syscall: string with NUL passed to StringToUTF16") 33 } 34 return a 35 } 36 37 // UTF16FromString returns the UTF-16 encoding of the UTF-8 string 38 // s, with a terminating NUL added. If s contains a NUL byte at any 39 // location, it returns (nil, EINVAL). Unpaired surrogates 40 // are encoded using WTF-8. 41 func UTF16FromString(s string) ([]uint16, error) { 42 if bytealg.IndexByteString(s, 0) != -1 { 43 return nil, EINVAL 44 } 45 // Valid UTF-8 characters between 1 and 3 bytes require one uint16. 46 // Valid UTF-8 characters of 4 bytes require two uint16. 47 // Bytes with invalid UTF-8 encoding require maximum one uint16 per byte. 48 // So the number of UTF-8 code units (len(s)) is always greater or 49 // equal than the number of UTF-16 code units. 50 // Also account for the terminating NUL character. 51 buf := make([]uint16, 0, len(s)+1) 52 buf = encodeWTF16(s, buf) 53 return append(buf, 0), nil 54 } 55 56 // UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, 57 // with a terminating NUL removed. Unpaired surrogates are decoded 58 // using WTF-8 instead of UTF-8 encoding. 59 func UTF16ToString(s []uint16) string { 60 maxLen := 0 61 for i, v := range s { 62 if v == 0 { 63 s = s[0:i] 64 break 65 } 66 switch { 67 case v <= rune1Max: 68 maxLen += 1 69 case v <= rune2Max: 70 maxLen += 2 71 default: 72 // r is a non-surrogate that decodes to 3 bytes, 73 // or is an unpaired surrogate (also 3 bytes in WTF-8), 74 // or is one half of a valid surrogate pair. 75 // If it is half of a pair, we will add 3 for the second surrogate 76 // (total of 6) and overestimate by 2 bytes for the pair, 77 // since the resulting rune only requires 4 bytes. 78 maxLen += 3 79 } 80 } 81 buf := decodeWTF16(s, make([]byte, 0, maxLen)) 82 return unsafe.String(unsafe.SliceData(buf), len(buf)) 83 } 84 85 // utf16PtrToString is like UTF16ToString, but takes *uint16 86 // as a parameter instead of []uint16. 87 func utf16PtrToString(p *uint16) string { 88 if p == nil { 89 return "" 90 } 91 end := unsafe.Pointer(p) 92 n := 0 93 for *(*uint16)(end) != 0 { 94 end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) 95 n++ 96 } 97 return UTF16ToString(unsafe.Slice(p, n)) 98 } 99 100 // StringToUTF16Ptr returns pointer to the UTF-16 encoding of 101 // the UTF-8 string s, with a terminating NUL added. If s 102 // contains a NUL byte this function panics instead of 103 // returning an error. 104 // 105 // Deprecated: Use UTF16PtrFromString instead. 106 func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] } 107 108 // UTF16PtrFromString returns pointer to the UTF-16 encoding of 109 // the UTF-8 string s, with a terminating NUL added. If s 110 // contains a NUL byte at any location, it returns (nil, EINVAL). 111 // Unpaired surrogates are encoded using WTF-8. 112 func UTF16PtrFromString(s string) (*uint16, error) { 113 a, err := UTF16FromString(s) 114 if err != nil { 115 return nil, err 116 } 117 return &a[0], nil 118 } 119 120 // Errno is the Windows error number. 121 // 122 // Errno values can be tested against error values using errors.Is. 123 // For example: 124 // 125 // _, _, err := syscall.Syscall(...) 126 // if errors.Is(err, fs.ErrNotExist) ... 127 type Errno uintptr 128 129 func langid(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) } 130 131 // FormatMessage is deprecated (msgsrc should be uintptr, not uint32, but can 132 // not be changed due to the Go 1 compatibility guarantee). 133 // 134 // Deprecated: Use FormatMessage from golang.org/x/sys/windows instead. 135 func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) { 136 return formatMessage(flags, uintptr(msgsrc), msgid, langid, buf, args) 137 } 138 139 func (e Errno) Error() string { 140 // deal with special go errors 141 idx := int(e - APPLICATION_ERROR) 142 if 0 <= idx && idx < len(errors) { 143 return errors[idx] 144 } 145 // ask windows for the remaining errors 146 var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS 147 b := make([]uint16, 300) 148 n, err := formatMessage(flags, 0, uint32(e), langid(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil) 149 if err != nil { 150 n, err = formatMessage(flags, 0, uint32(e), 0, b, nil) 151 if err != nil { 152 return "winapi error #" + itoa.Itoa(int(e)) 153 } 154 } 155 // trim terminating \r and \n 156 for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { 157 } 158 return UTF16ToString(b[:n]) 159 } 160 161 const ( 162 _ERROR_NOT_ENOUGH_MEMORY = Errno(8) 163 _ERROR_NOT_SUPPORTED = Errno(50) 164 _ERROR_BAD_NETPATH = Errno(53) 165 _ERROR_CALL_NOT_IMPLEMENTED = Errno(120) 166 ) 167 168 func (e Errno) Is(target error) bool { 169 switch target { 170 case oserror.ErrPermission: 171 return e == ERROR_ACCESS_DENIED || 172 e == EACCES || 173 e == EPERM 174 case oserror.ErrExist: 175 return e == ERROR_ALREADY_EXISTS || 176 e == ERROR_DIR_NOT_EMPTY || 177 e == ERROR_FILE_EXISTS || 178 e == EEXIST || 179 e == ENOTEMPTY 180 case oserror.ErrNotExist: 181 return e == ERROR_FILE_NOT_FOUND || 182 e == _ERROR_BAD_NETPATH || 183 e == ERROR_PATH_NOT_FOUND || 184 e == ENOENT 185 case errorspkg.ErrUnsupported: 186 return e == _ERROR_NOT_SUPPORTED || 187 e == _ERROR_CALL_NOT_IMPLEMENTED || 188 e == ENOSYS || 189 e == ENOTSUP || 190 e == EOPNOTSUPP || 191 e == EWINDOWS 192 } 193 return false 194 } 195 196 func (e Errno) Temporary() bool { 197 return e == EINTR || e == EMFILE || e.Timeout() 198 } 199 200 func (e Errno) Timeout() bool { 201 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT 202 } 203 204 // Implemented in runtime/syscall_windows.go. 205 func compileCallback(fn any, cleanstack bool) uintptr 206 207 // NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. 208 // This is useful when interoperating with Windows code requiring callbacks. 209 // The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. 210 // Only a limited number of callbacks may be created in a single Go process, and any memory allocated 211 // for these callbacks is never released. 212 // Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created. 213 func NewCallback(fn any) uintptr { 214 return compileCallback(fn, true) 215 } 216 217 // NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. 218 // This is useful when interoperating with Windows code requiring callbacks. 219 // The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. 220 // Only a limited number of callbacks may be created in a single Go process, and any memory allocated 221 // for these callbacks is never released. 222 // Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created. 223 func NewCallbackCDecl(fn any) uintptr { 224 return compileCallback(fn, false) 225 } 226 227 // windows api calls 228 229 //sys GetLastError() (lasterr error) 230 //sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW 231 //sys FreeLibrary(handle Handle) (err error) 232 //sys GetProcAddress(module Handle, procname string) (proc uintptr, err error) 233 //sys GetVersion() (ver uint32, err error) 234 //sys rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers 235 //sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW 236 //sys ExitProcess(exitcode uint32) 237 //sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW 238 //sys readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = ReadFile 239 //sys writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = WriteFile 240 //sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff] 241 //sys CloseHandle(handle Handle) (err error) 242 //sys GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle] 243 //sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW 244 //sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW 245 //sys FindClose(handle Handle) (err error) 246 //sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) 247 //sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW 248 //sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW 249 //sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW 250 //sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW 251 //sys DeleteFile(path *uint16) (err error) = DeleteFileW 252 //sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW 253 //sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW 254 //sys SetEndOfFile(handle Handle) (err error) 255 //sys GetSystemTimeAsFileTime(time *Filetime) 256 //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] 257 //sys createIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) = CreateIoCompletionPort 258 //sys getQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) = GetQueuedCompletionStatus 259 //sys postQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) = PostQueuedCompletionStatus 260 //sys CancelIo(s Handle) (err error) 261 //sys CancelIoEx(s Handle, o *Overlapped) (err error) 262 //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 263 //sys CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = advapi32.CreateProcessAsUserW 264 //sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) 265 //sys TerminateProcess(handle Handle, exitcode uint32) (err error) 266 //sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) 267 //sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW 268 //sys GetCurrentProcess() (pseudoHandle Handle, err error) 269 //sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) 270 //sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) 271 //sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] 272 //sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW 273 //sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) 274 //sys GetFileType(filehandle Handle) (n uint32, err error) 275 //sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW 276 //sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext 277 //sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom 278 //sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW 279 //sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW 280 //sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW 281 //sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW 282 //sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) 283 //sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW 284 //sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW 285 //sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW 286 //sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW 287 //sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW 288 //sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0] 289 //sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) 290 //sys FlushFileBuffers(handle Handle) (err error) 291 //sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW 292 //sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW 293 //sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW 294 //sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW 295 //sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) 296 //sys UnmapViewOfFile(addr uintptr) (err error) 297 //sys FlushViewOfFile(addr uintptr, length uintptr) (err error) 298 //sys VirtualLock(addr uintptr, length uintptr) (err error) 299 //sys VirtualUnlock(addr uintptr, length uintptr) (err error) 300 //sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile 301 //sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW 302 //sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW 303 //sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore 304 //sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore 305 //sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore 306 //sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore 307 //sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain 308 //sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain 309 //sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext 310 //sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext 311 //sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy 312 //sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW 313 //sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey 314 //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 315 //sys regEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW 316 //sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW 317 //sys getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId 318 //sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode 319 //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW 320 //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW 321 //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot 322 //sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW 323 //sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW 324 //sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) 325 // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. 326 //sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW 327 //sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW 328 //sys initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList 329 //sys deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) = DeleteProcThreadAttributeList 330 //sys updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute 331 //sys getFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) [n == 0 || n >= filePathSize] = kernel32.GetFinalPathNameByHandleW 332 333 // syscall interface implementation for other packages 334 335 func makeInheritSa() *SecurityAttributes { 336 var sa SecurityAttributes 337 sa.Length = uint32(unsafe.Sizeof(sa)) 338 sa.InheritHandle = 1 339 return &sa 340 } 341 342 func Open(path string, mode int, perm uint32) (fd Handle, err error) { 343 if len(path) == 0 { 344 return InvalidHandle, ERROR_FILE_NOT_FOUND 345 } 346 pathp, err := UTF16PtrFromString(path) 347 if err != nil { 348 return InvalidHandle, err 349 } 350 var access uint32 351 switch mode & (O_RDONLY | O_WRONLY | O_RDWR) { 352 case O_RDONLY: 353 access = GENERIC_READ 354 case O_WRONLY: 355 access = GENERIC_WRITE 356 case O_RDWR: 357 access = GENERIC_READ | GENERIC_WRITE 358 } 359 if mode&O_CREAT != 0 { 360 access |= GENERIC_WRITE 361 } 362 if mode&O_APPEND != 0 { 363 access &^= GENERIC_WRITE 364 access |= FILE_APPEND_DATA 365 } 366 sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE) 367 var sa *SecurityAttributes 368 if mode&O_CLOEXEC == 0 { 369 sa = makeInheritSa() 370 } 371 var createmode uint32 372 switch { 373 case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): 374 createmode = CREATE_NEW 375 case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC): 376 createmode = CREATE_ALWAYS 377 case mode&O_CREAT == O_CREAT: 378 createmode = OPEN_ALWAYS 379 case mode&O_TRUNC == O_TRUNC: 380 createmode = TRUNCATE_EXISTING 381 default: 382 createmode = OPEN_EXISTING 383 } 384 var attrs uint32 = FILE_ATTRIBUTE_NORMAL 385 if perm&S_IWRITE == 0 { 386 attrs = FILE_ATTRIBUTE_READONLY 387 if createmode == CREATE_ALWAYS { 388 // We have been asked to create a read-only file. 389 // If the file already exists, the semantics of 390 // the Unix open system call is to preserve the 391 // existing permissions. If we pass CREATE_ALWAYS 392 // and FILE_ATTRIBUTE_READONLY to CreateFile, 393 // and the file already exists, CreateFile will 394 // change the file permissions. 395 // Avoid that to preserve the Unix semantics. 396 h, e := CreateFile(pathp, access, sharemode, sa, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) 397 switch e { 398 case ERROR_FILE_NOT_FOUND, _ERROR_BAD_NETPATH, ERROR_PATH_NOT_FOUND: 399 // File does not exist. These are the same 400 // errors as Errno.Is checks for ErrNotExist. 401 // Carry on to create the file. 402 default: 403 // Success or some different error. 404 return h, e 405 } 406 } 407 } 408 if createmode == OPEN_EXISTING && access == GENERIC_READ { 409 // Necessary for opening directory handles. 410 attrs |= FILE_FLAG_BACKUP_SEMANTICS 411 } 412 return CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0) 413 } 414 415 func Read(fd Handle, p []byte) (n int, err error) { 416 var done uint32 417 e := ReadFile(fd, p, &done, nil) 418 if e != nil { 419 if e == ERROR_BROKEN_PIPE { 420 // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin 421 return 0, nil 422 } 423 return 0, e 424 } 425 return int(done), nil 426 } 427 428 func Write(fd Handle, p []byte) (n int, err error) { 429 var done uint32 430 e := WriteFile(fd, p, &done, nil) 431 if e != nil { 432 return 0, e 433 } 434 return int(done), nil 435 } 436 437 func ReadFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error { 438 err := readFile(fd, p, done, overlapped) 439 if race.Enabled { 440 if *done > 0 { 441 race.WriteRange(unsafe.Pointer(&p[0]), int(*done)) 442 } 443 race.Acquire(unsafe.Pointer(&ioSync)) 444 } 445 if msanenabled && *done > 0 { 446 msanWrite(unsafe.Pointer(&p[0]), int(*done)) 447 } 448 if asanenabled && *done > 0 { 449 asanWrite(unsafe.Pointer(&p[0]), int(*done)) 450 } 451 return err 452 } 453 454 func WriteFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error { 455 if race.Enabled { 456 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 457 } 458 err := writeFile(fd, p, done, overlapped) 459 if race.Enabled && *done > 0 { 460 race.ReadRange(unsafe.Pointer(&p[0]), int(*done)) 461 } 462 if msanenabled && *done > 0 { 463 msanRead(unsafe.Pointer(&p[0]), int(*done)) 464 } 465 if asanenabled && *done > 0 { 466 asanRead(unsafe.Pointer(&p[0]), int(*done)) 467 } 468 return err 469 } 470 471 var ioSync int64 472 473 var procSetFilePointerEx = modkernel32.NewProc("SetFilePointerEx") 474 475 const ptrSize = unsafe.Sizeof(uintptr(0)) 476 477 // setFilePointerEx calls SetFilePointerEx. 478 // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365542(v=vs.85).aspx 479 func setFilePointerEx(handle Handle, distToMove int64, newFilePointer *int64, whence uint32) error { 480 var e1 Errno 481 if unsafe.Sizeof(uintptr(0)) == 8 { 482 _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 4, uintptr(handle), uintptr(distToMove), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0, 0) 483 } else { 484 // Different 32-bit systems disgaree about whether distToMove starts 8-byte aligned. 485 switch runtime.GOARCH { 486 default: 487 panic("unsupported 32-bit architecture") 488 case "386": 489 // distToMove is a LARGE_INTEGER, which is 64 bits. 490 _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 5, uintptr(handle), uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0) 491 case "arm": 492 // distToMove must be 8-byte aligned per ARM calling convention 493 // https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions#stage-c-assignment-of-arguments-to-registers-and-stack 494 _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 6, uintptr(handle), 0, uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence)) 495 } 496 } 497 if e1 != 0 { 498 return errnoErr(e1) 499 } 500 return nil 501 } 502 503 func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) { 504 var w uint32 505 switch whence { 506 case 0: 507 w = FILE_BEGIN 508 case 1: 509 w = FILE_CURRENT 510 case 2: 511 w = FILE_END 512 } 513 err = setFilePointerEx(fd, offset, &newoffset, w) 514 return 515 } 516 517 func Close(fd Handle) (err error) { 518 return CloseHandle(fd) 519 } 520 521 var ( 522 Stdin = getStdHandle(STD_INPUT_HANDLE) 523 Stdout = getStdHandle(STD_OUTPUT_HANDLE) 524 Stderr = getStdHandle(STD_ERROR_HANDLE) 525 ) 526 527 func getStdHandle(h int) (fd Handle) { 528 r, _ := GetStdHandle(h) 529 return r 530 } 531 532 const ImplementsGetwd = true 533 534 func Getwd() (wd string, err error) { 535 b := make([]uint16, 300) 536 n, e := GetCurrentDirectory(uint32(len(b)), &b[0]) 537 if e != nil { 538 return "", e 539 } 540 return UTF16ToString(b[0:n]), nil 541 } 542 543 func Chdir(path string) (err error) { 544 pathp, err := UTF16PtrFromString(path) 545 if err != nil { 546 return err 547 } 548 return SetCurrentDirectory(pathp) 549 } 550 551 func Mkdir(path string, mode uint32) (err error) { 552 pathp, err := UTF16PtrFromString(path) 553 if err != nil { 554 return err 555 } 556 return CreateDirectory(pathp, nil) 557 } 558 559 func Rmdir(path string) (err error) { 560 pathp, err := UTF16PtrFromString(path) 561 if err != nil { 562 return err 563 } 564 return RemoveDirectory(pathp) 565 } 566 567 func Unlink(path string) (err error) { 568 pathp, err := UTF16PtrFromString(path) 569 if err != nil { 570 return err 571 } 572 return DeleteFile(pathp) 573 } 574 575 func Rename(oldpath, newpath string) (err error) { 576 from, err := UTF16PtrFromString(oldpath) 577 if err != nil { 578 return err 579 } 580 to, err := UTF16PtrFromString(newpath) 581 if err != nil { 582 return err 583 } 584 return MoveFile(from, to) 585 } 586 587 func ComputerName() (name string, err error) { 588 var n uint32 = MAX_COMPUTERNAME_LENGTH + 1 589 b := make([]uint16, n) 590 e := GetComputerName(&b[0], &n) 591 if e != nil { 592 return "", e 593 } 594 return UTF16ToString(b[:n]), nil 595 } 596 597 func Ftruncate(fd Handle, length int64) (err error) { 598 curoffset, e := Seek(fd, 0, 1) 599 if e != nil { 600 return e 601 } 602 defer Seek(fd, curoffset, 0) 603 _, e = Seek(fd, length, 0) 604 if e != nil { 605 return e 606 } 607 e = SetEndOfFile(fd) 608 if e != nil { 609 return e 610 } 611 return nil 612 } 613 614 func Gettimeofday(tv *Timeval) (err error) { 615 var ft Filetime 616 GetSystemTimeAsFileTime(&ft) 617 *tv = NsecToTimeval(ft.Nanoseconds()) 618 return nil 619 } 620 621 func Pipe(p []Handle) (err error) { 622 if len(p) != 2 { 623 return EINVAL 624 } 625 var r, w Handle 626 e := CreatePipe(&r, &w, makeInheritSa(), 0) 627 if e != nil { 628 return e 629 } 630 p[0] = r 631 p[1] = w 632 return nil 633 } 634 635 func Utimes(path string, tv []Timeval) (err error) { 636 if len(tv) != 2 { 637 return EINVAL 638 } 639 pathp, e := UTF16PtrFromString(path) 640 if e != nil { 641 return e 642 } 643 h, e := CreateFile(pathp, 644 FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, 645 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) 646 if e != nil { 647 return e 648 } 649 defer Close(h) 650 a := Filetime{} 651 w := Filetime{} 652 if tv[0].Nanoseconds() != 0 { 653 a = NsecToFiletime(tv[0].Nanoseconds()) 654 } 655 if tv[0].Nanoseconds() != 0 { 656 w = NsecToFiletime(tv[1].Nanoseconds()) 657 } 658 return SetFileTime(h, nil, &a, &w) 659 } 660 661 // This matches the value in os/file_windows.go. 662 const _UTIME_OMIT = -1 663 664 func UtimesNano(path string, ts []Timespec) (err error) { 665 if len(ts) != 2 { 666 return EINVAL 667 } 668 pathp, e := UTF16PtrFromString(path) 669 if e != nil { 670 return e 671 } 672 h, e := CreateFile(pathp, 673 FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, 674 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) 675 if e != nil { 676 return e 677 } 678 defer Close(h) 679 a := Filetime{} 680 w := Filetime{} 681 if ts[0].Nsec != _UTIME_OMIT { 682 a = NsecToFiletime(TimespecToNsec(ts[0])) 683 } 684 if ts[1].Nsec != _UTIME_OMIT { 685 w = NsecToFiletime(TimespecToNsec(ts[1])) 686 } 687 return SetFileTime(h, nil, &a, &w) 688 } 689 690 func Fsync(fd Handle) (err error) { 691 return FlushFileBuffers(fd) 692 } 693 694 func Chmod(path string, mode uint32) (err error) { 695 p, e := UTF16PtrFromString(path) 696 if e != nil { 697 return e 698 } 699 attrs, e := GetFileAttributes(p) 700 if e != nil { 701 return e 702 } 703 if mode&S_IWRITE != 0 { 704 attrs &^= FILE_ATTRIBUTE_READONLY 705 } else { 706 attrs |= FILE_ATTRIBUTE_READONLY 707 } 708 return SetFileAttributes(p, attrs) 709 } 710 711 func LoadCancelIoEx() error { 712 return procCancelIoEx.Find() 713 } 714 715 func LoadSetFileCompletionNotificationModes() error { 716 return procSetFileCompletionNotificationModes.Find() 717 } 718 719 // net api calls 720 721 const socket_error = uintptr(^uint32(0)) 722 723 //sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup 724 //sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup 725 //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 726 //sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket 727 //sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt 728 //sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt 729 //sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind 730 //sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect 731 //sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname 732 //sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername 733 //sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen 734 //sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown 735 //sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket 736 //sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx 737 //sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs 738 //sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv 739 //sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend 740 //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 741 //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 742 //sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname 743 //sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname 744 //sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs 745 //sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname 746 //sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W 747 //sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree 748 //sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W 749 //sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW 750 //sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW 751 //sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry 752 //sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo 753 //sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes 754 //sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW 755 756 // For testing: clients can set this flag to force 757 // creation of IPv6 sockets to return EAFNOSUPPORT. 758 var SocketDisableIPv6 bool 759 760 type RawSockaddrInet4 struct { 761 Family uint16 762 Port uint16 763 Addr [4]byte /* in_addr */ 764 Zero [8]uint8 765 } 766 767 type RawSockaddrInet6 struct { 768 Family uint16 769 Port uint16 770 Flowinfo uint32 771 Addr [16]byte /* in6_addr */ 772 Scope_id uint32 773 } 774 775 type RawSockaddr struct { 776 Family uint16 777 Data [14]int8 778 } 779 780 type RawSockaddrAny struct { 781 Addr RawSockaddr 782 Pad [100]int8 783 } 784 785 type Sockaddr interface { 786 sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs 787 } 788 789 type SockaddrInet4 struct { 790 Port int 791 Addr [4]byte 792 raw RawSockaddrInet4 793 } 794 795 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) { 796 if sa.Port < 0 || sa.Port > 0xFFFF { 797 return nil, 0, EINVAL 798 } 799 sa.raw.Family = AF_INET 800 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 801 p[0] = byte(sa.Port >> 8) 802 p[1] = byte(sa.Port) 803 sa.raw.Addr = sa.Addr 804 return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil 805 } 806 807 type SockaddrInet6 struct { 808 Port int 809 ZoneId uint32 810 Addr [16]byte 811 raw RawSockaddrInet6 812 } 813 814 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { 815 if sa.Port < 0 || sa.Port > 0xFFFF { 816 return nil, 0, EINVAL 817 } 818 sa.raw.Family = AF_INET6 819 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 820 p[0] = byte(sa.Port >> 8) 821 p[1] = byte(sa.Port) 822 sa.raw.Scope_id = sa.ZoneId 823 sa.raw.Addr = sa.Addr 824 return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil 825 } 826 827 type RawSockaddrUnix struct { 828 Family uint16 829 Path [UNIX_PATH_MAX]int8 830 } 831 832 type SockaddrUnix struct { 833 Name string 834 raw RawSockaddrUnix 835 } 836 837 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { 838 name := sa.Name 839 n := len(name) 840 if n > len(sa.raw.Path) { 841 return nil, 0, EINVAL 842 } 843 if n == len(sa.raw.Path) && name[0] != '@' { 844 return nil, 0, EINVAL 845 } 846 sa.raw.Family = AF_UNIX 847 for i := 0; i < n; i++ { 848 sa.raw.Path[i] = int8(name[i]) 849 } 850 // length is family (uint16), name, NUL. 851 sl := int32(2) 852 if n > 0 { 853 sl += int32(n) + 1 854 } 855 if sa.raw.Path[0] == '@' { 856 sa.raw.Path[0] = 0 857 // Don't count trailing NUL for abstract address. 858 sl-- 859 } 860 861 return unsafe.Pointer(&sa.raw), sl, nil 862 } 863 864 func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { 865 switch rsa.Addr.Family { 866 case AF_UNIX: 867 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 868 sa := new(SockaddrUnix) 869 if pp.Path[0] == 0 { 870 // "Abstract" Unix domain socket. 871 // Rewrite leading NUL as @ for textual display. 872 // (This is the standard convention.) 873 // Not friendly to overwrite in place, 874 // but the callers below don't care. 875 pp.Path[0] = '@' 876 } 877 878 // Assume path ends at NUL. 879 // This is not technically the Linux semantics for 880 // abstract Unix domain sockets--they are supposed 881 // to be uninterpreted fixed-size binary blobs--but 882 // everyone uses this convention. 883 n := 0 884 for n < len(pp.Path) && pp.Path[n] != 0 { 885 n++ 886 } 887 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) 888 return sa, nil 889 890 case AF_INET: 891 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 892 sa := new(SockaddrInet4) 893 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 894 sa.Port = int(p[0])<<8 + int(p[1]) 895 sa.Addr = pp.Addr 896 return sa, nil 897 898 case AF_INET6: 899 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 900 sa := new(SockaddrInet6) 901 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 902 sa.Port = int(p[0])<<8 + int(p[1]) 903 sa.ZoneId = pp.Scope_id 904 sa.Addr = pp.Addr 905 return sa, nil 906 } 907 return nil, EAFNOSUPPORT 908 } 909 910 func Socket(domain, typ, proto int) (fd Handle, err error) { 911 if domain == AF_INET6 && SocketDisableIPv6 { 912 return InvalidHandle, EAFNOSUPPORT 913 } 914 return socket(int32(domain), int32(typ), int32(proto)) 915 } 916 917 func SetsockoptInt(fd Handle, level, opt int, value int) (err error) { 918 v := int32(value) 919 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v))) 920 } 921 922 func Bind(fd Handle, sa Sockaddr) (err error) { 923 ptr, n, err := sa.sockaddr() 924 if err != nil { 925 return err 926 } 927 return bind(fd, ptr, n) 928 } 929 930 func Connect(fd Handle, sa Sockaddr) (err error) { 931 ptr, n, err := sa.sockaddr() 932 if err != nil { 933 return err 934 } 935 return connect(fd, ptr, n) 936 } 937 938 func Getsockname(fd Handle) (sa Sockaddr, err error) { 939 var rsa RawSockaddrAny 940 l := int32(unsafe.Sizeof(rsa)) 941 if err = getsockname(fd, &rsa, &l); err != nil { 942 return 943 } 944 return rsa.Sockaddr() 945 } 946 947 func Getpeername(fd Handle) (sa Sockaddr, err error) { 948 var rsa RawSockaddrAny 949 l := int32(unsafe.Sizeof(rsa)) 950 if err = getpeername(fd, &rsa, &l); err != nil { 951 return 952 } 953 return rsa.Sockaddr() 954 } 955 956 func Listen(s Handle, n int) (err error) { 957 return listen(s, int32(n)) 958 } 959 960 func Shutdown(fd Handle, how int) (err error) { 961 return shutdown(fd, int32(how)) 962 } 963 964 func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) { 965 var rsa unsafe.Pointer 966 var len int32 967 if to != nil { 968 rsa, len, err = to.sockaddr() 969 if err != nil { 970 return err 971 } 972 } 973 r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) 974 if r1 == socket_error { 975 if e1 != 0 { 976 err = errnoErr(e1) 977 } else { 978 err = EINVAL 979 } 980 } 981 return err 982 } 983 984 func wsaSendtoInet4(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *SockaddrInet4, overlapped *Overlapped, croutine *byte) (err error) { 985 rsa, len, err := to.sockaddr() 986 if err != nil { 987 return err 988 } 989 r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) 990 if r1 == socket_error { 991 if e1 != 0 { 992 err = errnoErr(e1) 993 } else { 994 err = EINVAL 995 } 996 } 997 return err 998 } 999 1000 func wsaSendtoInet6(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *SockaddrInet6, overlapped *Overlapped, croutine *byte) (err error) { 1001 rsa, len, err := to.sockaddr() 1002 if err != nil { 1003 return err 1004 } 1005 r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) 1006 if r1 == socket_error { 1007 if e1 != 0 { 1008 err = errnoErr(e1) 1009 } else { 1010 err = EINVAL 1011 } 1012 } 1013 return err 1014 } 1015 1016 func LoadGetAddrInfo() error { 1017 return procGetAddrInfoW.Find() 1018 } 1019 1020 var connectExFunc struct { 1021 once sync.Once 1022 addr uintptr 1023 err error 1024 } 1025 1026 func LoadConnectEx() error { 1027 connectExFunc.once.Do(func() { 1028 var s Handle 1029 s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) 1030 if connectExFunc.err != nil { 1031 return 1032 } 1033 defer CloseHandle(s) 1034 var n uint32 1035 connectExFunc.err = WSAIoctl(s, 1036 SIO_GET_EXTENSION_FUNCTION_POINTER, 1037 (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)), 1038 uint32(unsafe.Sizeof(WSAID_CONNECTEX)), 1039 (*byte)(unsafe.Pointer(&connectExFunc.addr)), 1040 uint32(unsafe.Sizeof(connectExFunc.addr)), 1041 &n, nil, 0) 1042 }) 1043 return connectExFunc.err 1044 } 1045 1046 func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) { 1047 r1, _, e1 := 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) 1048 if r1 == 0 { 1049 if e1 != 0 { 1050 err = error(e1) 1051 } else { 1052 err = EINVAL 1053 } 1054 } 1055 return 1056 } 1057 1058 func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error { 1059 err := LoadConnectEx() 1060 if err != nil { 1061 return errorspkg.New("failed to find ConnectEx: " + err.Error()) 1062 } 1063 ptr, n, err := sa.sockaddr() 1064 if err != nil { 1065 return err 1066 } 1067 return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped) 1068 } 1069 1070 // Invented structures to support what package os expects. 1071 type Rusage struct { 1072 CreationTime Filetime 1073 ExitTime Filetime 1074 KernelTime Filetime 1075 UserTime Filetime 1076 } 1077 1078 type WaitStatus struct { 1079 ExitCode uint32 1080 } 1081 1082 func (w WaitStatus) Exited() bool { return true } 1083 1084 func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) } 1085 1086 func (w WaitStatus) Signal() Signal { return -1 } 1087 1088 func (w WaitStatus) CoreDump() bool { return false } 1089 1090 func (w WaitStatus) Stopped() bool { return false } 1091 1092 func (w WaitStatus) Continued() bool { return false } 1093 1094 func (w WaitStatus) StopSignal() Signal { return -1 } 1095 1096 func (w WaitStatus) Signaled() bool { return false } 1097 1098 func (w WaitStatus) TrapCause() int { return -1 } 1099 1100 // Timespec is an invented structure on Windows, but here for 1101 // consistency with the syscall package for other operating systems. 1102 type Timespec struct { 1103 Sec int64 1104 Nsec int64 1105 } 1106 1107 func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 1108 1109 func NsecToTimespec(nsec int64) (ts Timespec) { 1110 ts.Sec = nsec / 1e9 1111 ts.Nsec = nsec % 1e9 1112 return 1113 } 1114 1115 // TODO(brainman): fix all needed for net 1116 1117 func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, EWINDOWS } 1118 func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) { 1119 return 0, nil, EWINDOWS 1120 } 1121 func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return EWINDOWS } 1122 func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return EWINDOWS } 1123 1124 // The Linger struct is wrong but we only noticed after Go 1. 1125 // sysLinger is the real system call structure. 1126 1127 // BUG(brainman): The definition of Linger is not appropriate for direct use 1128 // with Setsockopt and Getsockopt. 1129 // Use SetsockoptLinger instead. 1130 1131 type Linger struct { 1132 Onoff int32 1133 Linger int32 1134 } 1135 1136 type sysLinger struct { 1137 Onoff uint16 1138 Linger uint16 1139 } 1140 1141 type IPMreq struct { 1142 Multiaddr [4]byte /* in_addr */ 1143 Interface [4]byte /* in_addr */ 1144 } 1145 1146 type IPv6Mreq struct { 1147 Multiaddr [16]byte /* in6_addr */ 1148 Interface uint32 1149 } 1150 1151 func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS } 1152 1153 func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { 1154 sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} 1155 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys))) 1156 } 1157 1158 func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { 1159 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) 1160 } 1161 func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { 1162 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) 1163 } 1164 func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return EWINDOWS } 1165 1166 func Getpid() (pid int) { return int(getCurrentProcessId()) } 1167 1168 func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) { 1169 // NOTE(rsc): The Win32finddata struct is wrong for the system call: 1170 // the two paths are each one uint16 short. Use the correct struct, 1171 // a win32finddata1, and then copy the results out. 1172 // There is no loss of expressivity here, because the final 1173 // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that. 1174 // For Go 1.1, we might avoid the allocation of win32finddata1 here 1175 // by adding a final Bug [2]uint16 field to the struct and then 1176 // adjusting the fields in the result directly. 1177 var data1 win32finddata1 1178 handle, err = findFirstFile1(name, &data1) 1179 if err == nil { 1180 copyFindData(data, &data1) 1181 } 1182 return 1183 } 1184 1185 func FindNextFile(handle Handle, data *Win32finddata) (err error) { 1186 var data1 win32finddata1 1187 err = findNextFile1(handle, &data1) 1188 if err == nil { 1189 copyFindData(data, &data1) 1190 } 1191 return 1192 } 1193 1194 func getProcessEntry(pid int) (*ProcessEntry32, error) { 1195 snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) 1196 if err != nil { 1197 return nil, err 1198 } 1199 defer CloseHandle(snapshot) 1200 var procEntry ProcessEntry32 1201 procEntry.Size = uint32(unsafe.Sizeof(procEntry)) 1202 if err = Process32First(snapshot, &procEntry); err != nil { 1203 return nil, err 1204 } 1205 for { 1206 if procEntry.ProcessID == uint32(pid) { 1207 return &procEntry, nil 1208 } 1209 err = Process32Next(snapshot, &procEntry) 1210 if err != nil { 1211 return nil, err 1212 } 1213 } 1214 } 1215 1216 func Getppid() (ppid int) { 1217 pe, err := getProcessEntry(Getpid()) 1218 if err != nil { 1219 return -1 1220 } 1221 return int(pe.ParentProcessID) 1222 } 1223 1224 func fdpath(fd Handle, buf []uint16) ([]uint16, error) { 1225 const ( 1226 FILE_NAME_NORMALIZED = 0 1227 VOLUME_NAME_DOS = 0 1228 ) 1229 for { 1230 n, err := getFinalPathNameByHandle(fd, &buf[0], uint32(len(buf)), FILE_NAME_NORMALIZED|VOLUME_NAME_DOS) 1231 if err == nil { 1232 buf = buf[:n] 1233 break 1234 } 1235 if err != _ERROR_NOT_ENOUGH_MEMORY { 1236 return nil, err 1237 } 1238 buf = append(buf, make([]uint16, n-uint32(len(buf)))...) 1239 } 1240 return buf, nil 1241 } 1242 1243 func Fchdir(fd Handle) (err error) { 1244 var buf [MAX_PATH + 1]uint16 1245 path, err := fdpath(fd, buf[:]) 1246 if err != nil { 1247 return err 1248 } 1249 // When using VOLUME_NAME_DOS, the path is always pefixed by "\\?\". 1250 // That prefix tells the Windows APIs to disable all string parsing and to send 1251 // the string that follows it straight to the file system. 1252 // Although SetCurrentDirectory and GetCurrentDirectory do support the "\\?\" prefix, 1253 // some other Windows APIs don't. If the prefix is not removed here, it will leak 1254 // to Getwd, and we don't want such a general-purpose function to always return a 1255 // path with the "\\?\" prefix after Fchdir is called. 1256 // The downside is that APIs that do support it will parse the path and try to normalize it, 1257 // when it's already normalized. 1258 if len(path) >= 4 && path[0] == '\\' && path[1] == '\\' && path[2] == '?' && path[3] == '\\' { 1259 path = path[4:] 1260 } 1261 return SetCurrentDirectory(&path[0]) 1262 } 1263 1264 // TODO(brainman): fix all needed for os 1265 func Link(oldpath, newpath string) (err error) { return EWINDOWS } 1266 func Symlink(path, link string) (err error) { return EWINDOWS } 1267 1268 func Fchmod(fd Handle, mode uint32) (err error) { return EWINDOWS } 1269 func Chown(path string, uid int, gid int) (err error) { return EWINDOWS } 1270 func Lchown(path string, uid int, gid int) (err error) { return EWINDOWS } 1271 func Fchown(fd Handle, uid int, gid int) (err error) { return EWINDOWS } 1272 1273 func Getuid() (uid int) { return -1 } 1274 func Geteuid() (euid int) { return -1 } 1275 func Getgid() (gid int) { return -1 } 1276 func Getegid() (egid int) { return -1 } 1277 func Getgroups() (gids []int, err error) { return nil, EWINDOWS } 1278 1279 type Signal int 1280 1281 func (s Signal) Signal() {} 1282 1283 func (s Signal) String() string { 1284 if 0 <= s && int(s) < len(signals) { 1285 str := signals[s] 1286 if str != "" { 1287 return str 1288 } 1289 } 1290 return "signal " + itoa.Itoa(int(s)) 1291 } 1292 1293 func LoadCreateSymbolicLink() error { 1294 return procCreateSymbolicLinkW.Find() 1295 } 1296 1297 // Readlink returns the destination of the named symbolic link. 1298 func Readlink(path string, buf []byte) (n int, err error) { 1299 fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING, 1300 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0) 1301 if err != nil { 1302 return -1, err 1303 } 1304 defer CloseHandle(fd) 1305 1306 rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE) 1307 var bytesReturned uint32 1308 err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) 1309 if err != nil { 1310 return -1, err 1311 } 1312 1313 rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0])) 1314 var s string 1315 switch rdb.ReparseTag { 1316 case IO_REPARSE_TAG_SYMLINK: 1317 data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) 1318 p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) 1319 s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2]) 1320 if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 { 1321 if len(s) >= 4 && s[:4] == `\??\` { 1322 s = s[4:] 1323 switch { 1324 case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar 1325 // do nothing 1326 case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar 1327 s = `\\` + s[4:] 1328 default: 1329 // unexpected; do nothing 1330 } 1331 } else { 1332 // unexpected; do nothing 1333 } 1334 } 1335 case _IO_REPARSE_TAG_MOUNT_POINT: 1336 data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) 1337 p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) 1338 s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2]) 1339 if len(s) >= 4 && s[:4] == `\??\` { // \??\C:\foo\bar 1340 s = s[4:] 1341 } else { 1342 // unexpected; do nothing 1343 } 1344 default: 1345 // the path is not a symlink or junction but another type of reparse 1346 // point 1347 return -1, ENOENT 1348 } 1349 n = copy(buf, []byte(s)) 1350 1351 return n, nil 1352 } 1353 1354 // Deprecated: CreateIoCompletionPort has the wrong function signature. Use x/sys/windows.CreateIoCompletionPort. 1355 func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (Handle, error) { 1356 return createIoCompletionPort(filehandle, cphandle, uintptr(key), threadcnt) 1357 } 1358 1359 // Deprecated: GetQueuedCompletionStatus has the wrong function signature. Use x/sys/windows.GetQueuedCompletionStatus. 1360 func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) error { 1361 var ukey uintptr 1362 var pukey *uintptr 1363 if key != nil { 1364 ukey = uintptr(*key) 1365 pukey = &ukey 1366 } 1367 err := getQueuedCompletionStatus(cphandle, qty, pukey, overlapped, timeout) 1368 if key != nil { 1369 *key = uint32(ukey) 1370 if uintptr(*key) != ukey && err == nil { 1371 err = errorspkg.New("GetQueuedCompletionStatus returned key overflow") 1372 } 1373 } 1374 return err 1375 } 1376 1377 // Deprecated: PostQueuedCompletionStatus has the wrong function signature. Use x/sys/windows.PostQueuedCompletionStatus. 1378 func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) error { 1379 return postQueuedCompletionStatus(cphandle, qty, uintptr(key), overlapped) 1380 } 1381 1382 // newProcThreadAttributeList allocates new PROC_THREAD_ATTRIBUTE_LIST, with 1383 // the requested maximum number of attributes, which must be cleaned up by 1384 // deleteProcThreadAttributeList. 1385 func newProcThreadAttributeList(maxAttrCount uint32) (*_PROC_THREAD_ATTRIBUTE_LIST, error) { 1386 var size uintptr 1387 err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size) 1388 if err != ERROR_INSUFFICIENT_BUFFER { 1389 if err == nil { 1390 return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList") 1391 } 1392 return nil, err 1393 } 1394 // size is guaranteed to be ≥1 by initializeProcThreadAttributeList. 1395 al := (*_PROC_THREAD_ATTRIBUTE_LIST)(unsafe.Pointer(&make([]byte, size)[0])) 1396 err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size) 1397 if err != nil { 1398 return nil, err 1399 } 1400 return al, nil 1401 } 1402 1403 // RegEnumKeyEx enumerates the subkeys of an open registry key. 1404 // Each call retrieves information about one subkey. name is 1405 // a buffer that should be large enough to hold the name of the 1406 // subkey plus a null terminating character. nameLen is its 1407 // length. On return, nameLen will contain the actual length of the 1408 // subkey. 1409 // 1410 // Should name not be large enough to hold the subkey, this function 1411 // will return ERROR_MORE_DATA, and must be called again with an 1412 // appropriately sized buffer. 1413 // 1414 // reserved must be nil. class and classLen behave like name and nameLen 1415 // but for the class of the subkey, except that they are optional. 1416 // lastWriteTime, if not nil, will be populated with the time the subkey 1417 // was last written. 1418 // 1419 // The caller must enumerate all subkeys in order. That is 1420 // RegEnumKeyEx must be called with index starting at 0, incrementing 1421 // the index until the function returns ERROR_NO_MORE_ITEMS, or with 1422 // the index of the last subkey (obtainable from RegQueryInfoKey), 1423 // decrementing until index 0 is enumerated. 1424 // 1425 // Successive calls to this API must happen on the same OS thread, 1426 // so call runtime.LockOSThread before calling this function. 1427 func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { 1428 return regEnumKeyEx(key, index, name, nameLen, reserved, class, classLen, lastWriteTime) 1429 }