~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/gabriel-samfira/sys/windows/syscall_windows.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
        "sync"
 
12
        "syscall"
 
13
        "unicode/utf16"
 
14
        "unsafe"
 
15
)
 
16
 
 
17
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go
 
18
 
 
19
type Handle uintptr
 
20
 
 
21
const InvalidHandle = ^Handle(0)
 
22
 
 
23
// StringToUTF16 is deprecated. Use UTF16FromString instead.
 
24
// If s contains a NUL byte this function panics instead of
 
25
// returning an error.
 
26
func StringToUTF16(s string) []uint16 {
 
27
        a, err := UTF16FromString(s)
 
28
        if err != nil {
 
29
                panic("windows: string with NUL passed to StringToUTF16")
 
30
        }
 
31
        return a
 
32
}
 
33
 
 
34
// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
 
35
// s, with a terminating NUL added. If s contains a NUL byte at any
 
36
// location, it returns (nil, syscall.EINVAL).
 
37
func UTF16FromString(s string) ([]uint16, error) {
 
38
        for i := 0; i < len(s); i++ {
 
39
                if s[i] == 0 {
 
40
                        return nil, syscall.EINVAL
 
41
                }
 
42
        }
 
43
        return utf16.Encode([]rune(s + "\x00")), nil
 
44
}
 
45
 
 
46
// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
 
47
// with a terminating NUL removed.
 
48
func UTF16ToString(s []uint16) string {
 
49
        for i, v := range s {
 
50
                if v == 0 {
 
51
                        s = s[0:i]
 
52
                        break
 
53
                }
 
54
        }
 
55
        return string(utf16.Decode(s))
 
56
}
 
57
 
 
58
// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead.
 
59
// If s contains a NUL byte this function panics instead of
 
60
// returning an error.
 
61
func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
 
62
 
 
63
// UTF16PtrFromString returns pointer to the UTF-16 encoding of
 
64
// the UTF-8 string s, with a terminating NUL added. If s
 
65
// contains a NUL byte at any location, it returns (nil, syscall.EINVAL).
 
66
func UTF16PtrFromString(s string) (*uint16, error) {
 
67
        a, err := UTF16FromString(s)
 
68
        if err != nil {
 
69
                return nil, err
 
70
        }
 
71
        return &a[0], nil
 
72
}
 
73
 
 
74
func Getpagesize() int { return 4096 }
 
75
 
 
76
// Converts a Go function to a function pointer conforming
 
77
// to the stdcall or cdecl calling convention.  This is useful when
 
78
// interoperating with Windows code requiring callbacks.
 
79
// Implemented in runtime/syscall_windows.goc
 
80
func NewCallback(fn interface{}) uintptr
 
81
func NewCallbackCDecl(fn interface{}) uintptr
 
82
 
 
83
// windows api calls
 
84
 
 
85
//sys   GetLastError() (lasterr error)
 
86
//sys   LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
 
87
//sys   FreeLibrary(handle Handle) (err error)
 
88
//sys   GetProcAddress(module Handle, procname string) (proc uintptr, err error)
 
89
//sys   GetVersion() (ver uint32, err error)
 
90
//sys   FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
 
91
//sys   ExitProcess(exitcode uint32)
 
92
//sys   CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
 
93
//sys   ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
 
94
//sys   WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
 
95
//sys   SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
 
96
//sys   CloseHandle(handle Handle) (err error)
 
97
//sys   GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle]
 
98
//sys   findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
 
99
//sys   findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
 
100
//sys   FindClose(handle Handle) (err error)
 
101
//sys   GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
 
102
//sys   GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
 
103
//sys   SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
 
104
//sys   CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
 
105
//sys   RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
 
106
//sys   DeleteFile(path *uint16) (err error) = DeleteFileW
 
107
//sys   MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
 
108
//sys   GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
 
109
//sys   GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
 
110
//sys   SetEndOfFile(handle Handle) (err error)
 
111
//sys   GetSystemTimeAsFileTime(time *Filetime)
 
112
//sys   GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
 
113
//sys   CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
 
114
//sys   GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
 
115
//sys   PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
 
116
//sys   CancelIo(s Handle) (err error)
 
117
//sys   CancelIoEx(s Handle, o *Overlapped) (err error)
 
118
//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
 
119
//sys   OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
 
