Selaa lähdekoodia

Merge pull request #33094 from darrenstahlmsft/RevendorGoWinio

Update go-winio to v0.4.0 (go 1.8.x works on Windows)
Madhu Venugopal 8 vuotta sitten
vanhempi
commit
80bb6a46a3

+ 1 - 1
vendor.conf

@@ -1,7 +1,7 @@
 # the following lines are in sorted order, FYI
 # the following lines are in sorted order, FYI
 github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
 github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
 github.com/Microsoft/hcsshim v0.5.17
 github.com/Microsoft/hcsshim v0.5.17
-github.com/Microsoft/go-winio v0.3.9
+github.com/Microsoft/go-winio v0.4.0
 github.com/Sirupsen/logrus v0.11.0
 github.com/Sirupsen/logrus v0.11.0
 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a

+ 4 - 2
vendor/github.com/Microsoft/go-winio/backup.go

@@ -185,7 +185,6 @@ type BackupFileReader struct {
 // Read will attempt to read the security descriptor of the file.
 // Read will attempt to read the security descriptor of the file.
 func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
 func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
 	r := &BackupFileReader{f, includeSecurity, 0}
 	r := &BackupFileReader{f, includeSecurity, 0}
-	runtime.SetFinalizer(r, func(r *BackupFileReader) { r.Close() })
 	return r
 	return r
 }
 }
 
 
@@ -196,6 +195,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
 	if err != nil {
 	if err != nil {
 		return 0, &os.PathError{"BackupRead", r.f.Name(), err}
 		return 0, &os.PathError{"BackupRead", r.f.Name(), err}
 	}
 	}
+	runtime.KeepAlive(r.f)
 	if bytesRead == 0 {
 	if bytesRead == 0 {
 		return 0, io.EOF
 		return 0, io.EOF
 	}
 	}
