mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #19902 from Microsoft/jstarks/revendor_hcsshim_fix_docker_crash
Revendor Microsoft/hcsshim and vendor Microsoft/go-winio
This commit is contained in:
commit
a034ac66eb
34 changed files with 3320 additions and 1005 deletions
|
@ -7,6 +7,7 @@ source 'hack/.vendor-helpers.sh'
|
|||
|
||||
# the following lines are in sorted order, FYI
|
||||
clone git github.com/Azure/go-ansiterm 70b2c90b260171e829f1ebd7c17f600c11858dbe
|
||||
clone git github.com/Microsoft/go-winio 2b085935f02c272e7a1855df6f8fe03029ffcadd
|
||||
clone git github.com/Sirupsen/logrus v0.8.7 # logrus is a common dependency among multiple deps
|
||||
clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
|
||||
clone git github.com/go-check/check 11d3bc7aa68e238947792f30573146a3231fc0f1
|
||||
|
@ -15,7 +16,7 @@ clone git github.com/gorilla/mux e444e69cbd
|
|||
clone git github.com/kr/pty 5cf931ef8f
|
||||
clone git github.com/mattn/go-shellwords v1.0.0
|
||||
clone git github.com/mattn/go-sqlite3 v1.1.0
|
||||
clone git github.com/microsoft/hcsshim de43b42b5ce14dfdcbeedb0628b0032174d89caa
|
||||
clone git github.com/microsoft/hcsshim 35ad4d808a97203cb1748d7c43167e91f51e7f86
|
||||
clone git github.com/mistifyio/go-zfs v2.1.1
|
||||
clone git github.com/tchap/go-patricia v2.1.0
|
||||
clone git github.com/vdemeester/shakers 3c10293ce22b900c27acad7b28656196fcc2f73b
|
||||
|
|
22
vendor/src/github.com/Microsoft/go-winio/LICENSE
vendored
Normal file
22
vendor/src/github.com/Microsoft/go-winio/LICENSE
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
15
vendor/src/github.com/Microsoft/go-winio/README.md
vendored
Normal file
15
vendor/src/github.com/Microsoft/go-winio/README.md
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
# go-winio
|
||||
|
||||
This repository contains utilities for efficiently performing Win32 IO operations in
|
||||
Go. Currently, this is focused on accessing named pipes and other file handles, and
|
||||
for using named pipes as a net transport.
|
||||
|
||||
This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
|
||||
to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
|
||||
newer operating systems. This is similar to the implementation of network sockets in Go's net
|
||||
package.
|
||||
|
||||
Please see the LICENSE file for licensing information.
|
||||
|
||||
Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe
|
||||
for another named pipe implementation.
|
216
vendor/src/github.com/Microsoft/go-winio/file.go
vendored
Normal file
216
vendor/src/github.com/Microsoft/go-winio/file.go
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
package winio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
|
||||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||
|
||||
const (
|
||||
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
|
||||
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFileClosed = errors.New("file has already been closed")
|
||||
ErrTimeout = &timeoutError{}
|
||||
)
|
||||
|
||||
type timeoutError struct{}
|
||||
|
||||
func (e *timeoutError) Error() string { return "i/o timeout" }
|
||||
func (e *timeoutError) Timeout() bool { return true }
|
||||
func (e *timeoutError) Temporary() bool { return true }
|
||||
|
||||
var ioInitOnce sync.Once
|
||||
var ioCompletionPort syscall.Handle
|
||||
|
||||
// ioResult contains the result of an asynchronous IO operation
|
||||
type ioResult struct {
|
||||
bytes uint32
|
||||
err error
|
||||
}
|
||||
|
||||
// ioOperation represents an outstanding asynchronous Win32 IO
|
||||
type ioOperation struct {
|
||||
o syscall.Overlapped
|
||||
ch chan ioResult
|
||||
}
|
||||
|
||||
func initIo() {
|
||||
h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ioCompletionPort = h
|
||||
go ioCompletionProcessor(h)
|
||||
}
|
||||
|
||||
// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
|
||||
// It takes ownership of this handle and will close it if it is garbage collected.
|
||||
type win32File struct {
|
||||
handle syscall.Handle
|
||||
wg sync.WaitGroup
|
||||
closing bool
|
||||
readDeadline time.Time
|
||||
writeDeadline time.Time
|
||||
}
|
||||
|
||||
// makeWin32File makes a new win32File from an existing file handle
|
||||
func makeWin32File(h syscall.Handle) (*win32File, error) {
|
||||
f := &win32File{handle: h}
|
||||
ioInitOnce.Do(initIo)
|
||||
_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runtime.SetFinalizer(f, (*win32File).closeHandle)
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
||||
return makeWin32File(h)
|
||||
}
|
||||
|
||||
// closeHandle closes the resources associated with a Win32 handle
|
||||
func (f *win32File) closeHandle() {
|
||||
if !f.closing {
|
||||
// cancel all IO and wait for it to complete
|
||||
f.closing = true
|
||||
cancelIoEx(f.handle, nil)
|
||||
f.wg.Wait()
|
||||
// at this point, no new IO can start
|
||||
syscall.Close(f.handle)
|
||||
f.handle = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Close closes a win32File.
|
||||
func (f *win32File) Close() error {
|
||||
f.closeHandle()
|
||||
runtime.SetFinalizer(f, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareIo prepares for a new IO operation
|
||||
func (f *win32File) prepareIo() (*ioOperation, error) {
|
||||
f.wg.Add(1)
|
||||
if f.closing {
|
||||
return nil, ErrFileClosed
|
||||
}
|
||||
c := &ioOperation{}
|
||||
c.ch = make(chan ioResult)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ioCompletionProcessor processes completed async IOs forever
|
||||
func ioCompletionProcessor(h syscall.Handle) {
|
||||
for {
|
||||
var bytes uint32
|
||||
var key uintptr
|
||||
var op *ioOperation
|
||||
err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
|
||||
if op == nil {
|
||||
panic(err)
|
||||
}
|
||||
op.ch <- ioResult{bytes, err}
|
||||
}
|
||||
}
|
||||
|
||||
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
|
||||
// the operation has actually completed.
|
||||
func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) {
|
||||
if err != syscall.ERROR_IO_PENDING {
|
||||
f.wg.Done()
|
||||
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
|
||||
}
|
||||
err = r.err
|
||||
if err == syscall.ERROR_OPERATION_ABORTED {
|
||||
if f.closing {
|
||||
err = ErrFileClosed
|
||||
} else if timedout {
|
||||
err = ErrTimeout
|
||||
}
|
||||
}
|
||||
f.wg.Done()
|
||||
return int(r.bytes), err
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads from a file handle.
|
||||
func (f *win32File) Read(b []byte) (int, error) {
|
||||
c, err := f.prepareIo()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var bytes uint32
|
||||
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
|
||||
n, err := f.asyncIo(c, f.readDeadline, bytes, err)
|
||||
|
||||
// Handle EOF conditions.
|
||||
if err == nil && n == 0 && len(b) != 0 {
|
||||
return 0, io.EOF
|
||||
} else if err == syscall.ERROR_BROKEN_PIPE {
|
||||
return 0, io.EOF
|
||||
} else {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes to a file handle.
|
||||
func (f *win32File) Write(b []byte) (int, error) {
|
||||
c, err := f.prepareIo()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var bytes uint32
|
||||
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
|
||||
return f.asyncIo(c, f.writeDeadline, bytes, err)
|
||||
}
|
||||
|
||||
func (f *win32File) SetReadDeadline(t time.Time) error {
|
||||
f.readDeadline = t
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *win32File) SetWriteDeadline(t time.Time) error {
|
||||
f.writeDeadline = t
|
||||
return nil
|
||||
}
|
797
vendor/src/github.com/Microsoft/go-winio/mksyscall_windows.go
vendored
Normal file
797
vendor/src/github.com/Microsoft/go-winio/mksyscall_windows.go
vendored
Normal file
|
@ -0,0 +1,797 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
/*
|
||||
mksyscall_windows generates windows system call bodies
|
||||
|
||||
It parses all files specified on command line containing function
|
||||
prototypes (like syscall_windows.go) and prints system call bodies
|
||||
to standard output.
|
||||
|
||||
The prototypes are marked by lines beginning with "//sys" and read
|
||||
like func declarations if //sys is replaced by func, but:
|
||||
|
||||
* The parameter lists must give a name for each argument. This
|
||||
includes return parameters.
|
||||
|
||||
* The parameter lists must give a type for each argument:
|
||||
the (x, y, z int) shorthand is not allowed.
|
||||
|
||||
* If the return parameter is an error number, it must be named err.
|
||||
|
||||
* If go func name needs to be different from it's winapi dll name,
|
||||
the winapi name could be specified at the end, after "=" sign, like
|
||||
//sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA
|
||||
|
||||
* Each function that returns err needs to supply a condition, that
|
||||
return value of winapi will be tested against to detect failure.
|
||||
This would set err to windows "last-error", otherwise it will be nil.
|
||||
The value can be provided at end of //sys declaration, like
|
||||
//sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA
|
||||
and is [failretval==0] by default.
|
||||
|
||||
Usage:
|
||||
mksyscall_windows [flags] [path ...]
|
||||
|
||||
The flags are:
|
||||
-output
|
||||
Specify output file name (outputs to console if blank).
|
||||
-trace
|
||||
Generate print statement after every syscall.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var (
|
||||
filename = flag.String("output", "", "output file name (standard output if omitted)")
|
||||
printTraceFlag = flag.Bool("trace", false, "generate print statement after every syscall")
|
||||
)
|
||||
|
||||
func trim(s string) string {
|
||||
return strings.Trim(s, " \t")
|
||||
}
|
||||
|
||||
var packageName string
|
||||
|
||||
func packagename() string {
|
||||
return packageName
|
||||
}
|
||||
|
||||
func syscalldot() string {
|
||||
if packageName == "syscall" {
|
||||
return ""
|
||||
}
|
||||
return "syscall."
|
||||
}
|
||||
|
||||
// Param is function parameter
|
||||
type Param struct {
|
||||
Name string
|
||||
Type string
|
||||
fn *Fn
|
||||
tmpVarIdx int
|
||||
}
|
||||
|
||||
// tmpVar returns temp variable name that will be used to represent p during syscall.
|
||||
func (p *Param) tmpVar() string {
|
||||
if p.tmpVarIdx < 0 {
|
||||
p.tmpVarIdx = p.fn.curTmpVarIdx
|
||||
p.fn.curTmpVarIdx++
|
||||
}
|
||||
return fmt.Sprintf("_p%d", p.tmpVarIdx)
|
||||
}
|
||||
|
||||
// BoolTmpVarCode returns source code for bool temp variable.
|
||||
func (p *Param) BoolTmpVarCode() string {
|
||||
const code = `var %s uint32
|
||||
if %s {
|
||||
%s = 1
|
||||
} else {
|
||||
%s = 0
|
||||
}`
|
||||
tmp := p.tmpVar()
|
||||
return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
|
||||
}
|
||||
|
||||
// SliceTmpVarCode returns source code for slice temp variable.
|
||||
func (p *Param) SliceTmpVarCode() string {
|
||||
const code = `var %s *%s
|
||||
if len(%s) > 0 {
|
||||
%s = &%s[0]
|
||||
}`
|
||||
tmp := p.tmpVar()
|
||||
return fmt.Sprintf(code, tmp, p.Type[2:], p.Name, tmp, p.Name)
|
||||
}
|
||||
|
||||
// StringTmpVarCode returns source code for string temp variable.
|
||||
func (p *Param) StringTmpVarCode() string {
|
||||
errvar := p.fn.Rets.ErrorVarName()
|
||||
if errvar == "" {
|
||||
errvar = "_"
|
||||
}
|
||||
tmp := p.tmpVar()
|
||||
const code = `var %s %s
|
||||
%s, %s = %s(%s)`
|
||||
s := fmt.Sprintf(code, tmp, p.fn.StrconvType(), tmp, errvar, p.fn.StrconvFunc(), p.Name)
|
||||
if errvar == "-" {
|
||||
return s
|
||||
}
|
||||
const morecode = `
|
||||
if %s != nil {
|
||||
return
|
||||
}`
|
||||
return s + fmt.Sprintf(morecode, errvar)
|
||||
}
|
||||
|
||||
// TmpVarCode returns source code for temp variable.
|
||||
func (p *Param) TmpVarCode() string {
|
||||
switch {
|
||||
case p.Type == "bool":
|
||||
return p.BoolTmpVarCode()
|
||||
case strings.HasPrefix(p.Type, "[]"):
|
||||
return p.SliceTmpVarCode()
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// TmpVarHelperCode returns source code for helper's temp variable.
|
||||
func (p *Param) TmpVarHelperCode() string {
|
||||
if p.Type != "string" {
|
||||
return ""
|
||||
}
|
||||
return p.StringTmpVarCode()
|
||||
}
|
||||
|
||||
// SyscallArgList returns source code fragments representing p parameter
|
||||
// in syscall. Slices are translated into 2 syscall parameters: pointer to
|
||||
// the first element and length.
|
||||
func (p *Param) SyscallArgList() []string {
|
||||
t := p.HelperType()
|
||||
var s string
|
||||
switch {
|
||||
case t[0] == '*':
|
||||
s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
|
||||
case t == "bool":
|
||||
s = p.tmpVar()
|
||||
case strings.HasPrefix(t, "[]"):
|
||||
return []string{
|
||||
fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
|
||||
fmt.Sprintf("uintptr(len(%s))", p.Name),
|
||||
}
|
||||
default:
|
||||
s = p.Name
|
||||
}
|
||||
return []string{fmt.Sprintf("uintptr(%s)", s)}
|
||||
}
|
||||
|
||||
// IsError determines if p parameter is used to return error.
|
||||
func (p *Param) IsError() bool {
|
||||
return p.Name == "err" && p.Type == "error"
|
||||
}
|
||||
|
||||
// HelperType returns type of parameter p used in helper function.
|
||||
func (p *Param) HelperType() string {
|
||||
if p.Type == "string" {
|
||||
return p.fn.StrconvType()
|
||||
}
|
||||
return p.Type
|
||||
}
|
||||
|
||||
// join concatenates parameters ps into a string with sep separator.
|
||||
// Each parameter is converted into string by applying fn to it
|
||||
// before conversion.
|
||||
func join(ps []*Param, fn func(*Param) string, sep string) string {
|
||||
if len(ps) == 0 {
|
||||
return ""
|
||||
}
|
||||
a := make([]string, 0)
|
||||
for _, p := range ps {
|
||||
a = append(a, fn(p))
|
||||
}
|
||||
return strings.Join(a, sep)
|
||||
}
|
||||
|
||||
// Rets describes function return parameters.
|
||||
type Rets struct {
|
||||
Name string
|
||||
Type string
|
||||
ReturnsError bool
|
||||
FailCond string
|
||||
}
|
||||
|
||||
// ErrorVarName returns error variable name for r.
|
||||
func (r *Rets) ErrorVarName() string {
|
||||
if r.ReturnsError {
|
||||
return "err"
|
||||
}
|
||||
if r.Type == "error" {
|
||||
return r.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ToParams converts r into slice of *Param.
|
||||
func (r *Rets) ToParams() []*Param {
|
||||
ps := make([]*Param, 0)
|
||||
if len(r.Name) > 0 {
|
||||
ps = append(ps, &Param{Name: r.Name, Type: r.Type})
|
||||
}
|
||||
if r.ReturnsError {
|
||||
ps = append(ps, &Param{Name: "err", Type: "error"})
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
// List returns source code of syscall return parameters.
|
||||
func (r *Rets) List() string {
|
||||
s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ")
|
||||
if len(s) > 0 {
|
||||
s = "(" + s + ")"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// PrintList returns source code of trace printing part correspondent
|
||||
// to syscall return values.
|
||||
func (r *Rets) PrintList() string {
|
||||
return join(r.ToParams(), func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
|
||||
}
|
||||
|
||||
// SetReturnValuesCode returns source code that accepts syscall return values.
|
||||
func (r *Rets) SetReturnValuesCode() string {
|
||||
if r.Name == "" && !r.ReturnsError {
|
||||
return ""
|
||||
}
|
||||
retvar := "r0"
|
||||
if r.Name == "" {
|
||||
retvar = "r1"
|
||||
}
|
||||
errvar := "_"
|
||||
if r.ReturnsError {
|
||||
errvar = "e1"
|
||||
}
|
||||
return fmt.Sprintf("%s, _, %s := ", retvar, errvar)
|
||||
}
|
||||
|
||||
func (r *Rets) useLongHandleErrorCode(retvar string) string {
|
||||
const code = `if %s {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = %sEINVAL
|
||||
}
|
||||
}`
|
||||
cond := retvar + " == 0"
|
||||
if r.FailCond != "" {
|
||||
cond = strings.Replace(r.FailCond, "failretval", retvar, 1)
|
||||
}
|
||||
return fmt.Sprintf(code, cond, syscalldot())
|
||||
}
|
||||
|
||||
// SetErrorCode returns source code that sets return parameters.
|
||||
func (r *Rets) SetErrorCode() string {
|
||||
const code = `if r0 != 0 {
|
||||
%s = %sErrno(r0)
|
||||
}`
|
||||
if r.Name == "" && !r.ReturnsError {
|
||||
return ""
|
||||
}
|
||||
if r.Name == "" {
|
||||
return r.useLongHandleErrorCode("r1")
|
||||
}
|
||||
if r.Type == "error" {
|
||||
return fmt.Sprintf(code, r.Name, syscalldot())
|
||||
}
|
||||
s := ""
|
||||
switch {
|
||||
case r.Type[0] == '*':
|
||||
s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type)
|
||||
case r.Type == "bool":
|
||||
s = fmt.Sprintf("%s = r0 != 0", r.Name)
|
||||
default:
|
||||
s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type)
|
||||
}
|
||||
if !r.ReturnsError {
|
||||
return s
|
||||
}
|
||||
return s + "\n\t" + r.useLongHandleErrorCode(r.Name)
|
||||
}
|
||||
|
||||
// Fn describes syscall function.
|
||||
type Fn struct {
|
||||
Name string
|
||||
Params []*Param
|
||||
Rets *Rets
|
||||
PrintTrace bool
|
||||
confirmproc bool
|
||||
dllname string
|
||||
dllfuncname string
|
||||
src string
|
||||
// TODO: get rid of this field and just use parameter index instead
|
||||
curTmpVarIdx int // insure tmp variables have uniq names
|
||||
}
|
||||
|
||||
// extractParams parses s to extract function parameters.
|
||||
func extractParams(s string, f *Fn) ([]*Param, error) {
|
||||
s = trim(s)
|
||||
if s == "" {
|
||||
return nil, nil
|
||||
}
|
||||
a := strings.Split(s, ",")
|
||||
ps := make([]*Param, len(a))
|
||||
for i := range ps {
|
||||
s2 := trim(a[i])
|
||||
b := strings.Split(s2, " ")
|
||||
if len(b) != 2 {
|
||||
b = strings.Split(s2, "\t")
|
||||
if len(b) != 2 {
|
||||
return nil, errors.New("Could not extract function parameter from \"" + s2 + "\"")
|
||||
}
|
||||
}
|
||||
ps[i] = &Param{
|
||||
Name: trim(b[0]),
|
||||
Type: trim(b[1]),
|
||||
fn: f,
|
||||
tmpVarIdx: -1,
|
||||
}
|
||||
}
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
// extractSection extracts text out of string s starting after start
|
||||
// and ending just before end. found return value will indicate success,
|
||||
// and prefix, body and suffix will contain correspondent parts of string s.
|
||||
func extractSection(s string, start, end rune) (prefix, body, suffix string, found bool) {
|
||||
s = trim(s)
|
||||
if strings.HasPrefix(s, string(start)) {
|
||||
// no prefix
|
||||
body = s[1:]
|
||||
} else {
|
||||
a := strings.SplitN(s, string(start), 2)
|
||||
if len(a) != 2 {
|
||||
return "", "", s, false
|
||||
}
|
||||
prefix = a[0]
|
||||
body = a[1]
|
||||
}
|
||||
a := strings.SplitN(body, string(end), 2)
|
||||
if len(a) != 2 {
|
||||
return "", "", "", false
|
||||
}
|
||||
return prefix, a[0], a[1], true
|
||||
}
|
||||
|
||||
// newFn parses string s and return created function Fn.
|
||||
func newFn(s string) (*Fn, error) {
|
||||
s = trim(s)
|
||||
f := &Fn{
|
||||
Rets: &Rets{},
|
||||
src: s,
|
||||
PrintTrace: *printTraceFlag,
|
||||
}
|
||||
// function name and args
|
||||
prefix, body, s, found := extractSection(s, '(', ')')
|
||||
if !found || prefix == "" {
|
||||
return nil, errors.New("Could not extract function name and parameters from \"" + f.src + "\"")
|
||||
}
|
||||
f.Name = prefix
|
||||
var err error
|
||||
f.Params, err = extractParams(body, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// return values
|
||||
_, body, s, found = extractSection(s, '(', ')')
|
||||
if found {
|
||||
r, err := extractParams(body, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(r) {
|
||||
case 0:
|
||||
case 1:
|
||||
if r[0].IsError() {
|
||||
f.Rets.ReturnsError = true
|
||||
} else {
|
||||
f.Rets.Name = r[0].Name
|
||||
f.Rets.Type = r[0].Type
|
||||
}
|
||||
case 2:
|
||||
if !r[1].IsError() {
|
||||
return nil, errors.New("Only last windows error is allowed as second return value in \"" + f.src + "\"")
|
||||
}
|
||||
f.Rets.ReturnsError = true
|
||||
f.Rets.Name = r[0].Name
|
||||
f.Rets.Type = r[0].Type
|
||||
default:
|
||||
return nil, errors.New("Too many return values in \"" + f.src + "\"")
|
||||
}
|
||||
}
|
||||
// fail condition
|
||||
_, body, s, found = extractSection(s, '[', ']')
|
||||
if found {
|
||||
f.Rets.FailCond = body
|
||||
}
|
||||
// dll and dll function names
|
||||
s = trim(s)
|
||||
if s == "" {
|
||||
return f, nil
|
||||
}
|
||||
if !strings.HasPrefix(s, "=") {
|
||||
return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
|
||||
}
|
||||
s = trim(s[1:])
|
||||
a := strings.Split(s, ".")
|
||||
switch len(a) {
|
||||
case 1:
|
||||
f.dllfuncname = a[0]
|
||||
case 2:
|
||||
f.dllname = a[0]
|
||||
f.dllfuncname = a[1]
|
||||
default:
|
||||
return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
|
||||
}
|
||||
if f.dllfuncname[len(f.dllfuncname)-1] == '?' {
|
||||
f.confirmproc = true
|
||||
f.dllfuncname = f.dllfuncname[0 : len(f.dllfuncname)-1]
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// DLLName returns DLL name for function f.
|
||||
func (f *Fn) DLLName() string {
|
||||
if f.dllname == "" {
|
||||
return "kernel32"
|
||||
}
|
||||
return f.dllname
|
||||
}
|
||||
|
||||
// DLLName returns DLL function name for function f.
|
||||
func (f *Fn) DLLFuncName() string {
|
||||
if f.dllfuncname == "" {
|
||||
return f.Name
|
||||
}
|
||||
return f.dllfuncname
|
||||
}
|
||||
|
||||
func (f *Fn) ConfirmProc() bool {
|
||||
return f.confirmproc
|
||||
}
|
||||
|
||||
// ParamList returns source code for function f parameters.
|
||||
func (f *Fn) ParamList() string {
|
||||
return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
|
||||
}
|
||||
|
||||
// HelperParamList returns source code for helper function f parameters.
|
||||
func (f *Fn) HelperParamList() string {
|
||||
return join(f.Params, func(p *Param) string { return p.Name + " " + p.HelperType() }, ", ")
|
||||
}
|
||||
|
||||
// ParamPrintList returns source code of trace printing part correspondent
|
||||
// to syscall input parameters.
|
||||
func (f *Fn) ParamPrintList() string {
|
||||
return join(f.Params, func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
|
||||
}
|
||||
|
||||
// ParamCount return number of syscall parameters for function f.
|
||||
func (f *Fn) ParamCount() int {
|
||||
n := 0
|
||||
for _, p := range f.Params {
|
||||
n += len(p.SyscallArgList())
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// SyscallParamCount determines which version of Syscall/Syscall6/Syscall9/...
|
||||
// to use. It returns parameter count for correspondent SyscallX function.
|
||||
func (f *Fn) SyscallParamCount() int {
|
||||
n := f.ParamCount()
|
||||
switch {
|
||||
case n <= 3:
|
||||
return 3
|
||||
case n <= 6:
|
||||
return 6
|
||||
case n <= 9:
|
||||
return 9
|
||||
case n <= 12:
|
||||
return 12
|
||||
case n <= 15:
|
||||
return 15
|
||||
default:
|
||||
panic("too many arguments to system call")
|
||||
}
|
||||
}
|
||||
|
||||
// Syscall determines which SyscallX function to use for function f.
|
||||
func (f *Fn) Syscall() string {
|
||||
c := f.SyscallParamCount()
|
||||
if c == 3 {
|
||||
return syscalldot() + "Syscall"
|
||||
}
|
||||
return syscalldot() + "Syscall" + strconv.Itoa(c)
|
||||
}
|
||||
|
||||
// SyscallParamList returns source code for SyscallX parameters for function f.
|
||||
func (f *Fn) SyscallParamList() string {
|
||||
a := make([]string, 0)
|
||||
for _, p := range f.Params {
|
||||
a = append(a, p.SyscallArgList()...)
|
||||
}
|
||||
for len(a) < f.SyscallParamCount() {
|
||||
a = append(a, "0")
|
||||
}
|
||||
return strings.Join(a, ", ")
|
||||
}
|
||||
|
||||
// HelperCallParamList returns source code of call into function f helper.
|
||||
func (f *Fn) HelperCallParamList() string {
|
||||
a := make([]string, 0, len(f.Params))
|
||||
for _, p := range f.Params {
|
||||
s := p.Name
|
||||
if p.Type == "string" {
|
||||
s = p.tmpVar()
|
||||
}
|
||||
a = append(a, s)
|
||||
}
|
||||
return strings.Join(a, ", ")
|
||||
}
|
||||
|
||||
// IsUTF16 is true, if f is W (utf16) function. It is false
|
||||
// for all A (ascii) functions.
|
||||
func (_ *Fn) IsUTF16() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// StrconvFunc returns name of Go string to OS string function for f.
|
||||
func (f *Fn) StrconvFunc() string {
|
||||
if f.IsUTF16() {
|
||||
return syscalldot() + "UTF16PtrFromString"
|
||||
}
|
||||
return syscalldot() + "BytePtrFromString"
|
||||
}
|
||||
|
||||
// StrconvType returns Go type name used for OS string for f.
|
||||
func (f *Fn) StrconvType() string {
|
||||
if f.IsUTF16() {
|
||||
return "*uint16"
|
||||
}
|
||||
return "*byte"
|
||||
}
|
||||
|
||||
// HasStringParam is true, if f has at least one string parameter.
|
||||
// Otherwise it is false.
|
||||
func (f *Fn) HasStringParam() bool {
|
||||
for _, p := range f.Params {
|
||||
if p.Type == "string" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HelperName returns name of function f helper.
|
||||
func (f *Fn) HelperName() string {
|
||||
if !f.HasStringParam() {
|
||||
return f.Name
|
||||
}
|
||||
return "_" + f.Name
|
||||
}
|
||||
|
||||
// Source files and functions.
|
||||
type Source struct {
|
||||
Funcs []*Fn
|
||||
Files []string
|
||||
}
|
||||
|
||||
// ParseFiles parses files listed in fs and extracts all syscall
|
||||
// functions listed in sys comments. It returns source files
|
||||
// and functions collection *Source if successful.
|
||||
func ParseFiles(fs []string) (*Source, error) {
|
||||
src := &Source{
|
||||
Funcs: make([]*Fn, 0),
|
||||
Files: make([]string, 0),
|
||||
}
|
||||
for _, file := range fs {
|
||||
if err := src.ParseFile(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return src, nil
|
||||
}
|
||||
|
||||
// DLLs return dll names for a source set src.
|
||||
func (src *Source) DLLs() []string {
|
||||
uniq := make(map[string]bool)
|
||||
r := make([]string, 0)
|
||||
for _, f := range src.Funcs {
|
||||
name := f.DLLName()
|
||||
if _, found := uniq[name]; !found {
|
||||
uniq[name] = true
|
||||
r = append(r, name)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ParseFile adds additional file path to a source set src.
|
||||
func (src *Source) ParseFile(path string) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
s := bufio.NewScanner(file)
|
||||
for s.Scan() {
|
||||
t := trim(s.Text())
|
||||
if len(t) < 7 {
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(t, "//sys") {
|
||||
continue
|
||||
}
|
||||
t = t[5:]
|
||||
if !(t[0] == ' ' || t[0] == '\t') {
|
||||
continue
|
||||
}
|
||||
f, err := newFn(t[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
src.Funcs = append(src.Funcs, f)
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
src.Files = append(src.Files, path)
|
||||
|
||||
// get package name
|
||||
fset := token.NewFileSet()
|
||||
_, err = file.Seek(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pkg, err := parser.ParseFile(fset, "", file, parser.PackageClauseOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
packageName = pkg.Name.Name
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate output source file from a source set src.
|
||||
func (src *Source) Generate(w io.Writer) error {
|
||||
funcMap := template.FuncMap{
|
||||
"packagename": packagename,
|
||||
"syscalldot": syscalldot,
|
||||
}
|
||||
t := template.Must(template.New("main").Funcs(funcMap).Parse(srcTemplate))
|
||||
err := t.Execute(w, src)
|
||||
if err != nil {
|
||||
return errors.New("Failed to execute template: " + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: mksyscall_windows [flags] [path ...]\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
if len(flag.Args()) <= 0 {
|
||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
||||
usage()
|
||||
}
|
||||
|
||||
src, err := ParseFiles(flag.Args())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := src.Generate(&buf); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
data, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if *filename == "" {
|
||||
_, err = os.Stdout.Write(data)
|
||||
} else {
|
||||
err = ioutil.WriteFile(*filename, data, 0644)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use println instead to print in the following template
|
||||
const srcTemplate = `
|
||||
|
||||
{{define "main"}}// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
||||
|
||||
package {{packagename}}
|
||||
|
||||
import "unsafe"{{if syscalldot}}
|
||||
import "syscall"{{end}}
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
var (
|
||||
{{template "dlls" .}}
|
||||
{{template "funcnames" .}})
|
||||
{{range .Funcs}}{{if .HasStringParam}}{{template "helperbody" .}}{{end}}{{template "funcbody" .}}{{end}}
|
||||
{{end}}
|
||||
|
||||
{{/* help functions */}}
|
||||
|
||||
{{define "dlls"}}{{range .DLLs}} mod{{.}} = {{syscalldot}}NewLazyDLL("{{.}}.dll")
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "funcnames"}}{{range .Funcs}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}")
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "helperbody"}}
|
||||
func {{.Name}}({{.ParamList}}) {{template "results" .}}{
|
||||
{{template "helpertmpvars" .}} return {{.HelperName}}({{.HelperCallParamList}})
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{define "funcbody"}}
|
||||
func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
|
||||
{{template "tmpvars" .}} {{template "syscallcheck" .}}{{template "syscall" .}}
|
||||
{{template "seterror" .}}{{template "printtrace" .}} return
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
|
||||
|
||||
{{define "syscallcheck"}}{{if .ConfirmProc}}if {{.Rets.ErrorVarName}} = proc{{.DLLFuncName}}.Find(); {{.Rets.ErrorVarName}} != nil {
|
||||
return
|
||||
}
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
|
||||
|
||||
{{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "printtrace"}}{{if .PrintTrace}} print("SYSCALL: {{.Name}}(", {{.ParamPrintList}}") (", {{.Rets.PrintList}}")\n")
|
||||
{{end}}{{end}}
|
||||
|
||||
`
|
280
vendor/src/github.com/Microsoft/go-winio/pipe.go
vendored
Normal file
280
vendor/src/github.com/Microsoft/go-winio/pipe.go
vendored
Normal file
|
@ -0,0 +1,280 @@
|
|||
package winio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
|
||||
//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
|
||||
//sys createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
|
||||
//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
|
||||
|
||||
type securityAttributes struct {
|
||||
Length uint32
|
||||
SecurityDescriptor *byte
|
||||
InheritHandle uint32
|
||||
}
|
||||
|
||||
const (
|
||||
cERROR_PIPE_BUSY = syscall.Errno(231)
|
||||
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
||||
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
||||
|
||||
cPIPE_ACCESS_DUPLEX = 0x3
|
||||
cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000
|
||||
cSECURITY_SQOS_PRESENT = 0x100000
|
||||
cSECURITY_ANONYMOUS = 0
|
||||
|
||||
cPIPE_REJECT_REMOTE_CLIENTS = 0x8
|
||||
|
||||
cPIPE_UNLIMITED_INSTANCES = 255
|
||||
|
||||
cNMPWAIT_USE_DEFAULT_WAIT = 0
|
||||
cNMPWAIT_NOWAIT = 1
|
||||
)
|
||||
|
||||
var (
|
||||
// This error should match net.errClosing since docker takes a dependency on its text
|
||||
ErrPipeListenerClosed = errors.New("use of closed network connection")
|
||||
)
|
||||
|
||||
type win32Pipe struct {
|
||||
*win32File
|
||||
path string
|
||||
}
|
||||
|
||||
type pipeAddress string
|
||||
|
||||
func (f *win32Pipe) LocalAddr() net.Addr {
|
||||
return pipeAddress(f.path)
|
||||
}
|
||||
|
||||
func (f *win32Pipe) RemoteAddr() net.Addr {
|
||||
return pipeAddress(f.path)
|
||||
}
|
||||
|
||||
func (f *win32Pipe) SetDeadline(t time.Time) error {
|
||||
f.SetReadDeadline(t)
|
||||
f.SetWriteDeadline(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s pipeAddress) Network() string {
|
||||
return "pipe"
|
||||
}
|
||||
|
||||
func (s pipeAddress) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func makeWin32Pipe(h syscall.Handle, path string) (*win32Pipe, error) {
|
||||
f, err := makeWin32File(h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &win32Pipe{f, path}, nil
|
||||
}
|
||||
|
||||
// DialPipe connects to a named pipe by path, timing out if the connection
|
||||
// takes longer than the specified duration. If timeout is nil, then the timeout
|
||||
// is the default timeout established by the pipe server.
|
||||
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
||||
var absTimeout time.Time
|
||||
if timeout != nil {
|
||||
absTimeout = time.Now().Add(*timeout)
|
||||
}
|
||||
var err error
|
||||
var h syscall.Handle
|
||||
for {
|
||||
h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
||||
if err != cERROR_PIPE_BUSY {
|
||||
break
|
||||
}
|
||||
now := time.Now()
|
||||
var ms uint32
|
||||
if absTimeout.IsZero() {
|
||||
ms = cNMPWAIT_USE_DEFAULT_WAIT
|
||||
} else if now.After(absTimeout) {
|
||||
ms = cNMPWAIT_NOWAIT
|
||||
} else {
|
||||
ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000)
|
||||
}
|
||||
err = waitNamedPipe(path, ms)
|
||||
if err != nil {
|
||||
if err == cERROR_SEM_TIMEOUT {
|
||||
return nil, ErrTimeout
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, &os.PathError{"open", path, err}
|
||||
}
|
||||
p, err := makeWin32Pipe(h, path)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
type acceptResponse struct {
|
||||
p *win32Pipe
|
||||
err error
|
||||
}
|
||||
|
||||
type win32PipeListener struct {
|
||||
firstHandle syscall.Handle
|
||||
path string
|
||||
securityDescriptor []byte
|
||||
acceptCh chan (chan acceptResponse)
|
||||
closeCh chan int
|
||||
doneCh chan int
|
||||
}
|
||||
|
||||
func makeServerPipeHandle(path string, securityDescriptor []byte, first bool) (syscall.Handle, error) {
|
||||
var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED
|
||||
if first {
|
||||
flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
|
||||
}
|
||||
var sa securityAttributes
|
||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||
if securityDescriptor != nil {
|
||||
sa.SecurityDescriptor = &securityDescriptor[0]
|
||||
}
|
||||
h, err := createNamedPipe(path, flags, cPIPE_REJECT_REMOTE_CLIENTS, cPIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, &sa)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{"open", path, err}
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) makeServerPipe() (*win32Pipe, error) {
|
||||
h, err := makeServerPipeHandle(l.path, l.securityDescriptor, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := makeWin32Pipe(h, l.path)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) listenerRoutine() {
|
||||
closed := false
|
||||
for !closed {
|
||||
select {
|
||||
case <-l.closeCh:
|
||||
closed = true
|
||||
case responseCh := <-l.acceptCh:
|
||||
p, err := l.makeServerPipe()
|
||||
if err == nil {
|
||||
// Wait for the client to connect.
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
ch <- connectPipe(p)
|
||||
}()
|
||||
select {
|
||||
case err = <-ch:
|
||||
if err != nil {
|
||||
p.Close()
|
||||
p = nil
|
||||
}
|
||||
case <-l.closeCh:
|
||||
// Abort the connect request by closing the handle.
|
||||
p.Close()
|
||||
p = nil
|
||||
err = <-ch
|
||||
if err == nil || err == ErrFileClosed {
|
||||
err = ErrPipeListenerClosed
|
||||
}
|
||||
closed = true
|
||||
}
|
||||
}
|
||||
responseCh <- acceptResponse{p, err}
|
||||
}
|
||||
}
|
||||
syscall.Close(l.firstHandle)
|
||||
l.firstHandle = 0
|
||||
// Notify Close() and Accept() callers that the handle has been closed.
|
||||
close(l.doneCh)
|
||||
}
|
||||
|
||||
func ListenPipe(path, sddl string) (net.Listener, error) {
|
||||
var (
|
||||
sd []byte
|
||||
err error
|
||||
)
|
||||
if sddl != "" {
|
||||
sd, err = sddlToSecurityDescriptor(sddl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
h, err := makeServerPipeHandle(path, sd, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Immediately open and then close a client handle so that the named pipe is
|
||||
// created but not currently accepting connections.
|
||||
h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
syscall.Close(h2)
|
||||
l := &win32PipeListener{
|
||||
firstHandle: h,
|
||||
path: path,
|
||||
securityDescriptor: sd,
|
||||
acceptCh: make(chan (chan acceptResponse)),
|
||||
closeCh: make(chan int),
|
||||
doneCh: make(chan int),
|
||||
}
|
||||
go l.listenerRoutine()
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func connectPipe(p *win32Pipe) error {
|
||||
c, err := p.prepareIo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = connectNamedPipe(p.handle, &c.o)
|
||||
_, err = p.asyncIo(c, time.Time{}, 0, err)
|
||||
if err != nil && err != cERROR_PIPE_CONNECTED {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) Accept() (net.Conn, error) {
|
||||
ch := make(chan acceptResponse)
|
||||
select {
|
||||
case l.acceptCh <- ch:
|
||||
response := <-ch
|
||||
return response.p, response.err
|
||||
case <-l.doneCh:
|
||||
return nil, ErrPipeListenerClosed
|
||||
}
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) Close() error {
|
||||
select {
|
||||
case l.closeCh <- 1:
|
||||
<-l.doneCh
|
||||
case <-l.doneCh:
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) Addr() net.Addr {
|
||||
return pipeAddress(l.path)
|
||||
}
|
83
vendor/src/github.com/Microsoft/go-winio/sd.go
vendored
Normal file
83
vendor/src/github.com/Microsoft/go-winio/sd.go
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
package winio
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW
|
||||
//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
|
||||
//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
|
||||
//sys localFree(mem uintptr) = LocalFree
|
||||
//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
|
||||
|
||||
const (
|
||||
cERROR_NONE_MAPPED = syscall.Errno(1332)
|
||||
)
|
||||
|
||||
type AccountLookupError struct {
|
||||
Name string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *AccountLookupError) Error() string {
|
||||
if e.Name == "" {
|
||||
return "lookup account: empty account name specified"
|
||||
}
|
||||
var s string
|
||||
switch e.Err {
|
||||
case cERROR_NONE_MAPPED:
|
||||
s = "not found"
|
||||
default:
|
||||
s = e.Err.Error()
|
||||
}
|
||||
return "lookup account " + e.Name + ": " + s
|
||||
}
|
||||
|
||||
type SddlConversionError struct {
|
||||
Sddl string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *SddlConversionError) Error() string {
|
||||
return "convert " + e.Sddl + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
// LookupSidByName looks up the SID of an account by name
|
||||
func LookupSidByName(name string) (sid string, err error) {
|
||||
if name == "" {
|
||||
return "", &AccountLookupError{name, cERROR_NONE_MAPPED}
|
||||
}
|
||||
|
||||
var sidSize, sidNameUse, refDomainSize uint32
|
||||
err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
|
||||
if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER {
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
sidBuffer := make([]byte, sidSize)
|
||||
refDomainBuffer := make([]uint16, refDomainSize)
|
||||
err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
|
||||
if err != nil {
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
var strBuffer *uint16
|
||||
err = convertSidToStringSid(&sidBuffer[0], &strBuffer)
|
||||
if err != nil {
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
sid = syscall.UTF16ToString((*[1 << 30]uint16)(unsafe.Pointer(strBuffer))[:])
|
||||
localFree(uintptr(unsafe.Pointer(strBuffer)))
|
||||
return sid, nil
|
||||
}
|
||||
|
||||
func sddlToSecurityDescriptor(sddl string) ([]byte, error) {
|
||||
var sdBuffer uintptr
|
||||
err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)
|
||||
if err != nil {
|
||||
return nil, &SddlConversionError{sddl, err}
|
||||
}
|
||||
defer localFree(sdBuffer)
|
||||
sd := make([]byte, getSecurityDescriptorLength(sdBuffer))
|
||||
copy(sd, (*[1 << 30]byte)(unsafe.Pointer(sdBuffer))[:len(sd)])
|
||||
return sd, nil
|
||||
}
|
3
vendor/src/github.com/Microsoft/go-winio/syscall.go
vendored
Normal file
3
vendor/src/github.com/Microsoft/go-winio/syscall.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package winio
|
||||
|
||||
//go:generate go run mksyscall_windows.go -output zsyscall.go file.go pipe.go sd.go
|
218
vendor/src/github.com/Microsoft/go-winio/zsyscall.go
vendored
Normal file
218
vendor/src/github.com/Microsoft/go-winio/zsyscall.go
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
||||
|
||||
package winio
|
||||
|
||||
import "unsafe"
|
||||
import "syscall"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
var (
|
||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
||||
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
|
||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
||||
)
|
||||
|
||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
||||
newport = syscall.Handle(r0)
|
||||
if newport == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
||||
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 e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
||||
}
|
||||
|
||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
||||
}
|
||||
|
||||
func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func waitNamedPipe(name string, timeout uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _waitNamedPipe(_p0, timeout)
|
||||
}
|
||||
|
||||
func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
||||
}
|
||||
|
||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
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 e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(str)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
|
||||
}
|
||||
|
||||
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||
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 e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localFree(mem uintptr) {
|
||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
||||
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
|
||||
len = uint32(r0)
|
||||
return
|
||||
}
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// ActivateLayer will find the layer with the given id and mount it's filesystem.
|
||||
// For a read/write layer, the mounted filesystem will appear as a volume on the
|
||||
|
@ -16,42 +10,15 @@ func ActivateLayer(info DriverInfo, id string) error {
|
|||
title := "hcsshim::ActivateLayer "
|
||||
logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procActivateLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(idp)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), id, info.Flavour)
|
||||
err = activateLayer(&infop, id)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// CopyLayer performs a commit of the srcId (which is expected to be a read-write
|
||||
// layer) into a new read-only layer at dstId. This requires the full list of
|
||||
|
@ -16,70 +10,21 @@ func CopyLayer(info DriverInfo, srcId, dstId string, parentLayerPaths []string)
|
|||
title := "hcsshim::CopyLayer "
|
||||
logrus.Debugf(title+"srcId %s dstId", srcId, dstId)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procCopyLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert srcId to uint16 pointer for calling the procedure
|
||||
srcIdp, err := syscall.UTF16PtrFromString(srcId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of srcId %s to pointer %s", srcId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert dstId to uint16 pointer for calling the procedure
|
||||
dstIdp, err := syscall.UTF16PtrFromString(dstId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of dstId %s to pointer %s", dstId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate layer descriptors
|
||||
layers, err := layerPathsToDescriptors(parentLayerPaths)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed to generate layer descriptors %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var layerDescriptorsp *WC_LAYER_DESCRIPTOR
|
||||
if len(layers) > 0 {
|
||||
layerDescriptorsp = &(layers[0])
|
||||
} else {
|
||||
layerDescriptorsp = nil
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(srcIdp)),
|
||||
uintptr(unsafe.Pointer(dstIdp)),
|
||||
uintptr(unsafe.Pointer(layerDescriptorsp)),
|
||||
uintptr(len(layers)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(srcIdp))
|
||||
use(unsafe.Pointer(dstIdp))
|
||||
use(unsafe.Pointer(layerDescriptorsp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s srcId=%s dstId=%d",
|
||||
r1, syscall.Errno(r1), srcId, dstId)
|
||||
err = copyLayer(&infop, srcId, dstId, layers)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "srcId=%s dstId=%d", srcId, dstId)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// CreateComputeSystem creates a container, initializing its configuration in
|
||||
// the Host Compute Service such that it can be started by a call to the
|
||||
|
@ -16,40 +10,9 @@ func CreateComputeSystem(id string, configuration string) error {
|
|||
title := "HCSShim::CreateComputeSystem"
|
||||
logrus.Debugln(title+" id=%s, configuration=%s", id, configuration)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procCreateComputeSystem)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
err := createComputeSystem(id, configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointers for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert configuration to uint16 pointers for calling the procedure
|
||||
configurationp, err := syscall.UTF16PtrFromString(configuration)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of configuration %s to pointer %s", configuration, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(idp)), uintptr(unsafe.Pointer(configurationp)))
|
||||
|
||||
use(unsafe.Pointer(idp))
|
||||
use(unsafe.Pointer(configurationp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s configuration=%s", r1, syscall.Errno(r1), id, configuration)
|
||||
err = makeErrorf(err, title, "id=%s configuration=%s", id, configuration)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// CreateLayer creates a new, empty, read-only layer on the filesystem based on
|
||||
// the parent layer provided.
|
||||
|
@ -14,52 +8,16 @@ func CreateLayer(info DriverInfo, id, parent string) error {
|
|||
title := "hcsshim::CreateLayer "
|
||||
logrus.Debugf(title+"Flavour %d ID %s parent %s", info.Flavour, id, parent)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procCreateLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert parent to uint16 pointer for calling the procedure
|
||||
parentp, err := syscall.UTF16PtrFromString(parent)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of parent %s to pointer %s", parent, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion info struct %s", parent, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(idp)),
|
||||
uintptr(unsafe.Pointer(parentp)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(idp))
|
||||
use(unsafe.Pointer(parentp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s parent=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), id, parent, info.Flavour)
|
||||
err = createLayer(&infop, id, parent)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "id=%s parent=%s flavour=%d", id, parent, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -2,12 +2,10 @@ package hcsshim
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/go-winio"
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -22,77 +20,38 @@ type CreateProcessParams struct {
|
|||
ConsoleSize [2]int
|
||||
}
|
||||
|
||||
// pipe struct used for the stdin/stdout/stderr pipes
|
||||
type pipe struct {
|
||||
handle syscall.Handle
|
||||
}
|
||||
|
||||
func makePipe(h syscall.Handle) *pipe {
|
||||
p := &pipe{h}
|
||||
runtime.SetFinalizer(p, (*pipe).closeHandle)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *pipe) closeHandle() {
|
||||
if p.handle != 0 {
|
||||
syscall.CloseHandle(p.handle)
|
||||
p.handle = 0
|
||||
}
|
||||
}
|
||||
|
||||
func (p *pipe) Close() error {
|
||||
p.closeHandle()
|
||||
runtime.SetFinalizer(p, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *pipe) Read(b []byte) (int, error) {
|
||||
// syscall.Read returns 0, nil on ERROR_BROKEN_PIPE, but for
|
||||
// our purposes this should indicate EOF. This may be a go bug.
|
||||
var read uint32
|
||||
err := syscall.ReadFile(p.handle, b, &read, nil)
|
||||
if err != nil {
|
||||
if err == syscall.ERROR_BROKEN_PIPE {
|
||||
return 0, io.EOF
|
||||
// makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
|
||||
// if there is an error.
|
||||
func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
|
||||
fs := make([]io.ReadWriteCloser, len(hs))
|
||||
for i, h := range hs {
|
||||
if h != syscall.Handle(0) {
|
||||
if err == nil {
|
||||
fs[i], err = winio.MakeOpenFile(h)
|
||||
}
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return int(read), nil
|
||||
}
|
||||
|
||||
func (p *pipe) Write(b []byte) (int, error) {
|
||||
return syscall.Write(p.handle, b)
|
||||
if err != nil {
|
||||
for _, f := range fs {
|
||||
if f != nil {
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return fs, nil
|
||||
}
|
||||
|
||||
// CreateProcessInComputeSystem starts a process in a container. This is invoked, for example,
|
||||
// as a result of docker run, docker exec, or RUN in Dockerfile. If successful,
|
||||
// it returns the PID of the process.
|
||||
func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useStderr bool, params CreateProcessParams) (uint32, io.WriteCloser, io.ReadCloser, io.ReadCloser, uint32, error) {
|
||||
|
||||
var (
|
||||
stdin io.WriteCloser
|
||||
stdout, stderr io.ReadCloser
|
||||
)
|
||||
|
||||
func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useStderr bool, params CreateProcessParams) (_ uint32, _ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, hr uint32, err error) {
|
||||
title := "HCSShim::CreateProcessInComputeSystem"
|
||||
logrus.Debugf(title+" id=%s", id)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procCreateProcessWithStdHandlesInComputeSystem)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return 0, nil, nil, nil, 0xFFFFFFFF, err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return 0, nil, nil, nil, 0xFFFFFFFF, err
|
||||
}
|
||||
hr = 0xFFFFFFFF
|
||||
|
||||
// If we are not emulating a console, ignore any console size passed to us
|
||||
if !params.EmulateConsole {
|
||||
|
@ -102,65 +61,43 @@ func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useS
|
|||
|
||||
paramsJson, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed to marshall params %v %s", params, err)
|
||||
return 0, nil, nil, nil, 0xFFFFFFFF, err
|
||||
return
|
||||
}
|
||||
|
||||
// Convert paramsJson to uint16 pointer for calling the procedure
|
||||
paramsJsonp, err := syscall.UTF16PtrFromString(string(paramsJson))
|
||||
if err != nil {
|
||||
return 0, nil, nil, nil, 0xFFFFFFFF, err
|
||||
}
|
||||
|
||||
// Get a POINTER to variable to take the pid outparm
|
||||
pid := new(uint32)
|
||||
|
||||
logrus.Debugf(title+" - Calling Win32 %s %s", id, paramsJson)
|
||||
|
||||
var stdinHandle, stdoutHandle, stderrHandle syscall.Handle
|
||||
var stdinParam, stdoutParam, stderrParam uintptr
|
||||
var pid uint32
|
||||
|
||||
handles := make([]syscall.Handle, 3)
|
||||
var stdinParam, stdoutParam, stderrParam *syscall.Handle
|
||||
if useStdin {
|
||||
stdinParam = uintptr(unsafe.Pointer(&stdinHandle))
|
||||
stdinParam = &handles[0]
|
||||
}
|
||||
if useStdout {
|
||||
stdoutParam = uintptr(unsafe.Pointer(&stdoutHandle))
|
||||
stdoutParam = &handles[1]
|
||||
}
|
||||
if useStderr {
|
||||
stderrParam = uintptr(unsafe.Pointer(&stderrHandle))
|
||||
stderrParam = &handles[2]
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(idp)),
|
||||
uintptr(unsafe.Pointer(paramsJsonp)),
|
||||
uintptr(unsafe.Pointer(pid)),
|
||||
stdinParam,
|
||||
stdoutParam,
|
||||
stderrParam)
|
||||
|
||||
use(unsafe.Pointer(idp))
|
||||
use(unsafe.Pointer(paramsJsonp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s params=%v", r1, syscall.Errno(r1), id, params)
|
||||
err = createProcessWithStdHandlesInComputeSystem(id, string(paramsJson), &pid, stdinParam, stdoutParam, stderrParam)
|
||||
if err != nil {
|
||||
winerr := makeErrorf(err, title, "id=%s params=%v", id, params)
|
||||
hr = winerr.HResult()
|
||||
// Windows TP4: Hyper-V Containers may return this error with more than one
|
||||
// concurrent exec. Do not log it as an error
|
||||
if uint32(r1) != Win32InvalidArgument {
|
||||
logrus.Error(err)
|
||||
if hr != Win32InvalidArgument {
|
||||
logrus.Error(winerr)
|
||||
}
|
||||
return 0, nil, nil, nil, uint32(r1), err
|
||||
err = winerr
|
||||
return
|
||||
}
|
||||
|
||||
if useStdin {
|
||||
stdin = makePipe(stdinHandle)
|
||||
}
|
||||
if useStdout {
|
||||
stdout = makePipe(stdoutHandle)
|
||||
}
|
||||
if useStderr {
|
||||
stderr = makePipe(stderrHandle)
|
||||
pipes, err := makeOpenFiles(handles)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Debugf(title+" - succeeded id=%s params=%s pid=%d", id, paramsJson, *pid)
|
||||
return *pid, stdin, stdout, stderr, 0, nil
|
||||
logrus.Debugf(title+" - succeeded id=%s params=%s pid=%d", id, paramsJson, pid)
|
||||
return pid, pipes[0], pipes[1], pipes[2], 0, nil
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// CreateSandboxLayer creates and populates new read-write layer for use by a container.
|
||||
// This requires both the id of the direct parent layer, as well as the full list
|
||||
|
@ -16,69 +10,22 @@ func CreateSandboxLayer(info DriverInfo, layerId, parentId string, parentLayerPa
|
|||
title := "hcsshim::CreateSandboxLayer "
|
||||
logrus.Debugf(title+"layerId %s parentId %s", layerId, parentId)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procCreateSandboxLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate layer descriptors
|
||||
layers, err := layerPathsToDescriptors(parentLayerPaths)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed to generate layer descriptors ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert layerId to uint16 pointer for calling the procedure
|
||||
layerIdp, err := syscall.UTF16PtrFromString(layerId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of layerId %s to pointer %s", layerId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert parentId to uint16 pointer for calling the procedure
|
||||
parentIdp, err := syscall.UTF16PtrFromString(parentId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of parentId %s to pointer %s", parentId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var layerDescriptorsp *WC_LAYER_DESCRIPTOR
|
||||
if len(layers) > 0 {
|
||||
layerDescriptorsp = &(layers[0])
|
||||
} else {
|
||||
layerDescriptorsp = nil
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(layerIdp)),
|
||||
uintptr(unsafe.Pointer(parentIdp)),
|
||||
uintptr(unsafe.Pointer(layerDescriptorsp)),
|
||||
uintptr(len(layers)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(layerIdp))
|
||||
use(unsafe.Pointer(parentIdp))
|
||||
use(unsafe.Pointer(layerDescriptorsp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+"- Win32 API call returned error r1=%d err=%s layerId=%s parentId=%s",
|
||||
r1, syscall.Errno(r1), layerId, parentId)
|
||||
err = createSandboxLayer(&infop, layerId, parentId, layers)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "layerId=%s parentId=%s", layerId, parentId)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,54 +1,22 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
|
||||
func DeactivateLayer(info DriverInfo, id string) error {
|
||||
title := "hcsshim::DeactivateLayer "
|
||||
logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procDeactivateLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(idp)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), id, info.Flavour)
|
||||
err = deactivateLayer(&infop, id)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// DestroyLayer will remove the on-disk files representing the layer with the given
|
||||
// id, including that layer's containing folder, if any.
|
||||
|
@ -14,42 +8,16 @@ func DestroyLayer(info DriverInfo, id string) error {
|
|||
title := "hcsshim::DestroyLayer "
|
||||
logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procDestroyLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(idp)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), id, info.Flavour)
|
||||
err = destroyLayer(&infop, id)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// ExportLayer will create a folder at exportFolderPath and fill that folder with
|
||||
// the transport format version of the layer identified by layerId. This transport
|
||||
|
@ -17,68 +11,22 @@ func ExportLayer(info DriverInfo, layerId string, exportFolderPath string, paren
|
|||
title := "hcsshim::ExportLayer "
|
||||
logrus.Debugf(title+"flavour %d layerId %s folder %s", info.Flavour, layerId, exportFolderPath)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procExportLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate layer descriptors
|
||||
layers, err := layerPathsToDescriptors(parentLayerPaths)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed to generate layer descriptors ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert layerId to uint16 pointer for calling the procedure
|
||||
layerIdp, err := syscall.UTF16PtrFromString(layerId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of layerId %s to pointer %s", layerId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert exportFolderPath to uint16 pointer for calling the procedure
|
||||
exportFolderPathp, err := syscall.UTF16PtrFromString(exportFolderPath)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of exportFolderPath %s to pointer %s", exportFolderPath, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var layerDescriptorsp *WC_LAYER_DESCRIPTOR
|
||||
if len(layers) > 0 {
|
||||
layerDescriptorsp = &(layers[0])
|
||||
} else {
|
||||
layerDescriptorsp = nil
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(layerIdp)),
|
||||
uintptr(unsafe.Pointer(exportFolderPathp)),
|
||||
uintptr(unsafe.Pointer(layerDescriptorsp)),
|
||||
uintptr(len(layers)))
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(layerIdp))
|
||||
use(unsafe.Pointer(exportFolderPathp))
|
||||
use(unsafe.Pointer(layerDescriptorsp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+"- Win32 API call returned error r1=%d err=%s layerId=%s flavour=%d folder=%s",
|
||||
r1, syscall.Errno(r1), layerId, info.Flavour, exportFolderPath)
|
||||
err = exportLayer(&infop, layerId, exportFolderPath, layers)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "layerId=%s flavour=%d folder=%s", layerId, info.Flavour, exportFolderPath)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
@ -16,45 +14,21 @@ func GetLayerMountPath(info DriverInfo, id string) (string, error) {
|
|||
title := "hcsshim::GetLayerMountPath "
|
||||
logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procGetLayerMountPath)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
var mountPathLength uint64
|
||||
var mountPathLength uintptr
|
||||
mountPathLength = 0
|
||||
|
||||
// Call the procedure itself.
|
||||
logrus.Debugf("Calling proc (1)")
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(idp)),
|
||||
uintptr(unsafe.Pointer(&mountPathLength)),
|
||||
uintptr(unsafe.Pointer(nil)))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - First Win32 API call returned error r1=%d err=%s id=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), id, info.Flavour)
|
||||
err = getLayerMountPath(&infop, id, &mountPathLength, nil)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "(first call) id=%s flavour=%d", id, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return "", err
|
||||
}
|
||||
|
@ -68,19 +42,9 @@ func GetLayerMountPath(info DriverInfo, id string) (string, error) {
|
|||
|
||||
// Call the procedure again
|
||||
logrus.Debugf("Calling proc (2)")
|
||||
r1, _, _ = proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(idp)),
|
||||
uintptr(unsafe.Pointer(&mountPathLength)),
|
||||
uintptr(unsafe.Pointer(&mountPathp[0])))
|
||||
|
||||
use(unsafe.Pointer(&mountPathLength))
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Second Win32 API call returned error r1=%d err=%s id=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), id, info.Flavour)
|
||||
err = getLayerMountPath(&infop, id, &mountPathLength, &mountPathp[0])
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "(second call) id=%s flavour=%d", id, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// GetSharedBaseImages will enumerate the images stored in the common central
|
||||
// image store and return descriptive info about those images for the purpose
|
||||
|
@ -14,43 +8,15 @@ import (
|
|||
func GetSharedBaseImages() (imageData string, err error) {
|
||||
title := "hcsshim::GetSharedBaseImages "
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procGetSharedBaseImages)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Load the OLE DLL and get a handle to the CoTaskMemFree procedure
|
||||
dll2, proc2, err := loadAndFindFromDll(oleDLLName, procCoTaskMemFree)
|
||||
if dll2 != nil {
|
||||
defer dll2.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var output uintptr
|
||||
|
||||
// Call the procedure again
|
||||
logrus.Debugf("Calling proc")
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&output)))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d errno=%s",
|
||||
r1, syscall.Errno(r1))
|
||||
var buffer *uint16
|
||||
err = getBaseImages(&buffer)
|
||||
if err != nil {
|
||||
err = makeError(err, title, "")
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Defer the cleanup of the memory using CoTaskMemFree
|
||||
defer proc2.Call(output)
|
||||
|
||||
imageData = syscall.UTF16ToString((*[1 << 30]uint16)(unsafe.Pointer(output))[:])
|
||||
imageData = convertAndFreeCoTaskMemString(buffer)
|
||||
logrus.Debugf(title+" - succeeded output=%s", imageData)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
133
vendor/src/github.com/microsoft/hcsshim/hcsshim.go
vendored
133
vendor/src/github.com/microsoft/hcsshim/hcsshim.go
vendored
|
@ -7,46 +7,39 @@ import (
|
|||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
|
||||
|
||||
//sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree
|
||||
|
||||
//sys activateLayer(info *driverInfo, id string) (hr error) = vmcompute.ActivateLayer?
|
||||
//sys copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CopyLayer?
|
||||
//sys createLayer(info *driverInfo, id string, parent string) (hr error) = vmcompute.CreateLayer?
|
||||
//sys createSandboxLayer(info *driverInfo, id string, parent string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CreateSandboxLayer?
|
||||
//sys deactivateLayer(info *driverInfo, id string) (hr error) = vmcompute.DeactivateLayer?
|
||||
//sys destroyLayer(info *driverInfo, id string) (hr error) = vmcompute.DestroyLayer?
|
||||
//sys exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ExportLayer?
|
||||
//sys getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) = vmcompute.GetLayerMountPath?
|
||||
//sys getBaseImages(buffer **uint16) (hr error) = vmcompute.GetBaseImages?
|
||||
//sys importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ImportLayer?
|
||||
//sys layerExists(info *driverInfo, id string, exists *uint32) (hr error) = vmcompute.LayerExists?
|
||||
//sys nameToGuid(name string, guid *GUID) (hr error) = vmcompute.NameToGuid?
|
||||
//sys prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.PrepareLayer?
|
||||
//sys unprepareLayer(info *driverInfo, id string) (hr error) = vmcompute.UnprepareLayer?
|
||||
|
||||
//sys createComputeSystem(id string, configuration string) (hr error) = vmcompute.CreateComputeSystem?
|
||||
//sys createProcessWithStdHandlesInComputeSystem(id string, paramsJson string, pid *uint32, stdin *syscall.Handle, stdout *syscall.Handle, stderr *syscall.Handle) (hr error) = vmcompute.CreateProcessWithStdHandlesInComputeSystem?
|
||||
//sys resizeConsoleInComputeSystem(id string, pid uint32, height uint16, width uint16, flags uint32) (hr error) = vmcompute.ResizeConsoleInComputeSystem?
|
||||
//sys shutdownComputeSystem(id string, timeout uint32) (hr error) = vmcompute.ShutdownComputeSystem?
|
||||
//sys startComputeSystem(id string) (hr error) = vmcompute.StartComputeSystem?
|
||||
//sys terminateComputeSystem(id string) (hr error) = vmcompute.TerminateComputeSystem?
|
||||
//sys terminateProcessInComputeSystem(id string, pid uint32) (hr error) = vmcompute.TerminateProcessInComputeSystem?
|
||||
//sys waitForProcessInComputeSystem(id string, pid uint32, timeout uint32, exitCode *uint32) (hr error) = vmcompute.WaitForProcessInComputeSystem?
|
||||
|
||||
//sys _hnsCall(method string, path string, object string, response **uint16) (hr error) = vmcompute.HNSCall?
|
||||
|
||||
const (
|
||||
// Name of the shim DLL for access to the HCS
|
||||
shimDLLName = "vmcompute.dll"
|
||||
|
||||
// Container related functions in the shim DLL
|
||||
procCreateComputeSystem = "CreateComputeSystem"
|
||||
procStartComputeSystem = "StartComputeSystem"
|
||||
procCreateProcessWithStdHandlesInComputeSystem = "CreateProcessWithStdHandlesInComputeSystem"
|
||||
procWaitForProcessInComputeSystem = "WaitForProcessInComputeSystem"
|
||||
procShutdownComputeSystem = "ShutdownComputeSystem"
|
||||
procTerminateComputeSystem = "TerminateComputeSystem"
|
||||
procTerminateProcessInComputeSystem = "TerminateProcessInComputeSystem"
|
||||
procResizeConsoleInComputeSystem = "ResizeConsoleInComputeSystem"
|
||||
|
||||
// Storage related functions in the shim DLL
|
||||
procLayerExists = "LayerExists"
|
||||
procCreateLayer = "CreateLayer"
|
||||
procDestroyLayer = "DestroyLayer"
|
||||
procActivateLayer = "ActivateLayer"
|
||||
procDeactivateLayer = "DeactivateLayer"
|
||||
procGetLayerMountPath = "GetLayerMountPath"
|
||||
procCopyLayer = "CopyLayer"
|
||||
procCreateSandboxLayer = "CreateSandboxLayer"
|
||||
procPrepareLayer = "PrepareLayer"
|
||||
procUnprepareLayer = "UnprepareLayer"
|
||||
procExportLayer = "ExportLayer"
|
||||
procImportLayer = "ImportLayer"
|
||||
procGetSharedBaseImages = "GetBaseImages"
|
||||
procNameToGuid = "NameToGuid"
|
||||
|
||||
// Name of the standard OLE dll
|
||||
oleDLLName = "Ole32.dll"
|
||||
|
||||
// Utility functions
|
||||
procCoTaskMemFree = "CoTaskMemFree"
|
||||
|
||||
// Specific user-visible exit codes
|
||||
WaitErrExecFailed = 32767
|
||||
|
||||
|
@ -56,49 +49,45 @@ const (
|
|||
Win32SpecifiedPathInvalid = 0x800700A1 // ShutdownComputeSystem: The specified path is invalid
|
||||
Win32SystemCannotFindThePathSpecified = 0x80070003 // ShutdownComputeSystem: The system cannot find the path specified
|
||||
Win32InvalidArgument = 0x80072726 // CreateProcessInComputeSystem: An invalid argument was supplied
|
||||
EFail = 0x80004005
|
||||
|
||||
// Timeout on wait calls
|
||||
TimeoutInfinite = 0xFFFFFFFF
|
||||
)
|
||||
|
||||
// loadAndFindFromDll finds a procedure in the given DLL. Note we do NOT do lazy loading as
|
||||
// go is particularly unfriendly in the case of a mismatch. By that - it panics
|
||||
// if a function can't be found. By explicitly loading, we can control error
|
||||
// handling gracefully without the daemon terminating.
|
||||
func loadAndFindFromDll(dllName, procedure string) (dll *syscall.DLL, proc *syscall.Proc, err error) {
|
||||
dll, err = syscall.LoadDLL(dllName)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Failed to load %s - error %s", dllName, err)
|
||||
logrus.Error(err)
|
||||
return
|
||||
type hcsError struct {
|
||||
title string
|
||||
rest string
|
||||
err error
|
||||
}
|
||||
|
||||
type Win32Error interface {
|
||||
error
|
||||
HResult() uint32
|
||||
}
|
||||
|
||||
func makeError(err error, title, rest string) Win32Error {
|
||||
return &hcsError{title, rest, err}
|
||||
}
|
||||
|
||||
func makeErrorf(err error, title, format string, a ...interface{}) Win32Error {
|
||||
return makeError(err, title, fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
func (e *hcsError) HResult() uint32 {
|
||||
if hr, ok := e.err.(syscall.Errno); ok {
|
||||
return uint32(hr)
|
||||
} else {
|
||||
return EFail
|
||||
}
|
||||
|
||||
proc, err = dll.FindProc(procedure)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Failed to find %s in %s", procedure, dllName)
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// loadAndFind finds a procedure in the shim DLL.
|
||||
func loadAndFind(procedure string) (*syscall.DLL, *syscall.Proc, error) {
|
||||
|
||||
return loadAndFindFromDll(shimDLLName, procedure)
|
||||
func (e *hcsError) Error() string {
|
||||
return fmt.Sprintf("%s- Win32 API call returned error r1=0x%x err=%s%s", e.title, e.HResult(), e.err, e.rest)
|
||||
}
|
||||
|
||||
// use is a no-op, but the compiler cannot see that it is.
|
||||
// Calling use(p) ensures that p is kept live until that point.
|
||||
/*
|
||||
//go:noescape
|
||||
func use(p unsafe.Pointer)
|
||||
*/
|
||||
|
||||
// Alternate without using //go:noescape and asm.s
|
||||
var temp unsafe.Pointer
|
||||
|
||||
func use(p unsafe.Pointer) {
|
||||
temp = p
|
||||
func convertAndFreeCoTaskMemString(buffer *uint16) string {
|
||||
str := syscall.UTF16ToString((*[1 << 30]uint16)(unsafe.Pointer(buffer))[:])
|
||||
coTaskMemFree(unsafe.Pointer(buffer))
|
||||
return str
|
||||
}
|
||||
|
|
131
vendor/src/github.com/microsoft/hcsshim/hnsfuncs.go
vendored
Normal file
131
vendor/src/github.com/microsoft/hcsshim/hnsfuncs.go
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type NatPolicy struct {
|
||||
Type string
|
||||
Protocol string
|
||||
InternalPort uint16
|
||||
ExternalPort uint16
|
||||
}
|
||||
|
||||
type QosPolicy struct {
|
||||
Type string
|
||||
MaximumOutgoingBandwidthInBytes uint64
|
||||
}
|
||||
|
||||
// Subnet is assoicated with a network and represents a list
|
||||
// of subnets available to the network
|
||||
type Subnet struct {
|
||||
AddressPrefix string `json:",omitempty"`
|
||||
GatewayAddress string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// MacPool is assoicated with a network and represents a list
|
||||
// of macaddresses available to the network
|
||||
type MacPool struct {
|
||||
StartMacAddress string `json:",omitempty"`
|
||||
EndMacAddress string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// HNSNetwork represents a network in HNS
|
||||
type HNSNetwork struct {
|
||||
Id string `json:",omitempty"`
|
||||
Name string `json:",omitempty"`
|
||||
Type string `json:",omitempty"`
|
||||
Policies []json.RawMessage `json:",omitempty"`
|
||||
MacPools []MacPool `json:",omitempty"`
|
||||
Subnets []Subnet `json:",omitempty"`
|
||||
}
|
||||
|
||||
// HNSEndpoint represents a network endpoint in HNS
|
||||
type HNSEndpoint struct {
|
||||
Id string `json:",omitempty"`
|
||||
Name string `json:",omitempty"`
|
||||
VirtualNetwork string `json:",omitempty"`
|
||||
VirtualNetworkName string `json:",omitempty"`
|
||||
Policies []json.RawMessage `json:",omitempty"`
|
||||
MacAddress string `json:",omitempty"`
|
||||
IPAddress net.IP `json:",omitempty"`
|
||||
}
|
||||
|
||||
type hnsNetworkResponse struct {
|
||||
Success bool
|
||||
Error string
|
||||
Output HNSNetwork
|
||||
}
|
||||
|
||||
type hnsResponse struct {
|
||||
Success bool
|
||||
Error string
|
||||
Output json.RawMessage
|
||||
}
|
||||
|
||||
func hnsCall(method, path, request string, returnResponse interface{}) error {
|
||||
var responseBuffer *uint16
|
||||
err := _hnsCall(method, path, request, &responseBuffer)
|
||||
if err != nil {
|
||||
return makeError(err, "hnsCall ", "")
|
||||
}
|
||||
response := convertAndFreeCoTaskMemString(responseBuffer)
|
||||
|
||||
hnsresponse := &hnsResponse{}
|
||||
if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !hnsresponse.Success {
|
||||
return fmt.Errorf("HNS failed with error : %s", hnsresponse.Error)
|
||||
}
|
||||
|
||||
if len(hnsresponse.Output) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
logrus.Debugf("Network Response : %s", hnsresponse.Output)
|
||||
err = json.Unmarshal(hnsresponse.Output, returnResponse)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HNSNetworkRequest makes a call into HNS to update/query a single network
|
||||
func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
|
||||
var network HNSNetwork
|
||||
err := hnsCall(method, "/networks/"+path, request, &network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &network, nil
|
||||
}
|
||||
|
||||
// HNSListNetworkRequest makes a HNS call to query the list of available networks
|
||||
func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
|
||||
var network []HNSNetwork
|
||||
err := hnsCall(method, "/networks/"+path, request, &network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return network, nil
|
||||
}
|
||||
|
||||
// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
|
||||
func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
|
||||
endpoint := &HNSEndpoint{}
|
||||
err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return endpoint, nil
|
||||
}
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// ImportLayer will take the contents of the folder at importFolderPath and import
|
||||
// that into a layer with the id layerId. Note that in order to correctly populate
|
||||
|
@ -16,68 +10,22 @@ func ImportLayer(info DriverInfo, layerId string, importFolderPath string, paren
|
|||
title := "hcsshim::ImportLayer "
|
||||
logrus.Debugf(title+"flavour %d layerId %s folder %s", info.Flavour, layerId, importFolderPath)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procImportLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate layer descriptors
|
||||
layers, err := layerPathsToDescriptors(parentLayerPaths)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed to generate layer descriptors ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert layerId to uint16 pointer for calling the procedure
|
||||
layerIdp, err := syscall.UTF16PtrFromString(layerId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of layerId %s to pointer %s", layerId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert importFolderPath to uint16 pointer for calling the procedure
|
||||
importFolderPathp, err := syscall.UTF16PtrFromString(importFolderPath)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of importFolderPath %s to pointer %s", importFolderPath, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var layerDescriptorsp *WC_LAYER_DESCRIPTOR
|
||||
if len(layers) > 0 {
|
||||
layerDescriptorsp = &(layers[0])
|
||||
} else {
|
||||
layerDescriptorsp = nil
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(layerIdp)),
|
||||
uintptr(unsafe.Pointer(importFolderPathp)),
|
||||
uintptr(unsafe.Pointer(layerDescriptorsp)),
|
||||
uintptr(len(layers)))
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(layerIdp))
|
||||
use(unsafe.Pointer(importFolderPathp))
|
||||
use(unsafe.Pointer(layerDescriptorsp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+"- Win32 API call returned error r1=%d err=%s layerId=%s flavour=%d folder=%s",
|
||||
r1, syscall.Errno(r1), layerId, info.Flavour, importFolderPath)
|
||||
err = importLayer(&infop, layerId, importFolderPath, layers)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "layerId=%s flavour=%d folder=%s", layerId, info.Flavour, importFolderPath)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// LayerExists will return true if a layer with the given id exists and is known
|
||||
// to the system.
|
||||
|
@ -14,49 +8,23 @@ func LayerExists(info DriverInfo, id string) (bool, error) {
|
|||
title := "hcsshim::LayerExists "
|
||||
logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procLayerExists)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
var exists bool // Outparam from Win32
|
||||
var exists uint32
|
||||
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(idp)),
|
||||
uintptr(unsafe.Pointer(&exists)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), id, info.Flavour)
|
||||
err = layerExists(&infop, id, &exists)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
logrus.Debugf(title+"succeeded flavour=%d id=%s exists=%d", info.Flavour, id, exists)
|
||||
return exists, nil
|
||||
return exists != 0, nil
|
||||
}
|
||||
|
|
797
vendor/src/github.com/microsoft/hcsshim/mksyscall_windows.go
vendored
Normal file
797
vendor/src/github.com/microsoft/hcsshim/mksyscall_windows.go
vendored
Normal file
|
@ -0,0 +1,797 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
/*
|
||||
mksyscall_windows generates windows system call bodies
|
||||
|
||||
It parses all files specified on command line containing function
|
||||
prototypes (like syscall_windows.go) and prints system call bodies
|
||||
to standard output.
|
||||
|
||||
The prototypes are marked by lines beginning with "//sys" and read
|
||||
like func declarations if //sys is replaced by func, but:
|
||||
|
||||
* The parameter lists must give a name for each argument. This
|
||||
includes return parameters.
|
||||
|
||||
* The parameter lists must give a type for each argument:
|
||||
the (x, y, z int) shorthand is not allowed.
|
||||
|
||||
* If the return parameter is an error number, it must be named err.
|
||||
|
||||
* If go func name needs to be different from it's winapi dll name,
|
||||
the winapi name could be specified at the end, after "=" sign, like
|
||||
//sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA
|
||||
|
||||
* Each function that returns err needs to supply a condition, that
|
||||
return value of winapi will be tested against to detect failure.
|
||||
This would set err to windows "last-error", otherwise it will be nil.
|
||||
The value can be provided at end of //sys declaration, like
|
||||
//sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA
|
||||
and is [failretval==0] by default.
|
||||
|
||||
Usage:
|
||||
mksyscall_windows [flags] [path ...]
|
||||
|
||||
The flags are:
|
||||
-output
|
||||
Specify output file name (outputs to console if blank).
|
||||
-trace
|
||||
Generate print statement after every syscall.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var (
|
||||
filename = flag.String("output", "", "output file name (standard output if omitted)")
|
||||
printTraceFlag = flag.Bool("trace", false, "generate print statement after every syscall")
|
||||
)
|
||||
|
||||
func trim(s string) string {
|
||||
return strings.Trim(s, " \t")
|
||||
}
|
||||
|
||||
var packageName string
|
||||
|
||||
func packagename() string {
|
||||
return packageName
|
||||
}
|
||||
|
||||
func syscalldot() string {
|
||||
if packageName == "syscall" {
|
||||
return ""
|
||||
}
|
||||
return "syscall."
|
||||
}
|
||||
|
||||
// Param is function parameter
|
||||
type Param struct {
|
||||
Name string
|
||||
Type string
|
||||
fn *Fn
|
||||
tmpVarIdx int
|
||||
}
|
||||
|
||||
// tmpVar returns temp variable name that will be used to represent p during syscall.
|
||||
func (p *Param) tmpVar() string {
|
||||
if p.tmpVarIdx < 0 {
|
||||
p.tmpVarIdx = p.fn.curTmpVarIdx
|
||||
p.fn.curTmpVarIdx++
|
||||
}
|
||||
return fmt.Sprintf("_p%d", p.tmpVarIdx)
|
||||
}
|
||||
|
||||
// BoolTmpVarCode returns source code for bool temp variable.
|
||||
func (p *Param) BoolTmpVarCode() string {
|
||||
const code = `var %s uint32
|
||||
if %s {
|
||||
%s = 1
|
||||
} else {
|
||||
%s = 0
|
||||
}`
|
||||
tmp := p.tmpVar()
|
||||
return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
|
||||
}
|
||||
|
||||
// SliceTmpVarCode returns source code for slice temp variable.
|
||||
func (p *Param) SliceTmpVarCode() string {
|
||||
const code = `var %s *%s
|
||||
if len(%s) > 0 {
|
||||
%s = &%s[0]
|
||||
}`
|
||||
tmp := p.tmpVar()
|
||||
return fmt.Sprintf(code, tmp, p.Type[2:], p.Name, tmp, p.Name)
|
||||
}
|
||||
|
||||
// StringTmpVarCode returns source code for string temp variable.
|
||||
func (p *Param) StringTmpVarCode() string {
|
||||
errvar := p.fn.Rets.ErrorVarName()
|
||||
if errvar == "" {
|
||||
errvar = "_"
|
||||
}
|
||||
tmp := p.tmpVar()
|
||||
const code = `var %s %s
|
||||
%s, %s = %s(%s)`
|
||||
s := fmt.Sprintf(code, tmp, p.fn.StrconvType(), tmp, errvar, p.fn.StrconvFunc(), p.Name)
|
||||
if errvar == "-" {
|
||||
return s
|
||||
}
|
||||
const morecode = `
|
||||
if %s != nil {
|
||||
return
|
||||
}`
|
||||
return s + fmt.Sprintf(morecode, errvar)
|
||||
}
|
||||
|
||||
// TmpVarCode returns source code for temp variable.
|
||||
func (p *Param) TmpVarCode() string {
|
||||
switch {
|
||||
case p.Type == "bool":
|
||||
return p.BoolTmpVarCode()
|
||||
case strings.HasPrefix(p.Type, "[]"):
|
||||
return p.SliceTmpVarCode()
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// TmpVarHelperCode returns source code for helper's temp variable.
|
||||
func (p *Param) TmpVarHelperCode() string {
|
||||
if p.Type != "string" {
|
||||
return ""
|
||||
}
|
||||
return p.StringTmpVarCode()
|
||||
}
|
||||
|
||||
// SyscallArgList returns source code fragments representing p parameter
|
||||
// in syscall. Slices are translated into 2 syscall parameters: pointer to
|
||||
// the first element and length.
|
||||
func (p *Param) SyscallArgList() []string {
|
||||
t := p.HelperType()
|
||||
var s string
|
||||
switch {
|
||||
case t[0] == '*':
|
||||
s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
|
||||
case t == "bool":
|
||||
s = p.tmpVar()
|
||||
case strings.HasPrefix(t, "[]"):
|
||||
return []string{
|
||||
fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
|
||||
fmt.Sprintf("uintptr(len(%s))", p.Name),
|
||||
}
|
||||
default:
|
||||
s = p.Name
|
||||
}
|
||||
return []string{fmt.Sprintf("uintptr(%s)", s)}
|
||||
}
|
||||
|
||||
// IsError determines if p parameter is used to return error.
|
||||
func (p *Param) IsError() bool {
|
||||
return p.Name == "err" && p.Type == "error"
|
||||
}
|
||||
|
||||
// HelperType returns type of parameter p used in helper function.
|
||||
func (p *Param) HelperType() string {
|
||||
if p.Type == "string" {
|
||||
return p.fn.StrconvType()
|
||||
}
|
||||
return p.Type
|
||||
}
|
||||
|
||||
// join concatenates parameters ps into a string with sep separator.
|
||||
// Each parameter is converted into string by applying fn to it
|
||||
// before conversion.
|
||||
func join(ps []*Param, fn func(*Param) string, sep string) string {
|
||||
if len(ps) == 0 {
|
||||
return ""
|
||||
}
|
||||
a := make([]string, 0)
|
||||
for _, p := range ps {
|
||||
a = append(a, fn(p))
|
||||
}
|
||||
return strings.Join(a, sep)
|
||||
}
|
||||
|
||||
// Rets describes function return parameters.
|
||||
type Rets struct {
|
||||
Name string
|
||||
Type string
|
||||
ReturnsError bool
|
||||
FailCond string
|
||||
}
|
||||
|
||||
// ErrorVarName returns error variable name for r.
|
||||
func (r *Rets) ErrorVarName() string {
|
||||
if r.ReturnsError {
|
||||
return "err"
|
||||
}
|
||||
if r.Type == "error" {
|
||||
return r.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ToParams converts r into slice of *Param.
|
||||
func (r *Rets) ToParams() []*Param {
|
||||
ps := make([]*Param, 0)
|
||||
if len(r.Name) > 0 {
|
||||
ps = append(ps, &Param{Name: r.Name, Type: r.Type})
|
||||
}
|
||||
if r.ReturnsError {
|
||||
ps = append(ps, &Param{Name: "err", Type: "error"})
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
// List returns source code of syscall return parameters.
|
||||
func (r *Rets) List() string {
|
||||
s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ")
|
||||
if len(s) > 0 {
|
||||
s = "(" + s + ")"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// PrintList returns source code of trace printing part correspondent
|
||||
// to syscall return values.
|
||||
func (r *Rets) PrintList() string {
|
||||
return join(r.ToParams(), func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
|
||||
}
|
||||
|
||||
// SetReturnValuesCode returns source code that accepts syscall return values.
|
||||
func (r *Rets) SetReturnValuesCode() string {
|
||||
if r.Name == "" && !r.ReturnsError {
|
||||
return ""
|
||||
}
|
||||
retvar := "r0"
|
||||
if r.Name == "" {
|
||||
retvar = "r1"
|
||||
}
|
||||
errvar := "_"
|
||||
if r.ReturnsError {
|
||||
errvar = "e1"
|
||||
}
|
||||
return fmt.Sprintf("%s, _, %s := ", retvar, errvar)
|
||||
}
|
||||
|
||||
func (r *Rets) useLongHandleErrorCode(retvar string) string {
|
||||
const code = `if %s {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = %sEINVAL
|
||||
}
|
||||
}`
|
||||
cond := retvar + " == 0"
|
||||
if r.FailCond != "" {
|
||||
cond = strings.Replace(r.FailCond, "failretval", retvar, 1)
|
||||
}
|
||||
return fmt.Sprintf(code, cond, syscalldot())
|
||||
}
|
||||
|
||||
// SetErrorCode returns source code that sets return parameters.
|
||||
func (r *Rets) SetErrorCode() string {
|
||||
const code = `if r0 != 0 {
|
||||
%s = %sErrno(r0)
|
||||
}`
|
||||
if r.Name == "" && !r.ReturnsError {
|
||||
return ""
|
||||
}
|
||||
if r.Name == "" {
|
||||
return r.useLongHandleErrorCode("r1")
|
||||
}
|
||||
if r.Type == "error" {
|
||||
return fmt.Sprintf(code, r.Name, syscalldot())
|
||||
}
|
||||
s := ""
|
||||
switch {
|
||||
case r.Type[0] == '*':
|
||||
s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type)
|
||||
case r.Type == "bool":
|
||||
s = fmt.Sprintf("%s = r0 != 0", r.Name)
|
||||
default:
|
||||
s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type)
|
||||
}
|
||||
if !r.ReturnsError {
|
||||
return s
|
||||
}
|
||||
return s + "\n\t" + r.useLongHandleErrorCode(r.Name)
|
||||
}
|
||||
|
||||
// Fn describes syscall function.
|
||||
type Fn struct {
|
||||
Name string
|
||||
Params []*Param
|
||||
Rets *Rets
|
||||
PrintTrace bool
|
||||
confirmproc bool
|
||||
dllname string
|
||||
dllfuncname string
|
||||
src string
|
||||
// TODO: get rid of this field and just use parameter index instead
|
||||
curTmpVarIdx int // insure tmp variables have uniq names
|
||||
}
|
||||
|
||||
// extractParams parses s to extract function parameters.
|
||||
func extractParams(s string, f *Fn) ([]*Param, error) {
|
||||
s = trim(s)
|
||||
if s == "" {
|
||||
return nil, nil
|
||||
}
|
||||
a := strings.Split(s, ",")
|
||||
ps := make([]*Param, len(a))
|
||||
for i := range ps {
|
||||
s2 := trim(a[i])
|
||||
b := strings.Split(s2, " ")
|
||||
if len(b) != 2 {
|
||||
b = strings.Split(s2, "\t")
|
||||
if len(b) != 2 {
|
||||
return nil, errors.New("Could not extract function parameter from \"" + s2 + "\"")
|
||||
}
|
||||
}
|
||||
ps[i] = &Param{
|
||||
Name: trim(b[0]),
|
||||
Type: trim(b[1]),
|
||||
fn: f,
|
||||
tmpVarIdx: -1,
|
||||
}
|
||||
}
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
// extractSection extracts text out of string s starting after start
|
||||
// and ending just before end. found return value will indicate success,
|
||||
// and prefix, body and suffix will contain correspondent parts of string s.
|
||||
func extractSection(s string, start, end rune) (prefix, body, suffix string, found bool) {
|
||||
s = trim(s)
|
||||
if strings.HasPrefix(s, string(start)) {
|
||||
// no prefix
|
||||
body = s[1:]
|
||||
} else {
|
||||
a := strings.SplitN(s, string(start), 2)
|
||||
if len(a) != 2 {
|
||||
return "", "", s, false
|
||||
}
|
||||
prefix = a[0]
|
||||
body = a[1]
|
||||
}
|
||||
a := strings.SplitN(body, string(end), 2)
|
||||
if len(a) != 2 {
|
||||
return "", "", "", false
|
||||
}
|
||||
return prefix, a[0], a[1], true
|
||||
}
|
||||
|
||||
// newFn parses string s and return created function Fn.
|
||||
func newFn(s string) (*Fn, error) {
|
||||
s = trim(s)
|
||||
f := &Fn{
|
||||
Rets: &Rets{},
|
||||
src: s,
|
||||
PrintTrace: *printTraceFlag,
|
||||
}
|
||||
// function name and args
|
||||
prefix, body, s, found := extractSection(s, '(', ')')
|
||||
if !found || prefix == "" {
|
||||
return nil, errors.New("Could not extract function name and parameters from \"" + f.src + "\"")
|
||||
}
|
||||
f.Name = prefix
|
||||
var err error
|
||||
f.Params, err = extractParams(body, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// return values
|
||||
_, body, s, found = extractSection(s, '(', ')')
|
||||
if found {
|
||||
r, err := extractParams(body, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(r) {
|
||||
case 0:
|
||||
case 1:
|
||||
if r[0].IsError() {
|
||||
f.Rets.ReturnsError = true
|
||||
} else {
|
||||
f.Rets.Name = r[0].Name
|
||||
f.Rets.Type = r[0].Type
|
||||
}
|
||||
case 2:
|
||||
if !r[1].IsError() {
|
||||
return nil, errors.New("Only last windows error is allowed as second return value in \"" + f.src + "\"")
|
||||
}
|
||||
f.Rets.ReturnsError = true
|
||||
f.Rets.Name = r[0].Name
|
||||
f.Rets.Type = r[0].Type
|
||||
default:
|
||||
return nil, errors.New("Too many return values in \"" + f.src + "\"")
|
||||
}
|
||||
}
|
||||
// fail condition
|
||||
_, body, s, found = extractSection(s, '[', ']')
|
||||
if found {
|
||||
f.Rets.FailCond = body
|
||||
}
|
||||
// dll and dll function names
|
||||
s = trim(s)
|
||||
if s == "" {
|
||||
return f, nil
|
||||
}
|
||||
if !strings.HasPrefix(s, "=") {
|
||||
return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
|
||||
}
|
||||
s = trim(s[1:])
|
||||
a := strings.Split(s, ".")
|
||||
switch len(a) {
|
||||
case 1:
|
||||
f.dllfuncname = a[0]
|
||||
case 2:
|
||||
f.dllname = a[0]
|
||||
f.dllfuncname = a[1]
|
||||
default:
|
||||
return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
|
||||
}
|
||||
if f.dllfuncname[len(f.dllfuncname)-1] == '?' {
|
||||
f.confirmproc = true
|
||||
f.dllfuncname = f.dllfuncname[0 : len(f.dllfuncname)-1]
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// DLLName returns DLL name for function f.
|
||||
func (f *Fn) DLLName() string {
|
||||
if f.dllname == "" {
|
||||
return "kernel32"
|
||||
}
|
||||
return f.dllname
|
||||
}
|
||||
|
||||
// DLLName returns DLL function name for function f.
|
||||
func (f *Fn) DLLFuncName() string {
|
||||
if f.dllfuncname == "" {
|
||||
return f.Name
|
||||
}
|
||||
return f.dllfuncname
|
||||
}
|
||||
|
||||
func (f *Fn) ConfirmProc() bool {
|
||||
return f.confirmproc
|
||||
}
|
||||
|
||||
// ParamList returns source code for function f parameters.
|
||||
func (f *Fn) ParamList() string {
|
||||
return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
|
||||
}
|
||||
|
||||
// HelperParamList returns source code for helper function f parameters.
|
||||
func (f *Fn) HelperParamList() string {
|
||||
return join(f.Params, func(p *Param) string { return p.Name + " " + p.HelperType() }, ", ")
|
||||
}
|
||||
|
||||
// ParamPrintList returns source code of trace printing part correspondent
|
||||
// to syscall input parameters.
|
||||
func (f *Fn) ParamPrintList() string {
|
||||
return join(f.Params, func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
|
||||
}
|
||||
|
||||
// ParamCount return number of syscall parameters for function f.
|
||||
func (f *Fn) ParamCount() int {
|
||||
n := 0
|
||||
for _, p := range f.Params {
|
||||
n += len(p.SyscallArgList())
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// SyscallParamCount determines which version of Syscall/Syscall6/Syscall9/...
|
||||
// to use. It returns parameter count for correspondent SyscallX function.
|
||||
func (f *Fn) SyscallParamCount() int {
|
||||
n := f.ParamCount()
|
||||
switch {
|
||||
case n <= 3:
|
||||
return 3
|
||||
case n <= 6:
|
||||
return 6
|
||||
case n <= 9:
|
||||
return 9
|
||||
case n <= 12:
|
||||
return 12
|
||||
case n <= 15:
|
||||
return 15
|
||||
default:
|
||||
panic("too many arguments to system call")
|
||||
}
|
||||
}
|
||||
|
||||
// Syscall determines which SyscallX function to use for function f.
|
||||
func (f *Fn) Syscall() string {
|
||||
c := f.SyscallParamCount()
|
||||
if c == 3 {
|
||||
return syscalldot() + "Syscall"
|
||||
}
|
||||
return syscalldot() + "Syscall" + strconv.Itoa(c)
|
||||
}
|
||||
|
||||
// SyscallParamList returns source code for SyscallX parameters for function f.
|
||||
func (f *Fn) SyscallParamList() string {
|
||||
a := make([]string, 0)
|
||||
for _, p := range f.Params {
|
||||
a = append(a, p.SyscallArgList()...)
|
||||
}
|
||||
for len(a) < f.SyscallParamCount() {
|
||||
a = append(a, "0")
|
||||
}
|
||||
return strings.Join(a, ", ")
|
||||
}
|
||||
|
||||
// HelperCallParamList returns source code of call into function f helper.
|
||||
func (f *Fn) HelperCallParamList() string {
|
||||
a := make([]string, 0, len(f.Params))
|
||||
for _, p := range f.Params {
|
||||
s := p.Name
|
||||
if p.Type == "string" {
|
||||
s = p.tmpVar()
|
||||
}
|
||||
a = append(a, s)
|
||||
}
|
||||
return strings.Join(a, ", ")
|
||||
}
|
||||
|
||||
// IsUTF16 is true, if f is W (utf16) function. It is false
|
||||
// for all A (ascii) functions.
|
||||
func (_ *Fn) IsUTF16() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// StrconvFunc returns name of Go string to OS string function for f.
|
||||
func (f *Fn) StrconvFunc() string {
|
||||
if f.IsUTF16() {
|
||||
return syscalldot() + "UTF16PtrFromString"
|
||||
}
|
||||
return syscalldot() + "BytePtrFromString"
|
||||
}
|
||||
|
||||
// StrconvType returns Go type name used for OS string for f.
|
||||
func (f *Fn) StrconvType() string {
|
||||
if f.IsUTF16() {
|
||||
return "*uint16"
|
||||
}
|
||||
return "*byte"
|
||||
}
|
||||
|
||||
// HasStringParam is true, if f has at least one string parameter.
|
||||
// Otherwise it is false.
|
||||
func (f *Fn) HasStringParam() bool {
|
||||
for _, p := range f.Params {
|
||||
if p.Type == "string" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HelperName returns name of function f helper.
|
||||
func (f *Fn) HelperName() string {
|
||||
if !f.HasStringParam() {
|
||||
return f.Name
|
||||
}
|
||||
return "_" + f.Name
|
||||
}
|
||||
|
||||
// Source files and functions.
|
||||
type Source struct {
|
||||
Funcs []*Fn
|
||||
Files []string
|
||||
}
|
||||
|
||||
// ParseFiles parses files listed in fs and extracts all syscall
|
||||
// functions listed in sys comments. It returns source files
|
||||
// and functions collection *Source if successful.
|
||||
func ParseFiles(fs []string) (*Source, error) {
|
||||
src := &Source{
|
||||
Funcs: make([]*Fn, 0),
|
||||
Files: make([]string, 0),
|
||||
}
|
||||
for _, file := range fs {
|
||||
if err := src.ParseFile(file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return src, nil
|
||||
}
|
||||
|
||||
// DLLs return dll names for a source set src.
|
||||
func (src *Source) DLLs() []string {
|
||||
uniq := make(map[string]bool)
|
||||
r := make([]string, 0)
|
||||
for _, f := range src.Funcs {
|
||||
name := f.DLLName()
|
||||
if _, found := uniq[name]; !found {
|
||||
uniq[name] = true
|
||||
r = append(r, name)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ParseFile adds additional file path to a source set src.
|
||||
func (src *Source) ParseFile(path string) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
s := bufio.NewScanner(file)
|
||||
for s.Scan() {
|
||||
t := trim(s.Text())
|
||||
if len(t) < 7 {
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(t, "//sys") {
|
||||
continue
|
||||
}
|
||||
t = t[5:]
|
||||
if !(t[0] == ' ' || t[0] == '\t') {
|
||||
continue
|
||||
}
|
||||
f, err := newFn(t[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
src.Funcs = append(src.Funcs, f)
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
src.Files = append(src.Files, path)
|
||||
|
||||
// get package name
|
||||
fset := token.NewFileSet()
|
||||
_, err = file.Seek(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pkg, err := parser.ParseFile(fset, "", file, parser.PackageClauseOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
packageName = pkg.Name.Name
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate output source file from a source set src.
|
||||
func (src *Source) Generate(w io.Writer) error {
|
||||
funcMap := template.FuncMap{
|
||||
"packagename": packagename,
|
||||
"syscalldot": syscalldot,
|
||||
}
|
||||
t := template.Must(template.New("main").Funcs(funcMap).Parse(srcTemplate))
|
||||
err := t.Execute(w, src)
|
||||
if err != nil {
|
||||
return errors.New("Failed to execute template: " + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "usage: mksyscall_windows [flags] [path ...]\n")
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
if len(flag.Args()) <= 0 {
|
||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
||||
usage()
|
||||
}
|
||||
|
||||
src, err := ParseFiles(flag.Args())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := src.Generate(&buf); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
data, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if *filename == "" {
|
||||
_, err = os.Stdout.Write(data)
|
||||
} else {
|
||||
err = ioutil.WriteFile(*filename, data, 0644)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use println instead to print in the following template
|
||||
const srcTemplate = `
|
||||
|
||||
{{define "main"}}// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
||||
|
||||
package {{packagename}}
|
||||
|
||||
import "unsafe"{{if syscalldot}}
|
||||
import "syscall"{{end}}
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
var (
|
||||
{{template "dlls" .}}
|
||||
{{template "funcnames" .}})
|
||||
{{range .Funcs}}{{if .HasStringParam}}{{template "helperbody" .}}{{end}}{{template "funcbody" .}}{{end}}
|
||||
{{end}}
|
||||
|
||||
{{/* help functions */}}
|
||||
|
||||
{{define "dlls"}}{{range .DLLs}} mod{{.}} = {{syscalldot}}NewLazyDLL("{{.}}.dll")
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "funcnames"}}{{range .Funcs}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}")
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "helperbody"}}
|
||||
func {{.Name}}({{.ParamList}}) {{template "results" .}}{
|
||||
{{template "helpertmpvars" .}} return {{.HelperName}}({{.HelperCallParamList}})
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{define "funcbody"}}
|
||||
func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
|
||||
{{template "tmpvars" .}} {{template "syscallcheck" .}}{{template "syscall" .}}
|
||||
{{template "seterror" .}}{{template "printtrace" .}} return
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
|
||||
|
||||
{{define "syscallcheck"}}{{if .ConfirmProc}}if {{.Rets.ErrorVarName}} = proc{{.DLLFuncName}}.Find(); {{.Rets.ErrorVarName}} != nil {
|
||||
return
|
||||
}
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
|
||||
|
||||
{{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "printtrace"}}{{if .PrintTrace}} print("SYSCALL: {{.Name}}(", {{.ParamPrintList}}") (", {{.Rets.PrintList}}")\n")
|
||||
{{end}}{{end}}
|
||||
|
||||
`
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// NameToGuid converts the given string into a GUID using the algorithm in the
|
||||
// Host Compute Service, ensuring GUIDs generated with the same string are common
|
||||
|
@ -15,32 +9,9 @@ func NameToGuid(name string) (id GUID, err error) {
|
|||
title := "hcsshim::NameToGuid "
|
||||
logrus.Debugf(title+"Name %s", name)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procNameToGuid)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
err = nameToGuid(name, &id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Convert name to uint16 pointer for calling the procedure
|
||||
namep, err := syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of name %s to pointer %s", name, err)
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
logrus.Debugf("Calling proc")
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(namep)),
|
||||
uintptr(unsafe.Pointer(&id)))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s name=%s",
|
||||
r1, syscall.Errno(r1), name)
|
||||
err = makeErrorf(err, title, "name=%s", name)
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// PrepareLayer finds a mounted read-write layer matching layerId and enables the
|
||||
// the filesystem filter for use on that layer. This requires the paths to all
|
||||
|
@ -17,58 +11,22 @@ func PrepareLayer(info DriverInfo, layerId string, parentLayerPaths []string) er
|
|||
title := "hcsshim::PrepareLayer "
|
||||
logrus.Debugf(title+"flavour %d layerId %s", info.Flavour, layerId)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procPrepareLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Generate layer descriptors
|
||||
layers, err := layerPathsToDescriptors(parentLayerPaths)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed to generate layer descriptors ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert layerId to uint16 pointer for calling the procedure
|
||||
layerIdp, err := syscall.UTF16PtrFromString(layerId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of layerId %s to pointer %s", layerId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var layerDescriptorsp *WC_LAYER_DESCRIPTOR
|
||||
if len(layers) > 0 {
|
||||
layerDescriptorsp = &(layers[0])
|
||||
} else {
|
||||
layerDescriptorsp = nil
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(layerIdp)),
|
||||
uintptr(unsafe.Pointer(layerDescriptorsp)),
|
||||
uintptr(len(layers)))
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(layerIdp))
|
||||
use(unsafe.Pointer(layerDescriptorsp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+"- Win32 API call returned error r1=%d err=%s layerId=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), layerId, info.Flavour)
|
||||
err = prepareLayer(&infop, layerId, layers)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "layerId=%s flavour=%d", layerId, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// ResizeConsoleInComputeSystem updates the height and width of the console
|
||||
// session for the process with the given id in the container with the given id.
|
||||
|
@ -15,29 +9,9 @@ func ResizeConsoleInComputeSystem(id string, processid uint32, h, w int) error {
|
|||
title := "HCSShim::ResizeConsoleInComputeSystem"
|
||||
logrus.Debugf(title+" id=%s processid=%d (%d,%d)", id, processid, h, w)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procResizeConsoleInComputeSystem)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
err := resizeConsoleInComputeSystem(id, processid, uint16(h), uint16(w), 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
h16 := uint16(h)
|
||||
w16 := uint16(w)
|
||||
|
||||
r1, _, _ := proc.Call(uintptr(unsafe.Pointer(idp)), uintptr(processid), uintptr(h16), uintptr(w16), uintptr(0))
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s, id=%s pid=%d", r1, syscall.Errno(r1), id, processid)
|
||||
err = makeErrorf(err, title, "id=%s pid=%d", id, processid)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// TerminateComputeSystem force terminates a container.
|
||||
func TerminateComputeSystem(id string, timeout uint32, context string) (uint32, error) {
|
||||
|
@ -24,44 +18,25 @@ func ShutdownComputeSystem(id string, timeout uint32, context string) (uint32, e
|
|||
func shutdownTerminate(shutdown bool, id string, timeout uint32, context string) (uint32, error) {
|
||||
|
||||
var (
|
||||
title = "HCSShim::"
|
||||
procName string
|
||||
title = "HCSShim::"
|
||||
)
|
||||
if shutdown {
|
||||
title = title + "ShutdownComputeSystem"
|
||||
procName = procShutdownComputeSystem
|
||||
} else {
|
||||
title = title + "TerminateComputeSystem"
|
||||
procName = procTerminateComputeSystem
|
||||
}
|
||||
logrus.Debugf(title+" id=%s context=%s", id, context)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procName)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
var err error
|
||||
if shutdown {
|
||||
err = shutdownComputeSystem(id, timeout)
|
||||
} else {
|
||||
err = terminateComputeSystem(id)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return 0xffffffff, err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointers for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return 0xffffffff, err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, err := proc.Call(
|
||||
uintptr(unsafe.Pointer(idp)), uintptr(timeout))
|
||||
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=0x%X err=%s id=%s context=%s", r1, syscall.Errno(r1), id, context)
|
||||
return uint32(r1), err
|
||||
err := makeErrorf(err, title, "id=%s context=%s", id, context)
|
||||
return err.HResult(), err
|
||||
}
|
||||
|
||||
logrus.Debugf(title+" succeeded id=%s context=%s", id, context)
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// StartComputeSystem starts a container that has previously been created via
|
||||
// CreateComputeSystem.
|
||||
|
@ -15,30 +9,9 @@ func StartComputeSystem(id string) error {
|
|||
title := "HCSShim::StartComputeSystem"
|
||||
logrus.Debugf(title+" id=%s", id)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procStartComputeSystem)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
err := startComputeSystem(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert ID to uint16 pointers for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(uintptr(unsafe.Pointer(idp)))
|
||||
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s", r1, syscall.Errno(r1), id)
|
||||
err = makeErrorf(err, title, "id=%s", id)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// TerminateProcessInComputeSystem kills a process in a running container.
|
||||
func TerminateProcessInComputeSystem(id string, processid uint32) (err error) {
|
||||
|
@ -14,32 +8,9 @@ func TerminateProcessInComputeSystem(id string, processid uint32) (err error) {
|
|||
title := "HCSShim::TerminateProcessInComputeSystem"
|
||||
logrus.Debugf(title+" id=%s processid=%d", id, processid)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procTerminateProcessInComputeSystem)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
err = terminateProcessInComputeSystem(id, processid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert ID to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, err := proc.Call(
|
||||
uintptr(unsafe.Pointer(idp)),
|
||||
uintptr(processid))
|
||||
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s", r1, syscall.Errno(r1), id)
|
||||
err = makeErrorf(err, title, "err=%s id=%s", id)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// UnprepareLayer disables the filesystem filter for the read-write layer with
|
||||
// the given id.
|
||||
|
@ -14,42 +8,16 @@ func UnprepareLayer(info DriverInfo, layerId string) error {
|
|||
title := "hcsshim::UnprepareLayer "
|
||||
logrus.Debugf(title+"flavour %d layerId %s", info.Flavour, layerId)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procUnprepareLayer)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert layerId to uint16 pointer for calling the procedure
|
||||
layerIdp, err := syscall.UTF16PtrFromString(layerId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion of layerId %s to pointer %s", layerId, err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert info to API calling convention
|
||||
infop, err := convertDriverInfo(info)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+"- Failed conversion info struct %s", err)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, _ := proc.Call(
|
||||
uintptr(unsafe.Pointer(&infop)),
|
||||
uintptr(unsafe.Pointer(layerIdp)))
|
||||
|
||||
use(unsafe.Pointer(&infop))
|
||||
use(unsafe.Pointer(layerIdp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+"- Win32 API call returned error r1=%d err=%s layerId=%s flavour=%d",
|
||||
r1, syscall.Errno(r1), layerId, info.Flavour)
|
||||
err = unprepareLayer(&infop, layerId)
|
||||
if err != nil {
|
||||
err = makeErrorf(err, title, "layerId=%s flavour=%d", layerId, info.Flavour)
|
||||
logrus.Error(err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
import "github.com/Sirupsen/logrus"
|
||||
|
||||
// WaitForProcessInComputeSystem waits for a process ID to terminate and returns
|
||||
// the exit code. Returns exitcode, errno, error
|
||||
|
@ -15,40 +9,13 @@ func WaitForProcessInComputeSystem(id string, processid uint32, timeout uint32)
|
|||
title := "HCSShim::WaitForProcessInComputeSystem"
|
||||
logrus.Debugf(title+" id=%s processid=%d", id, processid)
|
||||
|
||||
// Load the DLL and get a handle to the procedure we need
|
||||
dll, proc, err := loadAndFind(procWaitForProcessInComputeSystem)
|
||||
if dll != nil {
|
||||
defer dll.Release()
|
||||
}
|
||||
var exitCode uint32
|
||||
err := waitForProcessInComputeSystem(id, processid, timeout, &exitCode)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
err := makeErrorf(err, title, "id=%s", id)
|
||||
return 0, err.HResult(), err
|
||||
}
|
||||
|
||||
// Convert id to uint16 pointer for calling the procedure
|
||||
idp, err := syscall.UTF16PtrFromString(id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err)
|
||||
logrus.Error(err)
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
// To get a POINTER to the ExitCode
|
||||
ec := new(int32)
|
||||
|
||||
// Call the procedure itself.
|
||||
r1, _, err := proc.Call(
|
||||
uintptr(unsafe.Pointer(idp)),
|
||||
uintptr(processid),
|
||||
uintptr(timeout),
|
||||
uintptr(unsafe.Pointer(ec)))
|
||||
|
||||
use(unsafe.Pointer(idp))
|
||||
|
||||
if r1 != 0 {
|
||||
err = fmt.Errorf(title+" - Win32 API call returned error r1=0x%X err=%s id=%s", r1, syscall.Errno(r1), id)
|
||||
return 0, uint32(r1), err
|
||||
}
|
||||
|
||||
logrus.Debugf(title+" succeeded id=%s processid=%d exitcode=%d", id, processid, *ec)
|
||||
return *ec, 0, nil
|
||||
logrus.Debugf(title+" succeeded id=%s processid=%d exitcode=%d", id, processid, exitCode)
|
||||
return int32(exitCode), 0, nil
|
||||
}
|
||||
|
|
559
vendor/src/github.com/microsoft/hcsshim/zhcsshim.go
vendored
Normal file
559
vendor/src/github.com/microsoft/hcsshim/zhcsshim.go
vendored
Normal file
|
@ -0,0 +1,559 @@
|
|||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
||||
|
||||
package hcsshim
|
||||
|
||||
import "unsafe"
|
||||
import "syscall"
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
var (
|
||||
modole32 = syscall.NewLazyDLL("ole32.dll")
|
||||
modvmcompute = syscall.NewLazyDLL("vmcompute.dll")
|
||||
|
||||
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
||||
procActivateLayer = modvmcompute.NewProc("ActivateLayer")
|
||||
procCopyLayer = modvmcompute.NewProc("CopyLayer")
|
||||
procCreateLayer = modvmcompute.NewProc("CreateLayer")
|
||||
procCreateSandboxLayer = modvmcompute.NewProc("CreateSandboxLayer")
|
||||
procDeactivateLayer = modvmcompute.NewProc("DeactivateLayer")
|
||||
procDestroyLayer = modvmcompute.NewProc("DestroyLayer")
|
||||
procExportLayer = modvmcompute.NewProc("ExportLayer")
|
||||
procGetLayerMountPath = modvmcompute.NewProc("GetLayerMountPath")
|
||||
procGetBaseImages = modvmcompute.NewProc("GetBaseImages")
|
||||
procImportLayer = modvmcompute.NewProc("ImportLayer")
|
||||
procLayerExists = modvmcompute.NewProc("LayerExists")
|
||||
procNameToGuid = modvmcompute.NewProc("NameToGuid")
|
||||
procPrepareLayer = modvmcompute.NewProc("PrepareLayer")
|
||||
procUnprepareLayer = modvmcompute.NewProc("UnprepareLayer")
|
||||
procCreateComputeSystem = modvmcompute.NewProc("CreateComputeSystem")
|
||||
procCreateProcessWithStdHandlesInComputeSystem = modvmcompute.NewProc("CreateProcessWithStdHandlesInComputeSystem")
|
||||
procResizeConsoleInComputeSystem = modvmcompute.NewProc("ResizeConsoleInComputeSystem")
|
||||
procShutdownComputeSystem = modvmcompute.NewProc("ShutdownComputeSystem")
|
||||
procStartComputeSystem = modvmcompute.NewProc("StartComputeSystem")
|
||||
procTerminateComputeSystem = modvmcompute.NewProc("TerminateComputeSystem")
|
||||
procTerminateProcessInComputeSystem = modvmcompute.NewProc("TerminateProcessInComputeSystem")
|
||||
procWaitForProcessInComputeSystem = modvmcompute.NewProc("WaitForProcessInComputeSystem")
|
||||
procHNSCall = modvmcompute.NewProc("HNSCall")
|
||||
)
|
||||
|
||||
func coTaskMemFree(buffer unsafe.Pointer) {
|
||||
syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(buffer), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func activateLayer(info *driverInfo, id string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _activateLayer(info, _p0)
|
||||
}
|
||||
|
||||
func _activateLayer(info *driverInfo, id *uint16) (hr error) {
|
||||
if hr = procActivateLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procActivateLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(srcId)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(dstId)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _copyLayer(info, _p0, _p1, descriptors)
|
||||
}
|
||||
|
||||
func _copyLayer(info *driverInfo, srcId *uint16, dstId *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p2 *WC_LAYER_DESCRIPTOR
|
||||
if len(descriptors) > 0 {
|
||||
_p2 = &descriptors[0]
|
||||
}
|
||||
if hr = procCopyLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procCopyLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(srcId)), uintptr(unsafe.Pointer(dstId)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createLayer(info *driverInfo, id string, parent string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(parent)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _createLayer(info, _p0, _p1)
|
||||
}
|
||||
|
||||
func _createLayer(info *driverInfo, id *uint16, parent *uint16) (hr error) {
|
||||
if hr = procCreateLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procCreateLayer.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(parent)))
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createSandboxLayer(info *driverInfo, id string, parent string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(parent)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _createSandboxLayer(info, _p0, _p1, descriptors)
|
||||
}
|
||||
|
||||
func _createSandboxLayer(info *driverInfo, id *uint16, parent *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p2 *WC_LAYER_DESCRIPTOR
|
||||
if len(descriptors) > 0 {
|
||||
_p2 = &descriptors[0]
|
||||
}
|
||||
if hr = procCreateSandboxLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procCreateSandboxLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(parent)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func deactivateLayer(info *driverInfo, id string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _deactivateLayer(info, _p0)
|
||||
}
|
||||
|
||||
func _deactivateLayer(info *driverInfo, id *uint16) (hr error) {
|
||||
if hr = procDeactivateLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procDeactivateLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func destroyLayer(info *driverInfo, id string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _destroyLayer(info, _p0)
|
||||
}
|
||||
|
||||
func _destroyLayer(info *driverInfo, id *uint16) (hr error) {
|
||||
if hr = procDestroyLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procDestroyLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(path)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _exportLayer(info, _p0, _p1, descriptors)
|
||||
}
|
||||
|
||||
func _exportLayer(info *driverInfo, id *uint16, path *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p2 *WC_LAYER_DESCRIPTOR
|
||||
if len(descriptors) > 0 {
|
||||
_p2 = &descriptors[0]
|
||||
}
|
||||
if hr = procExportLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procExportLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _getLayerMountPath(info, _p0, length, buffer)
|
||||
}
|
||||
|
||||
func _getLayerMountPath(info *driverInfo, id *uint16, length *uintptr, buffer *uint16) (hr error) {
|
||||
if hr = procGetLayerMountPath.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procGetLayerMountPath.Addr(), 4, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(length)), uintptr(unsafe.Pointer(buffer)), 0, 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getBaseImages(buffer **uint16) (hr error) {
|
||||
if hr = procGetBaseImages.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procGetBaseImages.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(path)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _importLayer(info, _p0, _p1, descriptors)
|
||||
}
|
||||
|
||||
func _importLayer(info *driverInfo, id *uint16, path *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p2 *WC_LAYER_DESCRIPTOR
|
||||
if len(descriptors) > 0 {
|
||||
_p2 = &descriptors[0]
|
||||
}
|
||||
if hr = procImportLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procImportLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func layerExists(info *driverInfo, id string, exists *uint32) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _layerExists(info, _p0, exists)
|
||||
}
|
||||
|
||||
func _layerExists(info *driverInfo, id *uint16, exists *uint32) (hr error) {
|
||||
if hr = procLayerExists.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procLayerExists.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(exists)))
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func nameToGuid(name string, guid *GUID) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(name)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _nameToGuid(_p0, guid)
|
||||
}
|
||||
|
||||
func _nameToGuid(name *uint16, guid *GUID) (hr error) {
|
||||
if hr = procNameToGuid.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procNameToGuid.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(guid)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _prepareLayer(info, _p0, descriptors)
|
||||
}
|
||||
|
||||
func _prepareLayer(info *driverInfo, id *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
|
||||
var _p1 *WC_LAYER_DESCRIPTOR
|
||||
if len(descriptors) > 0 {
|
||||
_p1 = &descriptors[0]
|
||||
}
|
||||
if hr = procPrepareLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procPrepareLayer.Addr(), 4, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), 0, 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func unprepareLayer(info *driverInfo, id string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _unprepareLayer(info, _p0)
|
||||
}
|
||||
|
||||
func _unprepareLayer(info *driverInfo, id *uint16) (hr error) {
|
||||
if hr = procUnprepareLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procUnprepareLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createComputeSystem(id string, configuration string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(configuration)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _createComputeSystem(_p0, _p1)
|
||||
}
|
||||
|
||||
func _createComputeSystem(id *uint16, configuration *uint16) (hr error) {
|
||||
if hr = procCreateComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procCreateComputeSystem.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(configuration)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createProcessWithStdHandlesInComputeSystem(id string, paramsJson string, pid *uint32, stdin *syscall.Handle, stdout *syscall.Handle, stderr *syscall.Handle) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(paramsJson)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _createProcessWithStdHandlesInComputeSystem(_p0, _p1, pid, stdin, stdout, stderr)
|
||||
}
|
||||
|
||||
func _createProcessWithStdHandlesInComputeSystem(id *uint16, paramsJson *uint16, pid *uint32, stdin *syscall.Handle, stdout *syscall.Handle, stderr *syscall.Handle) (hr error) {
|
||||
if hr = procCreateProcessWithStdHandlesInComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procCreateProcessWithStdHandlesInComputeSystem.Addr(), 6, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(paramsJson)), uintptr(unsafe.Pointer(pid)), uintptr(unsafe.Pointer(stdin)), uintptr(unsafe.Pointer(stdout)), uintptr(unsafe.Pointer(stderr)))
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func resizeConsoleInComputeSystem(id string, pid uint32, height uint16, width uint16, flags uint32) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _resizeConsoleInComputeSystem(_p0, pid, height, width, flags)
|
||||
}
|
||||
|
||||
func _resizeConsoleInComputeSystem(id *uint16, pid uint32, height uint16, width uint16, flags uint32) (hr error) {
|
||||
if hr = procResizeConsoleInComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procResizeConsoleInComputeSystem.Addr(), 5, uintptr(unsafe.Pointer(id)), uintptr(pid), uintptr(height), uintptr(width), uintptr(flags), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func shutdownComputeSystem(id string, timeout uint32) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _shutdownComputeSystem(_p0, timeout)
|
||||
}
|
||||
|
||||
func _shutdownComputeSystem(id *uint16, timeout uint32) (hr error) {
|
||||
if hr = procShutdownComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procShutdownComputeSystem.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(timeout), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func startComputeSystem(id string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _startComputeSystem(_p0)
|
||||
}
|
||||
|
||||
func _startComputeSystem(id *uint16) (hr error) {
|
||||
if hr = procStartComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procStartComputeSystem.Addr(), 1, uintptr(unsafe.Pointer(id)), 0, 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func terminateComputeSystem(id string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _terminateComputeSystem(_p0)
|
||||
}
|
||||
|
||||
func _terminateComputeSystem(id *uint16) (hr error) {
|
||||
if hr = procTerminateComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procTerminateComputeSystem.Addr(), 1, uintptr(unsafe.Pointer(id)), 0, 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func terminateProcessInComputeSystem(id string, pid uint32) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _terminateProcessInComputeSystem(_p0, pid)
|
||||
}
|
||||
|
||||
func _terminateProcessInComputeSystem(id *uint16, pid uint32) (hr error) {
|
||||
if hr = procTerminateProcessInComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procTerminateProcessInComputeSystem.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(pid), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func waitForProcessInComputeSystem(id string, pid uint32, timeout uint32, exitCode *uint32) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(id)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _waitForProcessInComputeSystem(_p0, pid, timeout, exitCode)
|
||||
}
|
||||
|
||||
func _waitForProcessInComputeSystem(id *uint16, pid uint32, timeout uint32, exitCode *uint32) (hr error) {
|
||||
if hr = procWaitForProcessInComputeSystem.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procWaitForProcessInComputeSystem.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(pid), uintptr(timeout), uintptr(unsafe.Pointer(exitCode)), 0, 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _hnsCall(method string, path string, object string, response **uint16) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(method)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(path)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p2 *uint16
|
||||
_p2, hr = syscall.UTF16PtrFromString(object)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return __hnsCall(_p0, _p1, _p2, response)
|
||||
}
|
||||
|
||||
func __hnsCall(method *uint16, path *uint16, object *uint16, response **uint16) (hr error) {
|
||||
if hr = procHNSCall.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHNSCall.Addr(), 4, uintptr(unsafe.Pointer(method)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(object)), uintptr(unsafe.Pointer(response)), 0, 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in a new issue