120
//sys   TerminateProcess(handle Handle, exitcode uint32) (err error)
 
121
//sys   GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
 
122
//sys   GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
 
123
//sys   GetCurrentProcess() (pseudoHandle Handle, err error)
 
124
//sys   GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
 
125
//sys   DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
 
126
//sys   WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
 
127
//sys   GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
 
128
//sys   CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
 
129
//sys   GetFileType(filehandle Handle) (n uint32, err error)
 
130
//sys   CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
 
131
//sys   CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
 
132
//sys   CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
 
133
//sys   GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
 
134
//sys   FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
 
135
//sys   GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
 
136
//sys   SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
 
137
//sys   SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
 
138
//sys   GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
 
139
//sys   SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
 
140
//sys   GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
 
141
//sys   GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
 
142
//sys   CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
 
143
//sys   LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
 
144
//sys   SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
 
145
//sys   FlushFileBuffers(handle Handle) (err error)
 
146
//sys   GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
 
147
//sys   GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
 
148
//sys   GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
 
149
//sys   CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
 
150
//sys   MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
 
151
//sys   UnmapViewOfFile(addr uintptr) (err error)
 
152
//sys   FlushViewOfFile(addr uintptr, length uintptr) (err error)
 
153
//sys   VirtualLock(addr uintptr, length uintptr) (err error)
 
154
//sys   VirtualUnlock(addr uintptr, length uintptr) (err error)
 
155
//sys   TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
 
156
//sys   ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
 
157
//sys   CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
 
158
//sys   CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore
 
159
//sys   CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
 
160
//sys   CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
 
161
//sys   CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
 
162
//sys   CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
 
163
//sys   CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
 
164
//sys   CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
 
165
//sys   CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
 
166
//sys   CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
 
167
//sys   RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
 
168
//sys   RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
 
169
//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
 
170
//sys   RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
 
171
//sys   RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
 
172
//sys   getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
 
173
//sys   GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
 
174
//sys   WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
 
175
//sys   ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
 
176
//sys   CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
 
177
//sys   Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW
 
178
//sys   Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW
 
179
//sys   DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error)
 
180
// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
 
181
//sys   CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
 
182
//sys   CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
 
183
//sys   GetCurrentThreadId() (id uint32)
 
184
//sys   CreateEvent(eventAttrs *syscall.SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW
 
185
//sys   SetEvent(event Handle) (err error) = kernel32.SetEvent
 
186
 
 
187
// syscall interface implementation for other packages
 
188
 
 
189
func Exit(code int) { ExitProcess(uint32(code)) }
 
190
 
 
191
func makeInheritSa() *SecurityAttributes {
 
192
        var sa SecurityAttributes
 
193
        sa.Length = uint32(unsafe.Sizeof(sa))
 
194
        sa.InheritHandle = 1
 
195
        return &sa
 
196
}
 
197
 
 
198
func Open(path string, mode int, perm uint32) (fd Handle, err error) {
 
199
        if len(path) == 0 {
 
200
                return InvalidHandle, ERROR_FILE_NOT_FOUND
 
201
        }
 
202
        pathp, err := UTF16PtrFromString(path)
 
203
        if err != nil {
 
204
                return InvalidHandle, err
 
205
        }
 
206
        var access uint32
 
207
        switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
 
208
        case O_RDONLY:
 
209
                access = GENERIC_READ
 
210
        case O_WRONLY:
 
211
                access = GENERIC_WRITE
 
212
        case O_RDWR:
 
213
                access = GENERIC_READ | GENERIC_WRITE
 
214
        }
 
215
        if mode&O_CREAT != 0 {
 
216
                access |= GENERIC_WRITE
 
217
        }
 
218
        if mode&O_APPEND != 0 {
 
219
                access &^= GENERIC_WRITE
 
220
                access |= FILE_APPEND_DATA
 
221
        }
 
222
        sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
 
223
        var sa *SecurityAttributes
 
224
        if mode&O_CLOEXEC == 0 {
 
225
                sa = makeInheritSa()
 
226
        }
 
227
        var createmode uint32
 
228
        switch {
 
229
        case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
 
230
                createmode = CREATE_NEW
 
231
        case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
 
232
                createmode = CREATE_ALWAYS
 
233
        case mode&O_CREAT == O_CREAT:
 
234
                createmode = OPEN_ALWAYS
 
235
        case mode&O_TRUNC == O_TRUNC:
 
236
                createmode = TRUNCATE_EXISTING
 
237
        default:
 
238
                createmode = OPEN_EXISTING
 
239
        }
 