@@ -207,6 +207,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
 func (r *BackupFileReader) Close() error {
 func (r *BackupFileReader) Close() error {
 	if r.ctx != 0 {
 	if r.ctx != 0 {
 		backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
 		backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
+		runtime.KeepAlive(r.f)
 		r.ctx = 0
 		r.ctx = 0
 	}
 	}
 	return nil
 	return nil
@@ -223,7 +224,6 @@ type BackupFileWriter struct {
 // Write() will attempt to restore the security descriptor from the stream.
 // Write() will attempt to restore the security descriptor from the stream.
 func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
 func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
 	w := &BackupFileWriter{f, includeSecurity, 0}
 	w := &BackupFileWriter{f, includeSecurity, 0}
-	runtime.SetFinalizer(w, func(w *BackupFileWriter) { w.Close() })
 	return w
 	return w
 }
 }
 
 
@@ -234,6 +234,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
 	if err != nil {
 	if err != nil {
 		return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
 		return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
 	}
 	}
+	runtime.KeepAlive(w.f)
 	if int(bytesWritten) != len(b) {
 	if int(bytesWritten) != len(b) {
 		return int(bytesWritten), errors.New("not all bytes could be written")
 		return int(bytesWritten), errors.New("not all bytes could be written")
 	}
 	}
@@ -245,6 +246,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
 func (w *BackupFileWriter) Close() error {
 func (w *BackupFileWriter) Close() error {
 	if w.ctx != 0 {
 	if w.ctx != 0 {
 		backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
 		backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
+		runtime.KeepAlive(w.f)
 		w.ctx = 0
 		w.ctx = 0
 	}
 	}
 	return nil
 	return nil

+ 111 - 43
vendor/github.com/Microsoft/go-winio/file.go

@@ -7,6 +7,7 @@ import (
 	"io"
 	"io"
 	"runtime"
 	"runtime"
 	"sync"
 	"sync"
+	"sync/atomic"
 	"syscall"
 	"syscall"
 	"time"
 	"time"
 )
 )
@@ -17,6 +18,12 @@ import (
 //sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
 //sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
 //sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
 //sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
 
 
+type atomicBool int32
+
+func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
+func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
+func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }
+
 const (
 const (
 	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
 	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
 	cFILE_SKIP_SET_EVENT_ON_HANDLE        = 2
 	cFILE_SKIP_SET_EVENT_ON_HANDLE        = 2
@@ -33,6 +40,8 @@ func (e *timeoutError) Error() string   { return "i/o timeout" }
 func (e *timeoutError) Timeout() bool   { return true }
 func (e *timeoutError) Timeout() bool   { return true }
 func (e *timeoutError) Temporary() bool { return true }
 func (e *timeoutError) Temporary() bool { return true }
 
 
+type timeoutChan chan struct{}
+
 var ioInitOnce sync.Once
 var ioInitOnce sync.Once
 var ioCompletionPort syscall.Handle
 var ioCompletionPort syscall.Handle
 
 
@@ -63,8 +72,16 @@ type win32File struct {
 	handle        syscall.Handle
 	handle        syscall.Handle
 	wg            sync.WaitGroup
 	wg            sync.WaitGroup
 	closing       bool
 	closing       bool
-	readDeadline  time.Time
-	writeDeadline time.Time
+	readDeadline  deadlineHandler
+	writeDeadline deadlineHandler
+}
+
+type deadlineHandler struct {
+	setLock     sync.Mutex
+	channel     timeoutChan
+	channelLock sync.RWMutex
+	timer       *time.Timer
+	timedout    atomicBool
 }
 }
 
 
 // makeWin32File makes a new win32File from an existing file handle
 // makeWin32File makes a new win32File from an existing file handle
@@ -79,7 +96,8 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	runtime.SetFinalizer(f, (*win32File).closeHandle)
+	f.readDeadline.channel = make(timeoutChan)
+	f.writeDeadline.channel = make(timeoutChan)
 	return f, nil
 	return f, nil
 }
 }
 
 
@@ -103,7 +121,6 @@ func (f *win32File) closeHandle() {
 // Close closes a win32File.
 // Close closes a win32File.
 func (f *win32File) Close() error {
 func (f *win32File) Close() error {
 	f.closeHandle()
 	f.closeHandle()
-	runtime.SetFinalizer(f, nil)
 	return nil
 	return nil
 }
 }
 
 
@@ -136,47 +153,47 @@ func ioCompletionProcessor(h syscall.Handle) {
 
 
 // asyncIo processes the return value from ReadFile or WriteFile, blocking until
 // asyncIo processes the return value from ReadFile or WriteFile, blocking until
 // the operation has actually completed.
 // the operation has actually completed.
-func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) {
+func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
 	if err != syscall.ERROR_IO_PENDING {
 	if err != syscall.ERROR_IO_PENDING {
 		f.wg.Done()
 		f.wg.Done()
 		return int(bytes), err
 		return int(bytes), err
-	} else {
-		var r ioResult
-		wait := true
-		timedout := false
-		if f.closing {
-			cancelIoEx(f.handle, &c.o)
-		} else if !deadline.IsZero() {
-			now := time.Now()
-			if !deadline.After(now) {
-				timedout = true
-			} else {
-				timeout := time.After(deadline.Sub(now))
-				select {
-				case r = <-c.ch:
-					wait = false
-				case <-timeout:
-					timedout = true
-				}
-			}
-		}
-		if timedout {
-			cancelIoEx(f.handle, &c.o)
-		}
-		if wait {
-			r = <-c.ch
-		}
+	}
+
+	if f.closing {
+		cancelIoEx(f.handle, &c.o)
+	}
+
+	var timeout timeoutChan
+	if d != nil {
+		d.channelLock.Lock()
+		timeout = d.channel
+		d.channelLock.Unlock()
+	}
+
+	var r ioResult
+	select {
+	case r = <-c.ch:
 		err = r.err
 		err = r.err
 		if err == syscall.ERROR_OPERATION_ABORTED {
 		if err == syscall.ERROR_OPERATION_ABORTED {
 			if f.closing {
 			if f.closing {
 				err = ErrFileClosed
 				err = ErrFileClosed
-			} else if timedout {
-				err = ErrTimeout
 			}
 			}
 		}
 		}
-		f.wg.Done()
-		return int(r.bytes), err
+	case <-timeout:
+		cancelIoEx(f.handle, &c.o)
+		r = <-c.ch
+		err = r.err
+		if err == syscall.ERROR_OPERATION_ABORTED {
+			err = ErrTimeout
+		}
 	}
 	}
+
+	// runtime.KeepAlive is needed, as c is passed via native
+	// code to ioCompletionProcessor, c must remain alive
+	// until the channel read is complete.
+	runtime.KeepAlive(c)
+	f.wg.Done()
+	return int(r.bytes), err
 }
 }
 
 
 // Read reads from a file handle.
 // Read reads from a file handle.
@@ -185,9 +202,15 @@ func (f *win32File) Read(b []byte) (int, error) {
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
+
+	if f.readDeadline.timedout.isSet() {
+		return 0, ErrTimeout
+	}
+
 	var bytes uint32
 	var bytes uint32
 	err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
 	err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
-	n, err := f.asyncIo(c, f.readDeadline, bytes, err)
+	n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
+	runtime.KeepAlive(b)
 
 
 	// Handle EOF conditions.
 	// Handle EOF conditions.
 	if err == nil && n == 0 && len(b) != 0 {
 	if err == nil && n == 0 && len(b) != 0 {
@@ -205,21 +228,66 @@ func (f *win32File) Write(b []byte) (int, error) {
 	if err != nil {
 	if err != nil {
 		return 0, err
 		return 0, err
 	}
 	}
+	if f.writeDeadline.timedout.isSet() {
+		return 0, ErrTimeout
+	}
+
 	var bytes uint32
 	var bytes uint32
 	err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
 	err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
-	return f.asyncIo(c, f.writeDeadline, bytes, err)
+	n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
+	runtime.KeepAlive(b)
+	return n, err
 }
 }
 
 
-func (f *win32File) SetReadDeadline(t time.Time) error {
-	f.readDeadline = t
-	return nil
+func (f *win32File) SetReadDeadline(deadline time.Time) error {
+	return f.readDeadline.set(deadline)
 }
 }
 
 
-func (f *win32File) SetWriteDeadline(t time.Time) error {
-	f.writeDeadline = t
-	return nil
+func (f *win32File) SetWriteDeadline(deadline time.Time) error {
+	return f.writeDeadline.set(deadline)
 }
 }
 
 
 func (f *win32File) Flush() error {
 func (f *win32File) Flush() error {
 	return syscall.FlushFileBuffers(f.handle)
 	return syscall.FlushFileBuffers(f.handle)
 }
 }
+
+func (d *deadlineHandler) set(deadline time.Time) error {
+	d.setLock.Lock()
+	defer d.setLock.Unlock()
+
+	if d.timer != nil {
+		if !d.timer.Stop() {
+			<-d.channel
+		}
+		d.timer = nil
+	}
+	d.timedout.setFalse()
+
+	select {
+	case <-d.channel:
+		d.channelLock.Lock()
+		d.channel = make(chan struct{})
+		d.channelLock.Unlock()
+	default:
+	}
+
+	if deadline.IsZero() {
+		return nil
+	}
+
+	timeoutIO := func() {
+		d.timedout.setTrue()
+		close(d.channel)
+	}
+
+	now := time.Now()
+	duration := deadline.Sub(now)
+	if deadline.After(now) {
+		// Deadline is in the future, set a timer to wait
+		d.timer = time.AfterFunc(duration, timeoutIO)
+	} else {
+		// Deadline is in the past. Cancel all pending IO now.
+		timeoutIO()
+	}
+	return nil
+}

+ 4 - 0
vendor/github.com/Microsoft/go-winio/fileinfo.go

@@ -4,6 +4,7 @@ package winio
 
 
 import (
 import (
 	"os"
 	"os"
+	"runtime"
 	"syscall"
 	"syscall"
 	"unsafe"
 	"unsafe"
 )
 )
@@ -28,6 +29,7 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
 	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
 	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
 		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
 		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
 	}
 	}
+	runtime.KeepAlive(f)
 	return bi, nil
 	return bi, nil
 }
 }
 
 
