Class: Exerb::Resource

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/exerb/resource.rb,
lib/exerb/resource/base.rb,
lib/exerb/resource/icon.rb,
lib/exerb/resource/binary.rb,
lib/exerb/resource/dialog.rb,
lib/exerb/resource/group_icon.rb,
lib/exerb/resource/version_info.rb

Overview

#

Defined Under Namespace

Classes: Base, Binary, Dialog, Entry, GroupIcon, Icon, VersionInfo

Constant Summary collapse

DEFAULT_LANG_ID =

Neutral

0x0400
RT_EXERB =
100
ID_EXERB =
1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResource

Returns a new instance of Resource.



34
35
36
# File 'lib/exerb/resource.rb', line 34

def initialize
   @entries = {}
end

Instance Attribute Details

#entriesObject (readonly)

Returns the value of attribute entries.



38
39
40
# File 'lib/exerb/resource.rb', line 38

def entries
  @entries
end

Class Method Details

.new_from_binary(bin, base) ⇒ Object



44
45
46
# File 'lib/exerb/resource.rb', line 44

def self.new_from_binary(bin, base)
  return self.read(StringIO.new(bin), base)
end

.new_from_pe_binary(bin) ⇒ Object

Raises:



48
49
50
51
52
53
54
# File 'lib/exerb/resource.rb', line 48

def self.new_from_pe_binary(bin)
  pe     = Exerb::Win32::PeFile.new_from_binary(bin)
  rsrc   = pe.sections.find { |sec| sec.name == '.rsrc' }
  raise(ExerbError, "a resource section was not found in the core") if rsrc.nil?

  return self.new_from_binary(bin[rsrc.pointer_to_raw_data, rsrc.virtual_size], rsrc.virtual_address)
end

.new_from_pe_file(filepath) ⇒ Object



56
57
58
# File 'lib/exerb/resource.rb', line 56

def self.new_from_pe_file(filepath)
  return File.open(filepath) { |file| self.new_from_pe_binary(file.read) }
end

.read(io, base) ⇒ Object



40
41
42
# File 'lib/exerb/resource.rb', line 40

def self.read(io, base)
  return self.new.read(io, base)
end

Instance Method Details

#add(type, id, data, lang = DEFAULT_LANG_ID) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/exerb/resource.rb', line 70

def add(type, id, data, lang = DEFAULT_LANG_ID)
  @entries[type] ||= {}
  @entries[type][id] ||= {}
  @entries[type][id][lang] = Exerb::Resource::Entry.new(type, id, lang, data)

  return self
end

#add_archive(archive) ⇒ Object



94
95
96
# File 'lib/exerb/resource.rb', line 94

def add_archive(archive)
  return self.add(Exerb::Resource::RT_EXERB, Exerb::Resource::ID_EXERB, archive)
end

#add_dialog(id, data, lang = DEFAULT_LANG_ID) ⇒ Object



86
87
88
# File 'lib/exerb/resource.rb', line 86

def add_dialog(id, data, lang = DEFAULT_LANG_ID)
  return self.add(Exerb::Win32::Const::RT_DIALOG, id, data, lang)
end

#add_group_icon(id, data, lang = DEFAULT_LANG_ID) ⇒ Object



82
83
84
# File 'lib/exerb/resource.rb', line 82

def add_group_icon(id, data, lang = DEFAULT_LANG_ID)
  return self.add(Exerb::Win32::Const::RT_GROUP_ICON, id, data, lang)
end

#add_icon(id, data, lang = DEFAULT_LANG_ID) ⇒ Object



78
79
80
# File 'lib/exerb/resource.rb', line 78

def add_icon(id, data, lang = DEFAULT_LANG_ID)
  return self.add(Exerb::Win32::Const::RT_ICON, id, data, lang)
end

#add_rcdata(id, contents) ⇒ Object



102
103
104
# File 'lib/exerb/resource.rb', line 102

def add_rcdata(id, contents)
  return self.add(Exerb::Win32::Const::RT_RCDATA, id, Exerb::Rcdata.new(contents))
end

#add_string(id, contents) ⇒ Object



98
99
100
# File 'lib/exerb/resource.rb', line 98

def add_string(id, contents)
   return self.add(Exerb::Win32::Const::RT_STRING, id, Exerb::String.new(id, contents))
end

#add_version(id, data, lang = DEFAULT_LANG_ID) ⇒ Object



90
91
92
# File 'lib/exerb/resource.rb', line 90

def add_version(id, data, lang = DEFAULT_LANG_ID)
  return self.add(Exerb::Win32::Const::RT_VERSION, id, data, lang)
end

#eachObject



60
61
62
63
64
65
66
67
68
# File 'lib/exerb/resource.rb', line 60

def each
  @entries.keys.sort.each { |type|
    @entries[type].keys.sort.each { |id|
      @entries[type][id].keys.sort.each { |lang|
        yield(@entries[type][id][lang])
      }
    }
  }
end

#merge(res) ⇒ Object



166
167
168
169
170
171
172
173
174
# File 'lib/exerb/resource.rb', line 166

def merge(res)
  res.each { |entry|
    @entries[entry.type] ||= {}
    @entries[entry.type][entry.id] ||= {}
    @entries[entry.type][entry.id][entry.lang] = entry
  }

  return self
end

#pack(base, reloc = []) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/exerb/resource.rb', line 106

def pack(base, reloc = [])
  root_dir = Exerb::Win32::ResourceDirectoryRoot.new

  @entries.keys.sort.each { |type|
    root_dir << Exerb::Win32::ResourceDirectory.new(type) { |type_dir|
      @entries[type].keys.sort.each { |id|
        type_dir << Exerb::Win32::ResourceDirectory.new(id) { |item_dir|
          @entries[type][id].keys.sort.each { |lang|
            item_dir << @entries[type][id][lang].to_resource_entry
          }
        }
      }
    }
  }

  return root_dir.pack_all(base, reloc)
end

#read(io, base) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/exerb/resource.rb', line 124

def read(io, base)
  root_dir = Exerb::Win32::ResourceDirectoryRoot.read(io, base)
  root_dir.entries.each { |type_dir|
    type_dir.entries.each { |item_dir|
      item_dir.entries.each { |item|
        type, id, lang = type_dir.name, item_dir.name, item.lang
        @entries[type] ||= {}
        @entries[type][id] ||= {}
        @entries[type][id][lang] = Exerb::Resource::Entry.new(type, id, lang, Exerb::Resource::Binary.new(item.entry_data.data))
      }
    }
  }

  return self
end

#remove(type, id = nil, lang = nil) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/exerb/resource.rb', line 140

def remove(type, id = nil, lang = nil)
  if type && id && lang
    if @entries[type] && @entries[type][id] && @entries[type][id][lang]
      @entries[type][id].delete(lang)
    end
  elsif type && id
    if @entries[type] && @entries[type][id]
      @entries[type].delete(id)
    end
  elsif type
    if @entries[type]
      @entries.delete(type)
    end
  end

  if type && id && @entries[type] && @entries[type][id] && @entries[type][id].empty?
    @entries[type].delete(id)
  end

  if type && @entries[type] && @entries[type].empty?
    @entries.delete(type)
  end

  return self
end