240
        h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
 
241
        return h, e
 
242
}
 
243
 
 
244
func Read(fd Handle, p []byte) (n int, err error) {
 
245
        var done uint32
 
246
        e := ReadFile(fd, p, &done, nil)
 
247
        if e != nil {
 
248
                if e == ERROR_BROKEN_PIPE {
 
249
                        // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
 
250
                        return 0, nil
 
251
                }
 
252
                return 0, e
 
253
        }
 
254
        if raceenabled {
 
255
                if done > 0 {
 
256
                        raceWriteRange(unsafe.Pointer(&p[0]), int(done))
 
257
                }
 
258
                raceAcquire(unsafe.Pointer(&ioSync))
 
259
        }
 
260
        return int(done), nil
 
261
}
 
262
 
 
263
func Write(fd Handle, p []byte) (n int, err error) {
 
264
        if raceenabled {
 
265
                raceReleaseMerge(unsafe.Pointer(&ioSync))
 
266
        }
 
267
        var done uint32
 
268
        e := WriteFile(fd, p, &done, nil)
 
269
        if e != nil {
 
270
                return 0, e
 
271
        }
 
272
        if raceenabled && done > 0 {
 
273
                raceReadRange(unsafe.Pointer(&p[0]), int(done))
 
274
        }
 
275
        return int(done), nil
 
276
}
 
277
 
 
278
var ioSync int64
 
279
 
 
280
func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
 
281
        var w uint32
 
282
        switch whence {
 
283
        case 0:
 
284
                w = FILE_BEGIN
 
285
        case 1:
 
286
                w = FILE_CURRENT
 
287
        case 2:
 
288
                w = FILE_END
 
289
        }
 
290
        hi := int32(offset >> 32)
 
291
        lo := int32(offset)
 
292
        // use GetFileType to check pipe, pipe can't do seek
 
293
        ft, _ := GetFileType(fd)
 
294
        if ft == FILE_TYPE_PIPE {
 
295
                return 0, syscall.EPIPE
 
296
        }
 
297
        rlo, e := SetFilePointer(fd, lo, &hi, w)
 
298
        if e != nil {
 
299
                return 0, e
 
300
        }
 
301
        return int64(hi)<<32 + int64(rlo), nil
 
302
}
 
303
 
 
304
func Close(fd Handle) (err error) {
 
305
        return CloseHandle(fd)
 
306
}
 
307
 
 
308
var (
 
309
        Stdin  = getStdHandle(STD_INPUT_HANDLE)
 
310
        Stdout = getStdHandle(STD_OUTPUT_HANDLE)
 
311
        Stderr = getStdHandle(STD_ERROR_HANDLE)
 
312
)
 
313
 
 
314
func getStdHandle(h int) (fd Handle) {
 
315
        r, _ := GetStdHandle(h)
 
316
        CloseOnExec(r)
 
317
        return r
 
318
}
 
319
 
 
320
const ImplementsGetwd = true
 
321
 
 
322
func Getwd() (wd string, err error) {
 
323
        b := make([]uint16, 300)
 
324
        n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
 
325
        if e != nil {
 
326
                return "", e
 
327
        }
 
328
        return string(utf16.Decode(b[0:n])), nil
 
329
}
 
330
 
 
331
func Chdir(path string) (err error) {
 
332
        pathp, err := UTF16PtrFromString(path)
 
333
        if err != nil {
 
334
                return err
 
335
        }
 
336
        return SetCurrentDirectory(pathp)
 
337
}
 
338
 
 
339
func Mkdir(path string, mode uint32) (err error) {
 
340
        pathp, err := UTF16PtrFromString(path)
 
341
        if err != nil {
 
342
                return err
 
343
        }
 
344
        return CreateDirectory(pathp, nil)
 
345
}
 
346
 
 
347
func Rmdir(path string) (err error) {
 
348
        pathp, err := UTF16PtrFromString(path)
 
349
        if err != nil {
 
350
                return err
 
351
        }
 
352
        return RemoveDirectory(pathp)
 
353
}
 
354
 
 
355
func Unlink(path string) (err error) {
 
356
        pathp, err := UTF16PtrFromString(path)
 
357
        if err != nil {
 
358
                return err
 
359
        }
 
360
        return DeleteFile(pathp)
 
361
}
 
