exchange-offline-address-book 0.0.19 → 0.0.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 89166334ab2ed9b41cbf6c72a960ea4d52abe202
4
- data.tar.gz: 69eb61e7448f01fae25d5c0ca91e1cc2c105724c
3
+ metadata.gz: 8780cd77c0b21204e73bb6d3b28750bcd55bc330
4
+ data.tar.gz: 6430ed9d45cd8749ab6541e577d856e5a1c661e3
5
5
  SHA512:
6
- metadata.gz: e31e567abc55fba1c16eecefaff45c7829d6a31c264ce44f0ca81c5b12068127c4c3c686789fd737dfef53046dac07c68171ecf0d769ad2d618a9bd49c4cb8a7
7
- data.tar.gz: 357d8dacb1a449073d830e0e56102f917b5863cbb2d768f22ed40f9c4e2abd2090d92c14ff5b85773daad6b475d3d3177c255191266fc12501fac4d6fbedc99c
6
+ metadata.gz: 7070d4ccf5241df1c060a4dcb211afaa2ac91f550a25138b3fdd91ccc7b508fb23d98cd27710dcedf5e333788a457b5c14956389fd775c0178e564ee67074864
7
+ data.tar.gz: 6aceec57248cb1d1719d52d028dc041eaf97de387ad6fbf029ad55b4fddbd3b4892246271adc8e18de390716505aa150a32b36361733984cfdcc6bcdd653e5ea
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- exchange-offline-address-book (0.0.19)
4
+ exchange-offline-address-book (0.0.20)
5
5
  autodiscover (~> 1)
6
6
  curb (~> 0.9)
7
7
  hashie
@@ -5,7 +5,7 @@ require "exchange-offline-address-book/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "exchange-offline-address-book"
8
- spec.version = OfflineAddressBook::VERSION
8
+ spec.version = Exchange::OfflineAddressBook::VERSION
9
9
  spec.authors = ["Emiliano Heyns"]
10
10
  spec.email = ["Emiliano.Heyns@iris-advies.com"]
11
11
  spec.description = %q{Get Exchange Offline Address Book}
@@ -8,115 +8,109 @@ require "autodiscover/debug" if ENV['DEBUG']
8
8
  require 'yaml'
9
9
  require 'nokogiri'
10
10
  require 'json'
11
- require 'hashie'
12
11
  require 'shellwords'
13
12
  require 'tmpdir'
14
13
 
15
14
  require_relative 'exchange-offline-address-book/parser'
16
15
  require_relative 'exchange-offline-address-book/mspack'
17
16
 
18
- # https://github.com/intridea/hashie/pull/416
19
- if Hashie::VERSION == '3.5.5'
20
- module Hashie
21
- class Mash
22
- def self.disable_warnings?
23
- @disable_warnings ||= false
17
+ module Exchange
18
+ module OfflineAddressBook
19
+
20
+ class AddressBook
21
+ def initialize(email: nil, password: nil, username: nil, cachedir: nil, baseurl: nil, update: true)
22
+ @email = email
23
+ @username = username || email
24
+ @password = password
25
+ @cachedir = cachedir
26
+ @update = update
27
+ @baseurl = baseurl
28
+
29
+ if cachedir
30
+ fetch_to(cachedir)
31
+ else
32
+ Dir.mktmpdir{|dir| fetch_to(dir) }
33
+ end
24
34
  end
25
- end
26
- end
27
- end
28
-
29
- class OfflineAddressBook
30
- def initialize(email: nil, password: nil, username: nil, cachedir: nil, baseurl: nil, update: true)
31
- @email = email
32
- @username = username || email
33
- @password = password
34
- @cachedir = cachedir
35
- @update = update
36
- @baseurl = baseurl
37
-
38
- if cachedir
39
- fetch_to(cachedir)
40
- else
41
- Dir.mktmpdir{|dir| fetch_to(dir) }
42
- end
43
- end
44
-
45
- attr_reader :records
46
-
47
- def baseurl
48
- @baseurl ||= begin
49
- client = Autodiscover::Client.new(email: @email, password: @password, username: @username)
50
- data = client.autodiscover(ignore_ssl_errors: true)
51
- raise "No data" unless data
52
- data.response['Account']['Protocol'].detect{|p| p['OABUrl'] && p['Type'] == 'EXPR'}['OABUrl']
53
- end
54
- end
55
35
 
56
- def header
57
- @parsed ||= Parser.new(addressbook)
58
- @parsed.header
59
- end
36
+ attr_reader :records
60
37
 
61
- def fetch_to(dir)
62
- begin
63
- @dir = dir
38
+ def baseurl
39
+ @baseurl ||= begin
40
+ client = Autodiscover::Client.new(email: @email, password: @password, username: @username)
41
+ data = client.autodiscover(ignore_ssl_errors: true)
42
+ raise "No data" unless data
43
+ data.response['Account']['Protocol'].detect{|p| p['OABUrl'] && p['Type'] == 'EXPR'}['OABUrl']
44
+ end
45
+ end
64
46
 
65
- if File.file?(cache)
66
- @records = JSON.parse(open(cache).read, object_class: Hashie::Mash)
67
- return
47
+ def header
48
+ @parsed ||= Exchange::OfflineAddressBook::Parser.new(addressbook)
49
+ @parsed.header
68
50
  end
69
51
 
70
- if !File.file?(addressbook)
71
- %w{json oab lzx}.each{|ext|
72
- Dir[File.join(@dir, "*.#{ext}")].each{|f| File.delete(f) }
73
- }
74
- lzx = File.basename(addressbook, File.extname(addressbook)) + '.lzx'
75
- puts "OfflineAddressBook: Downloading #{lzx}" if ENV['DEBUG']
76
- download(lzx)
77
- puts "OfflineAddressBook: Decompressing #{lzx} to #{addressbook}" if ENV['DEBUG']
78
- LibMsPack.oab_decompress(File.join(@dir, lzx), addressbook)
52
+ def fetch_to(dir)
53
+ begin
54
+ @dir = dir
55
+
56
+ if File.file?(cache)
57
+ @records = JSON.parse(open(cache).read, object_class: Exchange::OfflineAddressBook::Record)
58
+ return
59
+ end
60
+
61
+ if !File.file?(addressbook)
62
+ %w{json oab lzx}.each{|ext|
63
+ Dir[File.join(@dir, "*.#{ext}")].each{|f| File.delete(f) }
64
+ }
65
+ lzx = File.basename(addressbook, File.extname(addressbook)) + '.lzx'
66
+ puts "OfflineAddressBook: Downloading #{lzx}" if ENV['DEBUG']
67
+ download(lzx)
68
+ puts "OfflineAddressBook: Decompressing #{lzx} to #{addressbook}" if ENV['DEBUG']
69
+ LibMsPack.oab_decompress(File.join(@dir, lzx), addressbook)
70
+ end
71
+ puts "OfflineAddressBook: Addressbook ready at #{addressbook}" if ENV['DEBUG']
72
+
73
+ parsed = Exchange::OfflineAddressBook::Parser.new(addressbook)
74
+ @records = parsed.records.collect{|record|
75
+ record.to_h.each_pair{|k, v|
76
+ record[k] = v[0] if v.length == 1
77
+ }
78
+ # no idea what's going on here
79
+ record.AddressBookObjectGuid = record.AddressBookObjectGuid.inspect if record.AddressBookObjectGuid
80
+ record
81
+ }
82
+ open(cache, 'w'){|f| f.write(JSON.pretty_generate(@records)) } if @cachedir
83
+ ensure
84
+ @dir = nil
85
+ end
79
86
  end
80
- puts "OfflineAddressBook: Addressbook ready at #{addressbook}" if ENV['DEBUG']
81
-
82
- parsed = Parser.new(addressbook)
83
- @records = parsed.records.collect{|record|
84
- record.to_h.each_pair{|k, v|
85
- record[k] = v[0] if v.length == 1
86
- }
87
- # no idea what's going on here
88
- record.AddressBookObjectGuid = record.AddressBookObjectGuid.inspect if record.AddressBookObjectGuid
89
- record
90
- }
91
- open(cache, 'w'){|f| f.write(JSON.pretty_generate(@records)) } if @cachedir
92
- ensure
93
- @dir = nil
94
- end
95
- end
96
87
 
97
- private
88
+ private
98
89
 
99
- def download(name)
100
- puts "curl --#{ENV['DEBUG'] ? 'verbose' : 'silent'} --ntlm --user #{[@username, @password].join(':').shellescape} #{[baseurl, name].join('').shellescape} -o #{File.join(@dir, name).shellescape}" if ENV['DEBUG']
101
- system "curl --#{ENV['DEBUG'] ? 'verbose' : 'silent'} --ntlm --user #{[@username, @password].join(':').shellescape} #{[baseurl, name].join('').shellescape} -o #{File.join(@dir, name).shellescape}"
102
- return File.join(@dir, name)
103
- end
90
+ def download(name)
91
+ puts "curl --#{ENV['DEBUG'] ? 'verbose' : 'silent'} --ntlm --user #{[@username, @password].join(':').shellescape} #{[baseurl, name].join('').shellescape} -o #{File.join(@dir, name).shellescape}" if ENV['DEBUG']
92
+ system "curl --#{ENV['DEBUG'] ? 'verbose' : 'silent'} --ntlm --user #{[@username, @password].join(':').shellescape} #{[baseurl, name].join('').shellescape} -o #{File.join(@dir, name).shellescape}"
93
+ return File.join(@dir, name)
94
+ end
104
95
 
105
- def addressbook
106
- @addressbook ||= begin
107
- if !@update && Dir[File.join(@dir, '*.oab')].length > 0
108
- oab = File.basename(Dir[File.join(@dir, '*.oab')][0])
109
- puts "OfflineAddressBook: Reusing #{oab}" if ENV['DEBUG']
110
- else
111
- lzx = Nokogiri::XML(open(download('oab.xml'))).at('//Full').inner_text
112
- oab = File.basename(lzx, File.extname(lzx)) + '.oab'
96
+ def addressbook
97
+ @addressbook ||= begin
98
+ if !@update && Dir[File.join(@dir, '*.oab')].length > 0
99
+ oab = File.basename(Dir[File.join(@dir, '*.oab')][0])
100
+ puts "OfflineAddressBook: Reusing #{oab}" if ENV['DEBUG']
101
+ else
102
+ lzx = Nokogiri::XML(open(download('oab.xml'))).at('//Full').inner_text
103
+ oab = File.basename(lzx, File.extname(lzx)) + '.oab'
104
+ end
105
+
106
+ File.join(@dir, oab)
107
+ end
113
108
  end
114
109
 
115
- File.join(@dir, oab)
110
+ def cache
111
+ @cache ||= File.join(@dir, File.basename(addressbook, File.extname(addressbook)) + '.json')
112
+ end
116
113
  end
