func tarToBackupStreamWithMutatedFiles(buf *bufio.Writer, w io.Writer, t *tar.Reader, hdr *tar.Header, root string) (nextHdr *tar.Header, err error) {
	var (
		bcdBackup       *os.File
		bcdBackupWriter *winio.BackupFileWriter
	)
	if backupPath, ok := mutatedFiles[hdr.Name]; ok {
		bcdBackup, err = os.Create(filepath.Join(root, backupPath))
		if err != nil {
			return nil, err
		}
		defer func() {
			cerr := bcdBackup.Close()
			if err == nil {
				err = cerr
			}
		}()
		bcdBackupWriter = winio.NewBackupFileWriter(bcdBackup, false)
		defer func() {
			cerr := bcdBackupWriter.Close()
			if err == nil {
				err = cerr
			}
		}()
		buf.Reset(io.MultiWriter(w, bcdBackupWriter))
	} else {
		buf.Reset(w)
	}
	defer func() {
		ferr := buf.Flush()
		if err == nil {
			err = ferr
		}
	}()
	return writeBackupStreamFromTarFile(buf, t, hdr)
}
tarToBackupStreamWithMutatedFiles reads data from a tar stream and
writes it to a backup stream, and also saves any files that will be mutated
by the import layer process to a backup location.
package archive
import (
	"archive/tar"
	"bufio"
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"github.com/Microsoft/go-winio"
	"github.com/Microsoft/hcsshim"
	"github.com/containerd/containerd/sys"
)
const (
	hdrMSWindowsPrefix = "MSWINDOWS."
	hdrFileAttributes        = hdrMSWindowsPrefix + "fileattr"
	hdrSecurityDescriptor    = hdrMSWindowsPrefix + "sd"
	hdrRawSecurityDescriptor = hdrMSWindowsPrefix + "rawsd"
	hdrMountPoint            = hdrMSWindowsPrefix + "mountpoint"
	hdrEaPrefix              = hdrMSWindowsPrefix + "xattr."
	hdrLibArchivePrefix = "LIBARCHIVE."
	hdrCreateTime = hdrLibArchivePrefix + "creationtime"
)
var (
	mutatedFiles = map[string]string{
		"UtilityVM/Files/EFI/Microsoft/Boot/BCD":      "bcd.bak",
		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG":  "bcd.log.bak",
		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG1": "bcd.log1.bak",
		"UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG2": "bcd.log2.bak",
	}
)
func tarName(p string) (string, error) {
	if strings.Contains(p, "/") {
		return "", fmt.Errorf("windows path contains forward slash: %s", p)
	}
	return strings.Replace(p, string(os.PathSeparator), "/", -1), nil
}
func chmodTarEntry(perm os.FileMode) os.FileMode {
	perm &= 0755
	perm |= 0111
	return perm
}
func setHeaderForSpecialDevice(*tar.Header, string, os.FileInfo) error {
	return nil
}
func open(p string) (*os.File, error) {
	return sys.OpenSequential(p)
}
func openFile(name string, flag int, perm os.FileMode) (*os.File, error) {
	return sys.OpenFileSequential(name, flag, perm)
}
func mkdirAll(path string, perm os.FileMode) error {
	return sys.MkdirAll(path, perm)
}
func mkdir(path string, perm os.FileMode) error {
	return os.Mkdir(path, perm)
}
func skipFile(hdr *tar.Header) bool {
	return strings.Contains(hdr.Name, ":")
}
func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
	return nil
}
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
	return nil
}
func getxattr(path, attr string) ([]byte, error) {
	return nil, nil
}
func setxattr(path, key, value string) error {
	return errors.New("xattrs not supported on Windows")
}
func apply(ctx context.Context, root string, tr *tar.Reader, options ApplyOptions) (size int64, err error) {
	if options.IsWindowsContainerLayer {
		return applyWindowsLayer(ctx, root, tr, options)
	}
	return applyNaive(ctx, root, tr, options)
}
func applyWindowsLayer(ctx context.Context, root string, tr *tar.Reader, options ApplyOptions) (size int64, err error) {
	home, id := filepath.Split(root)
	info := hcsshim.DriverInfo{
		HomeDir: home,
	}
	w, err := hcsshim.NewLayerWriter(info, id, options.ParentLayerPaths)
	if err != nil {
		return 0, err
	}
	defer func() {
		if err2 := w.Close(); err2 != nil {
			if err == nil {
				err = err2
			}
		}
	}()
	buf := bufio.NewWriter(nil)
	hdr, nextErr := tr.Next()
	for {
		select {
		case <-ctx.Done():
			return 0, ctx.Err()
		default:
		}
		if nextErr == io.EOF {
			break
		}
		if nextErr != nil {
			return 0, nextErr
		}
		base := path.Base(hdr.Name)
		if strings.HasPrefix(base, whiteoutPrefix) {
			dir := path.Dir(hdr.Name)
			originalBase := base[len(whiteoutPrefix):]
			originalPath := path.Join(dir, originalBase)
			if err := w.Remove(filepath.FromSlash(originalPath)); err != nil {
				return 0, err
			}
			hdr, nextErr = tr.Next()
		} else if hdr.Typeflag == tar.TypeLink {
			err := w.AddLink(filepath.FromSlash(hdr.Name), filepath.FromSlash(hdr.Linkname))
			if err != nil {
				return 0, err
			}
			hdr, nextErr = tr.Next()
		} else {
			name, fileSize, fileInfo, err := fileInfoFromHeader(hdr)
			if err != nil {
				return 0, err
			}
			if err := w.Add(filepath.FromSlash(name), fileInfo); err != nil {
				return 0, err
			}
			size += fileSize
			hdr, nextErr = tarToBackupStreamWithMutatedFiles(buf, w, tr, hdr, root)
		}
	}
	return
}
func fileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *winio.FileBasicInfo, err error) {
	name = hdr.Name
	if hdr.Typeflag == tar.TypeReg || hdr.Typeflag == tar.TypeRegA {
		size = hdr.Size
	}
	fileInfo = &winio.FileBasicInfo{
		LastAccessTime: syscall.NsecToFiletime(hdr.AccessTime.UnixNano()),
		LastWriteTime:  syscall.NsecToFiletime(hdr.ModTime.UnixNano()),
		ChangeTime:     syscall.NsecToFiletime(hdr.ChangeTime.UnixNano()),
		CreationTime: syscall.NsecToFiletime(hdr.ModTime.UnixNano()),
	}
	if attrStr, ok := hdr.PAXRecords[hdrFileAttributes]; ok {
		attr, err := strconv.ParseUint(attrStr, 10, 32)
		if err != nil {
			return "", 0, nil, err
		}
		fileInfo.FileAttributes = uint32(attr)
	} else {
		if hdr.Typeflag == tar.TypeDir {
			fileInfo.FileAttributes |= syscall.FILE_ATTRIBUTE_DIRECTORY
		}
	}
	if createStr, ok := hdr.PAXRecords[hdrCreateTime]; ok {
		createTime, err := parsePAXTime(createStr)
		if err != nil {
			return "", 0, nil, err
		}
		fileInfo.CreationTime = syscall.NsecToFiletime(createTime.UnixNano())
	}
	return
}