forked from jim-minter/vhd-footer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
96 lines (79 loc) · 1.92 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package main
import (
"bytes"
"encoding/binary"
"flag"
"os"
"time"
"github.com/satori/go.uuid"
)
var (
size = flag.Uint64("size", 0, "image size in bytes")
)
// from
// http://download.microsoft.com/download/f/f/e/ffef50a5-07dd-4cf8-aaa3-442c0673a029/Virtual%20Hard%20Disk%20Format%20Spec_10_18_06.doc
type vhdFooter struct {
Cookie [8]byte
Features uint32
FileFormatVersion uint32
DataOffset uint64
TimeStamp uint32
CreatorApplication [4]byte
CreatorVersion uint32
CreatorHostOS [4]byte
OriginalSize uint64
CurrentSize uint64
DiskGeometry uint32
DiskType uint32
Checksum uint32
UniqueID uuid.UUID
SavedState uint8
Reserved [427]byte
}
func (f *vhdFooter) CalculateChecksum() error {
f.Checksum = 0
buf := &bytes.Buffer{}
err := binary.Write(buf, binary.BigEndian, f)
if err != nil {
return err
}
for _, b := range buf.Bytes() {
f.Checksum += uint32(b)
}
f.Checksum = ^f.Checksum
return nil
}
func main() {
flag.Parse()
if *size == 0 {
flag.Usage()
os.Exit(2)
}
id, err := uuid.NewV4()
if err != nil {
panic(err)
}
f := vhdFooter{
Features: 2, // reserved
FileFormatVersion: 0x00010000, // 1.0
DataOffset: 0xffffffffffffffff,
TimeStamp: uint32(time.Now().Sub(time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)) / time.Second),
CreatorVersion: 0x00050003, // 5.3
OriginalSize: *size,
CurrentSize: *size,
DiskGeometry: 0xffff10ff, // 65535 cylinders, 16 heads, 255 sectors
DiskType: 2, // fixed
UniqueID: id,
}
copy(f.Cookie[:], []byte("conectix"))
copy(f.CreatorApplication[:], []byte("qem2"))
copy(f.CreatorHostOS[:], []byte("Wi2k"))
err = f.CalculateChecksum()
if err != nil {
panic(err)
}
err = binary.Write(os.Stdout, binary.BigEndian, f)
if err != nil {
panic(err)
}
}