mirror of https://github.com/docker/cli.git
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
|
||
|
}
|