vndr hcsshim to 79062a5

Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
diff --git a/vendor.conf b/vendor.conf
index 91cde6d..559ac51 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -1,6 +1,6 @@
 # the following lines are in sorted order, FYI
 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
-github.com/Microsoft/hcsshim v0.6.8
+github.com/Microsoft/hcsshim 79062a5b985d24ef42a4252a1b63a93ec450e407
 github.com/Microsoft/go-winio v0.4.6
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
 github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
diff --git a/vendor/github.com/Microsoft/hcsshim/baselayer.go b/vendor/github.com/Microsoft/hcsshim/baselayer.go
index 9babd4e..860185c 100644
--- a/vendor/github.com/Microsoft/hcsshim/baselayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/baselayer.go
@@ -10,7 +10,7 @@
 )
 
 type baseLayerWriter struct {
-	root         string
+	root         *os.File
 	f            *os.File
 	bw           *winio.BackupFileWriter
 	err          error
@@ -26,10 +26,10 @@
 // reapplyDirectoryTimes reapplies directory modification, creation, etc. times
 // after processing of the directory tree has completed. The times are expected
 // to be ordered such that parent directories come before child directories.
-func reapplyDirectoryTimes(dis []dirInfo) error {
+func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
 	for i := range dis {
 		di := &dis[len(dis)-i-1] // reverse order: process child directories first
-		f, err := winio.OpenForBackup(di.path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, syscall.OPEN_EXISTING)
+		f, err := openRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, _FILE_OPEN, _FILE_DIRECTORY_FILE)
 		if err != nil {
 			return err
 		}
@@ -75,12 +75,6 @@
 		w.hasUtilityVM = true
 	}
 
-	path := filepath.Join(w.root, name)
-	path, err = makeLongAbsPath(path)
-	if err != nil {
-		return err
-	}
-
 	var f *os.File
 	defer func() {
 		if f != nil {
@@ -88,27 +82,23 @@
 		}
 	}()
 
-	createmode := uint32(syscall.CREATE_NEW)
+	extraFlags := uint32(0)
 	if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
-		err := os.Mkdir(path, 0)
-		if err != nil && !os.IsExist(err) {
-			return err
-		}
-		createmode = syscall.OPEN_EXISTING
+		extraFlags |= _FILE_DIRECTORY_FILE
 		if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
-			w.dirInfo = append(w.dirInfo, dirInfo{path, *fileInfo})
+			w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo})
 		}
 	}
 
 	mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY)
-	f, err = winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createmode)
+	f, err = openRelative(name, w.root, mode, syscall.FILE_SHARE_READ, _FILE_CREATE, extraFlags)
 	if err != nil {
-		return makeError(err, "Failed to OpenForBackup", path)
+		return makeError(err, "Failed to openRelative", name)
 	}
 
 	err = winio.SetFileBasicInfo(f, fileInfo)
 	if err != nil {
-		return makeError(err, "Failed to SetFileBasicInfo", path)
+		return makeError(err, "Failed to SetFileBasicInfo", name)
 	}
 
 	w.f = f
@@ -129,17 +119,7 @@
 		return err
 	}
 
-	linkpath, err := makeLongAbsPath(filepath.Join(w.root, name))
-	if err != nil {
-		return err
-	}
-
-	linktarget, err := makeLongAbsPath(filepath.Join(w.root, target))
-	if err != nil {
-		return err
-	}
-
-	return os.Link(linktarget, linkpath)
+	return linkRelative(target, w.root, name, w.root)
 }
 
 func (w *baseLayerWriter) Remove(name string) error {
@@ -155,6 +135,10 @@
 }
 
 func (w *baseLayerWriter) Close() error {
+	defer func() {
+		w.root.Close()
+		w.root = nil
+	}()
 	err := w.closeCurrentFile()
 	if err != nil {
 		return err
@@ -162,18 +146,22 @@
 	if w.err == nil {
 		// Restore the file times of all the directories, since they may have
 		// been modified by creating child directories.
-		err = reapplyDirectoryTimes(w.dirInfo)
+		err = reapplyDirectoryTimes(w.root, w.dirInfo)
 		if err != nil {
 			return err
 		}
 
-		err = ProcessBaseLayer(w.root)
+		err = ProcessBaseLayer(w.root.Name())
 		if err != nil {
 			return err
 		}
 
 		if w.hasUtilityVM {
-			err = ProcessUtilityVMImage(filepath.Join(w.root, "UtilityVM"))
+			err := ensureNotReparsePointRelative("UtilityVM", w.root)
+			if err != nil {
+				return err
+			}
+			err = ProcessUtilityVMImage(filepath.Join(w.root.Name(), "UtilityVM"))
 			if err != nil {
 				return err
 			}
diff --git a/vendor/github.com/Microsoft/hcsshim/hcsshim.go b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
index 236ba1f..b659531 100644
--- a/vendor/github.com/Microsoft/hcsshim/hcsshim.go
+++ b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
@@ -11,7 +11,7 @@
 	"github.com/sirupsen/logrus"
 )
 
-//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
+//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go safeopen.go
 
 //sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree
 //sys SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) = iphlpapi.SetCurrentThreadCompartmentId
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
index 7e516f8..90689cb 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
@@ -1,323 +1,323 @@
-package hcsshim

-

-import (

-	"encoding/json"

-	"net"

-

-	"github.com/sirupsen/logrus"

-)

-

-// HNSEndpoint represents a network endpoint in HNS

-type HNSEndpoint struct {

-	Id                 string            `json:"ID,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"`

-	DNSSuffix          string            `json:",omitempty"`

-	DNSServerList      string            `json:",omitempty"`

-	GatewayAddress     string            `json:",omitempty"`

-	EnableInternalDNS  bool              `json:",omitempty"`

-	DisableICC         bool              `json:",omitempty"`

-	PrefixLength       uint8             `json:",omitempty"`

-	IsRemoteEndpoint   bool              `json:",omitempty"`

-}

-

-//SystemType represents the type of the system on which actions are done

-type SystemType string

-

-// SystemType const

-const (

-	ContainerType      SystemType = "Container"

-	VirtualMachineType SystemType = "VirtualMachine"

-	HostType           SystemType = "Host"

-)

-

-// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system

-// Supported resource types are Network and Request Types are Add/Remove

-type EndpointAttachDetachRequest struct {

-	ContainerID    string     `json:"ContainerId,omitempty"`

-	SystemType     SystemType `json:"SystemType"`

-	CompartmentID  uint16     `json:"CompartmentId,omitempty"`

-	VirtualNICName string     `json:"VirtualNicName,omitempty"`

-}

-

-// EndpointResquestResponse is object to get the endpoint request response

-type EndpointResquestResponse struct {

-	Success bool

-	Error   string

-}

-

-// 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

-}

-

-// HNSListEndpointRequest makes a HNS call to query the list of available endpoints

-func HNSListEndpointRequest() ([]HNSEndpoint, error) {

-	var endpoint []HNSEndpoint

-	err := hnsCall("GET", "/endpoints/", "", &endpoint)

-	if err != nil {

-		return nil, err

-	}

-

-	return endpoint, nil

-}

-

-// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container

-func HotAttachEndpoint(containerID string, endpointID string) error {

-	return modifyNetworkEndpoint(containerID, endpointID, Add)

-}

-

-// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container

-func HotDetachEndpoint(containerID string, endpointID string) error {

-	return modifyNetworkEndpoint(containerID, endpointID, Remove)

-}

-

-// ModifyContainer corresponding to the container id, by sending a request

-func modifyContainer(id string, request *ResourceModificationRequestResponse) error {

-	container, err := OpenContainer(id)

-	if err != nil {

-		if IsNotExist(err) {

-			return ErrComputeSystemDoesNotExist

-		}

-		return getInnerError(err)

-	}

-	defer container.Close()

-	err = container.Modify(request)

-	if err != nil {

-		if IsNotSupported(err) {

-			return ErrPlatformNotSupported

-		}

-		return getInnerError(err)

-	}

-

-	return nil

-}

-

-func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {

-	requestMessage := &ResourceModificationRequestResponse{

-		Resource: Network,

-		Request:  request,

-		Data:     endpointID,

-	}

-	err := modifyContainer(containerID, requestMessage)

-

-	if err != nil {

-		return err

-	}

-

-	return nil

-}

-

-// GetHNSEndpointByID get the Endpoint by ID

-func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {

-	return HNSEndpointRequest("GET", endpointID, "")

-}

-

-// GetHNSEndpointByName gets the endpoint filtered by Name

-func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {

-	hnsResponse, err := HNSListEndpointRequest()

-	if err != nil {

-		return nil, err

-	}

-	for _, hnsEndpoint := range hnsResponse {

-		if hnsEndpoint.Name == endpointName {

-			return &hnsEndpoint, nil

-		}

-	}

-	return nil, EndpointNotFoundError{EndpointName: endpointName}

-}

-

-// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods

-func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {

-	operation := "Create"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-

-	jsonString, err := json.Marshal(endpoint)

-	if err != nil {

-		return nil, err

-	}

-	return HNSEndpointRequest("POST", "", string(jsonString))

-}

-

-// Delete Endpoint by sending EndpointRequest to HNS

-func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {

-	operation := "Delete"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-

-	return HNSEndpointRequest("DELETE", endpoint.Id, "")

-}

-

-// Update Endpoint

-func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {

-	operation := "Update"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-	jsonString, err := json.Marshal(endpoint)

-	if err != nil {

-		return nil, err

-	}

-	err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)

-

-	return endpoint, err

-}

-

-// ContainerHotAttach attaches an endpoint to a running container

-func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {

-	operation := "ContainerHotAttach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)

-

-	return modifyNetworkEndpoint(containerID, endpoint.Id, Add)

-}

-

-// ContainerHotDetach detaches an endpoint from a running container

-func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {

-	operation := "ContainerHotDetach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)

-

-	return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)

-}

-

-// ApplyACLPolicy applies a set of ACL Policies on the Endpoint

-func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {

-	operation := "ApplyACLPolicy"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-

-	for _, policy := range policies {

-		if policy == nil {

-			continue

-		}

-		jsonString, err := json.Marshal(policy)

-		if err != nil {

-			return err

-		}

-		endpoint.Policies = append(endpoint.Policies, jsonString)

-	}

-

-	_, err := endpoint.Update()

-	return err

-}