@@ -36,6 +38,7 @@ func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
 	if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
 	if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
 		return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
 		return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
 	}
 	}
+	runtime.KeepAlive(f)
 	return nil
 	return nil
 }
 }
 
 
@@ -52,5 +55,6 @@ func GetFileID(f *os.File) (*FileIDInfo, error) {
 	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
 	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
 		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
 		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
 	}
 	}
+	runtime.KeepAlive(f)
 	return fileID, nil
 	return fileID, nil
 }
 }

+ 11 - 6
vendor/github.com/Microsoft/go-winio/pipe.go

@@ -18,10 +18,12 @@ import (
 //sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
 //sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
 //sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
 //sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
 //sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
 //sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
+//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
+//sys copyMemory(dst uintptr, src uintptr, length uint32) = RtlCopyMemory
 
 
 type securityAttributes struct {
 type securityAttributes struct {
 	Length             uint32
 	Length             uint32
-	SecurityDescriptor *byte
+	SecurityDescriptor uintptr
 	InheritHandle      uint32
 	InheritHandle      uint32
 }
 }
 
 
@@ -231,12 +233,15 @@ func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig,
 		mode |= cPIPE_TYPE_MESSAGE
 		mode |= cPIPE_TYPE_MESSAGE
 	}
 	}
 
 