117
- end
118
114
 
119
- def cache
120
- @cache ||= File.join(@dir, File.basename(addressbook, File.extname(addressbook)) + '.json')
121
115
  end
122
116
  end
@@ -3,744 +3,759 @@
3
3
  require 'hashie'
4
4
  require 'ostruct'
5
5
 
6
- class Record < ::Hashie::Mash
7
- include Hashie::Extensions::Mash::SymbolizeKeys
6
+ # https://github.com/intridea/hashie/pull/416
7
+ if Hashie::VERSION == '3.5.5'
8
+ module Hashie
9
+ class Mash
10
+ def self.disable_warnings?
11
+ @disable_warnings ||= false
12
+ end
13
+ end
14
+ end
8
15
  end
9
16
 
10
- MapiPropertyDataType = OpenStruct.new({
11
- Unspecified: 0,
12
- Null: 1,
13
- Short: 2,
14
- Long: 3,
15
- Float: 4,
16
- Double: 5,
17
- Currency: 6,
18
- ApplicationTime: 7,
19
- Error: 10,
20
- Boolean: 11,
21
- Object: 13,
22
- LongLong: 20,
23
- AnsiString: 30,
24
- UnicodeString: 31,
25
- SystemTime: 64,
26
- Clsid: 72,
27
- Binary: 258,
28
- Mv: 0x1000 # Multi-value (aka array) flag
29
- })
30
- MapiPropertyDataType.MvShort = MapiPropertyDataType.Short | MapiPropertyDataType.Mv
31
- MapiPropertyDataType.MvLong = MapiPropertyDataType.Long | MapiPropertyDataType.Mv
32
- MapiPropertyDataType.MvFloat = MapiPropertyDataType.Float | MapiPropertyDataType.Mv
33
- MapiPropertyDataType.MvDouble = MapiPropertyDataType.Double | MapiPropertyDataType.Mv
34
- MapiPropertyDataType.MvCurrency = MapiPropertyDataType.Currency | MapiPropertyDataType.Mv
35
- MapiPropertyDataType.MvApplicationTime = MapiPropertyDataType.ApplicationTime | MapiPropertyDataType.Mv
36
- MapiPropertyDataType.MvLongLong = MapiPropertyDataType.LongLong | MapiPropertyDataType.Mv
37
- MapiPropertyDataType.MvAnsiString = MapiPropertyDataType.AnsiString | MapiPropertyDataType.Mv
38
- MapiPropertyDataType.MvUnicodeString = MapiPropertyDataType.UnicodeString | MapiPropertyDataType.Mv
39
- MapiPropertyDataType.MvSystemTime = MapiPropertyDataType.SystemTime | MapiPropertyDataType.Mv
40
- MapiPropertyDataType.MvClsid = MapiPropertyDataType.Clsid | MapiPropertyDataType.Mv
41
- MapiPropertyDataType.MvBinary = MapiPropertyDataType.Binary | MapiPropertyDataType.Mv
42
- MapiPropertyDataType.to_h.each_pair{|k, v| MapiPropertyDataType[v.to_s.to_sym] = k }
17
+ module Exchange
18
+ module OfflineAddressBook
43
19
 
