1// Shim for the Host Compute Service (HCS) to manage Windows Server 2// containers and Hyper-V containers. 3 4package hcsshim 5 6import ( 7 "fmt" 8 "syscall" 9 "unsafe" 10 11 "github.com/sirupsen/logrus" 12) 13 14//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go safeopen.go 15 16//sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree 17//sys SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) = iphlpapi.SetCurrentThreadCompartmentId 18 19//sys activateLayer(info *driverInfo, id string) (hr error) = vmcompute.ActivateLayer? 20//sys copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CopyLayer? 21//sys createLayer(info *driverInfo, id string, parent string) (hr error) = vmcompute.CreateLayer? 22//sys createSandboxLayer(info *driverInfo, id string, parent string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CreateSandboxLayer? 23//sys expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) = vmcompute.ExpandSandboxSize? 24//sys deactivateLayer(info *driverInfo, id string) (hr error) = vmcompute.DeactivateLayer? 25//sys destroyLayer(info *driverInfo, id string) (hr error) = vmcompute.DestroyLayer? 26//sys exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ExportLayer? 27//sys getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) = vmcompute.GetLayerMountPath? 28//sys getBaseImages(buffer **uint16) (hr error) = vmcompute.GetBaseImages? 29//sys importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ImportLayer? 30//sys layerExists(info *driverInfo, id string, exists *uint32) (hr error) = vmcompute.LayerExists? 31//sys nameToGuid(name string, guid *GUID) (hr error) = vmcompute.NameToGuid? 32//sys prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.PrepareLayer? 33//sys unprepareLayer(info *driverInfo, id string) (hr error) = vmcompute.UnprepareLayer? 34//sys processBaseImage(path string) (hr error) = vmcompute.ProcessBaseImage? 35//sys processUtilityImage(path string) (hr error) = vmcompute.ProcessUtilityImage? 36 37//sys importLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ImportLayerBegin? 38//sys importLayerNext(context uintptr, fileName string, fileInfo *winio.FileBasicInfo) (hr error) = vmcompute.ImportLayerNext? 39//sys importLayerWrite(context uintptr, buffer []byte) (hr error) = vmcompute.ImportLayerWrite? 40//sys importLayerEnd(context uintptr) (hr error) = vmcompute.ImportLayerEnd? 41 42//sys exportLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ExportLayerBegin? 43//sys exportLayerNext(context uintptr, fileName **uint16, fileInfo *winio.FileBasicInfo, fileSize *int64, deleted *uint32) (hr error) = vmcompute.ExportLayerNext? 44//sys exportLayerRead(context uintptr, buffer []byte, bytesRead *uint32) (hr error) = vmcompute.ExportLayerRead? 45//sys exportLayerEnd(context uintptr) (hr error) = vmcompute.ExportLayerEnd? 46 47//sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems? 48//sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem? 49//sys hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem? 50//sys hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem? 51//sys hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem? 52//sys hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem? 53//sys hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem? 54//sys hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem? 55//sys hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem? 56//sys hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties? 57//sys hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem? 58//sys hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback? 59//sys hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback? 60 61//sys hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess? 62//sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess? 63//sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess? 64//sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess? 65//sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo? 66//sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties? 67//sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess? 68//sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties? 69//sys hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback? 70//sys hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback? 71 72//sys hcsModifyServiceSettings(settings string, result **uint16) (hr error) = vmcompute.HcsModifyServiceSettings? 73 74//sys _hnsCall(method string, path string, object string, response **uint16) (hr error) = vmcompute.HNSCall? 75 76const ( 77 // Specific user-visible exit codes 78 WaitErrExecFailed = 32767 79 80 ERROR_GEN_FAILURE = syscall.Errno(31) 81 ERROR_SHUTDOWN_IN_PROGRESS = syscall.Errno(1115) 82 WSAEINVAL = syscall.Errno(10022) 83 84 // Timeout on wait calls 85 TimeoutInfinite = 0xFFFFFFFF 86) 87 88type HcsError struct { 89 title string 90 rest string 91 Err error 92} 93 94type hcsSystem syscall.Handle 95type hcsProcess syscall.Handle 96type hcsCallback syscall.Handle 97 98type hcsProcessInformation struct { 99 ProcessId uint32 100 Reserved uint32 101 StdInput syscall.Handle 102 StdOutput syscall.Handle 103 StdError syscall.Handle 104} 105 106func makeError(err error, title, rest string) error { 107 // Pass through DLL errors directly since they do not originate from HCS. 108 if _, ok := err.(*syscall.DLLError); ok { 109 return err 110 } 111 return &HcsError{title, rest, err} 112} 113 114func makeErrorf(err error, title, format string, a ...interface{}) error { 115 return makeError(err, title, fmt.Sprintf(format, a...)) 116} 117 118func win32FromError(err error) uint32 { 119 if herr, ok := err.(*HcsError); ok { 120 return win32FromError(herr.Err) 121 } 122 if code, ok := err.(syscall.Errno); ok { 123 return uint32(code) 124 } 125 return uint32(ERROR_GEN_FAILURE) 126} 127 128func win32FromHresult(hr uintptr) uintptr { 129 if hr&0x1fff0000 == 0x00070000 { 130 return hr & 0xffff 131 } 132 return hr 133} 134 135func (e *HcsError) Error() string { 136 s := e.title 137 if len(s) > 0 && s[len(s)-1] != ' ' { 138 s += " " 139 } 140 s += fmt.Sprintf("failed in Win32: %s (0x%x)", e.Err, win32FromError(e.Err)) 141 if e.rest != "" { 142 if e.rest[0] != ' ' { 143 s += " " 144 } 145 s += e.rest 146 } 147 return s 148} 149 150func convertAndFreeCoTaskMemString(buffer *uint16) string { 151 str := syscall.UTF16ToString((*[1 << 30]uint16)(unsafe.Pointer(buffer))[:]) 152 coTaskMemFree(unsafe.Pointer(buffer)) 153 return str 154} 155 156func convertAndFreeCoTaskMemBytes(buffer *uint16) []byte { 157 return []byte(convertAndFreeCoTaskMemString(buffer)) 158} 159 160func processHcsResult(err error, resultp *uint16) error { 161 if resultp != nil { 162 result := convertAndFreeCoTaskMemString(resultp) 163 logrus.Debugf("Result: %s", result) 164 } 165 return err 166} 167