-

-// ContainerAttach attaches an endpoint to container

-func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {

-	operation := "ContainerAttach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-

-	requestMessage := &EndpointAttachDetachRequest{

-		ContainerID:   containerID,

-		CompartmentID: compartmentID,

-		SystemType:    ContainerType,

-	}

-	response := &EndpointResquestResponse{}

-	jsonString, err := json.Marshal(requestMessage)

-	if err != nil {

-		return err

-	}

-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)

-}

-

-// ContainerDetach detaches an endpoint from container

-func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {

-	operation := "ContainerDetach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-

-	requestMessage := &EndpointAttachDetachRequest{

-		ContainerID: containerID,

-		SystemType:  ContainerType,

-	}

-	response := &EndpointResquestResponse{}

-

-	jsonString, err := json.Marshal(requestMessage)

-	if err != nil {

-		return err

-	}

-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)

-}

-

-// HostAttach attaches a nic on the host

-func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {

-	operation := "HostAttach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-	requestMessage := &EndpointAttachDetachRequest{

-		CompartmentID: compartmentID,

-		SystemType:    HostType,

-	}

-	response := &EndpointResquestResponse{}

-

-	jsonString, err := json.Marshal(requestMessage)

-	if err != nil {

-		return err

-	}

-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)

-

-}

-

-// HostDetach detaches a nic on the host

-func (endpoint *HNSEndpoint) HostDetach() error {

-	operation := "HostDetach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-	requestMessage := &EndpointAttachDetachRequest{

-		SystemType: HostType,

-	}

-	response := &EndpointResquestResponse{}

-

-	jsonString, err := json.Marshal(requestMessage)

-	if err != nil {

-		return err

-	}

-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)

-}

-

-// VirtualMachineNICAttach attaches a endpoint to a virtual machine

-func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {

-	operation := "VirtualMachineNicAttach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-	requestMessage := &EndpointAttachDetachRequest{

-		VirtualNICName: virtualMachineNICName,

-		SystemType:     VirtualMachineType,

-	}

-	response := &EndpointResquestResponse{}

-

-	jsonString, err := json.Marshal(requestMessage)

-	if err != nil {

-		return err

-	}

-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)

-}

-

-// VirtualMachineNICDetach detaches a endpoint  from a virtual machine

-func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {

-	operation := "VirtualMachineNicDetach"

-	title := "HCSShim::HNSEndpoint::" + operation

-	logrus.Debugf(title+" id=%s", endpoint.Id)

-

-	requestMessage := &EndpointAttachDetachRequest{

-		SystemType: VirtualMachineType,

-	}

-	response := &EndpointResquestResponse{}

-

-	jsonString, err := json.Marshal(requestMessage)

-	if err != nil {

-		return err

-	}

-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)

-}

+package hcsshim
+
+import (
+	"encoding/json"
+	"net"
+
+	"github.com/sirupsen/logrus"
+)
+
+// HNSEndpoint represents a network endpoint in HNS
+type HNSEndpoint struct {
+	Id                 string            `json:"ID,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"`
+	DNSSuffix          string            `json:",omitempty"`
+	DNSServerList      string            `json:",omitempty"`
+	GatewayAddress     string            `json:",omitempty"`
+	EnableInternalDNS  bool              `json:",omitempty"`
+	DisableICC         bool              `json:",omitempty"`
+	PrefixLength       uint8             `json:",omitempty"`
+	IsRemoteEndpoint   bool              `json:",omitempty"`
+}
+
+//SystemType represents the type of the system on which actions are done
+type SystemType string
+
+// SystemType const
+const (
+	ContainerType      SystemType = "Container"
+	VirtualMachineType SystemType = "VirtualMachine"
+	HostType           SystemType = "Host"
+)
+
+// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
+// Supported resource types are Network and Request Types are Add/Remove
+type EndpointAttachDetachRequest struct {
+	ContainerID    string     `json:"ContainerId,omitempty"`
+	SystemType     SystemType `json:"SystemType"`
+	CompartmentID  uint16     `json:"CompartmentId,omitempty"`
+	VirtualNICName string     `json:"VirtualNicName,omitempty"`
+}
+
+// EndpointResquestResponse is object to get the endpoint request response
+type EndpointResquestResponse struct {
+	Success bool
+	Error   string
+}
+
+// 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
+}
+
+// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
+func HNSListEndpointRequest() ([]HNSEndpoint, error) {
+	var endpoint []HNSEndpoint
+	err := hnsCall("GET", "/endpoints/", "", &endpoint)
+	if err != nil {
+		return nil, err
+	}
+
+	return endpoint, nil
+}
+
+// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
+func HotAttachEndpoint(containerID string, endpointID string) error {
+	return modifyNetworkEndpoint(containerID, endpointID, Add)
+}
+
+// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
+func HotDetachEndpoint(containerID string, endpointID string) error {
+	return modifyNetworkEndpoint(containerID, endpointID, Remove)
+}
+
+// ModifyContainer corresponding to the container id, by sending a request
+func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
+	container, err := OpenContainer(id)
+	if err != nil {
+		if IsNotExist(err) {
+			return ErrComputeSystemDoesNotExist
+		}
+		return getInnerError(err)
+	}
+	defer container.Close()
+	err = container.Modify(request)
+	if err != nil {
+		if IsNotSupported(err) {
+			return ErrPlatformNotSupported
+		}
+		return getInnerError(err)
+	}
+
+	return nil
+}
+
+func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
+	requestMessage := &ResourceModificationRequestResponse{
+		Resource: Network,
+		Request:  request,
+		Data:     endpointID,
+	}
+	err := modifyContainer(containerID, requestMessage)
+
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// GetHNSEndpointByID get the Endpoint by ID
+func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
+	return HNSEndpointRequest("GET", endpointID, "")
+}
+
+// GetHNSEndpointByName gets the endpoint filtered by Name
+func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
+	hnsResponse, err := HNSListEndpointRequest()
+	if err != nil {
+		return nil, err
+	}
+	for _, hnsEndpoint := range hnsResponse {
+		if hnsEndpoint.Name == endpointName {
+			return &hnsEndpoint, nil
+		}
+	}
+	return nil, EndpointNotFoundError{EndpointName: endpointName}
+}
+
+// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
+func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
+	operation := "Create"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	jsonString, err := json.Marshal(endpoint)
+	if err != nil {
+		return nil, err
+	}
+	return HNSEndpointRequest("POST", "", string(jsonString))
+}
+
+// Delete Endpoint by sending EndpointRequest to HNS
+func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
+	operation := "Delete"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	return HNSEndpointRequest("DELETE", endpoint.Id, "")
+}
+
+// Update Endpoint
+func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
+	operation := "Update"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	jsonString, err := json.Marshal(endpoint)
+	if err != nil {
+		return nil, err
+	}
+	err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
+
+	return endpoint, err
+}
+
+// ContainerHotAttach attaches an endpoint to a running container
+func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {
+	operation := "ContainerHotAttach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
+
+	return modifyNetworkEndpoint(containerID, endpoint.Id, Add)
+}
+
+// ContainerHotDetach detaches an endpoint from a running container
+func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {
+	operation := "ContainerHotDetach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
+
+	return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)
+}
+
+// ApplyACLPolicy applies a set of ACL Policies on the Endpoint
+func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
+	operation := "ApplyACLPolicy"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	for _, policy := range policies {
+		if policy == nil {
+			continue
+		}
+		jsonString, err := json.Marshal(policy)
+		if err != nil {
+			return err
+		}
+		endpoint.Policies = append(endpoint.Policies, jsonString)
+	}
+
+	_, err := endpoint.Update()
+	return err
+}
+
+// ContainerAttach attaches an endpoint to container
+func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
+	operation := "ContainerAttach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	requestMessage := &EndpointAttachDetachRequest{
+		ContainerID:   containerID,
+		CompartmentID: compartmentID,
+		SystemType:    ContainerType,
+	}
+	response := &EndpointResquestResponse{}
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// ContainerDetach detaches an endpoint from container
+func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
+	operation := "ContainerDetach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	requestMessage := &EndpointAttachDetachRequest{
+		ContainerID: containerID,
+		SystemType:  ContainerType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// HostAttach attaches a nic on the host
+func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
+	operation := "HostAttach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	requestMessage := &EndpointAttachDetachRequest{
+		CompartmentID: compartmentID,
+		SystemType:    HostType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+
+}
+
+// HostDetach detaches a nic on the host
+func (endpoint *HNSEndpoint) HostDetach() error {
+	operation := "HostDetach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	requestMessage := &EndpointAttachDetachRequest{
+		SystemType: HostType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// VirtualMachineNICAttach attaches a endpoint to a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
+	operation := "VirtualMachineNicAttach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	requestMessage := &EndpointAttachDetachRequest{
+		VirtualNICName: virtualMachineNICName,
+		SystemType:     VirtualMachineType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// VirtualMachineNICDetach detaches a endpoint  from a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
+	operation := "VirtualMachineNicDetach"
+	title := "HCSShim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	requestMessage := &EndpointAttachDetachRequest{
+		SystemType: VirtualMachineType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
index 04c1b59..398583a 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
@@ -1,141 +1,141 @@
-package hcsshim

-

-import (

-	"encoding/json"

-	"net"

-

-	"github.com/sirupsen/logrus"

-)

-

-// 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"`

-	Policies       []json.RawMessage `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:"ID,omitempty"`

-	Name                 string            `json:",omitempty"`

-	Type                 string            `json:",omitempty"`

-	NetworkAdapterName   string            `json:",omitempty"`

-	SourceMac            string            `json:",omitempty"`

-	Policies             []json.RawMessage `json:",omitempty"`

-	MacPools             []MacPool         `json:",omitempty"`

-	Subnets              []Subnet          `json:",omitempty"`

-	DNSSuffix            string            `json:",omitempty"`

-	DNSServerList        string            `json:",omitempty"`

-	DNSServerCompartment uint32            `json:",omitempty"`

-	ManagementIP         string            `json:",omitempty"`

-	AutomaticDNS         bool              `json:",omitempty"`

-}