44
- MapiPropertyName = {
45
- '0001' => :TemplateData,
46
- '0002' => :AlternateRecipientAllowed,
47
- '0004' => :AutoForwardComment,
48
- # '0004' => :ScriptData,
49
- '0005' => :AutoForwarded,
50
- '000F' => :DeferredDeliveryTime,
51
- '0015' => :ExpiryTime,
52
- '0017' => :Importance,
53
- '001A' => :MessageClass,
54
- '0023' => :OriginatorDeliveryReportRequested,
55
- '0025' => :ParentKey,
56
- '0026' => :Priority,
57
- '0029' => :ReadReceiptRequested,
58
- '002B' => :RecipientReassignmentProhibited,
59
- '002E' => :OriginalSensitivity,
60
- '0030' => :ReplyTime,
61
- '0031' => :ReportTag,
62
- '0032' => :ReportTime,
63
- '0036' => :Sensitivity,
64
- '0037' => :Subject,
65
- '0039' => :ClientSubmitTime,
66
- '003A' => :ReportName,
67
- '003B' => :SentRepresentingSearchKey,
68
- '003D' => :SubjectPrefix,
69
- '003F' => :ReceivedByEntryId,
70
- '0040' => :ReceivedByName,
71
- '0041' => :SentRepresentingEntryId,
72
- '0042' => :SentRepresentingName,
73
- '0043' => :ReceivedRepresentingEntryId,
74
- '0044' => :ReceivedRepresentingName,
75
- '0045' => :ReportEntryId,
76
- '0046' => :ReadReceiptEntryId,
77
- '0047' => :MessageSubmissionId,
78
- '0048' => :ProviderSubmitTime,
79
- '0049' => :OriginalSubject,
80
- '004B' => :OriginalMessageClass,
81
- '004C' => :OriginalAuthorEntryId,
82
- '004D' => :OriginalAuthorName,
83
- '004E' => :OriginalSubmitTime,
84
- '004F' => :ReplyRecipientEntries,
85
- '0050' => :ReplyRecipientNames,
86
- '0051' => :ReceivedBySearchKey,
87
- '0052' => :ReceivedRepresentingSearchKey,
88
- '0053' => :ReadReceiptSearchKey,
89
- '0054' => :ReportSearchKey,
90
- '0055' => :OriginalDeliveryTime,
91
- '0057' => :MessageToMe,
92
- '0058' => :MessageCcMe,
93
- '0059' => :MessageRecipientMe,
94
- '005A' => :OriginalSenderName,
95
- '005B' => :OriginalSenderEntryId,
96
- '005C' => :OriginalSenderSearchKey,
97
- '005D' => :OriginalSentRepresentingName,
98
- '005E' => :OriginalSentRepresentingEntryId,
99
- '005F' => :OriginalSentRepresentingSearchKey,
100
- '0060' => :StartDate,
101
- '0061' => :EndDate,
102
- '0062' => :OwnerAppointmentId,
103
- '0063' => :ResponseRequested,
104
- '0064' => :SentRepresentingAddressType,
105
- '0065' => :SentRepresentingEmailAddress,
106
- '0066' => :OriginalSenderAddressType,
107
- '0067' => :OriginalSenderEmailAddress,
108
- '0068' => :OriginalSentRepresentingAddressType,
109
- '0069' => :OriginalSentRepresentingEmailAddress,
110
- '0070' => :ConversationTopic,
111
- '0071' => :ConversationIndex,
112
- '0072' => :OriginalDisplayBcc,
113
- '0073' => :OriginalDisplayCc,
114
- '0074' => :OriginalDisplayTo,
115
- '0075' => :ReceivedByAddressType,
116
- '0076' => :ReceivedByEmailAddress,
117
- '0077' => :ReceivedRepresentingAddressType,
118
- '0078' => :ReceivedRepresentingEmailAddress,
119
- '007D' => :TransportMessageHeaders,
120
- '007F' => :TnefCorrelationKey,
121
- '0080' => :ReportDisposition,
122
- '0081' => :ReportDispositionMode,
123
- '0807' => :AddressBookRoomCapacity,
124
- '0809' => :AddressBookRoomDescription,
125
- '0C06' => :NonReceiptNotificationRequested,
126
- '0C08' => :OriginatorNonDeliveryReportRequested,
127
- '0C15' => :RecipientType,
128
- '0C17' => :ReplyRequested,
129
- '0C19' => :SenderEntryId,
130
- '0C1A' => :SenderName,
131
- '0C1D' => :SenderSearchKey,
132
- '0C1E' => :SenderAddressType,
133
- '0C1F' => :SenderEmailAddress,
134
- '0E01' => :DeleteAfterSubmit,
135
- '0E02' => :DisplayBcc,
136
- '0E03' => :DisplayCc,
137
- '0E04' => :DisplayTo,
138
- '0E06' => :MessageDeliveryTime,
139
- '0E07' => :MessageFlags,
140
- '0E08' => :MessageSize,
141
- # '0E08' => :MessageSizeExtended,
142
- '0E09' => :ParentEntryId,
143
- '0E0F' => :Responsibility,
144
- '0E12' => :MessageRecipients,
145
- '0E13' => :MessageAttachments,
146
- '0E17' => :MessageStatus,
147
- '0E1B' => :HasAttachments,
148
- '0E1D' => :NormalizedSubject,
149
- '0E1F' => :RtfInSync,
150
- '0E20' => :AttachSize,
151
- '0E21' => :AttachNumber,
152
- '0E23' => :InternetArticleNumber,
153
- '0E28' => :PrimarySendAccount,
154
- '0E29' => :NextSendAcct,
155
- '0E2B' => :ToDoItemFlags,
156
- '0E2C' => :SwappedToDoStore,
157
- '0E2D' => :SwappedToDoData,
158
- '0E69' => :Read,
159
- '0E6A' => :SecurityDescriptorAsXml,
160
- '0E79' => :TrustSender,
161
- '0E84' => :ExchangeNTSecurityDescriptor,
162
- '0E99' => :ExtendedRuleMessageActions,
163
- '0E9A' => :ExtendedRuleMessageCondition,
164
- '0E9B' => :ExtendedRuleSizeLimit,
165
- '0FF4' => :Access,
166
- '0FF5' => :RowType,
167
- '0FF6' => :InstanceKey,
168
- '0FF7' => :AccessLevel,
169
- '0FF8' => :MappingSignature,
170
- '0FF9' => :RecordKey,
171
- '0FFB' => :StoreEntryId,
172
- '0FFE' => :ObjectType,
173
- '0FFF' => :EntryId,
174
- '1000' => :Body,
175
- '1001' => :ReportText,
176
- '1009' => :RtfCompressed,
177
- '1013' => :BodyHtml,
178
- # '1013' => :Html,
179
- '1014' => :BodyContentLocation,
180
- '1015' => :BodyContentId,
181
- '1016' => :NativeBody,
182
- '1035' => :InternetMessageId,
183
- '1039' => :InternetReferences,
184
- '1042' => :InReplyToId,
185
- '1043' => :ListHelp,
186
- '1044' => :ListSubscribe,
187
- '1045' => :ListUnsubscribe,
188
- '1046' => :OriginalMessageId,
189
- '1080' => :IconIndex,
190
- '1081' => :LastVerbExecuted,
191
- '1082' => :LastVerbExecutionTime,
192
- '1090' => :FlagStatus,
193
- '1091' => :FlagCompleteTime,
194
- '1095' => :FollowupIcon,
195
- '1096' => :BlockStatus,
196
- '10C3' => :ICalendarStartTime,
197
- '10C4' => :ICalendarEndTime,
198
- '10C5' => :CdoRecurrenceid,
199
- '10CA' => :ICalendarReminderNextTime,
200
- '10F3' => :UrlCompName,
201
- '10F4' => :AttributeHidden,
202
- '10F6' => :AttributeReadOnly,
203
- '3000' => :Rowid,
204
- '3001' => :DisplayName,
205
- '3002' => :AddressType,
206
- '3003' => :EmailAddress,
207
- '3004' => :Comment,
208
- '3005' => :Depth,
209
- '3007' => :CreationTime,
210
- '3008' => :LastModificationTime,
211
- '300B' => :SearchKey,
212
- '3010' => :TargetEntryId,
213
- '3013' => :ConversationId,
214
- '3016' => :ConversationIndexTracking,
215
- '3018' => :ArchiveTag,
216
- '3019' => :PolicyTag,
217
- '301A' => :RetentionPeriod,
218
- '301B' => :StartDateEtc,
219
- '301C' => :RetentionDate,
220
- '301D' => :RetentionFlags,
221
- '301E' => :ArchivePeriod,
222
- '301F' => :ArchiveDate,
223
- '340D' => :StoreSupportMask,
224
- '340E' => :StoreState,
225
- '3600' => :ContainerFlags,
226
- '3601' => :FolderType,
227
- '3602' => :ContentCount,
228
- '3603' => :ContentUnreadCount,
229
- '3609' => :Selectable,
230
- '360A' => :Subfolders,
231
- '360C' => :Anr,
232
- '360E' => :ContainerHierarchy,
233
- '360F' => :ContainerContents,
234
- '3610' => :FolderAssociatedContents,
235
- '3613' => :ContainerClass,
236
- '36D0' => :IpmAppointmentEntryId,
237
- '36D1' => :IpmContactEntryId,
238
- '36D2' => :IpmJournalEntryId,
239
- '36D3' => :IpmNoteEntryId,
240
- '36D4' => :IpmTaskEntryId,
241
- '36D5' => :RemindersOnlineEntryId,
242
- '36D7' => :IpmDraftsEntryId,
243
- '36D8' => :AdditionalRenEntryIds,
244
- '36D9' => :AdditionalRenEntryIdsEx,
245
- '36DA' => :ExtendedFolderFlags,
246
- '36E2' => :OrdinalMost,
247
- '36E4' => :FreeBusyEntryIds,
248
- '36E5' => :DefaultPostMessageClass,
249
- '3701' => :AttachDataObject,
250
- # '3701' => :AttachDataBinary,
251
- '3702' => :AttachEncoding,
252
- '3703' => :AttachExtension,
253
- '3704' => :AttachFilename,
254
- '3705' => :AttachMethod,
255
- '3707' => :AttachLongFilename,
256
- '3708' => :AttachPathname,
257
- '3709' => :AttachRendering,
258
- '370A' => :AttachTag,
259
- '370B' => :RenderingPosition,
260
- '370C' => :AttachTransportName,
261
- '370D' => :AttachLongPathname,
262
- '370E' => :AttachMimeTag,
263
- '370F' => :AttachAdditionalInformation,
264
- '3711' => :AttachContentBase,
265
- '3712' => :CID,
266
- '3713' => :AttachContentLocation,
267
- '3714' => :AttachFlags,
268
- '3719' => :AttachPayloadProviderGuidString,
269
- '371A' => :AttachPayloadClass,
270
- '371B' => :TextAttachmentCharset,
271
- '3900' => :DisplayType,
272
- '3902' => :Templateid,
273
- '3905' => :DisplayTypeEx,
274
- '39FE' => :SmtpAddress,
275
- '39FF' => :AddressBookDisplayNamePrintable,
276
- '3A00' => :Account,
277
- '3A02' => :CallbackTelephoneNumber,
278
- '3A05' => :Generation,
279
- '3A06' => :GivenName,
280
- '3A07' => :GovernmentIdNumber,
281
- '3A08' => :BusinessTelephoneNumber,
282
- '3A09' => :HomeTelephoneNumber,
283
- '3A0A' => :Initials,
284
- '3A0B' => :Keyword,
285
- '3A0C' => :Language,
286
- '3A0D' => :Location,
287
- '3A0F' => :MessageHandlingSystemCommonName,
288
- '3A10' => :OrganizationalIdNumber,
289
- '3A11' => :Surname,
290
- '3A12' => :OriginalEntryId,
291
- '3A15' => :PostalAddress,
292
- '3A16' => :CompanyName,
293
- '3A17' => :Title,
294
- '3A18' => :DepartmentName,
295
- '3A19' => :OfficeLocation,
296
- '3A1A' => :PrimaryTelephoneNumber,
297
- '3A1B' => :Business2TelephoneNumber,
298
- # '3A1B' => :Business2TelephoneNumbers,
299
- '3A1C' => :MobileTelephoneNumber,
300
- '3A1D' => :RadioTelephoneNumber,
301
- '3A1E' => :CarTelephoneNumber,
302
- '3A1F' => :OtherTelephoneNumber,
303
- '3A20' => :TransmittableDisplayName,
304
- '3A21' => :PagerTelephoneNumber,
305
- '3A22' => :UserCertificate,
306
- '3A23' => :PrimaryFaxNumber,
307
- '3A24' => :BusinessFaxNumber,
308
- '3A25' => :HomeFaxNumber,
309
- '3A26' => :Country,
310
- '3A27' => :Locality,
311
- '3A28' => :StateOrProvince,
312
- '3A29' => :StreetAddress,
313
- '3A2A' => :PostalCode,
314
- '3A2B' => :PostOfficeBox,
315
- '3A2C' => :TelexNumber,
316
- '3A2D' => :IsdnNumber,
317
- '3A2E' => :AssistantTelephoneNumber,
318
- '3A2F' => :Home2TelephoneNumber,
319
- # '3A2F' => :Home2TelephoneNumbers,
320
- '3A30' => :Assistant,
321
- '3A40' => :SendRichInfo,
322
- '3A41' => :WeddingAnniversary,
323
- '3A42' => :Birthday,
324
- '3A43' => :Hobbies,
325
- '3A44' => :MiddleName,
326
- '3A45' => :DisplayNamePrefix,
327
- '3A46' => :Profession,
328
- '3A47' => :ReferredByName,
329
- '3A48' => :SpouseName,
330
- '3A49' => :ComputerNetworkName,
331
- '3A4A' => :CustomerId,
332
- '3A4B' => :TelecommunicationsDeviceForDeafTelephoneNumber,
333
- '3A4C' => :FtpSite,
334
- '3A4D' => :Gender,
335
- '3A4E' => :ManagerName,
336
- '3A4F' => :Nickname,
337
- '3A50' => :PersonalHomePage,
338
- '3A51' => :BusinessHomePage,
339
- '3A57' => :CompanyMainTelephoneNumber,
340
- '3A58' => :ChildrensNames,
341
- '3A59' => :HomeAddressCity,
342
- '3A5A' => :HomeAddressCountry,
343
- '3A5B' => :HomeAddressPostalCode,
344
- '3A5C' => :HomeAddressStateOrProvince,
345
- '3A5D' => :HomeAddressStreet,
346
- '3A5E' => :HomeAddressPostOfficeBox,
347
- '3A5F' => :OtherAddressCity,
348
- '3A60' => :OtherAddressCountry,
349
- '3A61' => :OtherAddressPostalCode,
350
- '3A62' => :OtherAddressStateOrProvince,
351
- '3A63' => :OtherAddressStreet,
352
- '3A64' => :OtherAddressPostOfficeBox,
353
- '3A70' => :UserX509Certificate,
354
- '3A71' => :SendInternetEncoding,
355
- '3F08' => :InitialDetailsPane,
356
- '3F20' => :TemporaryDefaultDocument,
357
- '3FDE' => :InternetCodepage,
358
- '3FDF' => :AutoResponseSuppress,
359
- '3FE0' => :AccessControlListData,
360
- '3FE3' => :DelegatedByRule,
361
- '3FE7' => :ResolveMethod,
362
- '3FEA' => :HasDeferredActionMessages,
363
- '3FEB' => :DeferredSendNumber,
364
- '3FEC' => :DeferredSendUnits,
365
- '3FED' => :ExpiryNumber,
366
- '3FEE' => :ExpiryUnits,
367
- '3FEF' => :DeferredSendTime,
368
- '3FF0' => :ConflictEntryId,
369
- '3FF1' => :MessageLocaleId,
370
- '3FF8' => :CreatorName,
371
- '3FF9' => :CreatorEntryId,
372
- '3FFA' => :LastModifierName,
373
- '3FFB' => :LastModifierEntryId,
374
- '3FFD' => :MessageCodepage,
375
- '401A' => :SentRepresentingFlags,
376
- '4029' => :ReadReceiptAddressType,
377
- '402A' => :ReadReceiptEmailAddress,
378
- '402B' => :ReadReceiptName,
379
- '4076' => :ContentFilterSpamConfidenceLevel,
380
- '4079' => :SenderIdStatus,
381
- '4083' => :PurportedSenderDomain,
382
- '5902' => :InternetMailOverrideFormat,
383
- '5909' => :MessageEditorFormat,
384
- '5D01' => :SenderSmtpAddress,
385
- '5FDE' => :RecipientResourceState,
386
- '5FDF' => :RecipientOrder,
387
- '5FE1' => :RecipientProposed,
388
- '5FE3' => :RecipientProposedStartTime,
389
- '5FE4' => :RecipientProposedEndTime,
390
- '5FF6' => :RecipientDisplayName,
391
- '5FF7' => :RecipientEntryId,
392
- '5FFB' => :RecipientTrackStatusTime,
393
- '5FFD' => :RecipientFlags,
394
- '5FFF' => :RecipientTrackStatus,
395
- '6100' => :JunkIncludeContacts,
396
- '6101' => :JunkThreshold,
397
- '6102' => :JunkPermanentlyDelete,
398
- '6103' => :JunkAddRecipientsToSafeSendersList,
399
- '6107' => :JunkPhishingEnableLinks,
400
- '64F0' => :MimeSkeleton,
401
- '65C2' => :ReplyTemplateId,
402
- '65E0' => :SourceKey,
403
- '65E1' => :ParentSourceKey,
404
- '65E2' => :ChangeKey,
405
- '65E3' => :PredecessorChangeList,
406
- '65E9' => :RuleMessageState,
407
- '65EA' => :RuleMessageUserFlags,
408
- '65EB' => :RuleMessageProvider,
409
- '65EC' => :RuleMessageName,
410
- '65ED' => :RuleMessageLevel,
411
- '65EE' => :RuleMessageProviderData,
412
- '65F3' => :RuleMessageSequence,
413
- '6619' => :UserEntryId,
414
- '661B' => :MailboxOwnerEntryId,
415
- '661C' => :MailboxOwnerName,
416
- '661D' => :OutOfOfficeState,
417
- '6622' => :ScheduleFreeBusy,
418
- '6639' => :Rights,
419
- '663A' => :HasRules,
420
- '663B' => :AddressBookEntryId,
421
- '663E' => :HierarchyChangeNumber,
422
- '6645' => :ClientActions,
423
- '6646' => :DamOriginalEntryId,
424
- '6647' => :DamBackPatched,
425
- '6648' => :RuleError,
426
- '6649' => :RuleActionType,
427
- '664A' => :HasNamedProperties,
428
- '6650' => :RuleActionNumber,
429
- '6651' => :RuleFolderEntryId,
430
- '666A' => :ProhibitReceiveQuota,
431
- '666C' => :InConflict,
432
- '666D' => :MaximumSubmitMessageSize,
433
- '666E' => :ProhibitSendQuota,
434
- '6671' => :MemberId,
435
- '6672' => :MemberName,
436
- '6673' => :MemberRights,
437
- '6674' => :RuleId,
438
- '6675' => :RuleIds,
439
- '6676' => :RuleSequence,
440
- '6677' => :RuleState,
441
- '6678' => :RuleUserFlags,
442
- '6679' => :RuleCondition,
443
- '6680' => :RuleActions,
444
- '6681' => :RuleProvider,
445
- '6682' => :RuleName,
446
- '6683' => :RuleLevel,
447
- '6684' => :RuleProviderData,
448
- '668F' => :DeletedOn,
449
- '66A1' => :LocaleId,
450
- '66B3' => :NormalMessageSize,
451
- '66C3' => :CodePageId,
452
- '6704' => :AddressBookManageDistributionList,
453
- '6705' => :SortLocaleId,
454
- '6707' => :UrlName,
455
- '6708' => :Subfolder,
456
- '6709' => :LocalCommitTime,
457
- '670A' => :LocalCommitTimeMax,
458
- '670B' => :DeletedCountTotal,
459
- '670E' => :FlatUrlName,
460
- '671C' => :PublicFolderAdministrativeDescription,
461
- '671D' => :PublicFolderProxy,
462
- '6740' => :SentMailSvrEID,
463
- '6741' => :DeferredActionMessageOriginalEntryId,
464
- '6748' => :FolderId,
465
- '6749' => :ParentFolderId,
466
- '674A' => :Mid,
467
- '674D' => :InstID,
468
- '674E' => :InstanceNum,
469
- '674F' => :AddressBookMessageId,
470
- '67A4' => :ChangeNumber,
471
- '67AA' => :Associated,
472
- '6800' => :OfflineAddressBookName,
473
- '6801' => :OfflineAddressBookSequence,
474
- # '6801' => :VoiceMessageDuration,
475
- '6802' => :OfflineAddressBookContainerGuid,
476
- # '6802' => :SenderTelephoneNumber,
477
- # '6802' => :RwRulesStream,
478
- '6803' => :OfflineAddressBookMessageClass,
479
- # '6803' => :VoiceMessageSenderName,
480
- '6804' => :FaxNumberOfPages,
481
- # '6804' => :OfflineAddressBookDistinguishedName,
482
- '6805' => :VoiceMessageAttachmentOrder,
483
- # '6805' => :OfflineAddressBookTruncatedProperties,
484
- '6806' => :CallId,
485
- '6834' => :SearchFolderLastUsed,
486
- '683A' => :SearchFolderExpiration,
487
- '6841' => :ScheduleInfoResourceType,
488
- # '6841' => :SearchFolderTemplateId,
489
- '6842' => :ScheduleInfoDelegatorWantsCopy,
490
- # '6842' => :SearchFolderId,
491
- # '6842' => :WlinkGroupHeaderID,
492
- '6843' => :ScheduleInfoDontMailDelegates,
493
- '6844' => :SearchFolderRecreateInfo,
494
- # '6844' => :ScheduleInfoDelegateNames,
495
- '6845' => :SearchFolderDefinition,
496
- # '6845' => :ScheduleInfoDelegateEntryIds,
497
- '6846' => :SearchFolderStorageType,
498
- # '6846' => :GatewayNeedsToRefresh,
499
- '6847' => :FreeBusyPublishStart,
500
- # '6847' => :SearchFolderTag,
501
- # '6847' => :WlinkSaveStamp,
502
- '6848' => :FreeBusyPublishEnd,
503
- # '6848' => :SearchFolderEfpFlags,
504
- '6849' => :WlinkType,
505
- # '6849' => :FreeBusyMessageEmailAddress,
506
- '684A' => :WlinkFlags,
507
- # '684A' => :ScheduleInfoDelegateNamesW,
508
- '684B' => :ScheduleInfoDelegatorWantsInfo,
509
- # '684B' => :WlinkOrdinal,
510
- '684C' => :WlinkEntryId,
511
- '684D' => :WlinkRecordKey,
512
- '684E' => :WlinkStoreEntryId,
513
- '684F' => :WlinkFolderType,
514
- # '684F' => :ScheduleInfoMonthsMerged,
515
- '6850' => :WlinkGroupClsid,
516
- # '6850' => :ScheduleInfoFreeBusyMerged,
517
- '6851' => :WlinkGroupName,
518
- # '6851' => :ScheduleInfoMonthsTentative,
519
- '6852' => :WlinkSection,
520
- # '6852' => :ScheduleInfoFreeBusyTentative,
521
- '6853' => :WlinkCalendarColor,
522
- # '6853' => :ScheduleInfoMonthsBusy,
523
- '6854' => :WlinkAddressBookEID,
524
- # '6854' => :ScheduleInfoFreeBusyBusy,
525
- '6855' => :ScheduleInfoMonthsAway,
526
- '6856' => :ScheduleInfoFreeBusyAway,
527
- '6868' => :FreeBusyRangeTimestamp,
528
- '6869' => :FreeBusyCountMonths,
529
- '686A' => :ScheduleInfoAppointmentTombstone,
530
- '686B' => :DelegateFlags,
531
- '686C' => :ScheduleInfoFreeBusy,
532
- '686D' => :ScheduleInfoAutoAcceptAppointments,
533
- '686F' => :ScheduleInfoDisallowOverlappingAppts,
534
- '6890' => :WlinkClientID,
535
- '6891' => :WlinkAddressBookStoreEID,
536
- '6892' => :WlinkROGroupType,
537
- '7001' => :ViewDescriptorBinary,
538
- '7002' => :ViewDescriptorStrings,
539
- '7006' => :ViewDescriptorName,
540
- '7007' => :ViewDescriptorVersion,
541
- '7C06' => :RoamingDatatypes,
542
- '7C07' => :RoamingDictionary,
543
- '7C08' => :RoamingXmlStream,
544
- '7C24' => :OscSyncEnabled,
545
- '7D01' => :Processed,
546
- '7FF9' => :ExceptionReplaceTime,
547
- '7FFA' => :AttachmentLinkId,
548
- '7FFB' => :ExceptionStartTime,
549
- '7FFC' => :ExceptionEndTime,
550
- '7FFD' => :AttachmentFlags,
551
- '7FFE' => :AttachmentHidden,
552
- '7FFF' => :AttachmentContactPhoto,
553
- '8004' => :AddressBookFolderPathname,
554
- '8005' => :AddressBookManager,
555
- # '8005' => :AddressBookManagerDistinguishedName,
556
- '8006' => :AddressBookHomeMessageDatabase,
557
- '8008' => :AddressBookIsMemberOfDistributionList,
558
- '8009' => :AddressBookMember,
559
- '800C' => :AddressBookOwner,
560
- '800E' => :AddressBookReports,
561
- '800F' => :AddressBookProxyAddresses,
562
- '8011' => :AddressBookTargetAddress,
563
- '8015' => :AddressBookPublicDelegates,
564
- '8024' => :AddressBookOwnerBackLink,
565
- '802D' => :AddressBookExtensionAttribute1,
566
- '802E' => :AddressBookExtensionAttribute2,
567
- '802F' => :AddressBookExtensionAttribute3,
568
- '8030' => :AddressBookExtensionAttribute4,
569
- '8031' => :AddressBookExtensionAttribute5,
570
- '8032' => :AddressBookExtensionAttribute6,
571
- '8033' => :AddressBookExtensionAttribute7,
572
- '8034' => :AddressBookExtensionAttribute8,
573
- '8035' => :AddressBookExtensionAttribute9,
574
- '8036' => :AddressBookExtensionAttribute10,
575
- '803C' => :AddressBookObjectDistinguishedName,
576
- '806A' => :AddressBookDeliveryContentLength,
577
- '8073' => :AddressBookDistributionListMemberSubmitAccepted,
578
- '8170' => :AddressBookNetworkAddress,
579
- '8C57' => :AddressBookExtensionAttribute11,
580
- '8C58' => :AddressBookExtensionAttribute12,
581
- '8C59' => :AddressBookExtensionAttribute13,
582
- '8C60' => :AddressBookExtensionAttribute14,
583
- '8C61' => :AddressBookExtensionAttribute15,
584
- '8C6A' => :AddressBookX509Certificate,
585
- '8C6D' => :AddressBookObjectGuid,
586
- '8C8E' => :AddressBookPhoneticGivenName,
587
- '8C8F' => :AddressBookPhoneticSurname,
588
- '8C90' => :AddressBookPhoneticDepartmentName,
589
- '8C91' => :AddressBookPhoneticCompanyName,
590
- '8C92' => :AddressBookPhoneticDisplayName,
591
- '8C93' => :AddressBookDisplayTypeExtended,
592
- '8C94' => :AddressBookHierarchicalShowInDepartments,
593
- '8C96' => :AddressBookRoomContainers,
594
- '8C97' => :AddressBookHierarchicalDepartmentMembers,
595
- '8C98' => :AddressBookHierarchicalRootDepartment,
596
- '8C99' => :AddressBookHierarchicalParentDepartment,
597
- '8C9A' => :AddressBookHierarchicalChildDepartments,
598
- '8C9E' => :ThumbnailPhoto,
599
- '8CA0' => :AddressBookSeniorityIndex,
600
- '8CA8' => :AddressBookOrganizationalUnitRootDistinguishedName,
601
- '8CAC' => :AddressBookSenderHintTranslations,
602
- '8CB5' => :AddressBookModerationEnabled,
603
- '8CC2' => :SpokenName,
604
- '8CD8' => :AddressBookAuthorizedSenders,
605
- '8CD9' => :AddressBookUnauthorizedSenders,
606
- '8CDA' => :AddressBookDistributionListMemberSubmitRejected,
607
- '8CDB' => :AddressBookDistributionListRejectMessagesFromDLMembers,
608
- '8CDD' => :AddressBookHierarchicalIsHierarchicalGroup,
609
- '8CE2' => :AddressBookDistributionListMemberCount,
610
- '8CE3' => :AddressBookDistributionListExternalMemberCount,
611
- 'FFFB' => :AddressBookIsMaster,
612
- 'FFFC' => :AddressBookParentEntryId,
613
- 'FFFD' => :AddressBookContainerId,
614
- }
615
-
616
- class OfflineAddressBook
617
- class Parser
618
- def initialize(oab)
619
- @oab = open(oab)
620
- @header = _header
621
- end
622
-
623
- def pos
624
- return sprintf('%08o', @oab.pos)
20
+ class Record < ::Hashie::Mash
21
+ include Hashie::Extensions::Mash::SymbolizeKeys
625
22
  end