362
 
 
363
func Rename(oldpath, newpath string) (err error) {
 
364
        from, err := UTF16PtrFromString(oldpath)
 
365
        if err != nil {
 
366
                return err
 
367
        }
 
368
        to, err := UTF16PtrFromString(newpath)
 
369
        if err != nil {
 
370
                return err
 
371
        }
 
372
        return MoveFile(from, to)
 
373
}
 
374
 
 
375
func ComputerName() (name string, err error) {
 
376
        var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
 
377
        b := make([]uint16, n)
 
378
        e := GetComputerName(&b[0], &n)
 
379
        if e != nil {
 
380
                return "", e
 
381
        }
 
382
        return string(utf16.Decode(b[0:n])), nil
 
383
}
 
384
 
 
385
func Ftruncate(fd Handle, length int64) (err error) {
 
386
        curoffset, e := Seek(fd, 0, 1)
 
387
        if e != nil {
 
388
                return e
 
389
        }
 
390
        defer Seek(fd, curoffset, 0)
 
391
        _, e = Seek(fd, length, 0)
 
392
        if e != nil {
 
393
                return e
 
394
        }
 
395
        e = SetEndOfFile(fd)
 
396
        if e != nil {
 
397
                return e
 
398
        }
 
399
        return nil
 
400
}
 
401
 
 
402
func Gettimeofday(tv *Timeval) (err error) {
 
403
        var ft Filetime
 
404
        GetSystemTimeAsFileTime(&ft)
 
405
        *tv = NsecToTimeval(ft.Nanoseconds())
 
406
        return nil
 
407
}
 
408
 
 
409
func Pipe(p []Handle) (err error) {
 
410
        if len(p) != 2 {
 
411
                return syscall.EINVAL
 
412
        }
 
413
        var r, w Handle
 
414
        e := CreatePipe(&r, &w, makeInheritSa(), 0)
 
415
        if e != nil {
 
416
                return e
 
417
        }
 
418
        p[0] = r
 
419
        p[1] = w
 
420
        return nil
 
421
}
 