-

-type hnsNetworkResponse struct {

-	Success bool

-	Error   string

-	Output  HNSNetwork

-}

-

-type hnsResponse struct {

-	Success bool

-	Error   string

-	Output  json.RawMessage

-}

-

-// 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

-}

-

-// GetHNSNetworkByID

-func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {

-	return HNSNetworkRequest("GET", networkID, "")

-}

-

-// GetHNSNetworkName filtered by Name

-func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {

-	hsnnetworks, err := HNSListNetworkRequest("GET", "", "")

-	if err != nil {

-		return nil, err

-	}

-	for _, hnsnetwork := range hsnnetworks {

-		if hnsnetwork.Name == networkName {

-			return &hnsnetwork, nil

-		}

-	}

-	return nil, NetworkNotFoundError{NetworkName: networkName}

-}

-

-// Create Network by sending NetworkRequest to HNS.

-func (network *HNSNetwork) Create() (*HNSNetwork, error) {

-	operation := "Create"

-	title := "HCSShim::HNSNetwork::" + operation

-	logrus.Debugf(title+" id=%s", network.Id)

-

-	jsonString, err := json.Marshal(network)

-	if err != nil {

-		return nil, err

-	}

-	return HNSNetworkRequest("POST", "", string(jsonString))

-}

-

-// Delete Network by sending NetworkRequest to HNS

-func (network *HNSNetwork) Delete() (*HNSNetwork, error) {

-	operation := "Delete"

-	title := "HCSShim::HNSNetwork::" + operation

-	logrus.Debugf(title+" id=%s", network.Id)

-

-	return HNSNetworkRequest("DELETE", network.Id, "")

-}

-

-// Creates an endpoint on the Network.

-func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {

-	return &HNSEndpoint{

-		VirtualNetwork: network.Id,

-		IPAddress:      ipAddress,

-		MacAddress:     string(macAddress),

-	}

-}

-

-func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {

-	operation := "CreateEndpoint"

-	title := "HCSShim::HNSNetwork::" + operation

-	logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)

-

-	endpoint.VirtualNetwork = network.Id

-	return endpoint.Create()

-}

-

-func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {

-	operation := "CreateRemoteEndpoint"

-	title := "HCSShim::HNSNetwork::" + operation

-	logrus.Debugf(title+" id=%s", network.Id)

-	endpoint.IsRemoteEndpoint = true

-	return network.CreateEndpoint(endpoint)

-}

+package hcsshim
+
+import (
+	"encoding/json"
+	"net"
+
+	"github.com/sirupsen/logrus"
+)
+
+// 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"`
+	Policies       []json.RawMessage `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:"ID,omitempty"`
+	Name                 string            `json:",omitempty"`
+	Type                 string            `json:",omitempty"`
+	NetworkAdapterName   string            `json:",omitempty"`
+	SourceMac            string            `json:",omitempty"`
+	Policies             []json.RawMessage `json:",omitempty"`
+	MacPools             []MacPool         `json:",omitempty"`
+	Subnets              []Subnet          `json:",omitempty"`
+	DNSSuffix            string            `json:",omitempty"`
+	DNSServerList        string            `json:",omitempty"`
+	DNSServerCompartment uint32            `json:",omitempty"`
+	ManagementIP         string            `json:",omitempty"`
+	AutomaticDNS         bool              `json:",omitempty"`
+}
+
+type hnsNetworkResponse struct {
+	Success bool
+	Error   string
+	Output  HNSNetwork
+}
+
+type hnsResponse struct {
+	Success bool
+	Error   string
+	Output  json.RawMessage
+}
+
+// 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
+}
+
+// GetHNSNetworkByID
+func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
+	return HNSNetworkRequest("GET", networkID, "")
+}
+
+// GetHNSNetworkName filtered by Name
+func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
+	hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
+	if err != nil {
+		return nil, err
+	}
+	for _, hnsnetwork := range hsnnetworks {
+		if hnsnetwork.Name == networkName {
+			return &hnsnetwork, nil
+		}
+	}
+	return nil, NetworkNotFoundError{NetworkName: networkName}
+}
+
+// Create Network by sending NetworkRequest to HNS.
+func (network *HNSNetwork) Create() (*HNSNetwork, error) {
+	operation := "Create"
+	title := "HCSShim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s", network.Id)
+
+	jsonString, err := json.Marshal(network)
+	if err != nil {
+		return nil, err
+	}
+	return HNSNetworkRequest("POST", "", string(jsonString))
+}
+
+// Delete Network by sending NetworkRequest to HNS
+func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
+	operation := "Delete"
+	title := "HCSShim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s", network.Id)
+
+	return HNSNetworkRequest("DELETE", network.Id, "")
+}
+
+// Creates an endpoint on the Network.
+func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
+	return &HNSEndpoint{
+		VirtualNetwork: network.Id,
+		IPAddress:      ipAddress,
+		MacAddress:     string(macAddress),
+	}
+}
+
+func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+	operation := "CreateEndpoint"
+	title := "HCSShim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
+
+	endpoint.VirtualNetwork = network.Id
+	return endpoint.Create()
+}
+
+func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+	operation := "CreateRemoteEndpoint"
+	title := "HCSShim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s", network.Id)
+	endpoint.IsRemoteEndpoint = true
+	return network.CreateEndpoint(endpoint)
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicy.go b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
index 65b8e93..bf860e9 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
@@ -1,94 +1,94 @@
-package hcsshim

-

-// Type of Request Support in ModifySystem

-type PolicyType string

-

-// RequestType const

-const (

-	Nat                  PolicyType = "NAT"

-	ACL                  PolicyType = "ACL"

-	PA                   PolicyType = "PA"

-	VLAN                 PolicyType = "VLAN"

-	VSID                 PolicyType = "VSID"

-	VNet                 PolicyType = "VNET"

-	L2Driver             PolicyType = "L2Driver"

-	Isolation            PolicyType = "Isolation"

-	QOS                  PolicyType = "QOS"

-	OutboundNat          PolicyType = "OutBoundNAT"

-	ExternalLoadBalancer PolicyType = "ELB"

-	Route                PolicyType = "ROUTE"

-)

-

-type NatPolicy struct {

-	Type         PolicyType `json:"Type"`

-	Protocol     string

-	InternalPort uint16

-	ExternalPort uint16

-}

-

-type QosPolicy struct {

-	Type                            PolicyType `json:"Type"`

-	MaximumOutgoingBandwidthInBytes uint64

-}

-

-type IsolationPolicy struct {

-	Type               PolicyType `json:"Type"`

-	VLAN               uint

-	VSID               uint

-	InDefaultIsolation bool

-}

-

-type VlanPolicy struct {

-	Type PolicyType `json:"Type"`

-	VLAN uint

-}

-

-type VsidPolicy struct {

-	Type PolicyType `json:"Type"`

-	VSID uint

-}

-

-type PaPolicy struct {

-	Type PolicyType `json:"Type"`

-	PA   string     `json:"PA"`

-}

-

-type OutboundNatPolicy struct {

-	Policy

-	VIP        string   `json:"VIP,omitempty"`

-	Exceptions []string `json:"ExceptionList,omitempty"`

-}

-

-type ActionType string

-type DirectionType string

-type RuleType string

-

-const (

-	Allow ActionType = "Allow"

-	Block ActionType = "Block"

-

-	In  DirectionType = "In"

-	Out DirectionType = "Out"

-

-	Host   RuleType = "Host"

-	Switch RuleType = "Switch"

-)

-

-type ACLPolicy struct {

-	Type            PolicyType `json:"Type"`

-	Protocol        uint16

-	InternalPort    uint16

-	Action          ActionType

-	Direction       DirectionType

-	LocalAddresses  string

-	RemoteAddresses string

-	LocalPort       uint16

-	RemotePort      uint16

-	RuleType        RuleType `json:"RuleType,omitempty"`

-	Priority        uint16

-	ServiceName     string

-}

-

-type Policy struct {

-	Type PolicyType `json:"Type"`

-}