626
- def typeof(type)
627
- return MapiPropertyDataType[type.to_s.to_sym]
628
- end
629
-
630
- attr_reader :serialNumber, :totalRecords, :header
631
-
632
- def _uint32
633
- return @oab.read(4).unpack('V*')[0]
634
- end
635
- def _ubyte
636
- return @oab.read(1).unpack('C*')[0]
637
- end
638
-
639
- def _integer
640
- firstByte = _ubyte
641
-
642
- return firstByte if firstByte < 0x80
643
-
644
- case firstByte
645
- when 0x81 then return _ubyte
646
- when 0x82 then return _ubyte + (_ubyte << 8)
647
- when 0x83 then return _ubyte + (_ubyte << 8) + (_ubyte << 16)
648
- when 0x84 then return _ubyte + (_ubyte << 8) + (_ubyte << 16) + (_ubyte << 24)
23
+
24
+ MapiPropertyDataType = OpenStruct.new({
25
+ Unspecified: 0,
26
+ Null: 1,
27
+ Short: 2,
28
+ Long: 3,
29
+ Float: 4,
30
+ Double: 5,
31
+ Currency: 6,
32
+ ApplicationTime: 7,
33
+ Error: 10,
34
+ Boolean: 11,
35
+ Object: 13,
36
+ LongLong: 20,
37
+ AnsiString: 30,
38
+ UnicodeString: 31,
39
+ SystemTime: 64,
40
+ Clsid: 72,
41
+ Binary: 258,
42
+ Mv: 0x1000 # Multi-value (aka array) flag
43
+ })
44
+ MapiPropertyDataType.MvShort = MapiPropertyDataType.Short | MapiPropertyDataType.Mv
45
+ MapiPropertyDataType.MvLong = MapiPropertyDataType.Long | MapiPropertyDataType.Mv
46
+ MapiPropertyDataType.MvFloat = MapiPropertyDataType.Float | MapiPropertyDataType.Mv
47
+ MapiPropertyDataType.MvDouble = MapiPropertyDataType.Double | MapiPropertyDataType.Mv
48
+ MapiPropertyDataType.MvCurrency = MapiPropertyDataType.Currency | MapiPropertyDataType.Mv
49
+ MapiPropertyDataType.MvApplicationTime = MapiPropertyDataType.ApplicationTime | MapiPropertyDataType.Mv
50
+ MapiPropertyDataType.MvLongLong = MapiPropertyDataType.LongLong | MapiPropertyDataType.Mv
51
+ MapiPropertyDataType.MvAnsiString = MapiPropertyDataType.AnsiString | MapiPropertyDataType.Mv
52
+ MapiPropertyDataType.MvUnicodeString = MapiPropertyDataType.UnicodeString | MapiPropertyDataType.Mv
53
+ MapiPropertyDataType.MvSystemTime = MapiPropertyDataType.SystemTime | MapiPropertyDataType.Mv
54
+ MapiPropertyDataType.MvClsid = MapiPropertyDataType.Clsid | MapiPropertyDataType.Mv
55
+ MapiPropertyDataType.MvBinary = MapiPropertyDataType.Binary | MapiPropertyDataType.Mv
56
+ MapiPropertyDataType.to_h.each_pair{|k, v| MapiPropertyDataType[v.to_s.to_sym] = k }
57
+
58
+ MapiPropertyName = {
59
+ '0001' => :TemplateData,
60
+ '0002' => :AlternateRecipientAllowed,
61
+ '0004' => :AutoForwardComment,
62
+ # '0004' => :ScriptData,
63
+ '0005' => :AutoForwarded,
64
+ '000F' => :DeferredDeliveryTime,
65
+ '0015' => :ExpiryTime,
66
+ '0017' => :Importance,
67
+ '001A' => :MessageClass,
68
+ '0023' => :OriginatorDeliveryReportRequested,
69
+ '0025' => :ParentKey,
70
+ '0026' => :Priority,
71
+ '0029' => :ReadReceiptRequested,
72
+ '002B' => :RecipientReassignmentProhibited,
73
+ '002E' => :OriginalSensitivity,
74
+ '0030' => :ReplyTime,
75
+ '0031' => :ReportTag,
76
+ '0032' => :ReportTime,
77
+ '0036' => :Sensitivity,
78
+ '0037' => :Subject,
79
+ '0039' => :ClientSubmitTime,
80
+ '003A' => :ReportName,
81
+ '003B' => :SentRepresentingSearchKey,
82
+ '003D' => :SubjectPrefix,
83
+ '003F' => :ReceivedByEntryId,
84
+ '0040' => :ReceivedByName,
85
+ '0041' => :SentRepresentingEntryId,
86
+ '0042' => :SentRepresentingName,
87
+ '0043' => :ReceivedRepresentingEntryId,
88
+ '0044' => :ReceivedRepresentingName,
89
+ '0045' => :ReportEntryId,
90
+ '0046' => :ReadReceiptEntryId,
91
+ '0047' => :MessageSubmissionId,
92
+ '0048' => :ProviderSubmitTime,
93
+ '0049' => :OriginalSubject,
94
+ '004B' => :OriginalMessageClass,
95
+ '004C' => :OriginalAuthorEntryId,
96
+ '004D' => :OriginalAuthorName,
97
+ '004E' => :OriginalSubmitTime,
98
+ '004F' => :ReplyRecipientEntries,
99
+ '0050' => :ReplyRecipientNames,
100
+ '0051' => :ReceivedBySearchKey,
101
+ '0052' => :ReceivedRepresentingSearchKey,
102
+ '0053' => :ReadReceiptSearchKey,
103
+ '0054' => :ReportSearchKey,
104
+ '0055' => :OriginalDeliveryTime,
105
+ '0057' => :MessageToMe,
106
+ '0058' => :MessageCcMe,
107
+ '0059' => :MessageRecipientMe,
108
+ '005A' => :OriginalSenderName,
109
+ '005B' => :OriginalSenderEntryId,
110
+ '005C' => :OriginalSenderSearchKey,
111
+ '005D' => :OriginalSentRepresentingName,
112
+ '005E' => :OriginalSentRepresentingEntryId,
113
+ '005F' => :OriginalSentRepresentingSearchKey,
114
+ '0060' => :StartDate,
115
+ '0061' => :EndDate,
116
+ '0062' => :OwnerAppointmentId,
117
+ '0063' => :ResponseRequested,
118
+ '0064' => :SentRepresentingAddressType,
119
+ '0065' => :SentRepresentingEmailAddress,
120
+ '0066' => :OriginalSenderAddressType,
121
+ '0067' => :OriginalSenderEmailAddress,
122
+ '0068' => :OriginalSentRepresentingAddressType,
123
+ '0069' => :OriginalSentRepresentingEmailAddress,
124
+ '0070' => :ConversationTopic,
125
+ '0071' => :ConversationIndex,
126
+ '0072' => :OriginalDisplayBcc,
127
+ '0073' => :OriginalDisplayCc,
128
+ '0074' => :OriginalDisplayTo,
129
+ '0075' => :ReceivedByAddressType,
130
+ '0076' => :ReceivedByEmailAddress,
131
+ '0077' => :ReceivedRepresentingAddressType,
132
+ '0078' => :ReceivedRepresentingEmailAddress,
133
+ '007D' => :TransportMessageHeaders,
134
+ '007F' => :TnefCorrelationKey,
135
+ '0080' => :ReportDisposition,
136
+ '0081' => :ReportDispositionMode,
137
+ '0807' => :AddressBookRoomCapacity,
138
+ '0809' => :AddressBookRoomDescription,
139
+ '0C06' => :NonReceiptNotificationRequested,
140
+ '0C08' => :OriginatorNonDeliveryReportRequested,
141
+ '0C15' => :RecipientType,
142
+ '0C17' => :ReplyRequested,
143
+ '0C19' => :SenderEntryId,
144
+ '0C1A' => :SenderName,
145
+ '0C1D' => :SenderSearchKey,
146
+ '0C1E' => :SenderAddressType,
147
+ '0C1F' => :SenderEmailAddress,
148
+ '0E01' => :DeleteAfterSubmit,
149
+ '0E02' => :DisplayBcc,
150
+ '0E03' => :DisplayCc,
151
+ '0E04' => :DisplayTo,
152
+ '0E06' => :MessageDeliveryTime,
153
+ '0E07' => :MessageFlags,
154
+ '0E08' => :MessageSize,
155
+ # '0E08' => :MessageSizeExtended,
156
+ '0E09' => :ParentEntryId,
157
+ '0E0F' => :Responsibility,
158
+ '0E12' => :MessageRecipients,
159
+ '0E13' => :MessageAttachments,
160
+ '0E17' => :MessageStatus,
161
+ '0E1B' => :HasAttachments,
162
+ '0E1D' => :NormalizedSubject,
163
+ '0E1F' => :RtfInSync,
164
+ '0E20' => :AttachSize,
165
+ '0E21' => :AttachNumber,
166
+ '0E23' => :InternetArticleNumber,
167
+ '0E28' => :PrimarySendAccount,
168
+ '0E29' => :NextSendAcct,
169
+ '0E2B' => :ToDoItemFlags,
170
+ '0E2C' => :SwappedToDoStore,
171
+ '0E2D' => :SwappedToDoData,
172
+ '0E69' => :Read,
173
+ '0E6A' => :SecurityDescriptorAsXml,
174
+ '0E79' => :TrustSender,
175
+ '0E84' => :ExchangeNTSecurityDescriptor,
176
+ '0E99' => :ExtendedRuleMessageActions,
177
+ '0E9A' => :ExtendedRuleMessageCondition,
178
+ '0E9B' => :ExtendedRuleSizeLimit,
179
+ '0FF4' => :Access,
180
+ '0FF5' => :RowType,
181
+ '0FF6' => :InstanceKey,
182
+ '0FF7' => :AccessLevel,
183
+ '0FF8' => :MappingSignature,
184
+ '0FF9' => :RecordKey,
185
+ '0FFB' => :StoreEntryId,
186
+ '0FFE' => :ObjectType,
187
+ '0FFF' => :EntryId,
188
+ '1000' => :Body,
189
+ '1001' => :ReportText,
190
+ '1009' => :RtfCompressed,
191
+ '1013' => :BodyHtml,
192
+ # '1013' => :Html,
193
+ '1014' => :BodyContentLocation,
194
+ '1015' => :BodyContentId,
195
+ '1016' => :NativeBody,
196
+ '1035' => :InternetMessageId,
197
+ '1039' => :InternetReferences,
198
+ '1042' => :InReplyToId,
199
+ '1043' => :ListHelp,
200
+ '1044' => :ListSubscribe,
201
+ '1045' => :ListUnsubscribe,
202
+ '1046' => :OriginalMessageId,
203
+ '1080' => :IconIndex,
204
+ '1081' => :LastVerbExecuted,
205
+ '1082' => :LastVerbExecutionTime,
206
+ '1090' => :FlagStatus,
207
+ '1091' => :FlagCompleteTime,
208
+ '1095' => :FollowupIcon,
209
+ '1096' => :BlockStatus,
210
+ '10C3' => :ICalendarStartTime,
211
+ '10C4' => :ICalendarEndTime,
212
+ '10C5' => :CdoRecurrenceid,
213
+ '10CA' => :ICalendarReminderNextTime,
214
+ '10F3' => :UrlCompName,
215
+ '10F4' => :AttributeHidden,
216
+ '10F6' => :AttributeReadOnly,
217
+ '3000' => :Rowid,
218
+ '3001' => :DisplayName,
219
+ '3002' => :AddressType,
220
+ '3003' => :EmailAddress,
221
+ '3004' => :Comment,
222
+ '3005' => :Depth,
223
+ '3007' => :CreationTime,
224
+ '3008' => :LastModificationTime,
225
+ '300B' => :SearchKey,
226
+ '3010' => :TargetEntryId,
227
+ '3013' => :ConversationId,
228
+ '3016' => :ConversationIndexTracking,
229
+ '3018' => :ArchiveTag,
230
+ '3019' => :PolicyTag,
231
+ '301A' => :RetentionPeriod,
232
+ '301B' => :StartDateEtc,
233
+ '301C' => :RetentionDate,
234
+ '301D' => :RetentionFlags,
235
+ '301E' => :ArchivePeriod,
236
+ '301F' => :ArchiveDate,
237
+ '340D' => :StoreSupportMask,
238
+ '340E' => :StoreState,
239
+ '3600' => :ContainerFlags,
240
+ '3601' => :FolderType,
241
+ '3602' => :ContentCount,
242
+ '3603' => :ContentUnreadCount,
243
+ '3609' => :Selectable,
244
+ '360A' => :Subfolders,
245
+ '360C' => :Anr,
246
+ '360E' => :ContainerHierarchy,
247
+ '360F' => :ContainerContents,
248
+ '3610' => :FolderAssociatedContents,
249
+ '3613' => :ContainerClass,
250
+ '36D0' => :IpmAppointmentEntryId,
251
+ '36D1' => :IpmContactEntryId,
252
+ '36D2' => :IpmJournalEntryId,
253
+ '36D3' => :IpmNoteEntryId,
254
+ '36D4' => :IpmTaskEntryId,
255
+ '36D5' => :RemindersOnlineEntryId,
256
+ '36D7' => :IpmDraftsEntryId,
257
+ '36D8' => :AdditionalRenEntryIds,
258
+ '36D9' => :AdditionalRenEntryIdsEx,
259
+ '36DA' => :ExtendedFolderFlags,
260
+ '36E2' => :OrdinalMost,
261
+ '36E4' => :FreeBusyEntryIds,
262
+ '36E5' => :DefaultPostMessageClass,
263
+ '3701' => :AttachDataObject,
264
+ # '3701' => :AttachDataBinary,
265
+ '3702' => :AttachEncoding,
266
+ '3703' => :AttachExtension,
267
+ '3704' => :AttachFilename,
268
+ '3705' => :AttachMethod,
269
+ '3707' => :AttachLongFilename,
270
+ '3708' => :AttachPathname,
271
+ '3709' => :AttachRendering,
272
+ '370A' => :AttachTag,
273
+ '370B' => :RenderingPosition,
274
+ '370C' => :AttachTransportName,
275
+ '370D' => :AttachLongPathname,
276
+ '370E' => :AttachMimeTag,
277
+ '370F' => :AttachAdditionalInformation,
278
+ '3711' => :AttachContentBase,
279
+ '3712' => :CID,
280
+ '3713' => :AttachContentLocation,
281
+ '3714' => :AttachFlags,
282
+ '3719' => :AttachPayloadProviderGuidString,
283
+ '371A' => :AttachPayloadClass,
284
+ '371B' => :TextAttachmentCharset,
285
+ '3900' => :DisplayType,
286
+ '3902' => :Templateid,
287
+ '3905' => :DisplayTypeEx,
288
+ '39FE' => :SmtpAddress,
289
+ '39FF' => :AddressBookDisplayNamePrintable,
290
+ '3A00' => :Account,
291
+ '3A02' => :CallbackTelephoneNumber,
292
+ '3A05' => :Generation,
293
+ '3A06' => :GivenName,
294
+ '3A07' => :GovernmentIdNumber,
295
+ '3A08' => :BusinessTelephoneNumber,
296
+ '3A09' => :HomeTelephoneNumber,
297
+ '3A0A' => :Initials,
298
+ '3A0B' => :Keyword,
299
+ '3A0C' => :Language,
300
+ '3A0D' => :Location,
301
+ '3A0F' => :MessageHandlingSystemCommonName,
302
+ '3A10' => :OrganizationalIdNumber,
303
+ '3A11' => :Surname,
304
+ '3A12' => :OriginalEntryId,
305
+ '3A15' => :PostalAddress,
306
+ '3A16' => :CompanyName,
307
+ '3A17' => :Title,
308
+ '3A18' => :DepartmentName,
309
+ '3A19' => :OfficeLocation,
310
+ '3A1A' => :PrimaryTelephoneNumber,
311
+ '3A1B' => :Business2TelephoneNumber,
312
+ # '3A1B' => :Business2TelephoneNumbers,
313
+ '3A1C' => :MobileTelephoneNumber,
314
+ '3A1D' => :RadioTelephoneNumber,
315
+ '3A1E' => :CarTelephoneNumber,
316
+ '3A1F' => :OtherTelephoneNumber,
317
+ '3A20' => :TransmittableDisplayName,
318
+ '3A21' => :PagerTelephoneNumber,
319
+ '3A22' => :UserCertificate,
320
+ '3A23' => :PrimaryFaxNumber,
321
+ '3A24' => :BusinessFaxNumber,
322
+ '3A25' => :HomeFaxNumber,
323
+ '3A26' => :Country,
324
+ '3A27' => :Locality,
325
+ '3A28' => :StateOrProvince,
326
+ '3A29' => :StreetAddress,
327
+ '3A2A' => :PostalCode,
328
+ '3A2B' => :PostOfficeBox,
329
+ '3A2C' => :TelexNumber,
330
+ '3A2D' => :IsdnNumber,
331
+ '3A2E' => :AssistantTelephoneNumber,
332
+ '3A2F' => :Home2TelephoneNumber,
333
+ # '3A2F' => :Home2TelephoneNumbers,
334
+ '3A30' => :Assistant,
335
+ '3A40' => :SendRichInfo,
336
+ '3A41' => :WeddingAnniversary,
337
+ '3A42' => :Birthday,
338
+ '3A43' => :Hobbies,
339
+ '3A44' => :MiddleName,
340
+ '3A45' => :DisplayNamePrefix,
341
+ '3A46' => :Profession,
342
+ '3A47' => :ReferredByName,
343
+ '3A48' => :SpouseName,
344
+ '3A49' => :ComputerNetworkName,
345
+ '3A4A' => :CustomerId,
346
+ '3A4B' => :TelecommunicationsDeviceForDeafTelephoneNumber,
347
+ '3A4C' => :FtpSite,
348
+ '3A4D' => :Gender,
349
+ '3A4E' => :ManagerName,
350
+ '3A4F' => :Nickname,
351
+ '3A50' => :PersonalHomePage,
352
+ '3A51' => :BusinessHomePage,
353
+ '3A57' => :CompanyMainTelephoneNumber,
354
+ '3A58' => :ChildrensNames,
355
+ '3A59' => :HomeAddressCity,
356
+ '3A5A' => :HomeAddressCountry,
357
+ '3A5B' => :HomeAddressPostalCode,
358
+ '3A5C' => :HomeAddressStateOrProvince,
359
+ '3A5D' => :HomeAddressStreet,
360
+ '3A5E' => :HomeAddressPostOfficeBox,
361
+ '3A5F' => :OtherAddressCity,
362
+ '3A60' => :OtherAddressCountry,
363
+ '3A61' => :OtherAddressPostalCode,
364
+ '3A62' => :OtherAddressStateOrProvince,
365
+ '3A63' => :OtherAddressStreet,
366
+ '3A64' => :OtherAddressPostOfficeBox,
367
+ '3A70' => :UserX509Certificate,
368
+ '3A71' => :SendInternetEncoding,
369
+ '3F08' => :InitialDetailsPane,
370
+ '3F20' => :TemporaryDefaultDocument,
371
+ '3FDE' => :InternetCodepage,
372
+ '3FDF' => :AutoResponseSuppress,
373
+ '3FE0' => :AccessControlListData,
374
+ '3FE3' => :DelegatedByRule,
375
+ '3FE7' => :ResolveMethod,
376
+ '3FEA' => :HasDeferredActionMessages,
377
+ '3FEB' => :DeferredSendNumber,
378
+ '3FEC' => :DeferredSendUnits,
379
+ '3FED' => :ExpiryNumber,
380
+ '3FEE' => :ExpiryUnits,
381
+ '3FEF' => :DeferredSendTime,
382
+ '3FF0' => :ConflictEntryId,
383
+ '3FF1' => :MessageLocaleId,
384
+ '3FF8' => :CreatorName,
385
+ '3FF9' => :CreatorEntryId,
386
+ '3FFA' => :LastModifierName,
387
+ '3FFB' => :LastModifierEntryId,
388
+ '3FFD' => :MessageCodepage,
389
+ '401A' => :SentRepresentingFlags,
390
+ '4029' => :ReadReceiptAddressType,
391
+ '402A' => :ReadReceiptEmailAddress,
392
+ '402B' => :ReadReceiptName,
393
+ '4076' => :ContentFilterSpamConfidenceLevel,
394
+ '4079' => :SenderIdStatus,
395
+ '4083' => :PurportedSenderDomain,
396
+ '5902' => :InternetMailOverrideFormat,
397
+ '5909' => :MessageEditorFormat,
398
+ '5D01' => :SenderSmtpAddress,
399
+ '5FDE' => :RecipientResourceState,
400
+ '5FDF' => :RecipientOrder,
401
+ '5FE1' => :RecipientProposed,
402
+ '5FE3' => :RecipientProposedStartTime,
403
+ '5FE4' => :RecipientProposedEndTime,
404
+ '5FF6' => :RecipientDisplayName,
405
+ '5FF7' => :RecipientEntryId,
406
+ '5FFB' => :RecipientTrackStatusTime,
407
+ '5FFD' => :RecipientFlags,
408
+ '5FFF' => :RecipientTrackStatus,
409
+ '6100' => :JunkIncludeContacts,
410
+ '6101' => :JunkThreshold,
411
+ '6102' => :JunkPermanentlyDelete,
412
+ '6103' => :JunkAddRecipientsToSafeSendersList,
413
+ '6107' => :JunkPhishingEnableLinks,
414
+ '64F0' => :MimeSkeleton,
415
+ '65C2' => :ReplyTemplateId,
416
+ '65E0' => :SourceKey,
417
+ '65E1' => :ParentSourceKey,
418
+ '65E2' => :ChangeKey,
419
+ '65E3' => :PredecessorChangeList,
420
+ '65E9' => :RuleMessageState,
421
+ '65EA' => :RuleMessageUserFlags,
422
+ '65EB' => :RuleMessageProvider,
423
+ '65EC' => :RuleMessageName,
424
+ '65ED' => :RuleMessageLevel,
425
+ '65EE' => :RuleMessageProviderData,
426
+ '65F3' => :RuleMessageSequence,
427
+ '6619' => :UserEntryId,
428
+ '661B' => :MailboxOwnerEntryId,
429
+ '661C' => :MailboxOwnerName,
430
+ '661D' => :OutOfOfficeState,
431
+ '6622' => :ScheduleFreeBusy,
432
+ '6639' => :Rights,
433
+ '663A' => :HasRules,
434
+ '663B' => :AddressBookEntryId,
435
+ '663E' => :HierarchyChangeNumber,
436
+ '6645' => :ClientActions,
437
+ '6646' => :DamOriginalEntryId,
438
+ '6647' => :DamBackPatched,
439
+ '6648' => :RuleError,
440
+ '6649' => :RuleActionType,
441
+ '664A' => :HasNamedProperties,
442
+ '6650' => :RuleActionNumber,
443
+ '6651' => :RuleFolderEntryId,
444
+ '666A' => :ProhibitReceiveQuota,
445
+ '666C' => :InConflict,
446
+ '666D' => :MaximumSubmitMessageSize,
447
+ '666E' => :ProhibitSendQuota,
448
+ '6671' => :MemberId,
449
+ '6672' => :MemberName,
450
+ '6673' => :MemberRights,
451
+ '6674' => :RuleId,
452
+ '6675' => :RuleIds,
453
+ '6676' => :RuleSequence,
454
+ '6677' => :RuleState,
455
+ '6678' => :RuleUserFlags,
456
+ '6679' => :RuleCondition,
457
+ '6680' => :RuleActions,
458
+ '6681' => :RuleProvider,
459
+ '6682' => :RuleName,
460
+ '6683' => :RuleLevel,
461
+ '6684' => :RuleProviderData,
462
+ '668F' => :DeletedOn,
463
+ '66A1' => :LocaleId,
464
+ '66B3' => :NormalMessageSize,
465
+ '66C3' => :CodePageId,
466
+ '6704' => :AddressBookManageDistributionList,
467
+ '6705' => :SortLocaleId,
468
+ '6707' => :UrlName,
469
+ '6708' => :Subfolder,
470
+ '6709' => :LocalCommitTime,
471
+ '670A' => :LocalCommitTimeMax,
472
+ '670B' => :DeletedCountTotal,
473
+ '670E' => :FlatUrlName,
474
+ '671C' => :PublicFolderAdministrativeDescription,
475
+ '671D' => :PublicFolderProxy,
476
+ '6740' => :SentMailSvrEID,
477
+ '6741' => :DeferredActionMessageOriginalEntryId,
478
+ '6748' => :FolderId,
479
+ '6749' => :ParentFolderId,
480
+ '674A' => :Mid,
481
+ '674D' => :InstID,
482
+ '674E' => :InstanceNum,
483
+ '674F' => :AddressBookMessageId,
484
+ '67A4' => :ChangeNumber,
485
+ '67AA' => :Associated,
486
+ '6800' => :OfflineAddressBookName,
487
+ '6801' => :OfflineAddressBookSequence,
488
+ # '6801' => :VoiceMessageDuration,
489
+ '6802' => :OfflineAddressBookContainerGuid,
490
+ # '6802' => :SenderTelephoneNumber,
491
+ # '6802' => :RwRulesStream,
492
+ '6803' => :OfflineAddressBookMessageClass,
493
+ # '6803' => :VoiceMessageSenderName,
494
+ '6804' => :FaxNumberOfPages,
495
+ # '6804' => :OfflineAddressBookDistinguishedName,
496
+ '6805' => :VoiceMessageAttachmentOrder,
497
+ # '6805' => :OfflineAddressBookTruncatedProperties,
498
+ '6806' => :CallId,
499
+ '6834' => :SearchFolderLastUsed,
500
+ '683A' => :SearchFolderExpiration,
501
+ '6841' => :ScheduleInfoResourceType,
502
+ # '6841' => :SearchFolderTemplateId,
503
+ '6842' => :ScheduleInfoDelegatorWantsCopy,
504
+ # '6842' => :SearchFolderId,
505
+ # '6842' => :WlinkGroupHeaderID,
506
+ '6843' => :ScheduleInfoDontMailDelegates,
507
+ '6844' => :SearchFolderRecreateInfo,
508
+ # '6844' => :ScheduleInfoDelegateNames,
509
+ '6845' => :SearchFolderDefinition,
510
+ # '6845' => :ScheduleInfoDelegateEntryIds,
511
+ '6846' => :SearchFolderStorageType,
512
+ # '6846' => :GatewayNeedsToRefresh,
513
+ '6847' => :FreeBusyPublishStart,
514
+ # '6847' => :SearchFolderTag,
515
+ # '6847' => :WlinkSaveStamp,
516
+ '6848' => :FreeBusyPublishEnd,
517
+ # '6848' => :SearchFolderEfpFlags,
518
+ '6849' => :WlinkType,
519
+ # '6849' => :FreeBusyMessageEmailAddress,
520
+ '684A' => :WlinkFlags,
521
+ # '684A' => :ScheduleInfoDelegateNamesW,
522
+ '684B' => :ScheduleInfoDelegatorWantsInfo,
523
+ # '684B' => :WlinkOrdinal,
524
+ '684C' => :WlinkEntryId,
525
+ '684D' => :WlinkRecordKey,
526
+ '684E' => :WlinkStoreEntryId,
527
+ '684F' => :WlinkFolderType,
528
+ # '684F' => :ScheduleInfoMonthsMerged,
529
+ '6850' => :WlinkGroupClsid,
530
+ # '6850' => :ScheduleInfoFreeBusyMerged,
531
+ '6851' => :WlinkGroupName,
532
+ # '6851' => :ScheduleInfoMonthsTentative,
533
+ '6852' => :WlinkSection,
534
+ # '6852' => :ScheduleInfoFreeBusyTentative,
535
+ '6853' => :WlinkCalendarColor,
536
+ # '6853' => :ScheduleInfoMonthsBusy,
537
+ '6854' => :WlinkAddressBookEID,
538
+ # '6854' => :ScheduleInfoFreeBusyBusy,
539
+ '6855' => :ScheduleInfoMonthsAway,
540
+ '6856' => :ScheduleInfoFreeBusyAway,
541
+ '6868' => :FreeBusyRangeTimestamp,
542
+ '6869' => :FreeBusyCountMonths,
543
+ '686A' => :ScheduleInfoAppointmentTombstone,
544
+ '686B' => :DelegateFlags,
545
+ '686C' => :ScheduleInfoFreeBusy,
546
+ '686D' => :ScheduleInfoAutoAcceptAppointments,
547
+ '686F' => :ScheduleInfoDisallowOverlappingAppts,
548
+ '6890' => :WlinkClientID,
549
+ '6891' => :WlinkAddressBookStoreEID,
550
+ '6892' => :WlinkROGroupType,
551
+ '7001' => :ViewDescriptorBinary,
552
+ '7002' => :ViewDescriptorStrings,
553
+ '7006' => :ViewDescriptorName,
554
+ '7007' => :ViewDescriptorVersion,
555
+ '7C06' => :RoamingDatatypes,
556
+ '7C07' => :RoamingDictionary,
557
+ '7C08' => :RoamingXmlStream,
558
+ '7C24' => :OscSyncEnabled,
559
+ '7D01' => :Processed,
560
+ '7FF9' => :ExceptionReplaceTime,
561
+ '7FFA' => :AttachmentLinkId,
562
+ '7FFB' => :ExceptionStartTime,
563
+ '7FFC' => :ExceptionEndTime,
564
+ '7FFD' => :AttachmentFlags,
565
+ '7FFE' => :AttachmentHidden,
566
+ '7FFF' => :AttachmentContactPhoto,
567
+ '8004' => :AddressBookFolderPathname,
568
+ '8005' => :AddressBookManager,
569
+ # '8005' => :AddressBookManagerDistinguishedName,
570
+ '8006' => :AddressBookHomeMessageDatabase,
571
+ '8008' => :AddressBookIsMemberOfDistributionList,
572
+ '8009' => :AddressBookMember,
573
+ '800C' => :AddressBookOwner,
574
+ '800E' => :AddressBookReports,
575
+ '800F' => :AddressBookProxyAddresses,
576
+ '8011' => :AddressBookTargetAddress,
577
+ '8015' => :AddressBookPublicDelegates,
578
+ '8024' => :AddressBookOwnerBackLink,
579
+ '802D' => :AddressBookExtensionAttribute1,
580
+ '802E' => :AddressBookExtensionAttribute2,
581
+ '802F' => :AddressBookExtensionAttribute3,
582
+ '8030' => :AddressBookExtensionAttribute4,
583
+ '8031' => :AddressBookExtensionAttribute5,
584
+ '8032' => :AddressBookExtensionAttribute6,
585
+ '8033' => :AddressBookExtensionAttribute7,
586
+ '8034' => :AddressBookExtensionAttribute8,
587
+ '8035' => :AddressBookExtensionAttribute9,
588
+ '8036' => :AddressBookExtensionAttribute10,
589
+ '803C' => :AddressBookObjectDistinguishedName,
590
+ '806A' => :AddressBookDeliveryContentLength,
591
+ '8073' => :AddressBookDistributionListMemberSubmitAccepted,
592
+ '8170' => :AddressBookNetworkAddress,
593
+ '8C57' => :AddressBookExtensionAttribute11,
594
+ '8C58' => :AddressBookExtensionAttribute12,
595
+ '8C59' => :AddressBookExtensionAttribute13,
596
+ '8C60' => :AddressBookExtensionAttribute14,
597
+ '8C61' => :AddressBookExtensionAttribute15,
598
+ '8C6A' => :AddressBookX509Certificate,
599
+ '8C6D' => :AddressBookObjectGuid,
600
+ '8C8E' => :AddressBookPhoneticGivenName,
601
+ '8C8F' => :AddressBookPhoneticSurname,
602
+ '8C90' => :AddressBookPhoneticDepartmentName,
603
+ '8C91' => :AddressBookPhoneticCompanyName,
604
+ '8C92' => :AddressBookPhoneticDisplayName,
605
+ '8C93' => :AddressBookDisplayTypeExtended,
606
+ '8C94' => :AddressBookHierarchicalShowInDepartments,
607
+ '8C96' => :AddressBookRoomContainers,
608
+ '8C97' => :AddressBookHierarchicalDepartmentMembers,
609
+ '8C98' => :AddressBookHierarchicalRootDepartment,
610
+ '8C99' => :AddressBookHierarchicalParentDepartment,
611
+ '8C9A' => :AddressBookHierarchicalChildDepartments,
612
+ '8C9E' => :ThumbnailPhoto,
613
+ '8CA0' => :AddressBookSeniorityIndex,
614
+ '8CA8' => :AddressBookOrganizationalUnitRootDistinguishedName,
615
+ '8CAC' => :AddressBookSenderHintTranslations,
616
+ '8CB5' => :AddressBookModerationEnabled,
617
+ '8CC2' => :SpokenName,
618
+ '8CD8' => :AddressBookAuthorizedSenders,
619
+ '8CD9' => :AddressBookUnauthorizedSenders,
620
+ '8CDA' => :AddressBookDistributionListMemberSubmitRejected,
621
+ '8CDB' => :AddressBookDistributionListRejectMessagesFromDLMembers,
622
+ '8CDD' => :AddressBookHierarchicalIsHierarchicalGroup,
623
+ '8CE2' => :AddressBookDistributionListMemberCount,
624
+ '8CE3' => :AddressBookDistributionListExternalMemberCount,
625
+ 'FFFB' => :AddressBookIsMaster,
626
+ 'FFFC' => :AddressBookParentEntryId,
627
+ 'FFFD' => :AddressBookContainerId,
628
+ }
629
+
630
+ class Parser
631
+ def initialize(oab)
632
+ @oab = open(oab)
633
+ @header = _header
649
634
  end