422
 
 
423
func Utimes(path string, tv []Timeval) (err error) {
 
424
        if len(tv) != 2 {
 
425
                return syscall.EINVAL
 
426
        }
 
427
        pathp, e := UTF16PtrFromString(path)
 
428
        if e != nil {
 
429
                return e
 
430
        }
 
431
        h, e := CreateFile(pathp,
 
432
                FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
 
433
                OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
 
434
        if e != nil {
 
435
                return e
 
436
        }
 
437
        defer Close(h)
 
438
        a := NsecToFiletime(tv[0].Nanoseconds())
 
439
        w := NsecToFiletime(tv[1].Nanoseconds())
 
440
        return SetFileTime(h, nil, &a, &w)
 
441
}
 
442
 
 
443
func UtimesNano(path string, ts []Timespec) (err error) {
 
444
        if len(ts) != 2 {
 
445
                return syscall.EINVAL
 
446
        }
 
447
        pathp, e := UTF16PtrFromString(path)
 
448
        if e != nil {
 
449
                return e
 
450
        }
 
451
        h, e := CreateFile(pathp,
 
452
                FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
 
453
                OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
 
454
        if e != nil {
 
455
                return e
 
456
        }
 
457
        defer Close(h)
 
458
        a := NsecToFiletime(TimespecToNsec(ts[0]))
 
459
        w := NsecToFiletime(TimespecToNsec(ts[1]))
 
460
        return SetFileTime(h, nil, &a, &w)
 
461
}
 
462
 
 
463
func Fsync(fd Handle) (err error) {
 
464
        return FlushFileBuffers(fd)
 
465
}
 
466
 
 
467
func Chmod(path string, mode uint32) (err error) {
 
468
        if mode == 0 {
 
469
                return syscall.EINVAL
 
470
        }
 
471
        p, e := UTF16PtrFromString(path)
 
472
        if e != nil {
 
473
                return e
 
474
        }
 
475
        attrs, e := GetFileAttributes(p)
 
476
        if e != nil {
 
477
                return e
 
478
        }
 
479
        if mode&S_IWRITE != 0 {
 
480
                attrs &^= FILE_ATTRIBUTE_READONLY
 
481
        } else {
 
482
                attrs |= FILE_ATTRIBUTE_READONLY
 
483
        }
 
484
        return SetFileAttributes(p, attrs)
 
485
}
 
486
 
 
487
func LoadCancelIoEx() error {
 
488
        return procCancelIoEx.Find()
 
489
}
 
490
 
 
491
func LoadSetFileCompletionNotificationModes() error {
 
492
        return procSetFileCompletionNotificationModes.Find()
 
493
}
 
494
 
 
495
// net api calls
 
496
 
 
497
const socket_error = uintptr(^uint32(0))
 
498
 
 
499
//sys   WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
 
500
//sys   WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
 
501
//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
 
502
//sys   socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
 
503
//sys   Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
 
504
//sys   Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
 
505
//sys   bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
 
506
//sys   connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
 
507
//sys   getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
 
508
//sys   getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
 
509
//sys   listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
 
510
//sys   shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
 
511
//sys   Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
 
512
//sys   AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
 
513
//sys   GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
 
514
//sys   WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
 
515
//sys   WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
 
516
//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
 
517
//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
 
518
//sys   GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
 
519
//sys   GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
 
520
//sys   Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
 
521
//sys   GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
 
522
//sys   DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
 
523
//sys   DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
 
524
//sys   DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W
 
525
//sys   GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
 
526
//sys   FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
 
527
//sys   GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
 
528
//sys   GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
 
529
//sys   SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
 
530
//sys   WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
 
531
 
 
532
// For testing: clients can set this flag to force
 
533
// creation of IPv6 sockets to return EAFNOSUPPORT.
 
534
var SocketDisableIPv6 bool
 
535
 
 
536
type RawSockaddrInet4 struct {
 
537
        Family uint16
 
538
        Port   uint16
 
539
        Addr   [4]byte /* in_addr */
 
540
        Zero   [8]uint8
 
541
}
 
542
 
 
543
type RawSockaddrInet6 struct {
 
544
        Family   uint16
 
545
        Port     uint16
 
546
        Flowinfo uint32
 
547
        Addr     [16]byte /* in6_addr */
 
548
        Scope_id uint32
 
549
}
 
550
 
 
551
type RawSockaddr struct {
 
552
        Family uint16
 
553
        Data   [14]int8
 
554
}
 
555
 
 
556
type RawSockaddrAny struct {
 
557
        Addr RawSockaddr
 
558
        Pad  [96]int8
 
559
}
 
560
 
 
561
type Sockaddr interface {
 
562
        sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
 
563
}
 
564
 
 
565
type SockaddrInet4 struct {
 
566
        Port int
 
567
        Addr [4]byte
 
568
        raw  RawSockaddrInet4
 
569
}
 
570
 
 
571
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
 
572
        if sa.Port < 0 || sa.Port > 0xFFFF {
 
573
                return nil, 0, syscall.EINVAL
 
574
        }
 
575
        sa.raw.Family = AF_INET
 
576
        p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
 
577
        p[0] = byte(sa.Port >> 8)
 
578
        p[1] = byte(sa.Port)
 
579
        for i := 0; i < len(sa.Addr); i++ {
 
580
                sa.raw.Addr[i] = sa.Addr[i]
 
581
        }
 
582
        return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
 
583
}
 
584
 
 
585
type SockaddrInet6 struct {
 
586
        Port   int
 
587
        ZoneId uint32
 
588
        Addr   [16]byte
 
589
        raw    RawSockaddrInet6
 
590
}
 
591
 
 
592
func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
 
593
        if sa.Port < 0 || sa.Port > 0xFFFF {
 
594
                return nil, 0, syscall.EINVAL
 
595
        }
 
596
        sa.raw.Family = AF_INET6
 
597
        p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
 
598
        p[0] = byte(sa.Port >> 8)
 
599
        p[1] = byte(sa.Port)
 
600
        sa.raw.Scope_id = sa.ZoneId
 
601
        for i := 0; i < len(sa.Addr); i++ {
 
602
                sa.raw.Addr[i] = sa.Addr[i]
 
603
        }
 
604
        return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
 
605
}
 
606
 
 
607
type SockaddrUnix struct {
 
608
        Name string
 
609
}
 
610
 
 
611
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
 
612
        // TODO(brainman): implement SockaddrUnix.sockaddr()
 
