Update continuity, go-winio and hcsshim
Update dependencies and remove the local bindfilter files. Those have been moved to go-winio. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
		
							
								
								
									
										15
									
								
								vendor/github.com/Microsoft/go-winio/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/Microsoft/go-winio/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -8,12 +8,8 @@ linters:
 | 
			
		||||
    - containedctx # struct contains a context
 | 
			
		||||
    - dupl # duplicate code
 | 
			
		||||
    - errname # erorrs are named correctly
 | 
			
		||||
    - goconst # strings that should be constants
 | 
			
		||||
    - godot # comments end in a period
 | 
			
		||||
    - misspell
 | 
			
		||||
    - nolintlint # "//nolint" directives are properly explained
 | 
			
		||||
    - revive # golint replacement
 | 
			
		||||
    - stylecheck # golint replacement, less configurable than revive
 | 
			
		||||
    - unconvert # unnecessary conversions
 | 
			
		||||
    - wastedassign
 | 
			
		||||
 | 
			
		||||
@@ -23,10 +19,7 @@ linters:
 | 
			
		||||
    - exhaustive # check exhaustiveness of enum switch statements
 | 
			
		||||
    - gofmt # files are gofmt'ed
 | 
			
		||||
    - gosec # security
 | 
			
		||||
    - nestif # deeply nested ifs
 | 
			
		||||
    - nilerr # returns nil even with non-nil error
 | 
			
		||||
    - prealloc # slices that can be pre-allocated
 | 
			
		||||
    - structcheck # unused struct fields
 | 
			
		||||
    - unparam # unused function params
 | 
			
		||||
 | 
			
		||||
issues:
 | 
			
		||||
@@ -56,6 +49,8 @@ issues:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
linters-settings:
 | 
			
		||||
  exhaustive:
 | 
			
		||||
    default-signifies-exhaustive: true
 | 
			
		||||
  govet:
 | 
			
		||||
    enable-all: true
 | 
			
		||||
    disable:
 | 
			
		||||
@@ -98,6 +93,8 @@ linters-settings:
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: flag-parameter # excessive, and a common idiom we use
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: unhandled-error # warns over common fmt.Print* and io.Close; rely on errcheck instead
 | 
			
		||||
        disabled: true
 | 
			
		||||
      # general config
 | 
			
		||||
      - name: line-length-limit
 | 
			
		||||
        arguments:
 | 
			
		||||
@@ -138,7 +135,3 @@ linters-settings:
 | 
			
		||||
            - VPCI
 | 
			
		||||
            - WCOW
 | 
			
		||||
            - WIM
 | 
			
		||||
  stylecheck:
 | 
			
		||||
    checks:
 | 
			
		||||
      - "all"
 | 
			
		||||
      - "-ST1003" # use revive's var naming
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										308
									
								
								vendor/github.com/Microsoft/go-winio/pkg/bindfilter/bind_filter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								vendor/github.com/Microsoft/go-winio/pkg/bindfilter/bind_filter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,308 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package bindfilter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./bind_filter.go
 | 
			
		||||
//sys bfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath string, virtTargetPath string, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) = bindfltapi.BfSetupFilter?
 | 
			
		||||
//sys bfRemoveMapping(jobHandle windows.Handle, virtRootPath string)  (hr error) = bindfltapi.BfRemoveMapping?
 | 
			
		||||
//sys bfGetMappings(flags uint32, jobHandle windows.Handle, virtRootPath *uint16, sid *windows.SID, bufferSize *uint32, outBuffer *byte)  (hr error) = bindfltapi.BfGetMappings?
 | 
			
		||||
 | 
			
		||||
// BfSetupFilter flags. See:
 | 
			
		||||
// https://github.com/microsoft/BuildXL/blob/a6dce509f0d4f774255e5fbfb75fa6d5290ed163/Public/Src/Utilities/Native/Processes/Windows/NativeContainerUtilities.cs#L193-L240
 | 
			
		||||
//
 | 
			
		||||
//nolint:revive // var-naming: ALL_CAPS
 | 
			
		||||