650
- raise "Unexpected first byte #{sprintf('%x', firstByte)} of integer"
651
- end
652
-
653
- def _propertyTypes
654
- n = _uint32
655
- return 1.upto(n).collect{|i|
656
- prop = OpenStruct.new
657
- prop.pos = pos
658
-
659
- id = _uint32
660
- prop._id = id.to_s(16)
661
- prop.id = sprintf('%04x', id >> 16).upcase
662
- prop.name = MapiPropertyName[prop.id]
663
- throw prop.id unless prop.name && prop.name != ''
664
- type = id & 0xffff
665
- prop.type = typeof(type & ~MapiPropertyDataType.Mv)
666
- prop._type = sprintf('%04x', (type & ~MapiPropertyDataType.Mv))
667
- prop.array = ((type & MapiPropertyDataType.Mv) != 0)
668
- prop.flags = _uint32
669
- prop
670
- }
671
- end
672
-
673
- def _header
674
- # Read OAB_HDR
675
- version = _uint32
676
- raise "Version not found, got #{version.inspect}" unless version == 0x20 # version
677
- @serialNumber = _uint32
678
- @totalRecords = _uint32
679
- # Read OAB_META_DATA
680
- metadataSize = _uint32
681
-
682
- @headerProperties = _propertyTypes
683
- @oabProperties = _propertyTypes
684
- return _record(true)
685
- end
686
-
687
- def _property(prop)
688
- if prop.array
689
- valueCount = _integer
690
- value = []
691
- valueCount.times{
692
- value << _scalar(prop.type)
693
- }
694
- else
695
- value = _scalar(prop.type)
635
+
636
+ def pos
637
+ return sprintf('%08o', @oab.pos)
696
638
  end