613
        return nil, 0, syscall.EWINDOWS
 
614
}
 
615
 
 
616
func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
 
617
        switch rsa.Addr.Family {
 
618
        case AF_UNIX:
 
619
                return nil, syscall.EWINDOWS
 
620
 
 
621
        case AF_INET:
 
622
                pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
 
623
                sa := new(SockaddrInet4)
 
624
                p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 
625
                sa.Port = int(p[0])<<8 + int(p[1])
 
626
                for i := 0; i < len(sa.Addr); i++ {
 
627
                        sa.Addr[i] = pp.Addr[i]
 
628
                }
 
629
                return sa, nil
 
630
 
 
631
        case AF_INET6:
 
632
                pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
 
633
                sa := new(SockaddrInet6)
 
634
                p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 
635
                sa.Port = int(p[0])<<8 + int(p[1])
 
636
                sa.ZoneId = pp.Scope_id
 
637
                for i := 0; i < len(sa.Addr); i++ {
 
638
                        sa.Addr[i] = pp.Addr[i]
 
639
                }
 
640
                return sa, nil
 
641
        }
 
642
        return nil, syscall.EAFNOSUPPORT
 
643
}
 
644
 
 
645
func Socket(domain, typ, proto int) (fd Handle, err error) {
 
646
        if domain == AF_INET6 && SocketDisableIPv6 {
 
647
                return InvalidHandle, syscall.EAFNOSUPPORT
 
648
        }
 
649
        return socket(int32(domain), int32(typ), int32(proto))
 
650
}
 
651
 
 
652
func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
 
653
        v := int32(value)
 
654
        return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
 
655
}
 
656
 
 
657
func Bind(fd Handle, sa Sockaddr) (err error) {
 
658
        ptr, n, err := sa.sockaddr()
 
659
        if err != nil {
 
660
                return err
 
661
        }
 
662
        return bind(fd, ptr, n)
 
663
}
 
664
 
 
665
func Connect(fd Handle, sa Sockaddr) (err error) {
 
666
        ptr, n, err := sa.sockaddr()
 
667
        if err != nil {
 
668
                return err
 
669
        }
 
670
        return connect(fd, ptr, n)
 
671
}
 
672
 
 
673
func Getsockname(fd Handle) (sa Sockaddr, err error) {
 
674
        var rsa RawSockaddrAny
 
675
        l := int32(unsafe.Sizeof(rsa))
 
676
        if err = getsockname(fd, &rsa, &l); err != nil {
 
677
                return
 
678
        }
 
679
        return rsa.Sockaddr()
 
680
}
 
681
 
 
682
func Getpeername(fd Handle) (sa Sockaddr, err error) {
 
683
        var rsa RawSockaddrAny
 
684
        l := int32(unsafe.Sizeof(rsa))
 
685
        if err = getpeername(fd, &rsa, &l); err != nil {
 
686
                return
 
687
        }
 
688
        return rsa.Sockaddr()
 
689
}
 
690
 
 
691
func Listen(s Handle, n int) (err error) {
 
692
        return listen(s, int32(n))
 
693
}
 
694
 
 
695
func Shutdown(fd Handle, how int) (err error) {
 
696
        return shutdown(fd, int32(how))
 
697
}
 
698
 
 
699
func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
 
700
        rsa, l, err := to.sockaddr()
 
701
        if err != nil {
 
702
                return err
 
703
        }
 
704
        return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
 
705
}
 
706
 
 
707
func LoadGetAddrInfo() error {
 
708
        return procGetAddrInfoW.Find()
 
709
}
 
710
 
 
711
var connectExFunc struct {
 
712
        once sync.Once
 
713
        addr uintptr
 
714
        err  error
 
715
}
 
716
 
 
717
func LoadConnectEx() error {
 
718
        connectExFunc.once.Do(func() {
 
719
                var s Handle
 
720
                s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
 
721
                if connectExFunc.err != nil {
 
722
                        return
 
723
                }
 
724
                defer CloseHandle(s)
 
725
                var n uint32
 
726
                connectExFunc.err = WSAIoctl(s,
 
727
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
 
728
                        (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
 
729
                        uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
 
730
                        (*byte)(unsafe.Pointer(&connectExFunc.addr)),
 
731
                        uint32(unsafe.Sizeof(connectExFunc.addr)),
 
732
                        &n, nil, 0)
 
733
        })
 
734
        return connectExFunc.err
 
735
}
 
736
 
 
737
func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
 
738
        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)
 
