mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			152 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build windows
 | 
						|
 | 
						|
package vhd
 | 
						|
 | 
						|
import "syscall"
 | 
						|
 | 
						|
//go:generate go run mksyscall_windows.go -output zvhd.go vhd.go
 | 
						|
 | 
						|
//sys createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.CreateVirtualDisk
 | 
						|
//sys openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.OpenVirtualDisk
 | 
						|
//sys detachVirtualDisk(handle syscall.Handle, flags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = VirtDisk.DetachVirtualDisk
 | 
						|
 | 
						|
type virtualStorageType struct {
 | 
						|
	DeviceID uint32
 | 
						|
	VendorID [16]byte
 | 
						|
}
 | 
						|
 | 
						|
type (
 | 
						|
	createVirtualDiskFlag uint32
 | 
						|
	VirtualDiskAccessMask uint32
 | 
						|
	VirtualDiskFlag       uint32
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	// Flags for creating a VHD (not exported)
 | 
						|
	createVirtualDiskFlagNone                        createVirtualDiskFlag = 0
 | 
						|
	createVirtualDiskFlagFullPhysicalAllocation      createVirtualDiskFlag = 1
 | 
						|
	createVirtualDiskFlagPreventWritesToSourceDisk   createVirtualDiskFlag = 2
 | 
						|
	createVirtualDiskFlagDoNotCopyMetadataFromParent createVirtualDiskFlag = 4
 | 
						|
 | 
						|
	// Access Mask for opening a VHD
 | 
						|
	VirtualDiskAccessNone     VirtualDiskAccessMask = 0
 | 
						|
	VirtualDiskAccessAttachRO VirtualDiskAccessMask = 65536
 | 
						|
	VirtualDiskAccessAttachRW VirtualDiskAccessMask = 131072
 | 
						|
	VirtualDiskAccessDetach   VirtualDiskAccessMask = 262144
 | 
						|
	VirtualDiskAccessGetInfo  VirtualDiskAccessMask = 524288
 | 
						|
	VirtualDiskAccessCreate   VirtualDiskAccessMask = 1048576
 | 
						|
	VirtualDiskAccessMetaOps  VirtualDiskAccessMask = 2097152
 | 
						|
	VirtualDiskAccessRead     VirtualDiskAccessMask = 851968
 | 
						|
	VirtualDiskAccessAll      VirtualDiskAccessMask = 4128768
 | 
						|
	VirtualDiskAccessWritable VirtualDiskAccessMask = 3276800
 | 
						|
 | 
						|
	// Flags for opening a VHD
 | 
						|
	OpenVirtualDiskFlagNone                        VirtualDiskFlag = 0
 | 
						|
	OpenVirtualDiskFlagNoParents                   VirtualDiskFlag = 0x1
 | 
						|
	OpenVirtualDiskFlagBlankFile                   VirtualDiskFlag = 0x2
 | 
						|
	OpenVirtualDiskFlagBootDrive                   VirtualDiskFlag = 0x4
 | 
						|
	OpenVirtualDiskFlagCachedIO                    VirtualDiskFlag = 0x8
 | 
						|
	OpenVirtualDiskFlagCustomDiffChain             VirtualDiskFlag = 0x10
 | 
						|
	OpenVirtualDiskFlagParentCachedIO              VirtualDiskFlag = 0x20
 | 
						|
	OpenVirtualDiskFlagVhdSetFileOnly              VirtualDiskFlag = 0x40
 | 
						|
	OpenVirtualDiskFlagIgnoreRelativeParentLocator VirtualDiskFlag = 0x80
 | 
						|
	OpenVirtualDiskFlagNoWriteHardening            VirtualDiskFlag = 0x100
 | 
						|
)
 | 
						|
 | 
						|
type createVersion2 struct {
 | 
						|
	UniqueID                 [16]byte // GUID
 | 
						|
	MaximumSize              uint64
 | 
						|
	BlockSizeInBytes         uint32
 | 
						|
	SectorSizeInBytes        uint32
 | 
						|
	ParentPath               *uint16 // string
 | 
						|
	SourcePath               *uint16 // string
 | 
						|
	OpenFlags                uint32
 | 
						|
	ParentVirtualStorageType virtualStorageType
 | 
						|
	SourceVirtualStorageType virtualStorageType
 | 
						|
	ResiliencyGUID           [16]byte // GUID
 | 
						|
}
 | 
						|
 | 
						|
type createVirtualDiskParameters struct {
 | 
						|
	Version  uint32 // Must always be set to 2
 | 
						|
	Version2 createVersion2
 | 
						|
}
 | 
						|
 | 
						|
type openVersion2 struct {
 | 
						|
	GetInfoOnly    int32    // bool but 4-byte aligned
 | 
						|
	ReadOnly       int32    // bool but 4-byte aligned
 | 
						|
	ResiliencyGUID [16]byte // GUID
 | 
						|
}
 | 
						|
 | 
						|
type openVirtualDiskParameters struct {
 | 
						|
	Version  uint32 // Must always be set to 2
 | 
						|
	Version2 openVersion2
 | 
						|
}
 | 
						|
 | 
						|
// CreateVhdx will create a simple vhdx file at the given path using default values.
 | 
						|
func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {
 | 
						|
	var (
 | 
						|
		defaultType virtualStorageType
 | 
						|
		handle      syscall.Handle
 | 
						|
	)
 | 
						|
 | 
						|
	parameters := createVirtualDiskParameters{
 | 
						|
		Version: 2,
 | 
						|
		Version2: createVersion2{
 | 
						|
			MaximumSize:      uint64(maxSizeInGb) * 1024 * 1024 * 1024,
 | 
						|
			BlockSizeInBytes: blockSizeInMb * 1024 * 1024,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	if err := createVirtualDisk(
 | 
						|
		&defaultType,
 | 
						|
		path,
 | 
						|
		uint32(VirtualDiskAccessNone),
 | 
						|
		nil,
 | 
						|
		uint32(createVirtualDiskFlagNone),
 | 
						|
		0,
 | 
						|
		¶meters,
 | 
						|
		nil,
 | 
						|
		&handle); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	if err := syscall.CloseHandle(handle); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// DetachVhd detaches a mounted container layer vhd found at `path`.
 | 
						|
func DetachVhd(path string) error {
 | 
						|
	handle, err := OpenVirtualDisk(
 | 
						|
		path,
 | 
						|
		VirtualDiskAccessNone,
 | 
						|
		OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator)
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	defer syscall.CloseHandle(handle)
 | 
						|
	return detachVirtualDisk(handle, 0, 0)
 | 
						|
}
 | 
						|
 | 
						|
// OpenVirtualDisk obtains a handle to a VHD opened with supplied access mask and flags.
 | 
						|
func OpenVirtualDisk(path string, accessMask VirtualDiskAccessMask, flag VirtualDiskFlag) (syscall.Handle, error) {
 | 
						|
	var (
 | 
						|
		defaultType virtualStorageType
 | 
						|
		handle      syscall.Handle
 | 
						|
	)
 | 
						|
	parameters := openVirtualDiskParameters{Version: 2}
 | 
						|
	if err := openVirtualDisk(
 | 
						|
		&defaultType,
 | 
						|
		path,
 | 
						|
		uint32(accessMask),
 | 
						|
		uint32(flag),
 | 
						|
		¶meters,
 | 
						|
		&handle); err != nil {
 | 
						|
		return 0, err
 | 
						|
	}
 | 
						|
	return handle, nil
 | 
						|
}
 |