class WimParser
Parser for the Windows Image Format (WIM).
Information found here: http://www.microsoft.com/en-us/download/details.aspx?id=13096 http://technet.microsoft.com/en-us/library/cc749478%28WS.10%29.aspx?ITPID=win7dtp http://www.freepatentsonline.com/y2010/0211943.html http://nunobrito1981.blogspot.com/2010/12/inaccuracy-on-wim-documentation.html
TODO: Add support for processing winnt.h GUID structures for wim_guid.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931%28v=vs.85%29.aspx http://stackoverflow.com/questions/679381/accessing-guid-members-in-c-sharp
Constants
- FLAG_HEADER_COMPRESSION
- FLAG_HEADER_COMPRESS_LZX
- FLAG_HEADER_COMPRESS_RESERVED
- FLAG_HEADER_COMPRESS_XPRESS
- FLAG_HEADER_METADATA_ONLY
- FLAG_HEADER_READONLY
- FLAG_HEADER_RESERVED
Flags values for the header struct
- FLAG_HEADER_RESOURCE_ONLY
- FLAG_HEADER_RP_FIX
- FLAG_HEADER_SPANNED
- FLAG_HEADER_WRITE_IN_PROGRESS
- HEADER_V1_STRUCT
- IMAGE_TAG
- SIZEOF_HEADER_V1_STRUCT
- VERSION
Attributes
filename[R]
Public Class Methods
new(filename)
click to toggle source
# File lib/wim_parser.rb, line 68 def initialize(filename) @filename = filename end
Public Instance Methods
header()
click to toggle source
# File lib/wim_parser.rb, line 72 def header data = File.open(filename, "rb") do |f| f.read(SIZEOF_HEADER_V1_STRUCT) end ret = HEADER_V1_STRUCT.decode(data) raise "#{filename} is not a WIM file" if ret["image_tag"] != IMAGE_TAG ret end
xml_data()
click to toggle source
# File lib/wim_parser.rb, line 81 def xml_data header_data = header xml = File.open(filename, "rb") do |f| f.seek(header_data["xml_data_offset"]) f.read(header_data["xml_data_size"]) end xml.force_encoding("UTF-16") xml = Nokogiri::XML(xml).xpath("/WIM") ret = {} ret["total_bytes"] = xml.xpath("./TOTALBYTES").text.to_i ret["images"] = xml.xpath("./IMAGE").collect do |i| # Deal with hex time parts by removing the 0x prefix, padding with 0s to # 8 characters, appending the low part to the high part, converting # to an integer, and then converting that to a time object. high_part = i.xpath("./CREATIONTIME/HIGHPART").text[2..-1].rjust(8, '0') low_part = i.xpath("./CREATIONTIME/LOWPART").text[2..-1].rjust(8, '0') creation_time = nt_filetime_to_ruby_time("#{high_part}#{low_part}".to_i(16)) high_part = i.xpath("./LASTMODIFICATIONTIME/HIGHPART").text[2..-1].rjust(8, '0') low_part = i.xpath("./LASTMODIFICATIONTIME/LOWPART").text[2..-1].rjust(8, '0') last_mod_time = nt_filetime_to_ruby_time("#{high_part}#{low_part}".to_i(16)) { "index" => i["INDEX"].to_i, "name" => i.xpath("./NAME").text, "description" => i.xpath("./DESCRIPTION").text, "dir_count" => i.xpath("./DIRCOUNT").text.to_i, "file_count" => i.xpath("./FILECOUNT").text.to_i, "total_bytes" => i.xpath("./TOTALBYTES").text.to_i, "hard_link_bytes" => i.xpath("./HARDLINKBYTES").text.to_i, "creation_time" => creation_time, "last_modification_time" => last_mod_time, } end ret end
Private Instance Methods
nt_filetime_to_ruby_time(nt_time)
click to toggle source
# File lib/wim_parser.rb, line 123 def nt_filetime_to_ruby_time(nt_time) # Convert an NT FILETIME to a Ruby Time object. nt_time = nt_time / 10_000_000 - 11_644_495_200 nt_time = 0 if nt_time < 0 Time.at(nt_time).gmtime rescue RangeError nt_time end