Class: Vhd::Library

Inherits:
Object
  • Object
show all
Defined in:
lib/vhd/library.rb

Constant Summary collapse

VALID_TYPES =
[:fixed]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Library

Returns a new instance of Library.



6
7
8
9
10
11
12
13
14
15
# File 'lib/vhd/library.rb', line 6

def initialize(options={})
  raise "Invalid vhd type" unless VALID_TYPES.include?(options[:type])
  raise "Name is required" unless options[:name]
  raise "Size is required" unless options[:size]
  @name   = options[:name]
  @footer = {}
  @size   = options[:size]

  self.generate_footer
end

Instance Attribute Details

Returns the value of attribute footer.



4
5
6
# File 'lib/vhd/library.rb', line 4

def footer
  @footer
end

#nameObject (readonly)

Returns the value of attribute name.



4
5
6
# File 'lib/vhd/library.rb', line 4

def name
  @name
end

#sizeObject (readonly)

Returns the value of attribute size.



4
5
6
# File 'lib/vhd/library.rb', line 4

def size
  @size
end

Instance Method Details

#checksumObject



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/vhd/library.rb', line 77

def checksum
  checksum = 0

  @footer.each do |k,v|
    next if k == :checksum

    checksum += v.codepoints.inject(0) { |r,c| r += c }
  end

  @footer[:checksum] = ["%08x" % ((~checksum).abs ^ 0xFFFFFFFF)].pack("H*")
end

#createObject



17
18
19
# File 'lib/vhd/library.rb', line 17

def create
  File.open(@name, "wb") { |f| f.print @footer.values.join }
end


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/vhd/library.rb', line 21

def generate_footer(options={})
  @footer[:cookie]       = "conectix".force_encoding("BINARY")
  @footer[:features]     = ["00000002"].pack("H*")
  @footer[:ff]           = ["00010000"].pack("H*")
  @footer[:offset]       = ["FFFFFFFFFFFFFFFF"].pack("H*")
  @footer[:time]         = [(Time.now - Time.parse("Jan 1, 2000 12:00:00 AM GMT")).to_i.to_s(16)].pack("H*")
  @footer[:creator_app]  = "rvhd".force_encoding("UTF-8")
  @footer[:creator_ver]  = ["00060002"].pack("H*")
  @footer[:creator_host] = "Wi2k".force_encoding("UTF-8")
  @footer[:orig_size]    = size_in_hex
  @footer[:curr_size]    = size_in_hex
  @footer[:geometry]     = nil
  @footer[:disk_type]    = ["00000002"].pack("H*")
  @footer[:checksum]     = nil
  @footer[:uuid]         = SecureRandom.hex.scan(/../).map { |c| c.hex.chr.force_encoding("BINARY") }.join
  @footer[:state]        = ["0"].pack("H*")
  @footer[:reserved]     = Array("00"*427).pack("H*")

  self.geometry
  self.checksum
end

#geometryObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/vhd/library.rb', line 53

def geometry
  max_size      = 65535 * 16 * 255 * 512
  capacity      = size_in_bytes > max_size ? max_size : size_in_bytes
  total_sectors = capacity / 512

  if total_sectors > (65535 * 16 * 63)
    sectors_per_track  = 255
    heads_per_cylinder = 16
  else
    sectors_per_track     = 17
    cylinders_times_heads = total_sectors / sectors_per_track
    heads_per_cylinder    = (cylinders_times_heads + 1023) / 1024
    heads_per_cylinder    = 4 if heads_per_cylinder < 4

    cylinders_times_heads >= ((heads_per_cylinder * 1024) or (heads_per_cylinder > 16))
    sectors_per_track  = 63
    heads_per_cylinder = 16
  end

  cylinders = (total_sectors / sectors_per_track) / heads_per_cylinder

  @footer[:geometry] = [cylinders, heads_per_cylinder, sectors_per_track].pack("SCC")
end

#size_in_bytesObject



43
44
45
# File 'lib/vhd/library.rb', line 43

def size_in_bytes
  (((@size * 1024) * 1024) * 1024).to_i
end

#size_in_hexObject



47
48
49
50
51
# File 'lib/vhd/library.rb', line 47

def size_in_hex
  hex_size = size_in_bytes.to_s(16)
  hex_size = "0" + hex_size until hex_size.length == 16
  [hex_size].pack("H*")
end