+package hcsshim
+
+// Type of Request Support in ModifySystem
+type PolicyType string
+
+// RequestType const
+const (
+	Nat                  PolicyType = "NAT"
+	ACL                  PolicyType = "ACL"
+	PA                   PolicyType = "PA"
+	VLAN                 PolicyType = "VLAN"
+	VSID                 PolicyType = "VSID"
+	VNet                 PolicyType = "VNET"
+	L2Driver             PolicyType = "L2Driver"
+	Isolation            PolicyType = "Isolation"
+	QOS                  PolicyType = "QOS"
+	OutboundNat          PolicyType = "OutBoundNAT"
+	ExternalLoadBalancer PolicyType = "ELB"
+	Route                PolicyType = "ROUTE"
+)
+
+type NatPolicy struct {
+	Type         PolicyType `json:"Type"`
+	Protocol     string
+	InternalPort uint16
+	ExternalPort uint16
+}
+
+type QosPolicy struct {
+	Type                            PolicyType `json:"Type"`
+	MaximumOutgoingBandwidthInBytes uint64
+}
+
+type IsolationPolicy struct {
+	Type               PolicyType `json:"Type"`
+	VLAN               uint
+	VSID               uint
+	InDefaultIsolation bool
+}
+
+type VlanPolicy struct {
+	Type PolicyType `json:"Type"`
+	VLAN uint
+}
+
+type VsidPolicy struct {
+	Type PolicyType `json:"Type"`
+	VSID uint
+}
+
+type PaPolicy struct {
+	Type PolicyType `json:"Type"`
+	PA   string     `json:"PA"`
+}
+
+type OutboundNatPolicy struct {
+	Policy
+	VIP        string   `json:"VIP,omitempty"`
+	Exceptions []string `json:"ExceptionList,omitempty"`
+}
+
+type ActionType string
+type DirectionType string
+type RuleType string
+
+const (
+	Allow ActionType = "Allow"
+	Block ActionType = "Block"
+
+	In  DirectionType = "In"
+	Out DirectionType = "Out"
+
+	Host   RuleType = "Host"
+	Switch RuleType = "Switch"
+)
+
+type ACLPolicy struct {
+	Type            PolicyType `json:"Type"`
+	Protocol        uint16
+	InternalPort    uint16
+	Action          ActionType
+	Direction       DirectionType
+	LocalAddresses  string
+	RemoteAddresses string
+	LocalPort       uint16
+	RemotePort      uint16
+	RuleType        RuleType `json:"RuleType,omitempty"`
+	Priority        uint16
+	ServiceName     string
+}
+
+type Policy struct {
+	Type PolicyType `json:"Type"`
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
index bbd7e1e..ef1ccab 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
@@ -1,200 +1,200 @@
-package hcsshim

-

-import (

-	"encoding/json"

-

-	"github.com/sirupsen/logrus"

-)

-

-// RoutePolicy is a structure defining schema for Route based Policy

-type RoutePolicy struct {

-	Policy

-	DestinationPrefix string `json:"DestinationPrefix,omitempty"`

-	NextHop           string `json:"NextHop,omitempty"`

-	EncapEnabled      bool   `json:"NeedEncap,omitempty"`

-}

-

-// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy

-type ELBPolicy struct {

-	LBPolicy

-	SourceVIP string   `json:"SourceVIP,omitempty"`

-	VIPs      []string `json:"VIPs,omitempty"`

-	ILB       bool     `json:"ILB,omitempty"`

-}

-

-// LBPolicy is a structure defining schema for LoadBalancing based Policy

-type LBPolicy struct {

-	Policy

-	Protocol     uint16 `json:"Protocol,omitempty"`

-	InternalPort uint16

-	ExternalPort uint16

-}

-

-// PolicyList is a structure defining schema for Policy list request

-type PolicyList struct {

-	ID                 string            `json:"ID,omitempty"`

-	EndpointReferences []string          `json:"References,omitempty"`

-	Policies           []json.RawMessage `json:"Policies,omitempty"`

-}

-

-// HNSPolicyListRequest makes a call into HNS to update/query a single network

-func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {

-	var policy PolicyList

-	err := hnsCall(method, "/policylists/"+path, request, &policy)

-	if err != nil {

-		return nil, err

-	}

-

-	return &policy, nil

-}

-

-// HNSListPolicyListRequest gets all the policy list

-func HNSListPolicyListRequest() ([]PolicyList, error) {

-	var plist []PolicyList

-	err := hnsCall("GET", "/policylists/", "", &plist)

-	if err != nil {

-		return nil, err

-	}

-

-	return plist, nil

-}

-

-// PolicyListRequest makes a HNS call to modify/query a network policy list

-func PolicyListRequest(method, path, request string) (*PolicyList, error) {

-	policylist := &PolicyList{}

-	err := hnsCall(method, "/policylists/"+path, request, &policylist)

-	if err != nil {

-		return nil, err

-	}

-

-	return policylist, nil

-}

-

-// GetPolicyListByID get the policy list by ID

-func GetPolicyListByID(policyListID string) (*PolicyList, error) {

-	return PolicyListRequest("GET", policyListID, "")

-}

-

-// Create PolicyList by sending PolicyListRequest to HNS.

-func (policylist *PolicyList) Create() (*PolicyList, error) {

-	operation := "Create"

-	title := "HCSShim::PolicyList::" + operation

-	logrus.Debugf(title+" id=%s", policylist.ID)

-	jsonString, err := json.Marshal(policylist)

-	if err != nil {

-		return nil, err

-	}

-	return PolicyListRequest("POST", "", string(jsonString))

-}

-

-// Delete deletes PolicyList

-func (policylist *PolicyList) Delete() (*PolicyList, error) {

-	operation := "Delete"

-	title := "HCSShim::PolicyList::" + operation

-	logrus.Debugf(title+" id=%s", policylist.ID)

-

-	return PolicyListRequest("DELETE", policylist.ID, "")

-}

-

-// AddEndpoint add an endpoint to a Policy List

-func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {

-	operation := "AddEndpoint"

-	title := "HCSShim::PolicyList::" + operation

-	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)

-

-	_, err := policylist.Delete()

-	if err != nil {

-		return nil, err

-	}

-

-	// Add Endpoint to the Existing List

-	policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)

-

-	return policylist.Create()

-}

-

-// RemoveEndpoint removes an endpoint from the Policy List

-func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {

-	operation := "RemoveEndpoint"

-	title := "HCSShim::PolicyList::" + operation

-	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)

-

-	_, err := policylist.Delete()

-	if err != nil {

-		return nil, err

-	}

-

-	elementToRemove := "/endpoints/" + endpoint.Id

-

-	var references []string

-

-	for _, endpointReference := range policylist.EndpointReferences {

-		if endpointReference == elementToRemove {

-			continue

-		}

-		references = append(references, endpointReference)

-	}

-	policylist.EndpointReferences = references

-	return policylist.Create()

-}

-

-// AddLoadBalancer policy list for the specified endpoints

-func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {

-	operation := "AddLoadBalancer"

-	title := "HCSShim::PolicyList::" + operation

-	logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)

-

-	policylist := &PolicyList{}

-

-	elbPolicy := &ELBPolicy{

-		SourceVIP: sourceVIP,

-		ILB:       isILB,

-	}

-

-	if len(vip) > 0 {

-		elbPolicy.VIPs = []string{vip}

-	}

-	elbPolicy.Type = ExternalLoadBalancer

-	elbPolicy.Protocol = protocol

-	elbPolicy.InternalPort = internalPort

-	elbPolicy.ExternalPort = externalPort

-

-	for _, endpoint := range endpoints {

-		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)

-	}

-

-	jsonString, err := json.Marshal(elbPolicy)

-	if err != nil {

-		return nil, err

-	}

-	policylist.Policies = append(policylist.Policies, jsonString)

-	return policylist.Create()

-}

-

-// AddRoute adds route policy list for the specified endpoints

-func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {

-	operation := "AddRoute"

-	title := "HCSShim::PolicyList::" + operation

-	logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)

-

-	policylist := &PolicyList{}

-

-	rPolicy := &RoutePolicy{

-		DestinationPrefix: destinationPrefix,

-		NextHop:           nextHop,

-		EncapEnabled:      encapEnabled,

-	}

-	rPolicy.Type = Route

-

-	for _, endpoint := range endpoints {

-		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)

-	}

-

-	jsonString, err := json.Marshal(rPolicy)

-	if err != nil {

-		return nil, err

-	}

-

-	policylist.Policies = append(policylist.Policies, jsonString)

-	return policylist.Create()

-}