-	var sa securityAttributes
-	sa.Length = uint32(unsafe.Sizeof(sa))
+	sa := &securityAttributes{}
+	sa.Length = uint32(unsafe.Sizeof(*sa))
 	if securityDescriptor != nil {
 	if securityDescriptor != nil {
-		sa.SecurityDescriptor = &securityDescriptor[0]
+		len := uint32(len(securityDescriptor))
+		sa.SecurityDescriptor = localAlloc(0, len)
+		defer localFree(sa.SecurityDescriptor)
+		copyMemory(sa.SecurityDescriptor, uintptr(unsafe.Pointer(&securityDescriptor[0])), len)
 	}
 	}
-	h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, &sa)
+	h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
 	if err != nil {
 	if err != nil {
 		return 0, &os.PathError{Op: "open", Path: path, Err: err}
 		return 0, &os.PathError{Op: "open", Path: path, Err: err}
 	}
 	}
@@ -363,7 +368,7 @@ func connectPipe(p *win32File) error {
 		return err
 		return err
 	}
 	}
 	err = connectNamedPipe(p.handle, &c.o)
 	err = connectNamedPipe(p.handle, &c.o)
-	_, err = p.asyncIo(c, time.Time{}, 0, err)
+	_, err = p.asyncIo(c, nil, 0, err)
 	if err != nil && err != cERROR_PIPE_CONNECTED {
 	if err != nil && err != cERROR_PIPE_CONNECTED {
 		return err
 		return err
 	}
 	}

+ 63 - 25
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go

