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 7package windows 8 9import ( 10 errorspkg "errors" 11 "sync" 12 "syscall" 13 "time" 14 "unicode/utf16" 15 "unsafe" 16 17 "golang.org/x/sys/internal/unsafeheader" 18) 19 20type Handle uintptr 21type HWND uintptr 22 23const ( 24 InvalidHandle = ^Handle(0) 25 26 // Flags for DefineDosDevice. 27 DDD_EXACT_MATCH_ON_REMOVE = 0x00000004 28 DDD_NO_BROADCAST_SYSTEM = 0x00000008 29 DDD_RAW_TARGET_PATH = 0x00000001 30 DDD_REMOVE_DEFINITION = 0x00000002 31 32 // Return values for GetDriveType. 33 DRIVE_UNKNOWN = 0 34 DRIVE_NO_ROOT_DIR = 1 35 DRIVE_REMOVABLE = 2 36 DRIVE_FIXED = 3 37 DRIVE_REMOTE = 4 38 DRIVE_CDROM = 5 39 DRIVE_RAMDISK = 6 40 41 // File system flags from GetVolumeInformation and GetVolumeInformationByHandle. 42 FILE_CASE_SENSITIVE_SEARCH = 0x00000001 43 FILE_CASE_PRESERVED_NAMES = 0x00000002 44 FILE_FILE_COMPRESSION = 0x00000010 45 FILE_DAX_VOLUME = 0x20000000 46 FILE_NAMED_STREAMS = 0x00040000 47 FILE_PERSISTENT_ACLS = 0x00000008 48 FILE_READ_ONLY_VOLUME = 0x00080000 49 FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000 50 FILE_SUPPORTS_ENCRYPTION = 0x00020000 51 FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000 52 FILE_SUPPORTS_HARD_LINKS = 0x00400000 53 FILE_SUPPORTS_OBJECT_IDS = 0x00010000 54 FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000 55 FILE_SUPPORTS_REPARSE_POINTS = 0x00000080 56 FILE_SUPPORTS_SPARSE_FILES = 0x00000040 57 FILE_SUPPORTS_TRANSACTIONS = 0x00200000 58 FILE_SUPPORTS_USN_JOURNAL = 0x02000000 59 FILE_UNICODE_ON_DISK = 0x00000004 60 FILE_VOLUME_IS_COMPRESSED = 0x00008000 61 FILE_VOLUME_QUOTAS = 0x00000020 62 63 // Flags for LockFileEx. 64 LOCKFILE_FAIL_IMMEDIATELY = 0x00000001 65 LOCKFILE_EXCLUSIVE_LOCK = 0x00000002 66 67 // Return values of SleepEx and other APC functions 68 STATUS_USER_APC = 0x000000C0 69 WAIT_IO_COMPLETION = STATUS_USER_APC 70) 71 72// StringToUTF16 is deprecated. Use UTF16FromString instead. 73// If s contains a NUL byte this function panics instead of 74// returning an error. 75func StringToUTF16(s string) []uint16 { 76 a, err := UTF16FromString(s) 77 if err != nil { 78 panic("windows: string with NUL passed to StringToUTF16") 79 } 80 return a 81} 82 83// UTF16FromString returns the UTF-16 encoding of the UTF-8 string 84// s, with a terminating NUL added. If s contains a NUL byte at any 85// location, it returns (nil, syscall.EINVAL). 86func UTF16FromString(s string) ([]uint16, error) { 87 for i := 0; i < len(s); i++ { 88 if s[i] == 0 { 89 return nil, syscall.EINVAL 90 } 91 } 92 return utf16.Encode([]rune(s + "\x00")), nil 93} 94 95// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, 96// with a terminating NUL and any bytes after the NUL removed. 97func UTF16ToString(s []uint16) string { 98 for i, v := range s { 99 if v == 0 { 100 s = s[:i] 101 break 102 } 103 } 104 return string(utf16.Decode(s)) 105} 106 107// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead. 108// If s contains a NUL byte this function panics instead of 109// returning an error. 110func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] } 111 112// UTF16PtrFromString returns pointer to the UTF-16 encoding of 113// the UTF-8 string s, with a terminating NUL added. If s 114// contains a NUL byte at any location, it returns (nil, syscall.EINVAL). 115func UTF16PtrFromString(s string) (*uint16, error) { 116 a, err := UTF16FromString(s) 117 if err != nil { 118 return nil, err 119 } 120 return &a[0], nil 121} 122 123// UTF16PtrToString takes a pointer to a UTF-16 sequence and returns the corresponding UTF-8 encoded string. 124// If the pointer is nil, it returns the empty string. It assumes that the UTF-16 sequence is terminated 125// at a zero word; if the zero word is not present, the program may crash. 126func UTF16PtrToString(p *uint16) string { 127 if p == nil { 128 return "" 129 } 130 if *p == 0 { 131 return "" 132 } 133 134 // Find NUL terminator. 135 n := 0 136 for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { 137 ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) 138 } 139 140 var s []uint16 141 h := (*unsafeheader.Slice)(unsafe.Pointer(&s)) 142 h.Data = unsafe.Pointer(p) 143 h.Len = n 144 h.Cap = n 145 146 return string(utf16.Decode(s)) 147} 148 149func Getpagesize() int { return 4096 } 150 151// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. 152// This is useful when interoperating with Windows code requiring callbacks. 153// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. 154func NewCallback(fn interface{}) uintptr { 155 return syscall.NewCallback(fn) 156} 157 158// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. 159// This is useful when interoperating with Windows code requiring callbacks. 160// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. 161func NewCallbackCDecl(fn interface{}) uintptr { 162 return syscall.NewCallbackCDecl(fn) 163} 164 165// windows api calls 166 167//sys GetLastError() (lasterr error) 168//sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW 169//sys LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, err error) = LoadLibraryExW 170//sys FreeLibrary(handle Handle) (err error) 171//sys GetProcAddress(module Handle, procname string) (proc uintptr, err error) 172//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW 173//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW 174//sys SetDefaultDllDirectories(directoryFlags uint32) (err error) 175//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW 176//sys GetVersion() (ver uint32, err error) 177//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW 178//sys ExitProcess(exitcode uint32) 179//sys IsWow64Process(handle Handle, isWow64 *bool) (err error) = IsWow64Process 180//sys IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint16) (err error) = IsWow64Process2? 181//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW 182//sys ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) 183//sys WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) 184//sys GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) 185//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff] 186//sys CloseHandle(handle Handle) (err error) 187//sys GetStdHandle(stdhandle uint32) (handle Handle, err error) [failretval==InvalidHandle] 188//sys SetStdHandle(stdhandle uint32, handle Handle) (err error) 189//sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW 190//sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW 191//sys FindClose(handle Handle) (err error) 192//sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) 193//sys GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) 194//sys SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inBufferLen uint32) (err error) 195//sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW 196//sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW 197//sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW 198//sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW 199//sys DeleteFile(path *uint16) (err error) = DeleteFileW 200//sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW 201//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW 202//sys LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) 203//sys UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) 204//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW 205//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW 206//sys SetEndOfFile(handle Handle) (err error) 207//sys GetSystemTimeAsFileTime(time *Filetime) 208//sys GetSystemTimePreciseAsFileTime(time *Filetime) 209//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] 210//sys CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) 211//sys GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) 212//sys PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) 213//sys CancelIo(s Handle) (err error) 214//sys CancelIoEx(s Handle, o *Overlapped) (err error) 215//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 216//sys OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (handle Handle, err error) 217//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) [failretval<=32] = shell32.ShellExecuteW 218//sys GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32) = user32.GetWindowThreadProcessId 219//sys GetShellWindow() (shellWindow HWND) = user32.GetShellWindow 220//sys MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) [failretval==0] = user32.MessageBoxW 221//sys ExitWindowsEx(flags uint32, reason uint32) (err error) = user32.ExitWindowsEx 222//sys shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) = shell32.SHGetKnownFolderPath 223//sys TerminateProcess(handle Handle, exitcode uint32) (err error) 224//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) 225//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW 226//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) 227//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) 228//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] 229//sys waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff] = WaitForMultipleObjects 230//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW 231//sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) 232//sys GetFileType(filehandle Handle) (n uint32, err error) 233//sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW 234//sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext 235//sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom 236//sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW 237//sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW 238//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW 239//sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW 240//sys CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock 241//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock 242//sys getTickCount64() (ms uint64) = kernel32.GetTickCount64 243//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) 244//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW 245//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW 246//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW 247//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW 248//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW 249//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0] 250//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) 251//sys FlushFileBuffers(handle Handle) (err error) 252//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW 253//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW 254//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW 255//sys GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW 256//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW 257//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) 258//sys UnmapViewOfFile(addr uintptr) (err error) 259//sys FlushViewOfFile(addr uintptr, length uintptr) (err error) 260//sys VirtualLock(addr uintptr, length uintptr) (err error) 261//sys VirtualUnlock(addr uintptr, length uintptr) (err error) 262//sys VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc 263//sys VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree 264//sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect 265//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile 266//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW 267//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW 268//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore 269//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore 270//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore 271//sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore 272//sys CertDeleteCertificateFromStore(certContext *CertContext) (err error) = crypt32.CertDeleteCertificateFromStore 273//sys CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) = crypt32.CertDuplicateCertificateContext 274//sys PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) = crypt32.PFXImportCertStore 275//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain 276//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain 277//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext 278//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext 279//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy 280//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW 281//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey 282//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 283//sys RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW 284//sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW 285//sys RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) = advapi32.RegNotifyChangeKeyValue 286//sys GetCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId 287//sys ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) = kernel32.ProcessIdToSessionId 288//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode 289//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode 290//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo 291//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition 292//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW 293//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW 294//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot 295//sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW 296//sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW 297//sys Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) 298//sys Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) 299//sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) 300// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL. 301//sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW 302//sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW 303//sys GetCurrentThreadId() (id uint32) 304//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW 305//sys CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateEventExW 306//sys OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW 307//sys SetEvent(event Handle) (err error) = kernel32.SetEvent 308//sys ResetEvent(event Handle) (err error) = kernel32.ResetEvent 309//sys PulseEvent(event Handle) (err error) = kernel32.PulseEvent 310//sys CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16) (handle Handle, err error) = kernel32.CreateMutexW 311//sys CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateMutexExW 312//sys OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenMutexW 313//sys ReleaseMutex(mutex Handle) (err error) = kernel32.ReleaseMutex 314//sys SleepEx(milliseconds uint32, alertable bool) (ret uint32) = kernel32.SleepEx 315//sys CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, err error) = kernel32.CreateJobObjectW 316//sys AssignProcessToJobObject(job Handle, process Handle) (err error) = kernel32.AssignProcessToJobObject 317//sys TerminateJobObject(job Handle, exitCode uint32) (err error) = kernel32.TerminateJobObject 318//sys SetErrorMode(mode uint32) (ret uint32) = kernel32.SetErrorMode 319//sys ResumeThread(thread Handle) (ret uint32, err error) [failretval==0xffffffff] = kernel32.ResumeThread 320//sys SetPriorityClass(process Handle, priorityClass uint32) (err error) = kernel32.SetPriorityClass 321//sys GetPriorityClass(process Handle) (ret uint32, err error) = kernel32.GetPriorityClass 322//sys QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) = kernel32.QueryInformationJobObject 323//sys SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) 324//sys GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) 325//sys GetProcessId(process Handle) (id uint32, err error) 326//sys OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error) 327//sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost 328//sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) 329//sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) 330 331// Volume Management Functions 332//sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW 333//sys DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) = DeleteVolumeMountPointW 334//sys FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeW 335//sys FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstVolumeMountPointW 336//sys FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) = FindNextVolumeW 337//sys FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW 338//sys FindVolumeClose(findVolume Handle) (err error) 339//sys FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) 340//sys GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = GetDiskFreeSpaceExW 341//sys GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW 342//sys GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0] 343//sys GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW 344//sys GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationW 345//sys GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW 346//sys GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW 347//sys GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) = GetVolumePathNameW 348//sys GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) = GetVolumePathNamesForVolumeNameW 349//sys QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) [failretval==0] = QueryDosDeviceW 350//sys SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) = SetVolumeLabelW 351//sys SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) = SetVolumeMountPointW 352//sys InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint32, forceAppsClosed bool, rebootAfterShutdown bool, reason uint32) (err error) = advapi32.InitiateSystemShutdownExW 353//sys SetProcessShutdownParameters(level uint32, flags uint32) (err error) = kernel32.SetProcessShutdownParameters 354//sys GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) = kernel32.GetProcessShutdownParameters 355//sys clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) = ole32.CLSIDFromString 356//sys stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) = ole32.StringFromGUID2 357//sys coCreateGuid(pguid *GUID) (ret error) = ole32.CoCreateGuid 358//sys CoTaskMemFree(address unsafe.Pointer) = ole32.CoTaskMemFree 359//sys rtlGetVersion(info *OsVersionInfoEx) (ret error) = ntdll.RtlGetVersion 360//sys rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers 361//sys getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetProcessPreferredUILanguages 362//sys getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetThreadPreferredUILanguages 363//sys getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetUserPreferredUILanguages 364//sys getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) = kernel32.GetSystemPreferredUILanguages 365 366// Process Status API (PSAPI) 367//sys EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses 368 369// syscall interface implementation for other packages 370 371// GetCurrentProcess returns the handle for the current process. 372// It is a pseudo handle that does not need to be closed. 373// The returned error is always nil. 374// 375// Deprecated: use CurrentProcess for the same Handle without the nil 376// error. 377func GetCurrentProcess() (Handle, error) { 378 return CurrentProcess(), nil 379} 380 381// CurrentProcess returns the handle for the current process. 382// It is a pseudo handle that does not need to be closed. 383func CurrentProcess() Handle { return Handle(^uintptr(1 - 1)) } 384 385// GetCurrentThread returns the handle for the current thread. 386// It is a pseudo handle that does not need to be closed. 387// The returned error is always nil. 388// 389// Deprecated: use CurrentThread for the same Handle without the nil 390// error. 391func GetCurrentThread() (Handle, error) { 392 return CurrentThread(), nil 393} 394 395// CurrentThread returns the handle for the current thread. 396// It is a pseudo handle that does not need to be closed. 397func CurrentThread() Handle { return Handle(^uintptr(2 - 1)) } 398 399// GetProcAddressByOrdinal retrieves the address of the exported 400// function from module by ordinal. 401func GetProcAddressByOrdinal(module Handle, ordinal uintptr) (proc uintptr, err error) { 402 r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0) 403 proc = uintptr(r0) 404 if proc == 0 { 405 err = errnoErr(e1) 406 } 407 return 408} 409 410func Exit(code int) { ExitProcess(uint32(code)) } 411 412func makeInheritSa() *SecurityAttributes { 413 var sa SecurityAttributes 414 sa.Length = uint32(unsafe.Sizeof(sa)) 415 sa.InheritHandle = 1 416 return &sa 417} 418 419func Open(path string, mode int, perm uint32) (fd Handle, err error) { 420 if len(path) == 0 { 421 return InvalidHandle, ERROR_FILE_NOT_FOUND 422 } 423 pathp, err := UTF16PtrFromString(path) 424 if err != nil { 425 return InvalidHandle, err 426 } 427 var access uint32 428 switch mode & (O_RDONLY | O_WRONLY | O_RDWR) { 429 case O_RDONLY: 430 access = GENERIC_READ 431 case O_WRONLY: 432 access = GENERIC_WRITE 433 case O_RDWR: 434 access = GENERIC_READ | GENERIC_WRITE 435 } 436 if mode&O_CREAT != 0 { 437 access |= GENERIC_WRITE 438 } 439 if mode&O_APPEND != 0 { 440 access &^= GENERIC_WRITE 441 access |= FILE_APPEND_DATA 442 } 443 sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE) 444 var sa *SecurityAttributes 445 if mode&O_CLOEXEC == 0 { 446 sa = makeInheritSa() 447 } 448 var createmode uint32 449 switch { 450 case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL): 451 createmode = CREATE_NEW 452 case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC): 453 createmode = CREATE_ALWAYS 454 case mode&O_CREAT == O_CREAT: 455 createmode = OPEN_ALWAYS 456 case mode&O_TRUNC == O_TRUNC: 457 createmode = TRUNCATE_EXISTING 458 default: 459 createmode = OPEN_EXISTING 460 } 461 var attrs uint32 = FILE_ATTRIBUTE_NORMAL 462 if perm&S_IWRITE == 0 { 463 attrs = FILE_ATTRIBUTE_READONLY 464 } 465 h, e := CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0) 466 return h, e 467} 468 469func Read(fd Handle, p []byte) (n int, err error) { 470 var done uint32 471 e := ReadFile(fd, p, &done, nil) 472 if e != nil { 473 if e == ERROR_BROKEN_PIPE { 474 // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin 475 return 0, nil 476 } 477 return 0, e 478 } 479 if raceenabled { 480 if done > 0 { 481 raceWriteRange(unsafe.Pointer(&p[0]), int(done)) 482 } 483 raceAcquire(unsafe.Pointer(&ioSync)) 484 } 485 return int(done), nil 486} 487 488func Write(fd Handle, p []byte) (n int, err error) { 489 if raceenabled { 490 raceReleaseMerge(unsafe.Pointer(&ioSync)) 491 } 492 var done uint32 493 e := WriteFile(fd, p, &done, nil) 494 if e != nil { 495 return 0, e 496 } 497 if raceenabled && done > 0 { 498 raceReadRange(unsafe.Pointer(&p[0]), int(done)) 499 } 500 return int(done), nil 501} 502 503var ioSync int64 504 505func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) { 506 var w uint32 507 switch whence { 508 case 0: 509 w = FILE_BEGIN 510 case 1: 511 w = FILE_CURRENT 512 case 2: 513 w = FILE_END 514 } 515 hi := int32(offset >> 32) 516 lo := int32(offset) 517 // use GetFileType to check pipe, pipe can't do seek 518 ft, _ := GetFileType(fd) 519 if ft == FILE_TYPE_PIPE { 520 return 0, syscall.EPIPE 521 } 522 rlo, e := SetFilePointer(fd, lo, &hi, w) 523 if e != nil { 524 return 0, e 525 } 526 return int64(hi)<<32 + int64(rlo), nil 527} 528 529func Close(fd Handle) (err error) { 530 return CloseHandle(fd) 531} 532 533var ( 534 Stdin = getStdHandle(STD_INPUT_HANDLE) 535 Stdout = getStdHandle(STD_OUTPUT_HANDLE) 536 Stderr = getStdHandle(STD_ERROR_HANDLE) 537) 538 539func getStdHandle(stdhandle uint32) (fd Handle) { 540 r, _ := GetStdHandle(stdhandle) 541 CloseOnExec(r) 542 return r 543} 544 545const ImplementsGetwd = true 546 547func Getwd() (wd string, err error) { 548 b := make([]uint16, 300) 549 n, e := GetCurrentDirectory(uint32(len(b)), &b[0]) 550 if e != nil { 551 return "", e 552 } 553 return string(utf16.Decode(b[0:n])), nil 554} 555 556func Chdir(path string) (err error) { 557 pathp, err := UTF16PtrFromString(path) 558 if err != nil { 559 return err 560 } 561 return SetCurrentDirectory(pathp) 562} 563 564func Mkdir(path string, mode uint32) (err error) { 565 pathp, err := UTF16PtrFromString(path) 566 if err != nil { 567 return err 568 } 569 return CreateDirectory(pathp, nil) 570} 571 572func Rmdir(path string) (err error) { 573 pathp, err := UTF16PtrFromString(path) 574 if err != nil { 575 return err 576 } 577 return RemoveDirectory(pathp) 578} 579 580func Unlink(path string) (err error) { 581 pathp, err := UTF16PtrFromString(path) 582 if err != nil { 583 return err 584 } 585 return DeleteFile(pathp) 586} 587 588func Rename(oldpath, newpath string) (err error) { 589 from, err := UTF16PtrFromString(oldpath) 590 if err != nil { 591 return err 592 } 593 to, err := UTF16PtrFromString(newpath) 594 if err != nil { 595 return err 596 } 597 return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) 598} 599 600func ComputerName() (name string, err error) { 601 var n uint32 = MAX_COMPUTERNAME_LENGTH + 1 602 b := make([]uint16, n) 603 e := GetComputerName(&b[0], &n) 604 if e != nil { 605 return "", e 606 } 607 return string(utf16.Decode(b[0:n])), nil 608} 609 610func DurationSinceBoot() time.Duration { 611 return time.Duration(getTickCount64()) * time.Millisecond 612} 613 614func Ftruncate(fd Handle, length int64) (err error) { 615 curoffset, e := Seek(fd, 0, 1) 616 if e != nil { 617 return e 618 } 619 defer Seek(fd, curoffset, 0) 620 _, e = Seek(fd, length, 0) 621 if e != nil { 622 return e 623 } 624 e = SetEndOfFile(fd) 625 if e != nil { 626 return e 627 } 628 return nil 629} 630 631func Gettimeofday(tv *Timeval) (err error) { 632 var ft Filetime 633 GetSystemTimeAsFileTime(&ft) 634 *tv = NsecToTimeval(ft.Nanoseconds()) 635 return nil 636} 637 638func Pipe(p []Handle) (err error) { 639 if len(p) != 2 { 640 return syscall.EINVAL 641 } 642 var r, w Handle 643 e := CreatePipe(&r, &w, makeInheritSa(), 0) 644 if e != nil { 645 return e 646 } 647 p[0] = r 648 p[1] = w 649 return nil 650} 651 652func Utimes(path string, tv []Timeval) (err error) { 653 if len(tv) != 2 { 654 return syscall.EINVAL 655 } 656 pathp, e := UTF16PtrFromString(path) 657 if e != nil { 658 return e 659 } 660 h, e := CreateFile(pathp, 661 FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, 662 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) 663 if e != nil { 664 return e 665 } 666 defer Close(h) 667 a := NsecToFiletime(tv[0].Nanoseconds()) 668 w := NsecToFiletime(tv[1].Nanoseconds()) 669 return SetFileTime(h, nil, &a, &w) 670} 671 672func UtimesNano(path string, ts []Timespec) (err error) { 673 if len(ts) != 2 { 674 return syscall.EINVAL 675 } 676 pathp, e := UTF16PtrFromString(path) 677 if e != nil { 678 return e 679 } 680 h, e := CreateFile(pathp, 681 FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil, 682 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0) 683 if e != nil { 684 return e 685 } 686 defer Close(h) 687 a := NsecToFiletime(TimespecToNsec(ts[0])) 688 w := NsecToFiletime(TimespecToNsec(ts[1])) 689 return SetFileTime(h, nil, &a, &w) 690} 691 692func Fsync(fd Handle) (err error) { 693 return FlushFileBuffers(fd) 694} 695 696func Chmod(path string, mode uint32) (err error) { 697 p, e := UTF16PtrFromString(path) 698 if e != nil { 699 return e 700 } 701 attrs, e := GetFileAttributes(p) 702 if e != nil { 703 return e 704 } 705 if mode&S_IWRITE != 0 { 706 attrs &^= FILE_ATTRIBUTE_READONLY 707 } else { 708 attrs |= FILE_ATTRIBUTE_READONLY 709 } 710 return SetFileAttributes(p, attrs) 711} 712 713func LoadGetSystemTimePreciseAsFileTime() error { 714 return procGetSystemTimePreciseAsFileTime.Find() 715} 716 717func LoadCancelIoEx() error { 718 return procCancelIoEx.Find() 719} 720 721func LoadSetFileCompletionNotificationModes() error { 722 return procSetFileCompletionNotificationModes.Find() 723} 724 725func WaitForMultipleObjects(handles []Handle, waitAll bool, waitMilliseconds uint32) (event uint32, err error) { 726 // Every other win32 array API takes arguments as "pointer, count", except for this function. So we 727 // can't declare it as a usual [] type, because mksyscall will use the opposite order. We therefore 728 // trivially stub this ourselves. 729 730 var handlePtr *Handle 731 if len(handles) > 0 { 732 handlePtr = &handles[0] 733 } 734 return waitForMultipleObjects(uint32(len(handles)), uintptr(unsafe.Pointer(handlePtr)), waitAll, waitMilliseconds) 735} 736 737// net api calls 738 739const socket_error = uintptr(^uint32(0)) 740 741//sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup 742//sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup 743//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 744//sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket 745//sys sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) (err error) [failretval==socket_error] = ws2_32.sendto 746//sys recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen *int32) (n int32, err error) [failretval==-1] = ws2_32.recvfrom 747//sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt 748//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt 749//sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind 750//sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect 751//sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname 752//sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername 753//sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen 754//sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown 755//sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket 756//sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx 757//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs 758//sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv 759//sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend 760//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 761//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 762//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname 763//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname 764//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs 765//sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname 766//sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W 767//sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree 768//sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W 769//sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW 770//sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW 771//sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry 772//sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo 773//sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes 774//sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW 775//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses 776//sys GetACP() (acp uint32) = kernel32.GetACP 777//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar 778 779// For testing: clients can set this flag to force 780// creation of IPv6 sockets to return EAFNOSUPPORT. 781var SocketDisableIPv6 bool 782 783type RawSockaddrInet4 struct { 784 Family uint16 785 Port uint16 786 Addr [4]byte /* in_addr */ 787 Zero [8]uint8 788} 789 790type RawSockaddrInet6 struct { 791 Family uint16 792 Port uint16 793 Flowinfo uint32 794 Addr [16]byte /* in6_addr */ 795 Scope_id uint32 796} 797 798type RawSockaddr struct { 799 Family uint16 800 Data [14]int8 801} 802 803type RawSockaddrAny struct { 804 Addr RawSockaddr 805 Pad [100]int8 806} 807 808type Sockaddr interface { 809 sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs 810} 811 812type SockaddrInet4 struct { 813 Port int 814 Addr [4]byte 815 raw RawSockaddrInet4 816} 817 818func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) { 819 if sa.Port < 0 || sa.Port > 0xFFFF { 820 return nil, 0, syscall.EINVAL 821 } 822 sa.raw.Family = AF_INET 823 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 824 p[0] = byte(sa.Port >> 8) 825 p[1] = byte(sa.Port) 826 for i := 0; i < len(sa.Addr); i++ { 827 sa.raw.Addr[i] = sa.Addr[i] 828 } 829 return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil 830} 831 832type SockaddrInet6 struct { 833 Port int 834 ZoneId uint32 835 Addr [16]byte 836 raw RawSockaddrInet6 837} 838 839func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) { 840 if sa.Port < 0 || sa.Port > 0xFFFF { 841 return nil, 0, syscall.EINVAL 842 } 843 sa.raw.Family = AF_INET6 844 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 845 p[0] = byte(sa.Port >> 8) 846 p[1] = byte(sa.Port) 847 sa.raw.Scope_id = sa.ZoneId 848 for i := 0; i < len(sa.Addr); i++ { 849 sa.raw.Addr[i] = sa.Addr[i] 850 } 851 return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil 852} 853 854type RawSockaddrUnix struct { 855 Family uint16 856 Path [UNIX_PATH_MAX]int8 857} 858 859type SockaddrUnix struct { 860 Name string 861 raw RawSockaddrUnix 862} 863 864func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { 865 name := sa.Name 866 n := len(name) 867 if n > len(sa.raw.Path) { 868 return nil, 0, syscall.EINVAL 869 } 870 if n == len(sa.raw.Path) && name[0] != '@' { 871 return nil, 0, syscall.EINVAL 872 } 873 sa.raw.Family = AF_UNIX 874 for i := 0; i < n; i++ { 875 sa.raw.Path[i] = int8(name[i]) 876 } 877 // length is family (uint16), name, NUL. 878 sl := int32(2) 879 if n > 0 { 880 sl += int32(n) + 1 881 } 882 if sa.raw.Path[0] == '@' { 883 sa.raw.Path[0] = 0 884 // Don't count trailing NUL for abstract address. 885 sl-- 886 } 887 888 return unsafe.Pointer(&sa.raw), sl, nil 889} 890 891func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { 892 switch rsa.Addr.Family { 893 case AF_UNIX: 894 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 895 sa := new(SockaddrUnix) 896 if pp.Path[0] == 0 { 897 // "Abstract" Unix domain socket. 898 // Rewrite leading NUL as @ for textual display. 899 // (This is the standard convention.) 900 // Not friendly to overwrite in place, 901 // but the callers below don't care. 902 pp.Path[0] = '@' 903 } 904 905 // Assume path ends at NUL. 906 // This is not technically the Linux semantics for 907 // abstract Unix domain sockets--they are supposed 908 // to be uninterpreted fixed-size binary blobs--but 909 // everyone uses this convention. 910 n := 0 911 for n < len(pp.Path) && pp.Path[n] != 0 { 912 n++ 913 } 914 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 915 sa.Name = string(bytes) 916 return sa, nil 917 918 case AF_INET: 919 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 920 sa := new(SockaddrInet4) 921 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 922 sa.Port = int(p[0])<<8 + int(p[1]) 923 for i := 0; i < len(sa.Addr); i++ { 924 sa.Addr[i] = pp.Addr[i] 925 } 926 return sa, nil 927 928 case AF_INET6: 929 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 930 sa := new(SockaddrInet6) 931 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 932 sa.Port = int(p[0])<<8 + int(p[1]) 933 sa.ZoneId = pp.Scope_id 934 for i := 0; i < len(sa.Addr); i++ { 935 sa.Addr[i] = pp.Addr[i] 936 } 937 return sa, nil 938 } 939 return nil, syscall.EAFNOSUPPORT 940} 941 942func Socket(domain, typ, proto int) (fd Handle, err error) { 943 if domain == AF_INET6 && SocketDisableIPv6 { 944 return InvalidHandle, syscall.EAFNOSUPPORT 945 } 946 return socket(int32(domain), int32(typ), int32(proto)) 947} 948 949func SetsockoptInt(fd Handle, level, opt int, value int) (err error) { 950 v := int32(value) 951 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v))) 952} 953 954func Bind(fd Handle, sa Sockaddr) (err error) { 955 ptr, n, err := sa.sockaddr() 956 if err != nil { 957 return err 958 } 959 return bind(fd, ptr, n) 960} 961 962func Connect(fd Handle, sa Sockaddr) (err error) { 963 ptr, n, err := sa.sockaddr() 964 if err != nil { 965 return err 966 } 967 return connect(fd, ptr, n) 968} 969 970func Getsockname(fd Handle) (sa Sockaddr, err error) { 971 var rsa RawSockaddrAny 972 l := int32(unsafe.Sizeof(rsa)) 973 if err = getsockname(fd, &rsa, &l); err != nil { 974 return 975 } 976 return rsa.Sockaddr() 977} 978 979func Getpeername(fd Handle) (sa Sockaddr, err error) { 980 var rsa RawSockaddrAny 981 l := int32(unsafe.Sizeof(rsa)) 982 if err = getpeername(fd, &rsa, &l); err != nil { 983 return 984 } 985 return rsa.Sockaddr() 986} 987 988func Listen(s Handle, n int) (err error) { 989 return listen(s, int32(n)) 990} 991 992func Shutdown(fd Handle, how int) (err error) { 993 return shutdown(fd, int32(how)) 994} 995 996func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) { 997 rsa, l, err := to.sockaddr() 998 if err != nil { 999 return err 1000 } 1001 return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine) 1002} 1003 1004func LoadGetAddrInfo() error { 1005 return procGetAddrInfoW.Find() 1006} 1007 1008var connectExFunc struct { 1009 once sync.Once 1010 addr uintptr 1011 err error 1012} 1013 1014func LoadConnectEx() error { 1015 connectExFunc.once.Do(func() { 1016 var s Handle 1017 s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) 1018 if connectExFunc.err != nil { 1019 return 1020 } 1021 defer CloseHandle(s) 1022 var n uint32 1023 connectExFunc.err = WSAIoctl(s, 1024 SIO_GET_EXTENSION_FUNCTION_POINTER, 1025 (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)), 1026 uint32(unsafe.Sizeof(WSAID_CONNECTEX)), 1027 (*byte)(unsafe.Pointer(&connectExFunc.addr)), 1028 uint32(unsafe.Sizeof(connectExFunc.addr)), 1029 &n, nil, 0) 1030 }) 1031 return connectExFunc.err 1032} 1033 1034func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) { 1035 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) 1036 if r1 == 0 { 1037 if e1 != 0 { 1038 err = error(e1) 1039 } else { 1040 err = syscall.EINVAL 1041 } 1042 } 1043 return 1044} 1045 1046func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error { 1047 err := LoadConnectEx() 1048 if err != nil { 1049 return errorspkg.New("failed to find ConnectEx: " + err.Error()) 1050 } 1051 ptr, n, err := sa.sockaddr() 1052 if err != nil { 1053 return err 1054 } 1055 return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped) 1056} 1057 1058var sendRecvMsgFunc struct { 1059 once sync.Once 1060 sendAddr uintptr 1061 recvAddr uintptr 1062 err error 1063} 1064 1065func loadWSASendRecvMsg() error { 1066 sendRecvMsgFunc.once.Do(func() { 1067 var s Handle 1068 s, sendRecvMsgFunc.err = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) 1069 if sendRecvMsgFunc.err != nil { 1070 return 1071 } 1072 defer CloseHandle(s) 1073 var n uint32 1074 sendRecvMsgFunc.err = WSAIoctl(s, 1075 SIO_GET_EXTENSION_FUNCTION_POINTER, 1076 (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), 1077 uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), 1078 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), 1079 uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), 1080 &n, nil, 0) 1081 if sendRecvMsgFunc.err != nil { 1082 return 1083 } 1084 sendRecvMsgFunc.err = WSAIoctl(s, 1085 SIO_GET_EXTENSION_FUNCTION_POINTER, 1086 (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), 1087 uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), 1088 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), 1089 uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), 1090 &n, nil, 0) 1091 }) 1092 return sendRecvMsgFunc.err 1093} 1094 1095func WSASendMsg(fd Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *Overlapped, croutine *byte) error { 1096 err := loadWSASendRecvMsg() 1097 if err != nil { 1098 return err 1099 } 1100 r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) 1101 if r1 == socket_error { 1102 err = errnoErr(e1) 1103 } 1104 return err 1105} 1106 1107func WSARecvMsg(fd Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *Overlapped, croutine *byte) error { 1108 err := loadWSASendRecvMsg() 1109 if err != nil { 1110 return err 1111 } 1112 r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) 1113 if r1 == socket_error { 1114 err = errnoErr(e1) 1115 } 1116 return err 1117} 1118 1119// Invented structures to support what package os expects. 1120type Rusage struct { 1121 CreationTime Filetime 1122 ExitTime Filetime 1123 KernelTime Filetime 1124 UserTime Filetime 1125} 1126 1127type WaitStatus struct { 1128 ExitCode uint32 1129} 1130 1131func (w WaitStatus) Exited() bool { return true } 1132 1133func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) } 1134 1135func (w WaitStatus) Signal() Signal { return -1 } 1136 1137func (w WaitStatus) CoreDump() bool { return false } 1138 1139func (w WaitStatus) Stopped() bool { return false } 1140 1141func (w WaitStatus) Continued() bool { return false } 1142 1143func (w WaitStatus) StopSignal() Signal { return -1 } 1144 1145func (w WaitStatus) Signaled() bool { return false } 1146 1147func (w WaitStatus) TrapCause() int { return -1 } 1148 1149// Timespec is an invented structure on Windows, but here for 1150// consistency with the corresponding package for other operating systems. 1151type Timespec struct { 1152 Sec int64 1153 Nsec int64 1154} 1155 1156func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 1157 1158func NsecToTimespec(nsec int64) (ts Timespec) { 1159 ts.Sec = nsec / 1e9 1160 ts.Nsec = nsec % 1e9 1161 return 1162} 1163 1164// TODO(brainman): fix all needed for net 1165 1166func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS } 1167 1168func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) { 1169 var rsa RawSockaddrAny 1170 l := int32(unsafe.Sizeof(rsa)) 1171 n32, err := recvfrom(fd, p, int32(flags), &rsa, &l) 1172 n = int(n32) 1173 if err != nil { 1174 return 1175 } 1176 from, err = rsa.Sockaddr() 1177 return 1178} 1179 1180func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { 1181 ptr, l, err := to.sockaddr() 1182 if err != nil { 1183 return err 1184 } 1185 return sendto(fd, p, int32(flags), ptr, l) 1186} 1187 1188func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS } 1189 1190// The Linger struct is wrong but we only noticed after Go 1. 1191// sysLinger is the real system call structure. 1192 1193// BUG(brainman): The definition of Linger is not appropriate for direct use 1194// with Setsockopt and Getsockopt. 1195// Use SetsockoptLinger instead. 1196 1197type Linger struct { 1198 Onoff int32 1199 Linger int32 1200} 1201 1202type sysLinger struct { 1203 Onoff uint16 1204 Linger uint16 1205} 1206 1207type IPMreq struct { 1208 Multiaddr [4]byte /* in_addr */ 1209 Interface [4]byte /* in_addr */ 1210} 1211 1212type IPv6Mreq struct { 1213 Multiaddr [16]byte /* in6_addr */ 1214 Interface uint32 1215} 1216 1217func GetsockoptInt(fd Handle, level, opt int) (int, error) { 1218 v := int32(0) 1219 l := int32(unsafe.Sizeof(v)) 1220 err := Getsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), &l) 1221 return int(v), err 1222} 1223 1224func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { 1225 sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)} 1226 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys))) 1227} 1228 1229func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { 1230 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) 1231} 1232func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { 1233 return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) 1234} 1235func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { 1236 return syscall.EWINDOWS 1237} 1238 1239func Getpid() (pid int) { return int(GetCurrentProcessId()) } 1240 1241func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) { 1242 // NOTE(rsc): The Win32finddata struct is wrong for the system call: 1243 // the two paths are each one uint16 short. Use the correct struct, 1244 // a win32finddata1, and then copy the results out. 1245 // There is no loss of expressivity here, because the final 1246 // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that. 1247 // For Go 1.1, we might avoid the allocation of win32finddata1 here 1248 // by adding a final Bug [2]uint16 field to the struct and then 1249 // adjusting the fields in the result directly. 1250 var data1 win32finddata1 1251 handle, err = findFirstFile1(name, &data1) 1252 if err == nil { 1253 copyFindData(data, &data1) 1254 } 1255 return 1256} 1257 1258func FindNextFile(handle Handle, data *Win32finddata) (err error) { 1259 var data1 win32finddata1 1260 err = findNextFile1(handle, &data1) 1261 if err == nil { 1262 copyFindData(data, &data1) 1263 } 1264 return 1265} 1266 1267func getProcessEntry(pid int) (*ProcessEntry32, error) { 1268 snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) 1269 if err != nil { 1270 return nil, err 1271 } 1272 defer CloseHandle(snapshot) 1273 var procEntry ProcessEntry32 1274 procEntry.Size = uint32(unsafe.Sizeof(procEntry)) 1275 if err = Process32First(snapshot, &procEntry); err != nil { 1276 return nil, err 1277 } 1278 for { 1279 if procEntry.ProcessID == uint32(pid) { 1280 return &procEntry, nil 1281 } 1282 err = Process32Next(snapshot, &procEntry) 1283 if err != nil { 1284 return nil, err 1285 } 1286 } 1287} 1288 1289func Getppid() (ppid int) { 1290 pe, err := getProcessEntry(Getpid()) 1291 if err != nil { 1292 return -1 1293 } 1294 return int(pe.ParentProcessID) 1295} 1296 1297// TODO(brainman): fix all needed for os 1298func Fchdir(fd Handle) (err error) { return syscall.EWINDOWS } 1299func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS } 1300func Symlink(path, link string) (err error) { return syscall.EWINDOWS } 1301 1302func Fchmod(fd Handle, mode uint32) (err error) { return syscall.EWINDOWS } 1303func Chown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } 1304func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS } 1305func Fchown(fd Handle, uid int, gid int) (err error) { return syscall.EWINDOWS } 1306 1307func Getuid() (uid int) { return -1 } 1308func Geteuid() (euid int) { return -1 } 1309func Getgid() (gid int) { return -1 } 1310func Getegid() (egid int) { return -1 } 1311func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS } 1312 1313type Signal int 1314 1315func (s Signal) Signal() {} 1316 1317func (s Signal) String() string { 1318 if 0 <= s && int(s) < len(signals) { 1319 str := signals[s] 1320 if str != "" { 1321 return str 1322 } 1323 } 1324 return "signal " + itoa(int(s)) 1325} 1326 1327func LoadCreateSymbolicLink() error { 1328 return procCreateSymbolicLinkW.Find() 1329} 1330 1331// Readlink returns the destination of the named symbolic link. 1332func Readlink(path string, buf []byte) (n int, err error) { 1333 fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING, 1334 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0) 1335 if err != nil { 1336 return -1, err 1337 } 1338 defer CloseHandle(fd) 1339 1340 rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE) 1341 var bytesReturned uint32 1342 err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) 1343 if err != nil { 1344 return -1, err 1345 } 1346 1347 rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0])) 1348 var s string 1349 switch rdb.ReparseTag { 1350 case IO_REPARSE_TAG_SYMLINK: 1351 data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) 1352 p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) 1353 s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) 1354 case IO_REPARSE_TAG_MOUNT_POINT: 1355 data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer)) 1356 p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0])) 1357 s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2]) 1358 default: 1359 // the path is not a symlink or junction but another type of reparse 1360 // point 1361 return -1, syscall.ENOENT 1362 } 1363 n = copy(buf, []byte(s)) 1364 1365 return n, nil 1366} 1367 1368// GUIDFromString parses a string in the form of 1369// "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" into a GUID. 1370func GUIDFromString(str string) (GUID, error) { 1371 guid := GUID{} 1372 str16, err := syscall.UTF16PtrFromString(str) 1373 if err != nil { 1374 return guid, err 1375 } 1376 err = clsidFromString(str16, &guid) 1377 if err != nil { 1378 return guid, err 1379 } 1380 return guid, nil 1381} 1382 1383// GenerateGUID creates a new random GUID. 1384func GenerateGUID() (GUID, error) { 1385 guid := GUID{} 1386 err := coCreateGuid(&guid) 1387 if err != nil { 1388 return guid, err 1389 } 1390 return guid, nil 1391} 1392 1393// String returns the canonical string form of the GUID, 1394// in the form of "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}". 1395func (guid GUID) String() string { 1396 var str [100]uint16 1397 chars := stringFromGUID2(&guid, &str[0], int32(len(str))) 1398 if chars <= 1 { 1399 return "" 1400 } 1401 return string(utf16.Decode(str[:chars-1])) 1402} 1403 1404// KnownFolderPath returns a well-known folder path for the current user, specified by one of 1405// the FOLDERID_ constants, and chosen and optionally created based on a KF_ flag. 1406func KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, error) { 1407 return Token(0).KnownFolderPath(folderID, flags) 1408} 1409 1410// KnownFolderPath returns a well-known folder path for the user token, specified by one of 1411// the FOLDERID_ constants, and chosen and optionally created based on a KF_ flag. 1412func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, error) { 1413 var p *uint16 1414 err := shGetKnownFolderPath(folderID, flags, t, &p) 1415 if err != nil { 1416 return "", err 1417 } 1418 defer CoTaskMemFree(unsafe.Pointer(p)) 1419 return UTF16PtrToString(p), nil 1420} 1421 1422// RtlGetVersion returns the version of the underlying operating system, ignoring 1423// manifest semantics but is affected by the application compatibility layer. 1424func RtlGetVersion() *OsVersionInfoEx { 1425 info := &OsVersionInfoEx{} 1426 info.osVersionInfoSize = uint32(unsafe.Sizeof(*info)) 1427 // According to documentation, this function always succeeds. 1428 // The function doesn't even check the validity of the 1429 // osVersionInfoSize member. Disassembling ntdll.dll indicates 1430 // that the documentation is indeed correct about that. 1431 _ = rtlGetVersion(info) 1432 return info 1433} 1434 1435// RtlGetNtVersionNumbers returns the version of the underlying operating system, 1436// ignoring manifest semantics and the application compatibility layer. 1437func RtlGetNtVersionNumbers() (majorVersion, minorVersion, buildNumber uint32) { 1438 rtlGetNtVersionNumbers(&majorVersion, &minorVersion, &buildNumber) 1439 buildNumber &= 0xffff 1440 return 1441} 1442 1443// GetProcessPreferredUILanguages retrieves the process preferred UI languages. 1444func GetProcessPreferredUILanguages(flags uint32) ([]string, error) { 1445 return getUILanguages(flags, getProcessPreferredUILanguages) 1446} 1447 1448// GetThreadPreferredUILanguages retrieves the thread preferred UI languages for the current thread. 1449func GetThreadPreferredUILanguages(flags uint32) ([]string, error) { 1450 return getUILanguages(flags, getThreadPreferredUILanguages) 1451} 1452 1453// GetUserPreferredUILanguages retrieves information about the user preferred UI languages. 1454func GetUserPreferredUILanguages(flags uint32) ([]string, error) { 1455 return getUILanguages(flags, getUserPreferredUILanguages) 1456} 1457 1458// GetSystemPreferredUILanguages retrieves the system preferred UI languages. 1459func GetSystemPreferredUILanguages(flags uint32) ([]string, error) { 1460 return getUILanguages(flags, getSystemPreferredUILanguages) 1461} 1462 1463func getUILanguages(flags uint32, f func(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) error) ([]string, error) { 1464 size := uint32(128) 1465 for { 1466 var numLanguages uint32 1467 buf := make([]uint16, size) 1468 err := f(flags, &numLanguages, &buf[0], &size) 1469 if err == ERROR_INSUFFICIENT_BUFFER { 1470 continue 1471 } 1472 if err != nil { 1473 return nil, err 1474 } 1475 buf = buf[:size] 1476 if numLanguages == 0 || len(buf) == 0 { // GetProcessPreferredUILanguages may return numLanguages==0 with "\0\0" 1477 return []string{}, nil 1478 } 1479 if buf[len(buf)-1] == 0 { 1480 buf = buf[:len(buf)-1] // remove terminating null 1481 } 1482 languages := make([]string, 0, numLanguages) 1483 from := 0 1484 for i, c := range buf { 1485 if c == 0 { 1486 languages = append(languages, string(utf16.Decode(buf[from:i]))) 1487 from = i + 1 1488 } 1489 } 1490 return languages, nil 1491 } 1492} 1493 1494func SetConsoleCursorPosition(console Handle, position Coord) error { 1495 return setConsoleCursorPosition(console, *((*uint32)(unsafe.Pointer(&position)))) 1496} 1497