const (
 | 
			
		||||
	BINDFLT_FLAG_READ_ONLY_MAPPING uint32 = 0x00000001
 | 
			
		||||
	// Tells bindflt to fail mapping with STATUS_INVALID_PARAMETER if a mapping produces
 | 
			
		||||
	// multiple targets.
 | 
			
		||||
	BINDFLT_FLAG_NO_MULTIPLE_TARGETS uint32 = 0x00000040
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//nolint:revive // var-naming: ALL_CAPS
 | 
			
		||||
const (
 | 
			
		||||
	BINDFLT_GET_MAPPINGS_FLAG_VOLUME uint32 = 0x00000001
 | 
			
		||||
	BINDFLT_GET_MAPPINGS_FLAG_SILO   uint32 = 0x00000002
 | 
			
		||||
	BINDFLT_GET_MAPPINGS_FLAG_USER   uint32 = 0x00000004
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ApplyFileBinding creates a global mount of the source in root, with an optional
 | 
			
		||||
// read only flag.
 | 
			
		||||
// The bind filter allows us to create mounts of directories and volumes. By default it allows
 | 
			
		||||
// us to mount multiple sources inside a single root, acting as an overlay. Files from the
 | 
			
		||||
// second source will superscede the first source that was mounted.
 | 
			
		||||
// This function disables this behavior and sets the BINDFLT_FLAG_NO_MULTIPLE_TARGETS flag
 | 
			
		||||
// on the mount.
 | 
			
		||||
func ApplyFileBinding(root, source string, readOnly bool) error {
 | 
			
		||||
	// The parent directory needs to exist for the bind to work. MkdirAll stats and
 | 
			
		||||
	// returns nil if the directory exists internally so we should be fine to mkdirall
 | 
			
		||||
	// every time.
 | 
			
		||||
	if err := os.MkdirAll(filepath.Dir(root), 0); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if strings.Contains(source, "Volume{") && !strings.HasSuffix(source, "\\") {
 | 
			
		||||
		// Add trailing slash to volumes, otherwise we get an error when binding it to
 | 
			
		||||
		// a folder.
 | 
			
		||||
		source = source + "\\"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flags := BINDFLT_FLAG_NO_MULTIPLE_TARGETS
 | 
			
		||||
	if readOnly {
 | 
			
		||||
		flags |= BINDFLT_FLAG_READ_ONLY_MAPPING
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set the job handle to 0 to create a global mount.
 | 
			
		||||
	if err := bfSetupFilter(
 | 
			
		||||
		0,
 | 
			
		||||
		flags,
 | 
			
		||||
		root,
 | 
			
		||||
		source,
 | 
			
		||||
		nil,
 | 
			
		||||
		0,
 | 
			
		||||
	); err != nil {
 | 
			
		||||
		return fmt.Errorf("failed to bind target %q to root %q: %w", source, root, err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RemoveFileBinding removes a mount from the root path.
 | 
			
		||||
func RemoveFileBinding(root string) error {
 | 
			
		||||
	if err := bfRemoveMapping(0, root); err != nil {
 | 
			
		||||
		return fmt.Errorf("removing file binding: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetBindMappings returns a list of bind mappings that have their root on a
 | 
			
		||||
// particular volume. The volumePath parameter can be any path that exists on
 | 
			
		||||
// a volume. For example, if a number of mappings are created in C:\ProgramData\test,
 | 
			
		||||
// to get a list of those mappings, the volumePath parameter would have to be set to
 | 
			
		||||
// C:\ or the VOLUME_NAME_GUID notation of C:\ (\\?\Volume{GUID}\), or any child
 | 
			
		||||
// path that exists.
 | 
			
		||||
func GetBindMappings(volumePath string) ([]BindMapping, error) {
 | 
			
		||||
	rootPtr, err := windows.UTF16PtrFromString(volumePath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flags := BINDFLT_GET_MAPPINGS_FLAG_VOLUME
 | 
			
		||||
	// allocate a large buffer for results
 | 
			
		||||
	var outBuffSize uint32 = 256 * 1024
 | 
			
		||||
	buf := make([]byte, outBuffSize)
 | 
			
		||||
 | 
			
		||||
	if err := bfGetMappings(flags, 0, rootPtr, nil, &outBuffSize, &buf[0]); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if outBuffSize < 12 {
 | 
			
		||||
		return nil, fmt.Errorf("invalid buffer returned")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result := buf[:outBuffSize]
 | 
			
		||||
 | 
			
		||||
	// The first 12 bytes are the three uint32 fields in getMappingsResponseHeader{}
 | 
			
		||||
	headerBuffer := result[:12]
 | 
			
		||||
	// The alternative to using unsafe and casting it to the above defined structures, is to manually
 | 
			
		||||
	// parse the fields. Not too terrible, but not sure it'd worth the trouble.
 | 
			
		||||
	header := *(*getMappingsResponseHeader)(unsafe.Pointer(&headerBuffer[0]))
 | 
			
		||||
 | 
			
		||||
	if header.MappingCount == 0 {
 | 
			
		||||
		// no mappings
 | 
			
		||||
		return []BindMapping{}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mappingsBuffer := result[12 : int(unsafe.Sizeof(mappingEntry{}))*int(header.MappingCount)]
 | 
			
		||||
	// Get a pointer to the first mapping in the slice
 | 
			
		||||
	mappingsPointer := (*mappingEntry)(unsafe.Pointer(&mappingsBuffer[0]))
 | 
			
		||||
	// Get slice of mappings
 | 
			
		||||
	mappings := unsafe.Slice(mappingsPointer, header.MappingCount)
 | 
			
		||||
 | 
			
		||||
	mappingEntries := make([]BindMapping, header.MappingCount)
 | 
			
		||||
	for i := 0; i < int(header.MappingCount); i++ {
 | 
			
		||||
		bindMapping, err := getBindMappingFromBuffer(result, mappings[i])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("fetching bind mappings: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
		mappingEntries[i] = bindMapping
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mappingEntries, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mappingEntry holds information about where in the response buffer we can
 | 
			
		||||
// find information about the virtual root (the mount point) and the targets (sources)
 | 
			
		||||
// that get mounted, as well as the flags used to bind the targets to the virtual root.
 | 
			
		||||
type mappingEntry struct {
 | 
			
		||||
	VirtRootLength      uint32
 | 
			
		||||
	VirtRootOffset      uint32
 | 
			
		||||
	Flags               uint32
 | 
			
		||||
	NumberOfTargets     uint32
 | 
			
		||||
	TargetEntriesOffset uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type mappingTargetEntry struct {
 | 
			
		||||
	TargetRootLength uint32
 | 
			
		||||
	TargetRootOffset uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getMappingsResponseHeader represents the first 12 bytes of the BfGetMappings() response.
 | 
			
		||||
// It gives us the size of the buffer, the status of the call and the number of mappings.
 | 
			
		||||
// A response
 | 
			
		||||
type getMappingsResponseHeader struct {
 | 
			
		||||
	Size         uint32
 | 
			
		||||
	Status       uint32
 | 
			
		||||
	MappingCount uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type BindMapping struct {
 | 
			
		||||
	MountPoint string
 | 
			
		||||
	Flags      uint32
 | 
			
		||||
	Targets    []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func decodeEntry(buffer []byte) (string, error) {
 | 
			
		||||
	name := make([]uint16, len(buffer)/2)
 | 
			
		||||
	err := binary.Read(bytes.NewReader(buffer), binary.LittleEndian, &name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", fmt.Errorf("decoding name: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return windows.UTF16ToString(name), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getTargetsFromBuffer(buffer []byte, offset, count int) ([]string, error) {
 | 
			
		||||
	if len(buffer) < offset+count*6 {
 | 
			
		||||
		return nil, fmt.Errorf("invalid buffer")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	targets := make([]string, count)
 | 
			
		||||
	for i := 0; i < count; i++ {
 | 
			
		||||
		entryBuf := buffer[offset+i*8 : offset+i*8+8]
 | 
			
		||||
		tgt := *(*mappingTargetEntry)(unsafe.Pointer(&entryBuf[0]))
 | 
			
		||||
		if len(buffer) < int(tgt.TargetRootOffset)+int(tgt.TargetRootLength) {
 | 
			
		||||
			return nil, fmt.Errorf("invalid buffer")
 | 
			
		||||
		}
 | 
			
		||||
		decoded, err := decodeEntry(buffer[tgt.TargetRootOffset : tgt.TargetRootOffset+tgt.TargetRootLength])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("decoding name: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
		decoded, err = getFinalPath(decoded)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("fetching final path: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		targets[i] = decoded
 | 
			
		||||
	}
 | 
			
		||||
	return targets, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getFinalPath(pth string) (string, error) {
 | 
			
		||||
	// BfGetMappings returns VOLUME_NAME_NT paths like \Device\HarddiskVolume2\ProgramData.
 | 
			
		||||
	// These can be accessed by prepending \\.\GLOBALROOT to the path. We use this to get the
 | 
			
		||||
	// DOS paths for these files.
 | 
			
		||||
	if strings.HasPrefix(pth, `\Device`) {
 | 
			
		||||
		pth = `\\.\GLOBALROOT` + pth
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	han, err := openPath(pth)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", fmt.Errorf("fetching file handle: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		_ = windows.CloseHandle(han)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	buf := make([]uint16, 100)
 | 
			
		||||
	var flags uint32 = 0x0
 | 
			
		||||
	for {
 | 
			
		||||
		n, err := windows.GetFinalPathNameByHandle(han, &buf[0], uint32(len(buf)), flags)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// if we mounted a volume that does not also have a drive letter assigned, attempting to
 | 
			
		||||
			// fetch the VOLUME_NAME_DOS will fail with os.ErrNotExist. Attempt to get the VOLUME_NAME_GUID.
 | 
			
		||||
			if errors.Is(err, os.ErrNotExist) && flags != 0x1 {
 | 
			
		||||
				flags = 0x1
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			return "", fmt.Errorf("getting final path name: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
		if n < uint32(len(buf)) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		buf = make([]uint16, n)
 | 
			
		||||
	}
 | 
			
		||||
	finalPath := syscall.UTF16ToString(buf)
 | 
			
		||||
	// We got VOLUME_NAME_DOS, we need to strip away some leading slashes.
 | 
			
		||||
	// Leave unchanged if we ended up requesting VOLUME_NAME_GUID
 | 
			
		||||
	if len(finalPath) > 4 && finalPath[:4] == `\\?\` && flags == 0x0 {
 | 
			
		||||
		finalPath = finalPath[4:]
 | 
			
		||||
		if len(finalPath) > 3 && finalPath[:3] == `UNC` {
 | 
			
		||||
			// return path like \\server\share\...
 | 
			
		||||
			finalPath = `\` + finalPath[3:]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return finalPath, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getBindMappingFromBuffer(buffer []byte, entry mappingEntry) (BindMapping, error) {
 | 
			
		||||
	if len(buffer) < int(entry.VirtRootOffset)+int(entry.VirtRootLength) {
 | 
			
		||||
		return BindMapping{}, fmt.Errorf("invalid buffer")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	src, err := decodeEntry(buffer[entry.VirtRootOffset : entry.VirtRootOffset+entry.VirtRootLength])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return BindMapping{}, fmt.Errorf("decoding entry: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	targets, err := getTargetsFromBuffer(buffer, int(entry.TargetEntriesOffset), int(entry.NumberOfTargets))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return BindMapping{}, fmt.Errorf("fetching targets: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	src, err = getFinalPath(src)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return BindMapping{}, fmt.Errorf("fetching final path: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return BindMapping{
 | 
			
		||||
		Flags:      entry.Flags,
 | 
			
		||||
		Targets:    targets,
 | 
			
		||||
		MountPoint: src,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func openPath(path string) (windows.Handle, error) {
 | 
			
		||||
	u16, err := windows.UTF16PtrFromString(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	h, err := windows.CreateFile(
 | 
			
		||||
		u16,
 | 
			
		||||
		0,
 | 
			
		||||
		windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
 | 
			
		||||
		nil,
 | 
			
		||||
		windows.OPEN_EXISTING,
 | 
			
		||||
		windows.FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory handle.
 | 
			
		||||
		0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, &os.PathError{
 | 
			
		||||
			Op:   "CreateFile",
 | 
			
		||||
			Path: path,
 | 
			
		||||
			Err:  err,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return h, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								vendor/github.com/Microsoft/go-winio/pkg/bindfilter/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								vendor/github.com/Microsoft/go-winio/pkg/bindfilter/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package bindfilter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ unsafe.Pointer
 | 
			
		||||
 | 
			
		||||
// Do the interface allocations only once for common
 | 
			
		||||
// Errno values.
 | 
			
		||||
const (
 | 
			
		||||
	errnoERROR_IO_PENDING = 997
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
 | 
			
		||||
	errERROR_EINVAL     error = syscall.EINVAL
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// errnoErr returns common boxed Errno values, to prevent
 | 
			
		||||
// allocations at runtime.
 | 
			
		||||
func errnoErr(e syscall.Errno) error {
 | 
			
		||||
	switch e {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return errERROR_EINVAL
 | 
			
		||||
	case errnoERROR_IO_PENDING:
 | 
			
		||||
		return errERROR_IO_PENDING
 | 
			
		||||
	}
 | 
			
		||||
	// TODO: add more here, after collecting data on the common
 | 
			
		||||
	// error values see on Windows. (perhaps when running
 | 
			
		||||
	// all.bat?)
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	modbindfltapi = windows.NewLazySystemDLL("bindfltapi.dll")
 | 
			
		||||
 | 
			
		||||
	procBfGetMappings   = modbindfltapi.NewProc("BfGetMappings")
 | 
			
		||||
	procBfRemoveMapping = modbindfltapi.NewProc("BfRemoveMapping")
 | 
			
		||||
	procBfSetupFilter   = modbindfltapi.NewProc("BfSetupFilter")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func bfGetMappings(flags uint32, jobHandle windows.Handle, virtRootPath *uint16, sid *windows.SID, bufferSize *uint32, outBuffer *byte) (hr error) {
 | 
			
		||||
	hr = procBfGetMappings.Find()
 | 
			
		||||
	if hr != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	r0, _, _ := syscall.Syscall6(procBfGetMappings.Addr(), 6, uintptr(flags), uintptr(jobHandle), uintptr(unsafe.Pointer(virtRootPath)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(bufferSize)), uintptr(unsafe.Pointer(outBuffer)))
 | 
			
		||||
	if int32(r0) < 0 {
 | 
			
		||||
		if r0&0x1fff0000 == 0x00070000 {
 | 
			
		||||
			r0 &= 0xffff
 | 
			
		||||
		}
 | 
			
		||||
		hr = syscall.Errno(r0)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func bfRemoveMapping(jobHandle windows.Handle, virtRootPath string) (hr error) {
 | 
			
		||||
	var _p0 *uint16
 | 
			
		||||
	_p0, hr = syscall.UTF16PtrFromString(virtRootPath)
 | 
			
		||||
	if hr != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return _bfRemoveMapping(jobHandle, _p0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func _bfRemoveMapping(jobHandle windows.Handle, virtRootPath *uint16) (hr error) {
 | 
			
		||||
	hr = procBfRemoveMapping.Find()
 | 
			
		||||
	if hr != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	r0, _, _ := syscall.Syscall(procBfRemoveMapping.Addr(), 2, uintptr(jobHandle), uintptr(unsafe.Pointer(virtRootPath)), 0)
 | 
			
		||||
	if int32(r0) < 0 {
 | 
			
		||||
		if r0&0x1fff0000 == 0x00070000 {
 | 
			
		||||
			r0 &= 0xffff
 | 
			
		||||
		}
 | 
			
		||||
		hr = syscall.Errno(r0)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func bfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath string, virtTargetPath string, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) {
 | 
			
		||||
	var _p0 *uint16
 | 
			
		||||
	_p0, hr = syscall.UTF16PtrFromString(virtRootPath)
 | 
			
		||||
	if hr != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var _p1 *uint16
 | 
			
		||||
	_p1, hr = syscall.UTF16PtrFromString(virtTargetPath)
 | 
			
		||||
	if hr != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return _bfSetupFilter(jobHandle, flags, _p0, _p1, virtExceptions, virtExceptionPathCount)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func _bfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath *uint16, virtTargetPath *uint16, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) {
 | 
			
		||||
	hr = procBfSetupFilter.Find()
 | 
			
		||||
	if hr != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	r0, _, _ := syscall.Syscall6(procBfSetupFilter.Addr(), 6, uintptr(jobHandle), uintptr(flags), uintptr(unsafe.Pointer(virtRootPath)), uintptr(unsafe.Pointer(virtTargetPath)), uintptr(unsafe.Pointer(virtExceptions)), uintptr(virtExceptionPathCount))
 | 
			
		||||
	if int32(r0) < 0 {
 | 
			
		||||
		if r0&0x1fff0000 == 0x00070000 {
 | 
			
		||||
			r0 &= 0xffff
 | 
			
		||||
		}
 | 
			
		||||
		hr = syscall.Errno(r0)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user