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