697
- p = OpenStruct.new(type: prop.type, id: prop.id, name: prop.name, value: value)
698
- return p
699
- end
700
-
701
- def _scalar(type)
702
- case type.to_sym
703
- when :Long then return _integer
704
- when :Boolean then return (_ubyte > 0)
705
- when :Binary then return @oab.read(_integer)
706
- when :AnsiString, :UnicodeString
707
- string = ''
708
- while (byte = @oab.read(1)) != "\x00"
709
- string << byte
710
- end
711
- # TODO: string.force_encoding(MapiPropertyDataType.UnicodeString ? 'UTF-8' : 'ASCII')
712
- string.force_encoding(type == :UnicodeString ? 'UTF-8' : 'ASCII')
713
- return string
639
+ def typeof(type)
640
+ return MapiPropertyDataType[type.to_s.to_sym]
714
641
  end
715
- raise "Unknown scalar type #{type}"
716
- end
717
-
718
- def _record(headerRecord = false)
719
- initialPosition = @oab.pos
720
- recordSize = 0
721
- record = Record.new
722
- begin
723
- properties = headerRecord ? @headerProperties : @oabProperties
724
- recordSize = _uint32
725
- recordPresence = @oab.read((properties.length + 7) / 8).unpack("b*").join.split('').collect{|bit| bit.to_i != 0 }
726
- properties.each_with_index{|prop, i|
727
- next unless recordPresence[i + 7 - 2 * (i % 8)]
728
- p = _property(prop)
729
- pn = p.name.to_s
730
- record[pn] ||= []
731
- record[pn] << p.value
642
+
643
+ attr_reader :serialNumber, :totalRecords, :header
644
+
645
+ def _uint32
646
+ return @oab.read(4).unpack('V*')[0]
647
+ end
648
+ def _ubyte
649
+ return @oab.read(1).unpack('C*')[0]
650
+ end
651
+
652
+ def _integer
653
+ firstByte = _ubyte
654
+
655
+ return firstByte if firstByte < 0x80
656
+
657
+ case firstByte
658
+ when 0x81 then return _ubyte
659
+ when 0x82 then return _ubyte + (_ubyte << 8)
660
+ when 0x83 then return _ubyte + (_ubyte << 8) + (_ubyte << 16)
661
+ when 0x84 then return _ubyte + (_ubyte << 8) + (_ubyte << 16) + (_ubyte << 24)
662
+ end
663
+ raise "Unexpected first byte #{sprintf('%x', firstByte)} of integer"
664
+ end
665
+
666
+ def _propertyTypes
667
+ n = _uint32
668
+ return 1.upto(n).collect{|i|
669
+ prop = OpenStruct.new
670
+ prop.pos = pos
671
+
672
+ id = _uint32
673
+ prop._id = id.to_s(16)
674
+ prop.id = sprintf('%04x', id >> 16).upcase
675
+ prop.name = MapiPropertyName[prop.id]
676
+ throw prop.id unless prop.name && prop.name != ''
677
+ type = id & 0xffff
678
+ prop.type = typeof(type & ~MapiPropertyDataType.Mv)
679
+ prop._type = sprintf('%04x', (type & ~MapiPropertyDataType.Mv))
680
+ prop.array = ((type & MapiPropertyDataType.Mv) != 0)
681
+ prop.flags = _uint32
682
+ prop
732
683
  }
733
- ensure
734
- @oab.pos = initialPosition + recordSize
735
684
  end
736
- return record
737
- end
738
-
739
- def records
740
- @records = Enumerator.new(@totalRecords) do |y|
741
- @totalRecords.times { y.yield _record }
685
+
686
+ def _header
687
+ # Read OAB_HDR
688
+ version = _uint32
689
+ raise "Version not found, got #{version.inspect}" unless version == 0x20 # version
690
+ @serialNumber = _uint32
691
+ @totalRecords = _uint32
692
+ # Read OAB_META_DATA
693
+ metadataSize = _uint32
694
+
695
+ @headerProperties = _propertyTypes
696
+ @oabProperties = _propertyTypes
697
+ return _record(true)
698
+ end
699
+
700
+ def _property(prop)
701
+ if prop.array
702
+ valueCount = _integer
703
+ value = []
704
+ valueCount.times{
705
+ value << _scalar(prop.type)
706
+ }
707
+ else
708
+ value = _scalar(prop.type)
709
+ end
710
+ p = OpenStruct.new(type: prop.type, id: prop.id, name: prop.name, value: value)
711
+ return p
712
+ end
713
+
714
+ def _scalar(type)
715
+ case type.to_sym
716
+ when :Long then return _integer
717
+ when :Boolean then return (_ubyte > 0)
718
+ when :Binary then return @oab.read(_integer)
719
+ when :AnsiString, :UnicodeString
720
+ string = ''
721
+ while (byte = @oab.read(1)) != "\x00"
722
+ string << byte
723
+ end
724
+ # TODO: string.force_encoding(MapiPropertyDataType.UnicodeString ? 'UTF-8' : 'ASCII')
725
+ string.force_encoding(type == :UnicodeString ? 'UTF-8' : 'ASCII')
726
+ return string
727
+ end
728
+ raise "Unknown scalar type #{type}"
729
+ end
730
+
731
+ def _record(headerRecord = false)
732
+ initialPosition = @oab.pos
733
+ recordSize = 0
734
+ record = Record.new
735
+ begin
736
+ properties = headerRecord ? @headerProperties : @oabProperties
737
+ recordSize = _uint32
738
+ recordPresence = @oab.read((properties.length + 7) / 8).unpack("b*").join.split('').collect{|bit| bit.to_i != 0 }
739
+ properties.each_with_index{|prop, i|
740
+ next unless recordPresence[i + 7 - 2 * (i % 8)]
741
+ p = _property(prop)
742
+ pn = p.name.to_s
743
+ record[pn] ||= []
744
+ record[pn] << p.value
745
+ }
746
+ ensure
747
+ @oab.pos = initialPosition + recordSize
748
+ end
749
+ return record
750
+ end
751
+
752
+ def records
753
+ @records = Enumerator.new(@totalRecords) do |y|
754
+ @totalRecords.times { y.yield _record }
755
+ end
756
+ return @records
742
757
  end
743
- return @records
744
758
  end
759
+
745
760
  end
746
761
  end