Class: Mapi::Pst::Header
- Inherits:
-
Object
- Object
- Mapi::Pst::Header
- Defined in:
- lib/mapi/pst.rb
Overview
class which encapsulates the pst header
Constant Summary collapse
- SIZE =
512
- MAGIC =
0x2142444e
- INDEX_TYPE_OFFSET =
these are the constants defined in libpst.c, that are referenced in pst_open()
0x0A
- FILE_SIZE_POINTER =
0xA8
- FILE_SIZE_POINTER_64 =
0xB8
- SECOND_POINTER =
0xBC
- INDEX_POINTER =
0xC4
- SECOND_POINTER_64 =
0xE0
- INDEX_POINTER_64 =
0xF0
- ENC_OFFSET =
0x1CD
Instance Attribute Summary collapse
- #block_btree ⇒ Integer readonly
- #block_btree_count ⇒ Integer readonly
- #encrypt_type ⇒ Integer readonly
- #index_type ⇒ Integer readonly
- #magic ⇒ Integer readonly
- #node_btree ⇒ Integer readonly
- #node_btree_count ⇒ Integer readonly
- #size ⇒ Integer readonly
- #version ⇒ Integer readonly
Instance Method Summary collapse
- #encrypted? ⇒ Boolean
-
#initialize(data) ⇒ Header
constructor
A new instance of Header.
- #validate! ⇒ Object
-
#version_2003? ⇒ Boolean
return ‘true` if pst is an Unicode version.
Constructor Details
#initialize(data) ⇒ Header
Returns a new instance of Header.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/mapi/pst.rb', line 163 def initialize data @magic = data.unpack('N')[0] @index_type = data[INDEX_TYPE_OFFSET].ord @version = {0x0e => 1997, 0x17 => 2003, 0x24 => 2003}[@index_type] if version_2003? # don't know? # >> data1.unpack('V*').zip(data2.unpack('V*')).enum_with_index.select { |(c, d), i| c != d and not [46, 56, 60].include?(i) }.select { |(a, b), i| b == 0 }.map { |(a, b), i| [a / 256, i] } # [8, 76], [32768, 84], [128, 89] # >> data1.unpack('C*').zip(data2.unpack('C*')).enum_with_index.select { |(c, d), i| c != d and not [184..187, 224..227, 240..243].any? { |r| r === i } }.select { |(a, b), i| b == 0 and ((Math.log(a) / Math.log(2)) % 1) < 0.0001 } # [[[2, 0], 61], [[2, 0], 76], [[2, 0], 195], [[2, 0], 257], [[8, 0], 305], [[128, 0], 338], [[128, 0], 357]] # i have only 2 psts to base this guess on, so i can't really come up with anything that looks reasonable yet. not sure what the offset is. unfortunately there is so much in the header # that isn't understood... @encrypt_type = 1 @node_btree_count, @node_btree = Pst.unpack(data[SECOND_POINTER_64 - 8, 16], "T2") @block_btree_count, @block_btree = Pst.unpack(data[INDEX_POINTER_64 - 8, 16], "T2") @size = data[FILE_SIZE_POINTER_64, 4].unpack('V')[0] else @encrypt_type = data[ENC_OFFSET].ord @node_btree_count, @node_btree = data[SECOND_POINTER - 4, 8].unpack('V2') @block_btree_count, @block_btree = data[INDEX_POINTER - 4, 8].unpack('V2') @size = data[FILE_SIZE_POINTER, 4].unpack('V')[0] end validate! end |
Instance Attribute Details
#block_btree ⇒ Integer (readonly)
155 156 157 |
# File 'lib/mapi/pst.rb', line 155 def block_btree @block_btree end |
#block_btree_count ⇒ Integer (readonly)
153 154 155 |
# File 'lib/mapi/pst.rb', line 153 def block_btree_count @block_btree_count end |
#encrypt_type ⇒ Integer (readonly)
149 150 151 |
# File 'lib/mapi/pst.rb', line 149 def encrypt_type @encrypt_type end |
#index_type ⇒ Integer (readonly)
147 148 149 |
# File 'lib/mapi/pst.rb', line 147 def index_type @index_type end |
#magic ⇒ Integer (readonly)
145 146 147 |
# File 'lib/mapi/pst.rb', line 145 def magic @magic end |
#node_btree ⇒ Integer (readonly)
159 160 161 |
# File 'lib/mapi/pst.rb', line 159 def node_btree @node_btree end |
#node_btree_count ⇒ Integer (readonly)
157 158 159 |
# File 'lib/mapi/pst.rb', line 157 def node_btree_count @node_btree_count end |
#size ⇒ Integer (readonly)
151 152 153 |
# File 'lib/mapi/pst.rb', line 151 def size @size end |
#version ⇒ Integer (readonly)
161 162 163 |
# File 'lib/mapi/pst.rb', line 161 def version @version end |
Instance Method Details
#encrypted? ⇒ Boolean
202 203 204 |
# File 'lib/mapi/pst.rb', line 202 def encrypted? encrypt_type != 0 end |
#validate! ⇒ Object
206 207 208 209 210 |
# File 'lib/mapi/pst.rb', line 206 def validate! raise FormatError, "bad signature on pst file (#{'0x%x' % magic})" unless magic == MAGIC raise FormatError, "only index types 0x0e, 0x17 and 0x24 are handled (#{'0x%x' % index_type})" unless [0x0e, 0x17, 0x24].include?(index_type) raise FormatError, "only encrytion types 0 and 1 are handled (#{encrypt_type.inspect})" unless [0, 1].include?(encrypt_type) end |
#version_2003? ⇒ Boolean
return ‘true` if pst is an Unicode version. Unicode version also uses 64-bit file pointer. otherwise return `false` where pst is an ANSI version. ANSI version uses 32-bit file pointer.
198 199 200 |
# File 'lib/mapi/pst.rb', line 198 def version_2003? version == 2003 end |