update vendor pkg to support azure disk provisioning
Signed-off-by: Huamin Chen <hchen@redhat.com>
This commit is contained in:
22
vendor/github.com/rubiojr/go-vhd/LICENSE
generated
vendored
Normal file
22
vendor/github.com/rubiojr/go-vhd/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Sergio Rubio
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
73
vendor/github.com/rubiojr/go-vhd/vhd/util.go
generated
vendored
Normal file
73
vendor/github.com/rubiojr/go-vhd/vhd/util.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
package vhd
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// https://groups.google.com/forum/#!msg/golang-nuts/d0nF_k4dSx4/rPGgfXv6QCoJ
|
||||
func uuidgen() string {
|
||||
b := uuidgenBytes()
|
||||
return fmt.Sprintf("%x-%x-%x-%x-%x",
|
||||
b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
}
|
||||
|
||||
func fmtField(name, value string) {
|
||||
fmt.Printf("%-25s%s\n", name+":", value)
|
||||
}
|
||||
|
||||
func uuidgenBytes() []byte {
|
||||
f, err := os.Open("/dev/urandom")
|
||||
check(err)
|
||||
b := make([]byte, 16)
|
||||
f.Read(b)
|
||||
return b
|
||||
}
|
||||
|
||||
func check(e error) {
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
func hexs(a []byte) string {
|
||||
return "0x" + hex.EncodeToString(a[:])
|
||||
}
|
||||
|
||||
func uuid(a []byte) string {
|
||||
return fmt.Sprintf("%08x-%04x-%04x-%04x-%04x",
|
||||
a[:4],
|
||||
a[4:6],
|
||||
a[6:8],
|
||||
a[8:10],
|
||||
a[10:16])
|
||||
}
|
||||
|
||||
func uuidToBytes(uuid string) []byte {
|
||||
s := strings.Replace(uuid, "-", "", -1)
|
||||
h, err := hex.DecodeString(s)
|
||||
check(err)
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
/*
|
||||
utf16BytesToString converts UTF-16 encoded bytes, in big or
|
||||
little endian byte order, to a UTF-8 encoded string.
|
||||
http://stackoverflow.com/a/15794113
|
||||
*/
|
||||
func utf16BytesToString(b []byte, o binary.ByteOrder) string {
|
||||
utf := make([]uint16, (len(b)+(2-1))/2)
|
||||
for i := 0; i+(2-1) < len(b); i += 2 {
|
||||
utf[i/2] = o.Uint16(b[i:])
|
||||
}
|
||||
if len(b)/2 < len(utf) {
|
||||
utf[len(utf)-1] = utf8.RuneError
|
||||
}
|
||||
return string(utf16.Decode(utf))
|
||||
}
|
480
vendor/github.com/rubiojr/go-vhd/vhd/vhd.go
generated
vendored
Normal file
480
vendor/github.com/rubiojr/go-vhd/vhd/vhd.go
generated
vendored
Normal file
@@ -0,0 +1,480 @@
|
||||
// Package to work with VHD images
|
||||
// See https://technet.microsoft.com/en-us/virtualization/bb676673.aspx
|
||||
package vhd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const VHD_COOKIE = "636f6e6563746978" // conectix
|
||||
const VHD_DYN_COOKIE = "6378737061727365" // cxsparse
|
||||
const VHD_CREATOR_APP = "676f2d766864" // go-vhd
|
||||
const VHD_CREATOR_HOST_OS = "5769326B" // Win2k
|
||||
const VHD_BLOCK_SIZE = 2 * 1024 * 1024 // 2MB
|
||||
const VHD_HEADER_SIZE = 512
|
||||
const SECTOR_SIZE = 512
|
||||
const FOURK_SECTOR_SIZE = 4096
|
||||
const VHD_EXTRA_HEADER_SIZE = 1024
|
||||
|
||||
// A VDH file
|
||||
type VHD struct {
|
||||
Footer VHDHeader
|
||||
ExtraHeader VHDExtraHeader
|
||||
}
|
||||
|
||||
// VHD Header
|
||||
type VHDHeader struct {
|
||||
Cookie [8]byte
|
||||
Features [4]byte
|
||||
FileFormatVersion [4]byte
|
||||
DataOffset [8]byte
|
||||
Timestamp [4]byte
|
||||
CreatorApplication [4]byte
|
||||
CreatorVersion [4]byte
|
||||
CreatorHostOS [4]byte
|
||||
OriginalSize [8]byte
|
||||
CurrentSize [8]byte
|
||||
DiskGeometry [4]byte
|
||||
DiskType [4]byte
|
||||
Checksum [4]byte
|
||||
UniqueId [16]byte
|
||||
SavedState [1]byte
|
||||
Reserved [427]byte
|
||||
}
|
||||
|
||||
// VHD extra header, for dynamic and differential disks
|
||||
type VHDExtraHeader struct {
|
||||
Cookie [8]byte
|
||||
DataOffset [8]byte
|
||||
TableOffset [8]byte
|
||||
HeaderVersion [4]byte
|
||||
MaxTableEntries [4]byte
|
||||
BlockSize [4]byte
|
||||
Checksum [4]byte
|
||||
ParentUUID [16]byte
|
||||
ParentTimestamp [4]byte
|
||||
Reserved [4]byte
|
||||
ParentUnicodeName [512]byte
|
||||
ParentLocatorEntry1 [24]byte
|
||||
ParentLocatorEntry2 [24]byte
|
||||
ParentLocatorEntry3 [24]byte
|
||||
ParentLocatorEntry4 [24]byte
|
||||
ParentLocatorEntry5 [24]byte
|
||||
ParentLocatorEntry6 [24]byte
|
||||
ParentLocatorEntry7 [24]byte
|
||||
ParentLocatorEntry8 [24]byte
|
||||
Reserved2 [256]byte
|
||||
}
|
||||
|
||||
// Options for the CreateSparseVHD function
|
||||
type VHDOptions struct {
|
||||
UUID string
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
/*
|
||||
* VHDExtraHeader methods
|
||||
*/
|
||||
|
||||
func (header *VHDExtraHeader) CookieString() string {
|
||||
return string(header.Cookie[:])
|
||||
}
|
||||
|
||||
// Calculate and add the VHD dynamic/differential header checksum
|
||||
func (h *VHDExtraHeader) addChecksum() {
|
||||
buffer := new(bytes.Buffer)
|
||||
binary.Write(buffer, binary.BigEndian, h)
|
||||
checksum := 0
|
||||
bb := buffer.Bytes()
|
||||
|
||||
for counter := 0; counter < VHD_EXTRA_HEADER_SIZE; counter++ {
|
||||
checksum += int(bb[counter])
|
||||
}
|
||||
|
||||
binary.BigEndian.PutUint32(h.Checksum[:], uint32(^checksum))
|
||||
}
|
||||
|
||||
/*
|
||||
* VHDHeader methods
|
||||
*/
|
||||
|
||||
func (h *VHDHeader) DiskTypeStr() (dt string) {
|
||||
switch h.DiskType[3] {
|
||||
case 0x00:
|
||||
dt = "None"
|
||||
case 0x01:
|
||||
dt = "Deprecated"
|
||||
case 0x02:
|
||||
dt = "Fixed"
|
||||
case 0x03:
|
||||
dt = "Dynamic"
|
||||
case 0x04:
|
||||
dt = "Differential"
|
||||
case 0x05:
|
||||
dt = "Reserved"
|
||||
case 0x06:
|
||||
dt = "Reserved"
|
||||
default:
|
||||
panic("Invalid disk type detected!")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Return the timestamp of the header
|
||||
func (h *VHDHeader) TimestampTime() time.Time {
|
||||
tstamp := binary.BigEndian.Uint32(h.Timestamp[:])
|
||||
return time.Unix(int64(946684800+tstamp), 0)
|
||||
}
|
||||
|
||||
// Calculate and add the VHD header checksum
|
||||
func (h *VHDHeader) addChecksum() {
|
||||
buffer := new(bytes.Buffer)
|
||||
binary.Write(buffer, binary.BigEndian, h)
|
||||
checksum := 0
|
||||
bb := buffer.Bytes()
|
||||
|
||||
for counter := 0; counter < VHD_HEADER_SIZE; counter++ {
|
||||
checksum += int(bb[counter])
|
||||
}
|
||||
|
||||
binary.BigEndian.PutUint32(h.Checksum[:], uint32(^checksum))
|
||||
}
|
||||
|
||||
func CreateFixedHeader(size uint64, options *VHDOptions) VHDHeader {
|
||||
header := VHDHeader{}
|
||||
hexToField(VHD_COOKIE, header.Cookie[:])
|
||||
hexToField("00000002", header.Features[:])
|
||||
hexToField("00010000", header.FileFormatVersion[:])
|
||||
hexToField("ffffffffffffffff", header.DataOffset[:])
|
||||
|
||||
// LOL Y2038
|
||||
if options.Timestamp != 0 {
|
||||
binary.BigEndian.PutUint32(header.Timestamp[:], uint32(options.Timestamp))
|
||||
} else {
|
||||
t := uint32(time.Now().Unix() - 946684800)
|
||||
binary.BigEndian.PutUint32(header.Timestamp[:], t)
|
||||
}
|
||||
|
||||
hexToField(VHD_CREATOR_APP, header.CreatorApplication[:])
|
||||
hexToField(VHD_CREATOR_HOST_OS, header.CreatorHostOS[:])
|
||||
binary.BigEndian.PutUint64(header.OriginalSize[:], size)
|
||||
binary.BigEndian.PutUint64(header.CurrentSize[:], size)
|
||||
|
||||
// total sectors = disk size / 512b sector size
|
||||
totalSectors := math.Floor(float64(size / 512))
|
||||
// [C, H, S]
|
||||
geometry := calculateCHS(uint64(totalSectors))
|
||||
binary.BigEndian.PutUint16(header.DiskGeometry[:2], uint16(geometry[0]))
|
||||
header.DiskGeometry[2] = uint8(geometry[1])
|
||||
header.DiskGeometry[3] = uint8(geometry[2])
|
||||
|
||||
hexToField("00000002", header.DiskType[:]) // Fixed 0x00000002
|
||||
hexToField("00000000", header.Checksum[:])
|
||||
|
||||
if options.UUID != "" {
|
||||
copy(header.UniqueId[:], uuidToBytes(options.UUID))
|
||||
} else {
|
||||
copy(header.UniqueId[:], uuidgenBytes())
|
||||
}
|
||||
|
||||
header.addChecksum()
|
||||
return header
|
||||
}
|
||||
|
||||
func RawToFixed(f *os.File, options *VHDOptions) {
|
||||
info, err := f.Stat()
|
||||
check(err)
|
||||
size := uint64(info.Size())
|
||||
header := CreateFixedHeader(size, options)
|
||||
binary.Write(f, binary.BigEndian, header)
|
||||
}
|
||||
|
||||
func VHDCreateSparse(size uint64, name string, options VHDOptions) VHD {
|
||||
header := VHDHeader{}
|
||||
hexToField(VHD_COOKIE, header.Cookie[:])
|
||||
hexToField("00000002", header.Features[:])
|
||||
hexToField("00010000", header.FileFormatVersion[:])
|
||||
hexToField("0000000000000200", header.DataOffset[:])
|
||||
|
||||
// LOL Y2038
|
||||
if options.Timestamp != 0 {
|
||||
binary.BigEndian.PutUint32(header.Timestamp[:], uint32(options.Timestamp))
|
||||
} else {
|
||||
t := uint32(time.Now().Unix() - 946684800)
|
||||
binary.BigEndian.PutUint32(header.Timestamp[:], t)
|
||||
}
|
||||
|
||||
hexToField(VHD_CREATOR_APP, header.CreatorApplication[:])
|
||||
hexToField(VHD_CREATOR_HOST_OS, header.CreatorHostOS[:])
|
||||
binary.BigEndian.PutUint64(header.OriginalSize[:], size)
|
||||
binary.BigEndian.PutUint64(header.CurrentSize[:], size)
|
||||
|
||||
// total sectors = disk size / 512b sector size
|
||||
totalSectors := math.Floor(float64(size / 512))
|
||||
// [C, H, S]
|
||||
geometry := calculateCHS(uint64(totalSectors))
|
||||
binary.BigEndian.PutUint16(header.DiskGeometry[:2], uint16(geometry[0]))
|
||||
header.DiskGeometry[2] = uint8(geometry[1])
|
||||
header.DiskGeometry[3] = uint8(geometry[2])
|
||||
|
||||
hexToField("00000003", header.DiskType[:]) // Sparse 0x00000003
|
||||
hexToField("00000000", header.Checksum[:])
|
||||
|
||||
if options.UUID != "" {
|
||||
copy(header.UniqueId[:], uuidToBytes(options.UUID))
|
||||
} else {
|
||||
copy(header.UniqueId[:], uuidgenBytes())
|
||||
}
|
||||
|
||||
header.addChecksum()
|
||||
|
||||
// Fill the sparse header
|
||||
header2 := VHDExtraHeader{}
|
||||
hexToField(VHD_DYN_COOKIE, header2.Cookie[:])
|
||||
hexToField("ffffffffffffffff", header2.DataOffset[:])
|
||||
// header size + sparse header size
|
||||
binary.BigEndian.PutUint64(header2.TableOffset[:], uint64(VHD_EXTRA_HEADER_SIZE+VHD_HEADER_SIZE))
|
||||
hexToField("00010000", header2.HeaderVersion[:])
|
||||
|
||||
maxTableSize := uint32(size / (VHD_BLOCK_SIZE))
|
||||
binary.BigEndian.PutUint32(header2.MaxTableEntries[:], maxTableSize)
|
||||
|
||||
binary.BigEndian.PutUint32(header2.BlockSize[:], VHD_BLOCK_SIZE)
|
||||
binary.BigEndian.PutUint32(header2.ParentTimestamp[:], uint32(0))
|
||||
header2.addChecksum()
|
||||
|
||||
f, err := os.Create(name)
|
||||
check(err)
|
||||
defer f.Close()
|
||||
|
||||
binary.Write(f, binary.BigEndian, header)
|
||||
binary.Write(f, binary.BigEndian, header2)
|
||||
|
||||
/*
|
||||
Write BAT entries
|
||||
The BAT is always extended to a sector (4K) boundary
|
||||
1536 = 512 + 1024 (the VHD Header + VHD Sparse header size)
|
||||
*/
|
||||
for count := uint32(0); count < (FOURK_SECTOR_SIZE - 1536); count += 1 {
|
||||
f.Write([]byte{0xff})
|
||||
}
|
||||
|
||||
/* Windows creates 8K VHDs by default */
|
||||
for i := 0; i < (FOURK_SECTOR_SIZE - VHD_HEADER_SIZE); i += 1 {
|
||||
f.Write([]byte{0x0})
|
||||
}
|
||||
|
||||
binary.Write(f, binary.BigEndian, header)
|
||||
|
||||
return VHD{
|
||||
Footer: header,
|
||||
ExtraHeader: header2,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* VHD
|
||||
*/
|
||||
|
||||
func FromFile(f *os.File) (vhd VHD) {
|
||||
vhd = VHD{}
|
||||
vhd.Footer = readVHDFooter(f)
|
||||
vhd.ExtraHeader = readVHDExtraHeader(f)
|
||||
|
||||
return vhd
|
||||
}
|
||||
|
||||
func (vhd *VHD) PrintInfo() {
|
||||
fmt.Println("\nVHD footer")
|
||||
fmt.Println("==========")
|
||||
vhd.PrintFooter()
|
||||
|
||||
if vhd.Footer.DiskType[3] == 0x3 || vhd.Footer.DiskType[3] == 0x04 {
|
||||
fmt.Println("\nVHD sparse/differential header")
|
||||
fmt.Println("===============================")
|
||||
vhd.PrintExtraHeader()
|
||||
}
|
||||
}
|
||||
|
||||
func (vhd *VHD) PrintExtraHeader() {
|
||||
header := vhd.ExtraHeader
|
||||
|
||||
fmtField("Cookie", fmt.Sprintf("%s (%s)",
|
||||
hexs(header.Cookie[:]), header.CookieString()))
|
||||
fmtField("Data offset", hexs(header.DataOffset[:]))
|
||||
fmtField("Table offset", hexs(header.TableOffset[:]))
|
||||
fmtField("Header version", hexs(header.HeaderVersion[:]))
|
||||
fmtField("Max table entries", hexs(header.MaxTableEntries[:]))
|
||||
fmtField("Block size", hexs(header.BlockSize[:]))
|
||||
fmtField("Checksum", hexs(header.Checksum[:]))
|
||||
fmtField("Parent UUID", uuid(header.ParentUUID[:]))
|
||||
|
||||
// Seconds since January 1, 1970 12:00:00 AM in UTC/GMT.
|
||||
// 946684800 = January 1, 2000 12:00:00 AM in UTC/GMT.
|
||||
tstamp := binary.BigEndian.Uint32(header.ParentTimestamp[:])
|
||||
t := time.Unix(int64(946684800+tstamp), 0)
|
||||
fmtField("Parent timestamp", fmt.Sprintf("%s", t))
|
||||
|
||||
fmtField("Reserved", hexs(header.Reserved[:]))
|
||||
parentName := utf16BytesToString(header.ParentUnicodeName[:],
|
||||
binary.BigEndian)
|
||||
fmtField("Parent Name", parentName)
|
||||
// Parent locator entries ignored since it's a dynamic disk
|
||||
sum := 0
|
||||
for _, b := range header.Reserved2 {
|
||||
sum += int(b)
|
||||
}
|
||||
fmtField("Reserved2", strconv.Itoa(sum))
|
||||
}
|
||||
|
||||
func (vhd *VHD) PrintFooter() {
|
||||
header := vhd.Footer
|
||||
|
||||
//fmtField("Cookie", string(header.Cookie[:]))
|
||||
fmtField("Cookie", fmt.Sprintf("%s (%s)",
|
||||
hexs(header.Cookie[:]), string(header.Cookie[:])))
|
||||
fmtField("Features", hexs(header.Features[:]))
|
||||
fmtField("File format version", hexs(header.FileFormatVersion[:]))
|
||||
|
||||
dataOffset := binary.BigEndian.Uint64(header.DataOffset[:])
|
||||
fmtField("Data offset",
|
||||
fmt.Sprintf("%s (%d bytes)", hexs(header.DataOffset[:]), dataOffset))
|
||||
|
||||
//// Seconds since January 1, 1970 12:00:00 AM in UTC/GMT.
|
||||
//// 946684800 = January 1, 2000 12:00:00 AM in UTC/GMT.
|
||||
t := time.Unix(int64(946684800+binary.BigEndian.Uint32(header.Timestamp[:])), 0)
|
||||
fmtField("Timestamp", fmt.Sprintf("%s", t))
|
||||
|
||||
fmtField("Creator application", string(header.CreatorApplication[:]))
|
||||
fmtField("Creator version", hexs(header.CreatorVersion[:]))
|
||||
fmtField("Creator OS", string(header.CreatorHostOS[:]))
|
||||
|
||||
originalSize := binary.BigEndian.Uint64(header.OriginalSize[:])
|
||||
fmtField("Original size",
|
||||
fmt.Sprintf("%s ( %d bytes )", hexs(header.OriginalSize[:]), originalSize))
|
||||
|
||||
currentSize := binary.BigEndian.Uint64(header.OriginalSize[:])
|
||||
fmtField("Current size",
|
||||
fmt.Sprintf("%s ( %d bytes )", hexs(header.CurrentSize[:]), currentSize))
|
||||
|
||||
cilinders := int64(binary.BigEndian.Uint16(header.DiskGeometry[:2]))
|
||||
heads := int64(header.DiskGeometry[2])
|
||||
sectors := int64(header.DiskGeometry[3])
|
||||
dsize := cilinders * heads * sectors * 512
|
||||
fmtField("Disk geometry",
|
||||
fmt.Sprintf("%s (c: %d, h: %d, s: %d) (%d bytes)",
|
||||
hexs(header.DiskGeometry[:]),
|
||||
cilinders,
|
||||
heads,
|
||||
sectors,
|
||||
dsize))
|
||||
|
||||
fmtField("Disk type",
|
||||
fmt.Sprintf("%s (%s)", hexs(header.DiskType[:]), header.DiskTypeStr()))
|
||||
|
||||
fmtField("Checksum", hexs(header.Checksum[:]))
|
||||
fmtField("UUID", uuid(header.UniqueId[:]))
|
||||
fmtField("Saved state", fmt.Sprintf("%d", header.SavedState[0]))
|
||||
}
|
||||
|
||||
/*
|
||||
Utility functions
|
||||
*/
|
||||
func calculateCHS(ts uint64) []uint {
|
||||
var sectorsPerTrack,
|
||||
heads,
|
||||
cylinderTimesHeads,
|
||||
cylinders float64
|
||||
totalSectors := float64(ts)
|
||||
|
||||
ret := make([]uint, 3)
|
||||
|
||||
if totalSectors > 65535*16*255 {
|
||||
totalSectors = 65535 * 16 * 255
|
||||
}
|
||||
|
||||
if totalSectors >= 65535*16*63 {
|
||||
sectorsPerTrack = 255
|
||||
heads = 16
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
} else {
|
||||
sectorsPerTrack = 17
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
heads = math.Floor((cylinderTimesHeads + 1023) / 1024)
|
||||
if heads < 4 {
|
||||
heads = 4
|
||||
}
|
||||
if (cylinderTimesHeads >= (heads * 1024)) || heads > 16 {
|
||||
sectorsPerTrack = 31
|
||||
heads = 16
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
}
|
||||
if cylinderTimesHeads >= (heads * 1024) {
|
||||
sectorsPerTrack = 63
|
||||
heads = 16
|
||||
cylinderTimesHeads = math.Floor(totalSectors / sectorsPerTrack)
|
||||
}
|
||||
}
|
||||
|
||||
cylinders = cylinderTimesHeads / heads
|
||||
|
||||
// This will floor the values
|
||||
ret[0] = uint(cylinders)
|
||||
ret[1] = uint(heads)
|
||||
ret[2] = uint(sectorsPerTrack)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func hexToField(hexs string, field []byte) {
|
||||
h, err := hex.DecodeString(hexs)
|
||||
check(err)
|
||||
|
||||
copy(field, h)
|
||||
}
|
||||
|
||||
// Return the number of blocks in the disk, diskSize in bytes
|
||||
func getMaxTableEntries(diskSize uint64) uint64 {
|
||||
return diskSize * (2 * 1024 * 1024) // block size is 2M
|
||||
}
|
||||
|
||||
func readVHDExtraHeader(f *os.File) (header VHDExtraHeader) {
|
||||
buff := make([]byte, 1024)
|
||||
_, err := f.ReadAt(buff, 512)
|
||||
check(err)
|
||||
|
||||
binary.Read(bytes.NewBuffer(buff[:]), binary.BigEndian, &header)
|
||||
|
||||
return header
|
||||
}
|
||||
|
||||
func readVHDFooter(f *os.File) (header VHDHeader) {
|
||||
info, err := f.Stat()
|
||||
check(err)
|
||||
|
||||
buff := make([]byte, 512)
|
||||
_, err = f.ReadAt(buff, info.Size()-512)
|
||||
check(err)
|
||||
|
||||
binary.Read(bytes.NewBuffer(buff[:]), binary.BigEndian, &header)
|
||||
|
||||
return header
|
||||
}
|
||||
|
||||
func readVHDHeader(f *os.File) (header VHDHeader) {
|
||||
buff := make([]byte, 512)
|
||||
_, err := f.ReadAt(buff, 0)
|
||||
check(err)
|
||||
|
||||
binary.Read(bytes.NewBuffer(buff[:]), binary.BigEndian, &header)
|
||||
|
||||
return header
|
||||
}
|
Reference in New Issue
Block a user