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