739
        if r1 == 0 {
 
740
                if e1 != 0 {
 
741
                        err = error(e1)
 
742
                } else {
 
743
                        err = syscall.EINVAL
 
744
                }
 
745
        }
 
746
        return
 
747
}
 
748
 
 
749
func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
 
750
        err := LoadConnectEx()
 
751
        if err != nil {
 
752
                return errorspkg.New("failed to find ConnectEx: " + err.Error())
 
753
        }
 
754
        ptr, n, err := sa.sockaddr()
 
755
        if err != nil {
 
756
                return err
 
757
        }
 
758
        return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
 
759
}
 
760
 
 
761
// Invented structures to support what package os expects.
 
762
type Rusage struct {
 
763
        CreationTime Filetime
 
764
        ExitTime     Filetime
 
765
        KernelTime   Filetime
 
766
        UserTime     Filetime
 
767
}
 
768
 
 
769
type WaitStatus struct {
 
770
        ExitCode uint32
 
771
}
 
772
 
 
773
func (w WaitStatus) Exited() bool { return true }
 
774
 
 
775
func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
 
776
 
 
777
func (w WaitStatus) Signal() Signal { return -1 }
 
778
 
 
779
func (w WaitStatus) CoreDump() bool { return false }
 
780
 
 
781
func (w WaitStatus) Stopped() bool { return false }
 
782
 
 
783
func (w WaitStatus) Continued() bool { return false }
 
784
 
 
785
func (w WaitStatus) StopSignal() Signal { return -1 }
 
786
 
 
787
func (w WaitStatus) Signaled() bool { return false }
 
788
 
 
789
func (w WaitStatus) TrapCause() int { return -1 }
 
790
 
 
791
// Timespec is an invented structure on Windows, but here for
 
792
// consistency with the corresponding package for other operating systems.
 
793
type Timespec struct {
 
794
        Sec  int64
 
795
        Nsec int64
 
796
}
 
797
 
 
798
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
 
799
 
 
800
func NsecToTimespec(nsec int64) (ts Timespec) {
 
801
        ts.Sec = nsec / 1e9
 
802
        ts.Nsec = nsec % 1e9
 
803
        return
 
804
}
 
805
 
 
806
// TODO(brainman): fix all needed for net
 
807
 
 
808
func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS }
 
809
func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
 
810
        return 0, nil, syscall.EWINDOWS
 
811
}
 
812
func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error)       { return syscall.EWINDOWS }
 
813
func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS }
 
814
 
 
815
// The Linger struct is wrong but we only noticed after Go 1.
 
816
// sysLinger is the real system call structure.
 
817
 
 
818
// BUG(brainman): The definition of Linger is not appropriate for direct use
 
819
// with Setsockopt and Getsockopt.
 
820
// Use SetsockoptLinger instead.
 
821
 
 
822
type Linger struct {
 
823
        Onoff  int32
 
824
        Linger int32
 
825
}
 
826
 
 
827
type sysLinger struct {
 
828
        Onoff  uint16
 
829
        Linger uint16
 
830
}
 
831
 
 
832
type IPMreq struct {
 
833
        Multiaddr [4]byte /* in_addr */
 
834
        Interface [4]byte /* in_addr */
 
835
}
 
836
 
 
837
type IPv6Mreq struct {
 
838
        Multiaddr [16]byte /* in6_addr */
 
839
        Interface uint32
 
840
}
 
841
 
 
842
func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS }
 
843
 
 
844
func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
 
845
        sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
 
846
        return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
 
847
}
 
848
 
 
849
func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
 
850
        return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
 
851
}
 
852
func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
 
853
        return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
 
854
}
 
855
func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
 
856
        return syscall.EWINDOWS
 
857
}
 
858
 
 
859
func Getpid() (pid int) { return int(getCurrentProcessId()) }
 
860
 
 
861
func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
 
862
        // NOTE(rsc): The Win32finddata struct is wrong for the system call:
 
863
        // the two paths are each one uint16 short. Use the correct struct,
 
864
        // a win32finddata1, and then copy the results out.
 
865
        // There is no loss of expressivity here, because the final
 
866
        // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
 
867
        // For Go 1.1, we might avoid the allocation of win32finddata1 here
 