+package hcsshim
+
+import (
+	"encoding/json"
+
+	"github.com/sirupsen/logrus"
+)
+
+// RoutePolicy is a structure defining schema for Route based Policy
+type RoutePolicy struct {
+	Policy
+	DestinationPrefix string `json:"DestinationPrefix,omitempty"`
+	NextHop           string `json:"NextHop,omitempty"`
+	EncapEnabled      bool   `json:"NeedEncap,omitempty"`
+}
+
+// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy
+type ELBPolicy struct {
+	LBPolicy
+	SourceVIP string   `json:"SourceVIP,omitempty"`
+	VIPs      []string `json:"VIPs,omitempty"`
+	ILB       bool     `json:"ILB,omitempty"`
+}
+
+// LBPolicy is a structure defining schema for LoadBalancing based Policy
+type LBPolicy struct {
+	Policy
+	Protocol     uint16 `json:"Protocol,omitempty"`
+	InternalPort uint16
+	ExternalPort uint16
+}
+
+// PolicyList is a structure defining schema for Policy list request
+type PolicyList struct {
+	ID                 string            `json:"ID,omitempty"`
+	EndpointReferences []string          `json:"References,omitempty"`
+	Policies           []json.RawMessage `json:"Policies,omitempty"`
+}
+
+// HNSPolicyListRequest makes a call into HNS to update/query a single network
+func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
+	var policy PolicyList
+	err := hnsCall(method, "/policylists/"+path, request, &policy)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
+
+// HNSListPolicyListRequest gets all the policy list
+func HNSListPolicyListRequest() ([]PolicyList, error) {
+	var plist []PolicyList
+	err := hnsCall("GET", "/policylists/", "", &plist)
+	if err != nil {
+		return nil, err
+	}
+
+	return plist, nil
+}
+
+// PolicyListRequest makes a HNS call to modify/query a network policy list
+func PolicyListRequest(method, path, request string) (*PolicyList, error) {
+	policylist := &PolicyList{}
+	err := hnsCall(method, "/policylists/"+path, request, &policylist)
+	if err != nil {
+		return nil, err
+	}
+
+	return policylist, nil
+}
+
+// GetPolicyListByID get the policy list by ID
+func GetPolicyListByID(policyListID string) (*PolicyList, error) {
+	return PolicyListRequest("GET", policyListID, "")
+}
+
+// Create PolicyList by sending PolicyListRequest to HNS.
+func (policylist *PolicyList) Create() (*PolicyList, error) {
+	operation := "Create"
+	title := "HCSShim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s", policylist.ID)
+	jsonString, err := json.Marshal(policylist)
+	if err != nil {
+		return nil, err
+	}
+	return PolicyListRequest("POST", "", string(jsonString))
+}
+
+// Delete deletes PolicyList
+func (policylist *PolicyList) Delete() (*PolicyList, error) {
+	operation := "Delete"
+	title := "HCSShim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s", policylist.ID)
+
+	return PolicyListRequest("DELETE", policylist.ID, "")
+}
+
+// AddEndpoint add an endpoint to a Policy List
+func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+	operation := "AddEndpoint"
+	title := "HCSShim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+	_, err := policylist.Delete()
+	if err != nil {
+		return nil, err
+	}
+
+	// Add Endpoint to the Existing List
+	policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+
+	return policylist.Create()
+}
+
+// RemoveEndpoint removes an endpoint from the Policy List
+func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+	operation := "RemoveEndpoint"
+	title := "HCSShim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+	_, err := policylist.Delete()
+	if err != nil {
+		return nil, err
+	}
+
+	elementToRemove := "/endpoints/" + endpoint.Id
+
+	var references []string
+
+	for _, endpointReference := range policylist.EndpointReferences {
+		if endpointReference == elementToRemove {
+			continue
+		}
+		references = append(references, endpointReference)
+	}
+	policylist.EndpointReferences = references
+	return policylist.Create()
+}
+
+// AddLoadBalancer policy list for the specified endpoints
+func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
+	operation := "AddLoadBalancer"
+	title := "HCSShim::PolicyList::" + operation
+	logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
+
+	policylist := &PolicyList{}
+
+	elbPolicy := &ELBPolicy{
+		SourceVIP: sourceVIP,
+		ILB:       isILB,
+	}
+
+	if len(vip) > 0 {
+		elbPolicy.VIPs = []string{vip}
+	}
+	elbPolicy.Type = ExternalLoadBalancer
+	elbPolicy.Protocol = protocol
+	elbPolicy.InternalPort = internalPort
+	elbPolicy.ExternalPort = externalPort
+
+	for _, endpoint := range endpoints {
+		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+	}
+
+	jsonString, err := json.Marshal(elbPolicy)
+	if err != nil {
+		return nil, err
+	}
+	policylist.Policies = append(policylist.Policies, jsonString)
+	return policylist.Create()
+}
+
+// AddRoute adds route policy list for the specified endpoints
+func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
+	operation := "AddRoute"
+	title := "HCSShim::PolicyList::" + operation
+	logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)
+
+	policylist := &PolicyList{}
+
+	rPolicy := &RoutePolicy{
+		DestinationPrefix: destinationPrefix,
+		NextHop:           nextHop,
+		EncapEnabled:      encapEnabled,
+	}
+	rPolicy.Type = Route
+
+	for _, endpoint := range endpoints {
+		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+	}
+
+	jsonString, err := json.Marshal(rPolicy)
+	if err != nil {
+		return nil, err
+	}
+
+	policylist.Policies = append(policylist.Policies, jsonString)
+	return policylist.Create()
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/importlayer.go b/vendor/github.com/Microsoft/hcsshim/importlayer.go
index 3aed143..2742b9f 100644
--- a/vendor/github.com/Microsoft/hcsshim/importlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/importlayer.go
@@ -129,37 +129,39 @@
 }
 
 func (r *legacyLayerWriterWrapper) Close() error {
-	defer os.RemoveAll(r.root)
+	defer os.RemoveAll(r.root.Name())
+	defer r.legacyLayerWriter.CloseRoots()
 	err := r.legacyLayerWriter.Close()
 	if err != nil {
 		return err
 	}
 
-	// Use the original path here because ImportLayer does not support long paths for the source in TP5.
-	// But do use a long path for the destination to work around another bug with directories
-	// with MAX_PATH - 12 < length < MAX_PATH.
 	info := r.info
-	fullPath, err := makeLongAbsPath(filepath.Join(info.HomeDir, r.layerID))
-	if err != nil {
+	info.HomeDir = ""
+	if err = ImportLayer(info, r.destRoot.Name(), r.path, r.parentLayerPaths); err != nil {
 		return err
 	}
-
-	info.HomeDir = ""
-	if err = ImportLayer(info, fullPath, r.path, r.parentLayerPaths); err != nil {
-		return err
+	for _, name := range r.Tombstones {
+		if err = removeRelative(name, r.destRoot); err != nil && !os.IsNotExist(err) {
+			return err
+		}
 	}
 	// Add any hard links that were collected.
 	for _, lnk := range r.PendingLinks {
-		if err = os.Remove(lnk.Path); err != nil && !os.IsNotExist(err) {
+		if err = removeRelative(lnk.Path, r.destRoot); err != nil && !os.IsNotExist(err) {
 			return err
 		}
-		if err = os.Link(lnk.Target, lnk.Path); err != nil {
+		if err = linkRelative(lnk.Target, lnk.TargetRoot, lnk.Path, r.destRoot); err != nil {
 			return err
 		}
 	}
 	// Prepare the utility VM for use if one is present in the layer.
 	if r.HasUtilityVM {
-		err = ProcessUtilityVMImage(filepath.Join(fullPath, "UtilityVM"))
+		err := ensureNotReparsePointRelative("UtilityVM", r.destRoot)
+		if err != nil {
+			return err
+		}
+		err = ProcessUtilityVMImage(filepath.Join(r.destRoot.Name(), "UtilityVM"))
 		if err != nil {
 			return err
 		}
@@ -173,8 +175,12 @@
 func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string) (LayerWriter, error) {
 	if len(parentLayerPaths) == 0 {
 		// This is a base layer. It gets imported differently.
+		f, err := openRoot(filepath.Join(info.HomeDir, layerID))
+		if err != nil {
+			return nil, err
+		}
 		return &baseLayerWriter{
-			root: filepath.Join(info.HomeDir, layerID),
+			root: f,
 		}, nil
 	}
 
@@ -185,8 +191,12 @@
 		if err != nil {
 			return nil, err
 		}
+		w, err := newLegacyLayerWriter(path, parentLayerPaths, filepath.Join(info.HomeDir, layerID))
+		if err != nil {
+			return nil, err
+		}
 		return &legacyLayerWriterWrapper{
-			legacyLayerWriter: newLegacyLayerWriter(path, parentLayerPaths, filepath.Join(info.HomeDir, layerID)),
+			legacyLayerWriter: w,
 			info:              info,
 			layerID:           layerID,
 			path:              path,
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy.go b/vendor/github.com/Microsoft/hcsshim/legacy.go
index 673a4f8..85c7791 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy.go
@@ -336,59 +336,79 @@
 
 type pendingLink struct {
 	Path, Target string
+	TargetRoot   *os.File
+}
+
+type pendingDir struct {
+	Path string
+	Root *os.File
 }
 
 type legacyLayerWriter struct {
-	root         string
-	parentRoots  []string
-	destRoot     string
-	currentFile  *os.File
-	backupWriter *winio.BackupFileWriter
-	tombstones   []string
-	pathFixed    bool
-	HasUtilityVM bool
-	uvmDi        []dirInfo
-	addedFiles   map[string]bool
-	PendingLinks []pendingLink
+	root            *os.File
+	destRoot        *os.File
+	parentRoots     []*os.File
+	currentFile     *os.File
+	currentFileName string
+	currentFileRoot *os.File
+	backupWriter    *winio.BackupFileWriter
+	Tombstones      []string
+	HasUtilityVM    bool
+	uvmDi           []dirInfo
+	addedFiles      map[string]bool
+	PendingLinks    []pendingLink
+	pendingDirs     []pendingDir
+	currentIsDir    bool
 }
 
 // newLegacyLayerWriter returns a LayerWriter that can write the contaler layer
 // transport format to disk.
-func newLegacyLayerWriter(root string, parentRoots []string, destRoot string) *legacyLayerWriter {
-	return &legacyLayerWriter{
-		root:        root,
-		parentRoots: parentRoots,
-		destRoot:    destRoot,
-		addedFiles:  make(map[string]bool),
+func newLegacyLayerWriter(root string, parentRoots []string, destRoot string) (w *legacyLayerWriter, err error) {
+	w = &legacyLayerWriter{
+		addedFiles: make(map[string]bool),
 	}
+	defer func() {
+		if err != nil {
+			w.CloseRoots()
+			w = nil
+		}
+	}()
+	w.root, err = openRoot(root)
+	if err != nil {
+		return
+	}
+	w.destRoot, err = openRoot(destRoot)
+	if err != nil {
+		return
+	}
+	for _, r := range parentRoots {
+		f, err := openRoot(r)
+		if err != nil {
+			return w, err
+		}
+		w.parentRoots = append(w.parentRoots, f)
+	}
+	return
 }
 
-func (w *legacyLayerWriter) init() error {
-	if !w.pathFixed {
-		path, err := makeLongAbsPath(w.root)
-		if err != nil {
-			return err
-		}
-		for i, p := range w.parentRoots {
-			w.parentRoots[i], err = makeLongAbsPath(p)
-			if err != nil {
-				return err
-			}
-		}
-		destPath, err := makeLongAbsPath(w.destRoot)
-		if err != nil {
-			return err
-		}
-		w.root = path
-		w.destRoot = destPath
-		w.pathFixed = true
+func (w *legacyLayerWriter) CloseRoots() {
+	if w.root != nil {
+		w.root.Close()
+		w.root = nil
 	}
-	return nil
+	if w.destRoot != nil {
+		w.destRoot.Close()
+		w.destRoot = nil
+	}
+	for i := range w.parentRoots {
+		w.parentRoots[i].Close()
+	}
+	w.parentRoots = nil
 }
 
 func (w *legacyLayerWriter) initUtilityVM() error {
 	if !w.HasUtilityVM {
-		err := os.Mkdir(filepath.Join(w.destRoot, utilityVMPath), 0)
+		err := mkdirRelative(utilityVMPath, w.destRoot)
 		if err != nil {
 			return err
 		}
@@ -396,7 +416,7 @@
 		// clone the utility VM from the parent layer into this layer. Use hard
 		// links to avoid unnecessary copying, since most of the files are
 		// immutable.
-		err = cloneTree(filepath.Join(w.parentRoots[0], utilityVMFilesPath), filepath.Join(w.destRoot, utilityVMFilesPath), mutatedUtilityVMFiles)
+		err = cloneTree(w.parentRoots[0], w.destRoot, utilityVMFilesPath, mutatedUtilityVMFiles)
 		if err != nil {
 			return fmt.Errorf("cloning the parent utility VM image failed: %s", err)
 		}
@@ -405,7 +425,40 @@
 	return nil
 }
 
-func (w *legacyLayerWriter) reset() {
+func (w *legacyLayerWriter) reset() error {
+	if w.currentIsDir {
+		r := w.currentFile
+		br := winio.NewBackupStreamReader(r)
+		// Seek to the beginning of the backup stream, skipping the fileattrs
+		if _, err := r.Seek(4, io.SeekStart); err != nil {
+			return err
+		}
+
+		for {
+			bhdr, err := br.Next()
+			if err == io.EOF {
+				// end of backupstream data
+				break
+			}
+			if err != nil {
+				return err
+			}
+			switch bhdr.Id {
+			case winio.BackupReparseData:
+				// The current file is a `.$wcidirs$` metadata file that
+				// describes a directory reparse point. Delete the placeholder
+				// directory to prevent future files being added into the
+				// destination of the reparse point during the ImportLayer call
+				if err := removeRelative(w.currentFileName, w.currentFileRoot); err != nil {
+					return err
+				}
+				w.pendingDirs = append(w.pendingDirs, pendingDir{Path: w.currentFileName, Root: w.currentFileRoot})
+			default:
+				// ignore all other stream types, as we only care about directory reparse points
+			}
+		}
+		w.currentIsDir = false
+	}
 	if w.backupWriter != nil {
 		w.backupWriter.Close()
 		w.backupWriter = nil
@@ -413,21 +466,21 @@
 	if w.currentFile != nil {
 		w.currentFile.Close()
 		w.currentFile = nil
+		w.currentFileName = ""
+		w.currentFileRoot = nil
 	}
+	return nil
 }
 
 // copyFileWithMetadata copies a file using the backup/restore APIs in order to preserve metadata
-func copyFileWithMetadata(srcPath, destPath string, isDir bool) (fileInfo *winio.FileBasicInfo, err error) {
-	createDisposition := uint32(syscall.CREATE_NEW)
-	if isDir {
-		err = os.Mkdir(destPath, 0)
-		if err != nil {
-			return nil, err
-		}
-		createDisposition = syscall.OPEN_EXISTING
-	}
-
-	src, err := openFileOrDir(srcPath, syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY, syscall.OPEN_EXISTING)
+func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool) (fileInfo *winio.FileBasicInfo, err error) {
+	src, err := openRelative(
+		subPath,
+		srcRoot,
+		syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY,
+		syscall.FILE_SHARE_READ,
+		_FILE_OPEN,
+		_FILE_OPEN_REPARSE_POINT)
 	if err != nil {
 		return nil, err
 	}
@@ -440,7 +493,17 @@
 		return nil, err
 	}
 
-	dest, err := openFileOrDir(destPath, syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY, createDisposition)
+	extraFlags := uint32(0)
+	if isDir {
+		extraFlags |= _FILE_DIRECTORY_FILE
+	}
+	dest, err := openRelative(
+		subPath,
+		destRoot,
+		syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
+		syscall.FILE_SHARE_READ,
+		_FILE_CREATE,
+		extraFlags)
 	if err != nil {
 		return nil, err
 	}
@@ -469,18 +532,21 @@
 
 // cloneTree clones a directory tree using hard links. It skips hard links for
 // the file names in the provided map and just copies those files.
-func cloneTree(srcPath, destPath string, mutatedFiles map[string]bool) error {
+func cloneTree(srcRoot *os.File, destRoot *os.File, subPath string, mutatedFiles map[string]bool) error {
 	var di []dirInfo
-	err := filepath.Walk(srcPath, func(srcFilePath string, info os.FileInfo, err error) error {
+	err := ensureNotReparsePointRelative(subPath, srcRoot)
+	if err != nil {
+		return err
+	}
+	err = filepath.Walk(filepath.Join(srcRoot.Name(), subPath), func(srcFilePath string, info os.FileInfo, err error) error {
 		if err != nil {
 			return err
 		}
 
-		relPath, err := filepath.Rel(srcPath, srcFilePath)
+		relPath, err := filepath.Rel(srcRoot.Name(), srcFilePath)
 		if err != nil {
 			return err
 		}
-		destFilePath := filepath.Join(destPath, relPath)
 
 		fileAttributes := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 		// Directories, reparse points, and files that will be mutated during
@@ -492,15 +558,15 @@
 		isDir := fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0
 
 		if isDir || isReparsePoint || mutatedFiles[relPath] {
-			fi, err := copyFileWithMetadata(srcFilePath, destFilePath, isDir)
+			fi, err := copyFileWithMetadata(srcRoot, destRoot, relPath, isDir)
 			if err != nil {
 				return err
 			}
 			if isDir && !isReparsePoint {
-				di = append(di, dirInfo{path: destFilePath, fileInfo: *fi})
+				di = append(di, dirInfo{path: relPath, fileInfo: *fi})
 			}
 		} else {
-			err = os.Link(srcFilePath, destFilePath)
+			err = linkRelative(relPath, srcRoot, relPath, destRoot)
 			if err != nil {
 				return err
 			}
@@ -518,13 +584,11 @@
 		return err
 	}
 
-	return reapplyDirectoryTimes(di)
+	return reapplyDirectoryTimes(destRoot, di)
 }
 
 func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) error {
-	w.reset()
-	err := w.init()
-	if err != nil {
+	if err := w.reset(); err != nil {
 		return err
 	}
 
@@ -532,6 +596,7 @@
 		return w.initUtilityVM()
 	}
 
+	name = filepath.Clean(name)
 	if hasPathPrefix(name, utilityVMPath) {
 		if !w.HasUtilityVM {
 			return errors.New("missing UtilityVM directory")
@@ -539,10 +604,9 @@
 		if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
 			return errors.New("invalid UtilityVM layer")
 		}
-		path := filepath.Join(w.destRoot, name)
-		createDisposition := uint32(syscall.OPEN_EXISTING)
+		createDisposition := uint32(_FILE_OPEN)
 		if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
-			st, err := os.Lstat(path)
+			st, err := lstatRelative(name, w.destRoot)
 			if err != nil && !os.IsNotExist(err) {
 				return err
 			}
@@ -550,37 +614,44 @@
 				// Delete the existing file/directory if it is not the same type as this directory.
 				existingAttr := st.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 				if (uint32(fileInfo.FileAttributes)^existingAttr)&(syscall.FILE_ATTRIBUTE_DIRECTORY|syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
-					if err = os.RemoveAll(path); err != nil {
+					if err = removeAllRelative(name, w.destRoot); err != nil {
 						return err
 					}
 					st = nil
 				}
 			}
 			if st == nil {
-				if err = os.Mkdir(path, 0); err != nil {
+				if err = mkdirRelative(name, w.destRoot); err != nil {
 					return err
 				}
 			}
 			if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
-				w.uvmDi = append(w.uvmDi, dirInfo{path: path, fileInfo: *fileInfo})
+				w.uvmDi = append(w.uvmDi, dirInfo{path: name, fileInfo: *fileInfo})
 			}
 		} else {
 			// Overwrite any existing hard link.
-			err = os.Remove(path)
+			err := removeRelative(name, w.destRoot)
 			if err != nil && !os.IsNotExist(err) {
 				return err
 			}
-			createDisposition = syscall.CREATE_NEW
+			createDisposition = _FILE_CREATE
 		}
 
-		f, err := openFileOrDir(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY, createDisposition)
+		f, err := openRelative(
+			name,
+			w.destRoot,
+			syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
+			syscall.FILE_SHARE_READ,
+			createDisposition,
+			_FILE_OPEN_REPARSE_POINT,
+		)
 		if err != nil {
 			return err
 		}
 		defer func() {
 			if f != nil {
 				f.Close()
-				os.Remove(path)
+				removeRelative(name, w.destRoot)
 			}
 		}()
 
@@ -591,28 +662,31 @@
 
 		w.backupWriter = winio.NewBackupFileWriter(f, true)
 		w.currentFile = f
+		w.currentFileName = name
+		w.currentFileRoot = w.destRoot
 		w.addedFiles[name] = true
 		f = nil
 		return nil
 	}
 
-	path := filepath.Join(w.root, name)
+	fname := name
 	if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
-		err := os.Mkdir(path, 0)
+		err := mkdirRelative(name, w.root)
 		if err != nil {
 			return err
 		}
-		path += ".$wcidirs$"
+		fname += ".$wcidirs$"
+		w.currentIsDir = true
 	}
 
-	f, err := openFileOrDir(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.CREATE_NEW)
+	f, err := openRelative(fname, w.root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, _FILE_CREATE, 0)
 	if err != nil {
 		return err
 	}
 	defer func() {
 		if f != nil {
 			f.Close()
-			os.Remove(path)
+			removeRelative(fname, w.root)
 		}
 	}()
 
@@ -634,19 +708,20 @@
 	}
 
 	w.currentFile = f
+	w.currentFileName = name
+	w.currentFileRoot = w.root
 	w.addedFiles[name] = true
 	f = nil
 	return nil
 }
 
 func (w *legacyLayerWriter) AddLink(name string, target string) error {
-	w.reset()
-	err := w.init()
-	if err != nil {
+	if err := w.reset(); err != nil {
 		return err
 	}
 
-	var roots []string
+	target = filepath.Clean(target)
+	var roots []*os.File
 	if hasPathPrefix(target, filesPath) {
 		// Look for cross-layer hard link targets in the parent layers, since
 		// nothing is in the destination path yet.
@@ -655,7 +730,7 @@
 		// Since the utility VM is fully cloned into the destination path
 		// already, look for cross-layer hard link targets directly in the
 		// destination path.
-		roots = []string{w.destRoot}
+		roots = []*os.File{w.destRoot}
 	}
 
 	if roots == nil || (!hasPathPrefix(name, filesPath) && !hasPathPrefix(name, utilityVMFilesPath)) {
@@ -664,12 +739,12 @@
 
 	// Find to try the target of the link in a previously added file. If that
 	// fails, search in parent layers.
-	var selectedRoot string
+	var selectedRoot *os.File
 	if _, ok := w.addedFiles[target]; ok {
 		selectedRoot = w.destRoot
 	} else {
 		for _, r := range roots {
-			if _, err = os.Lstat(filepath.Join(r, target)); err != nil {
+			if _, err := lstatRelative(target, r); err != nil {
 				if !os.IsNotExist(err) {
 					return err
 				}
@@ -678,22 +753,25 @@
 				break
 			}
 		}
-		if selectedRoot == "" {
+		if selectedRoot == nil {
 			return fmt.Errorf("failed to find link target for '%s' -> '%s'", name, target)
 		}
 	}
+
 	// The link can't be written until after the ImportLayer call.
 	w.PendingLinks = append(w.PendingLinks, pendingLink{
-		Path:   filepath.Join(w.destRoot, name),
-		Target: filepath.Join(selectedRoot, target),
+		Path:       name,
+		Target:     target,
+		TargetRoot: selectedRoot,
 	})
 	w.addedFiles[name] = true
 	return nil
 }
 
 func (w *legacyLayerWriter) Remove(name string) error {
+	name = filepath.Clean(name)
 	if hasPathPrefix(name, filesPath) {
-		w.tombstones = append(w.tombstones, name[len(filesPath)+1:])
+		w.Tombstones = append(w.Tombstones, name)
 	} else if hasPathPrefix(name, utilityVMFilesPath) {
 		err := w.initUtilityVM()
 		if err != nil {
@@ -702,11 +780,10 @@
 		// Make sure the path exists; os.RemoveAll will not fail if the file is
 		// already gone, and this needs to be a fatal error for diagnostics
 		// purposes.
-		path := filepath.Join(w.destRoot, name)
-		if _, err := os.Lstat(path); err != nil {
+		if _, err := lstatRelative(name, w.destRoot); err != nil {
 			return err
 		}
-		err = os.RemoveAll(path)
+		err = removeAllRelative(name, w.destRoot)
 		if err != nil {
 			return err
 		}
@@ -728,28 +805,20 @@
 }
 
 func (w *legacyLayerWriter) Close() error {
-	w.reset()
-	err := w.init()
-	if err != nil {
+	if err := w.reset(); err != nil {
 		return err
 	}
-	tf, err := os.Create(filepath.Join(w.root, "tombstones.txt"))
-	if err != nil {
+	if err := removeRelative("tombstones.txt", w.root); err != nil && !os.IsNotExist(err) {
 		return err
 	}
-	defer tf.Close()
-	_, err = tf.Write([]byte("\xef\xbb\xbfVersion 1.0\n"))
-	if err != nil {
-		return err
-	}
-	for _, t := range w.tombstones {
-		_, err = tf.Write([]byte(filepath.Join(`\`, t) + "\n"))
+	for _, pd := range w.pendingDirs {
+		err := mkdirRelative(pd.Path, pd.Root)
 		if err != nil {
 			return err
 		}
 	}
 	if w.HasUtilityVM {
-		err = reapplyDirectoryTimes(w.uvmDi)
+		err := reapplyDirectoryTimes(w.destRoot, w.uvmDi)
 		if err != nil {
 			return err
 		}
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy18.go b/vendor/github.com/Microsoft/hcsshim/legacy18.go
index 578552f..0f593e8 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy18.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy18.go
@@ -1,7 +1,7 @@
-// +build !go1.9

-

-package hcsshim

-

-// Due to a bug in go1.8 and before, directory reparse points need to be skipped

-// during filepath.Walk. This is fixed in go1.9

-var shouldSkipDirectoryReparse = true

+// +build !go1.9
+
+package hcsshim
+
+// Due to a bug in go1.8 and before, directory reparse points need to be skipped
+// during filepath.Walk. This is fixed in go1.9
+var shouldSkipDirectoryReparse = true
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy19.go b/vendor/github.com/Microsoft/hcsshim/legacy19.go
index 6aa1dc0..fb0b764 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy19.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy19.go
@@ -1,7 +1,7 @@
-// +build go1.9

-

-package hcsshim

-

-// Due to a bug in go1.8 and before, directory reparse points need to be skipped

-// during filepath.Walk. This is fixed in go1.9

-var shouldSkipDirectoryReparse = false

+// +build go1.9
+
+package hcsshim
+
+// Due to a bug in go1.8 and before, directory reparse points need to be skipped
+// during filepath.Walk. This is fixed in go1.9
+var shouldSkipDirectoryReparse = false
diff --git a/vendor/github.com/Microsoft/hcsshim/safeopen.go b/vendor/github.com/Microsoft/hcsshim/safeopen.go
new file mode 100644
index 0000000..5356456
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/safeopen.go
@@ -0,0 +1,427 @@
+package hcsshim
+
+import (
+	"errors"
+	"io"
+	"os"
+	"path/filepath"
+	"strings"
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+
+	winio "github.com/Microsoft/go-winio"
+)
+
+//sys ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) = ntdll.NtCreateFile
+//sys ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) = ntdll.NtSetInformationFile
+//sys rtlNtStatusToDosError(status uint32) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
+//sys localAlloc(flags uint32, size int) (ptr uintptr) = kernel32.LocalAlloc
+//sys localFree(ptr uintptr) = kernel32.LocalFree
+
+type ioStatusBlock struct {
+	Status, Information uintptr
+}
+
+type objectAttributes struct {
+	Length             uintptr
+	RootDirectory      uintptr
+	ObjectName         uintptr
+	Attributes         uintptr
+	SecurityDescriptor uintptr
+	SecurityQoS        uintptr
+}
+
+type unicodeString struct {
+	Length        uint16
+	MaximumLength uint16
+	Buffer        uintptr
+}
+
+type fileLinkInformation struct {
+	ReplaceIfExists bool
+	RootDirectory   uintptr
+	FileNameLength  uint32
+	FileName        [1]uint16
+}
+
+type fileDispositionInformationEx struct {
+	Flags uintptr
+}
+
+const (
+	_FileLinkInformation          = 11
+	_FileDispositionInformationEx = 64
+
+	_FILE_READ_ATTRIBUTES  = 0x0080
+	_FILE_WRITE_ATTRIBUTES = 0x0100
+	_DELETE                = 0x10000
+
+	_FILE_OPEN   = 1
+	_FILE_CREATE = 2
+
+	_FILE_DIRECTORY_FILE          = 0x00000001
+	_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020
+	_FILE_DELETE_ON_CLOSE         = 0x00001000
+	_FILE_OPEN_FOR_BACKUP_INTENT  = 0x00004000
+	_FILE_OPEN_REPARSE_POINT      = 0x00200000
+
+	_FILE_DISPOSITION_DELETE = 0x00000001
+
+	_OBJ_DONT_REPARSE = 0x1000
+
+	_STATUS_REPARSE_POINT_ENCOUNTERED = 0xC000050B
+)
+
+func openRoot(path string) (*os.File, error) {
+	longpath, err := makeLongAbsPath(path)
+	if err != nil {
+		return nil, err
+	}
+	return winio.OpenForBackup(longpath, syscall.GENERIC_READ, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, syscall.OPEN_EXISTING)
+}
+
+func ntRelativePath(path string) ([]uint16, error) {
+	path = filepath.Clean(path)
+	if strings.Contains(":", path) {
+		// Since alternate data streams must follow the file they
+		// are attached to, finding one here (out of order) is invalid.
+		return nil, errors.New("path contains invalid character `:`")
+	}
+	fspath := filepath.FromSlash(path)
+	if len(fspath) > 0 && fspath[0] == '\\' {
+		return nil, errors.New("expected relative path")
+	}
+
+	path16 := utf16.Encode(([]rune)(fspath))
+	if len(path16) > 32767 {
+		return nil, syscall.ENAMETOOLONG
+	}
+
+	return path16, nil
+}
+
+// openRelativeInternal opens a relative path from the given root, failing if
+// any of the intermediate path components are reparse points.
+func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFlags uint32, createDisposition uint32, flags uint32) (*os.File, error) {
+	var (
+		h    uintptr
+		iosb ioStatusBlock
+		oa   objectAttributes
+	)
+
+	path16, err := ntRelativePath(path)
+	if err != nil {
+		return nil, err
+	}
+
+	if root == nil || root.Fd() == 0 {
+		return nil, errors.New("missing root directory")
+	}
+
+	upathBuffer := localAlloc(0, int(unsafe.Sizeof(unicodeString{}))+len(path16)*2)
+	defer localFree(upathBuffer)
+
+	upath := (*unicodeString)(unsafe.Pointer(upathBuffer))
+	upath.Length = uint16(len(path16) * 2)
+	upath.MaximumLength = upath.Length
+	upath.Buffer = upathBuffer + unsafe.Sizeof(*upath)
+	copy((*[32768]uint16)(unsafe.Pointer(upath.Buffer))[:], path16)
+
+	oa.Length = unsafe.Sizeof(oa)
+	oa.ObjectName = upathBuffer
+	oa.RootDirectory = uintptr(root.Fd())
+	oa.Attributes = _OBJ_DONT_REPARSE
+	status := ntCreateFile(
+		&h,
+		accessMask|syscall.SYNCHRONIZE,
+		&oa,
+		&iosb,
+		nil,
+		0,
+		shareFlags,
+		createDisposition,
+		_FILE_OPEN_FOR_BACKUP_INTENT|_FILE_SYNCHRONOUS_IO_NONALERT|flags,
+		nil,
+		0,
+	)
+	if status != 0 {
+		return nil, rtlNtStatusToDosError(status)
+	}
+
+	fullPath, err := makeLongAbsPath(filepath.Join(root.Name(), path))
+	if err != nil {
+		syscall.Close(syscall.Handle(h))
+		return nil, err
+	}
+
+	return os.NewFile(h, fullPath), nil
+}
+
+// openRelative opens a relative path from the given root, failing if
+// any of the intermediate path components are reparse points.
+func openRelative(path string, root *os.File, accessMask uint32, shareFlags uint32, createDisposition uint32, flags uint32) (*os.File, error) {
+	f, err := openRelativeInternal(path, root, accessMask, shareFlags, createDisposition, flags)
+	if err != nil {
+		err = &os.PathError{Op: "open", Path: filepath.Join(root.Name(), path), Err: err}
+	}
+	return f, err
+}
+
+// linkRelative creates a hard link from oldname to newname (relative to oldroot
+// and newroot), failing if any of the intermediate path components are reparse
+// points.
+func linkRelative(oldname string, oldroot *os.File, newname string, newroot *os.File) error {
+	// Open the old file.
+	oldf, err := openRelativeInternal(
+		oldname,
+		oldroot,
+		syscall.FILE_WRITE_ATTRIBUTES,
+		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+		_FILE_OPEN,
+		0,
+	)
+	if err != nil {
+		return &os.LinkError{Op: "link", Old: filepath.Join(oldroot.Name(), oldname), New: filepath.Join(newroot.Name(), newname), Err: err}
+	}
+	defer oldf.Close()
+
+	// Open the parent of the new file.
+	var parent *os.File
+	parentPath := filepath.Dir(newname)
+	if parentPath != "." {
+		parent, err = openRelativeInternal(
+			parentPath,
+			newroot,
+			syscall.GENERIC_READ,
+			syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+			_FILE_OPEN,
+			_FILE_DIRECTORY_FILE)
+		if err != nil {
+			return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: err}
+		}
+		defer parent.Close()
+
+		fi, err := winio.GetFileBasicInfo(parent)
+		if err != nil {
+			return err
+		}
+		if (fi.FileAttributes & syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
+			return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: rtlNtStatusToDosError(_STATUS_REPARSE_POINT_ENCOUNTERED)}
+		}
+
+	} else {
+		parent = newroot
+	}
+
+	// Issue an NT call to create the link. This will be safe because NT will
+	// not open any more directories to create the link, so it cannot walk any
+	// more reparse points.
+	newbase := filepath.Base(newname)
+	newbase16, err := ntRelativePath(newbase)
+	if err != nil {
+		return err
+	}
+
+	size := int(unsafe.Offsetof(fileLinkInformation{}.FileName)) + len(newbase16)*2
+	linkinfoBuffer := localAlloc(0, size)
+	defer localFree(linkinfoBuffer)
+	linkinfo := (*fileLinkInformation)(unsafe.Pointer(linkinfoBuffer))
+	linkinfo.RootDirectory = parent.Fd()
+	linkinfo.FileNameLength = uint32(len(newbase16) * 2)
+	copy((*[32768]uint16)(unsafe.Pointer(&linkinfo.FileName[0]))[:], newbase16)
+
+	var iosb ioStatusBlock
+	status := ntSetInformationFile(
+		oldf.Fd(),
+		&iosb,
+		linkinfoBuffer,
+		uint32(size),
+		_FileLinkInformation,
+	)
+	if status != 0 {
+		return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(parent.Name(), newbase), Err: rtlNtStatusToDosError(status)}
+	}
+
+	return nil
+}
+
+// deleteOnClose marks a file to be deleted when the handle is closed.
+func deleteOnClose(f *os.File) error {
+	disposition := fileDispositionInformationEx{Flags: _FILE_DISPOSITION_DELETE}
+	var iosb ioStatusBlock
+	status := ntSetInformationFile(
+		f.Fd(),
+		&iosb,
+		uintptr(unsafe.Pointer(&disposition)),
+		uint32(unsafe.Sizeof(disposition)),
+		_FileDispositionInformationEx,
+	)
+	if status != 0 {
+		return rtlNtStatusToDosError(status)
+	}
+	return nil
+}
+
+// clearReadOnly clears the readonly attribute on a file.
+func clearReadOnly(f *os.File) error {
+	bi, err := winio.GetFileBasicInfo(f)
+	if err != nil {
+		return err
+	}
+	if bi.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY == 0 {
+		return nil
+	}
+	sbi := winio.FileBasicInfo{
+		FileAttributes: bi.FileAttributes &^ syscall.FILE_ATTRIBUTE_READONLY,
+	}
+	if sbi.FileAttributes == 0 {
+		sbi.FileAttributes = syscall.FILE_ATTRIBUTE_NORMAL
+	}
+	return winio.SetFileBasicInfo(f, &sbi)
+}
+
+// removeRelative removes a file or directory relative to a root, failing if any
+// intermediate path components are reparse points.
+func removeRelative(path string, root *os.File) error {
+	f, err := openRelativeInternal(
+		path,
+		root,
+		_FILE_READ_ATTRIBUTES|_FILE_WRITE_ATTRIBUTES|_DELETE,
+		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+		_FILE_OPEN,
+		_FILE_OPEN_REPARSE_POINT)
+	if err == nil {
+		defer f.Close()
+		err = deleteOnClose(f)
+		if err == syscall.ERROR_ACCESS_DENIED {
+			// Maybe the file is marked readonly. Clear the bit and retry.
+			clearReadOnly(f)
+			err = deleteOnClose(f)
+		}
+	}
+	if err != nil {
+		return &os.PathError{Op: "remove", Path: filepath.Join(root.Name(), path), Err: err}
+	}
+	return nil
+}
+
+// removeAllRelative removes a directory tree relative to a root, failing if any
+// intermediate path components are reparse points.
+func removeAllRelative(path string, root *os.File) error {
+	fi, err := lstatRelative(path, root)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return nil
+		}
+		return err
+	}
+	fileAttributes := fi.Sys().(*syscall.Win32FileAttributeData).FileAttributes
+	if fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 || fileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+		// If this is a reparse point, it can't have children. Simple remove will do.
+		err := removeRelative(path, root)
+		if err == nil || os.IsNotExist(err) {
+			return nil
+		}
+		return err
+	}
+
+	// It is necessary to use os.Open as Readdirnames does not work with
+	// openRelative. This is safe because the above lstatrelative fails
+	// if the target is outside the root, and we know this is not a
+	// symlink from the above FILE_ATTRIBUTE_REPARSE_POINT check.
+	fd, err := os.Open(filepath.Join(root.Name(), path))
+	if err != nil {
+		if os.IsNotExist(err) {
+			// Race. It was deleted between the Lstat and Open.
+			// Return nil per RemoveAll's docs.
+			return nil
+		}
+		return err
+	}
+
+	// Remove contents & return first error.
+	for {
+		names, err1 := fd.Readdirnames(100)
+		for _, name := range names {
+			err1 := removeAllRelative(path+string(os.PathSeparator)+name, root)
+			if err == nil {
+				err = err1
+			}
+		}
+		if err1 == io.EOF {
+			break
+		}
+		// If Readdirnames returned an error, use it.
+		if err == nil {
+			err = err1
+		}
+		if len(names) == 0 {
+			break
+		}
+	}
+	fd.Close()
+
+	// Remove directory.
+	err1 := removeRelative(path, root)
+	if err1 == nil || os.IsNotExist(err1) {
+		return nil
+	}
+	if err == nil {
+		err = err1
+	}
+	return err
+}
+
+// mkdirRelative creates a directory relative to a root, failing if any
+// intermediate path components are reparse points.
+func mkdirRelative(path string, root *os.File) error {
+	f, err := openRelativeInternal(
+		path,
+		root,
+		0,
+		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+		_FILE_CREATE,
+		_FILE_DIRECTORY_FILE)
+	if err == nil {
+		f.Close()
+	} else {
+		err = &os.PathError{Op: "mkdir", Path: filepath.Join(root.Name(), path), Err: err}
+	}
+	return err
+}
+
+// lstatRelative performs a stat operation on a file relative to a root, failing
+// if any intermediate path components are reparse points.
+func lstatRelative(path string, root *os.File) (os.FileInfo, error) {
+	f, err := openRelativeInternal(
+		path,
+		root,
+		_FILE_READ_ATTRIBUTES,
+		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+		_FILE_OPEN,
+		_FILE_OPEN_REPARSE_POINT)
+	if err != nil {
+		return nil, &os.PathError{Op: "stat", Path: filepath.Join(root.Name(), path), Err: err}
+	}
+	defer f.Close()
+	return f.Stat()
+}
+
+// ensureNotReparsePointRelative validates that a given file (relative to a
+// root) and all intermediate path components are not a reparse points.
+func ensureNotReparsePointRelative(path string, root *os.File) error {
+	// Perform an open with OBJ_DONT_REPARSE but without specifying FILE_OPEN_REPARSE_POINT.
+	f, err := openRelative(
+		path,
+		root,
+		0,
+		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+		_FILE_OPEN,
+		0)
+	if err != nil {
+		return err
+	}
+	f.Close()
+	return nil
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/zhcsshim.go b/vendor/github.com/Microsoft/hcsshim/zhcsshim.go
index 5d1a851..5123e8d 100644
--- a/vendor/github.com/Microsoft/hcsshim/zhcsshim.go
+++ b/vendor/github.com/Microsoft/hcsshim/zhcsshim.go
@@ -41,6 +41,8 @@
 	modole32     = windows.NewLazySystemDLL("ole32.dll")
 	modiphlpapi  = windows.NewLazySystemDLL("iphlpapi.dll")
 	modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
+	modntdll     = windows.NewLazySystemDLL("ntdll.dll")
+	modkernel32  = windows.NewLazySystemDLL("kernel32.dll")
 
 	procCoTaskMemFree                      = modole32.NewProc("CoTaskMemFree")
 	procSetCurrentThreadCompartmentId      = modiphlpapi.NewProc("SetCurrentThreadCompartmentId")
@@ -94,6 +96,11 @@
 	procHcsUnregisterProcessCallback       = modvmcompute.NewProc("HcsUnregisterProcessCallback")
 	procHcsModifyServiceSettings           = modvmcompute.NewProc("HcsModifyServiceSettings")
 	procHNSCall                            = modvmcompute.NewProc("HNSCall")
+	procNtCreateFile                       = modntdll.NewProc("NtCreateFile")
+	procNtSetInformationFile               = modntdll.NewProc("NtSetInformationFile")
+	procRtlNtStatusToDosErrorNoTeb         = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
+	procLocalAlloc                         = modkernel32.NewProc("LocalAlloc")
+	procLocalFree                          = modkernel32.NewProc("LocalFree")
 )
 
 func coTaskMemFree(buffer unsafe.Pointer) {
@@ -1040,3 +1047,34 @@
 	}
 	return
 }
+
+func ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) {
+	r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(accessMask), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(fileAttributes), uintptr(shareAccess), uintptr(createDisposition), uintptr(createOptions), uintptr(unsafe.Pointer(eaBuffer)), uintptr(eaLength), 0)
+	status = uint32(r0)
+	return
+}
+
+func ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) {
+	r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(information), uintptr(length), uintptr(class), 0)
+	status = uint32(r0)
+	return
+}
+
+func rtlNtStatusToDosError(status uint32) (winerr error) {
+	r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
+	if r0 != 0 {
+		winerr = syscall.Errno(r0)
+	}
+	return
+}
+
+func localAlloc(flags uint32, size int) (ptr uintptr) {
+	r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(size), 0)
+	ptr = uintptr(r0)
+	return
+}
+
+func localFree(ptr uintptr) {
+	syscall.Syscall(procLocalFree.Addr(), 1, uintptr(ptr), 0, 0)
+	return
+}