@@ -11,6 +11,31 @@ import (
 
 
 var _ unsafe.Pointer
 var _ unsafe.Pointer
 
 
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
 var (
 var (
 	modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
 	modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
 	modwinmm    = windows.NewLazySystemDLL("winmm.dll")
 	modwinmm    = windows.NewLazySystemDLL("winmm.dll")
@@ -27,6 +52,8 @@ var (
 	procWaitNamedPipeW                                       = modkernel32.NewProc("WaitNamedPipeW")
 	procWaitNamedPipeW                                       = modkernel32.NewProc("WaitNamedPipeW")
 	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo")
 	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo")
 	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW")
 	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW")
+	procLocalAlloc                                           = modkernel32.NewProc("LocalAlloc")
+	procRtlCopyMemory                                        = modkernel32.NewProc("RtlCopyMemory")
 	procLookupAccountNameW                                   = modadvapi32.NewProc("LookupAccountNameW")
 	procLookupAccountNameW                                   = modadvapi32.NewProc("LookupAccountNameW")
 	procConvertSidToStringSidW                               = modadvapi32.NewProc("ConvertSidToStringSidW")
 	procConvertSidToStringSidW                               = modadvapi32.NewProc("ConvertSidToStringSidW")
 	procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
 	procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
@@ -51,7 +78,7 @@ func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
 	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
 	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -64,7 +91,7 @@ func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintpt
 	newport = syscall.Handle(r0)
 	newport = syscall.Handle(r0)
 	if newport == 0 {
 	if newport == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -76,7 +103,7 @@ func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr,
 	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
 	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -88,7 +115,7 @@ func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err erro
 	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
 	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -106,7 +133,7 @@ func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
 	r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
 	r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -128,7 +155,7 @@ func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances
 	handle = syscall.Handle(r0)
 	handle = syscall.Handle(r0)
 	if handle == syscall.InvalidHandle {
 	if handle == syscall.InvalidHandle {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -150,7 +177,7 @@ func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttribute
 	handle = syscall.Handle(r0)
 	handle = syscall.Handle(r0)
 	if handle == syscall.InvalidHandle {
 	if handle == syscall.InvalidHandle {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -171,7 +198,7 @@ func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
 	r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -183,7 +210,7 @@ func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSiz
 	r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
 	r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -195,7 +222,7 @@ func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *u
 	r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
 	r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -203,6 +230,17 @@ func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *u
 	return
 	return
 }
 }
 
 
+func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
+	r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
+	ptr = uintptr(r0)
+	return
+}
+
+func copyMemory(dst uintptr, src uintptr, length uint32) {
+	syscall.Syscall(procRtlCopyMemory.Addr(), 3, uintptr(dst), uintptr(src), uintptr(length))
+	return
+}
+
 func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
 func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
 	var _p0 *uint16
 	var _p0 *uint16
 	_p0, err = syscall.UTF16PtrFromString(accountName)
 	_p0, err = syscall.UTF16PtrFromString(accountName)
@@ -216,7 +254,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS
 	r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
 	r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -228,7 +266,7 @@ func convertSidToStringSid(sid *byte, str **uint16) (err error) {
 	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
 	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -249,7 +287,7 @@ func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision
 	r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
 	r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -261,7 +299,7 @@ func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint
 	r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
 	r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -284,7 +322,7 @@ func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte,
 	r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
 	r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -296,7 +334,7 @@ func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, si
 	r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
 	r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -315,7 +353,7 @@ func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, ou
 	success = r0 != 0
 	success = r0 != 0
 	if true {
 	if true {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -327,7 +365,7 @@ func impersonateSelf(level uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
 	r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -339,7 +377,7 @@ func revertToSelf() (err error) {
 	r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
 	r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -357,7 +395,7 @@ func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool,
 	r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
 	r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -389,7 +427,7 @@ func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err
 	r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
 	r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -410,7 +448,7 @@ func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size
 	r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
 	r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -431,7 +469,7 @@ func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint1
 	r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
 	r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -459,7 +497,7 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce
 	r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
 	r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}
@@ -487,7 +525,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
 	r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
 	r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
 	if r1 == 0 {
 	if r1 == 0 {
 		if e1 != 0 {
 		if e1 != 0 {
-			err = error(e1)
+			err = errnoErr(e1)
 		} else {
 		} else {
 			err = syscall.EINVAL
 			err = syscall.EINVAL
 		}
 		}