868
        // by adding a final Bug [2]uint16 field to the struct and then
 
869
        // adjusting the fields in the result directly.
 
870
        var data1 win32finddata1
 
871
        handle, err = findFirstFile1(name, &data1)
 
872
        if err == nil {
 
873
                copyFindData(data, &data1)
 
874
        }
 
875
        return
 
876
}
 
877
 
 
878
func FindNextFile(handle Handle, data *Win32finddata) (err error) {
 
879
        var data1 win32finddata1
 
880
        err = findNextFile1(handle, &data1)
 
881
        if err == nil {
 
882
                copyFindData(data, &data1)
 
883
        }
 
884
        return
 
885
}
 
886
 
 
887
func getProcessEntry(pid int) (*ProcessEntry32, error) {
 
888
        snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
 
889
        if err != nil {
 
890
                return nil, err
 
891
        }
 
892
        defer CloseHandle(snapshot)
 
893
        var procEntry ProcessEntry32
 
894
        procEntry.Size = uint32(unsafe.Sizeof(procEntry))
 
895
        if err = Process32First(snapshot, &procEntry); err != nil {
 
896
                return nil, err
 
897
        }
 
898
        for {
 
899
                if procEntry.ProcessID == uint32(pid) {
 
900
                        return &procEntry, nil
 
901
                }
 
902
                err = Process32Next(snapshot, &procEntry)
 
903
                if err != nil {
 
904
                        return nil, err
 
905
                }
 
906
        }
 
907
}
 
908
 
 
909
func Getppid() (ppid int) {
 
910
        pe, err := getProcessEntry(Getpid())
 
911
        if err != nil {
 
912
                return -1
 
913
        }
 
914
        return int(pe.ParentProcessID)
 
915
}
 
916
 
 
917
// TODO(brainman): fix all needed for os
 
918
func Fchdir(fd Handle) (err error)             { return syscall.EWINDOWS }
 
919
func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS }
 
920
func Symlink(path, link string) (err error)    { return syscall.EWINDOWS }
 
921
 
 
922
func Fchmod(fd Handle, mode uint32) (err error)        { return syscall.EWINDOWS }
 
923
func Chown(path string, uid int, gid int) (err error)  { return syscall.EWINDOWS }
 
924
func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS }
 
925
func Fchown(fd Handle, uid int, gid int) (err error)   { return syscall.EWINDOWS }
 
926
 
 
927
func Getuid() (uid int)                  { return -1 }
 
928
func Geteuid() (euid int)                { return -1 }
 
929
func Getgid() (gid int)                  { return -1 }
 
930
func Getegid() (egid int)                { return -1 }
 
931
func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS }
 
932
 
 
933
type Signal int
 
934
 
 
935
func (s Signal) Signal() {}
 
936
 
 
937
func (s Signal) String() string {
 
938
        if 0 <= s && int(s) < len(signals) {
 
939
                str := signals[s]
 
940
                if str != "" {
 
941
                        return str
 
942
                }
 
943
        }
 
944
        return "signal " + itoa(int(s))
 
945
}
 
946
 
 
947
func LoadCreateSymbolicLink() error {
 
948
        return procCreateSymbolicLinkW.Find()
 
949
}
 
950
 
 
951
// Readlink returns the destination of the named symbolic link.
 
952
func Readlink(path string, buf []byte) (n int, err error) {
 
953
        fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
 
954
                FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
 
955
        if err != nil {
 
956
                return -1, err
 
957
        }
 
958
        defer CloseHandle(fd)
 
959
 
 
960
        rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
 
961
        var bytesReturned uint32
 
962
        err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
 
963
        if err != nil {
 
964
                return -1, err
 
965
        }
 
966
 
 
967
        rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
 
968
        var s string
 
969
        switch rdb.ReparseTag {
 
970
        case IO_REPARSE_TAG_SYMLINK:
 
971
                data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
 
972
                p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
 
973
                s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
 
974
        case IO_REPARSE_TAG_MOUNT_POINT:
 
975
                data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
 
976
                p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
 
977
                s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
 
978
        default:
 
979
                // the path is not a symlink or junction but another type of reparse
 
980
                // point
 
981
                return -1, syscall.ENOENT
 
982
        }
 
983
        n = copy(buf, []byte(s))
 
984
 
 
985
        return n, nil
 
986
}