2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2004 Net Integration Technologies, Inc.
5 * This is the main TNEF handling class.
15 #include "wvlinklist.h"
16 #include "wvscatterhash.h"
19 #include "wvtnefdefs.h"
20 #include "wvmapipart.h"
24 DeclareWvList2(WvMapiPartList
, WvMapiPart
);
25 DeclareWvList2(Uint32List
, uint32_t);
34 /** Keys for the wvtnef internal hash table.
35 * These keys have 4 properties: tag, guid, name_id and name_string.
36 * At most, 2 of these are needed to find a MAPI property. If its
37 * MAPI ID is less than 0x8000, it is a "normal" MAPI property, and
38 * all you need to find it is the tag. If its MAPI ID is >= 0x8000,
39 * however, it is a "named" property, and you will need its GUID in
40 * addition to either the name ID (another 2-byte ID that is also
41 * usually, but not always, >= 0x8000) or the name string, which is
43 * @see str2guid() for how to get a GUID structure from a C string
44 * @see str2ustr() for how to get a 2-byte string from a C string. */
48 { tag
= 0; name_id
= 0; }
49 PropertyKey(uint32_t t
)
50 { tag
= t
; name_id
= 0; }
51 PropertyKey(const string
&g
, uint32_t id
)
52 { tag
= 0; guid
= g
; name_id
= id
; }
53 PropertyKey(const string
&g
, const string
&n
)
54 { tag
= 0; guid
= g
; name_id
= 0; name_str
= n
; }
61 bool operator==(const PropertyKey
&k
) const
63 if(k
.guid
.length() > 0)
65 && name_str
== k
.name_str
66 && name_id
== k
.name_id
;
71 PropertyKey
&operator=(const PropertyKey
&k
)
75 name_str
= k
.name_str
;
81 /** Makes a GUID structure from a C string (or WvString).
82 * Takes a string in the format "ca7331d4-2c89-46a6-a173-eb06ec2367c7"
83 * and makes a GUID structure from it.
84 * @param str String to use for making a GUID.
85 * @return A GUID structure in a std::string. */
86 string
str2guid(WvStringParm str
);
88 /** Fakes a 2-byte string from a C string (or WvString).
89 * Takes a string and pads it with NULs between each character.
90 * @param str String to use for making "fake" 2-byte string.
91 * @return A "fake" 2-byte string in a std::string. */
92 string
str2ustr(WvStringParm str
);
98 * Make a new WvTnef object.
99 * Constructs a new WvTnef object.
100 * @param istream The input stream containing the TNEF.
101 * @param ostream An optional output stream.
103 WvTnef(WvStream
*istream
, WvStream
*ostream
= NULL
);
106 * Make a new WvTnef object.
107 * Constructs a new WvTnef object (with no properties).
114 * Rewrite a TNEF from the properties currently in memory.
115 * @param filename The file in which to place the re-written TNEF.
116 * @return Whether we were able to successfully re-write the TNEF.
118 bool rewrite(WvStringParm filename
);
121 * Remove a single MAPI property.
122 * @param key The key of the property to remove.
123 * @return Whether the property was successfully removed.
125 bool remove_mapi_prop(const PropertyKey
&key
);
128 * Get a single MAPI property.
129 * Looks up a MAPI property in the internal hash table using its
130 * MAPI tag. This will only work, of course, with tags whose
131 * MAPI IDs are less than 0x8000.
132 * @param tag The MAPI tag of the property to get.
133 * @return The value of the MAPI property, or NULL if not found.
135 const WvMapiPart
*get_property(const uint32_t tag
,
136 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
137 const int store_num
= 0) const;
140 * Get a single MAPI property.
141 * Looks up a MAPI property in the internal hash table using its
142 * MAPI GUID and name ID. This will only work, of course, with
143 * properties whose MAPI IDs are >= 0x8000.
144 * @param guid The MAPI GUID of the property to get.
145 * @param name_id The MAPI name ID of the property to get.
146 * @return The value of the MAPI property, or NULL if not found.
148 const WvMapiPart
*get_property(const string
&guid
,
149 const uint32_t name_id
,
150 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
151 const int store_num
= 0) const;
153 * Get a single MAPI property.
154 * Looks up a MAPI property in the internal hash table using its
155 * MAPI GUID and name string. This will only work, of course, with
156 * properties whose MAPI IDs are >= 0x8000.
157 * @param guid The MAPI GUID of the property to get.
158 * @param name_str The MAPI name string of the property to get.
159 * @return The value of the MAPI property, or NULL if not found.
161 const WvMapiPart
*get_property(const string
&guid
,
162 const string
&name_str
,
163 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
164 const int store_num
= 0) const;
167 * Get a MAPI property list.
168 * Looks up a MAPI property in the internal hash table using its
169 * MAPI tag, and returns all values of that property. This only
170 * really makes sense for multivalue properties.
171 * @param tag The MAPI tag of the property list to get.
172 * @return A list of all the values of the specified property.
174 const WvMapiPartList
*get_properties(const uint32_t tag
,
175 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
176 const int store_num
= 0) const;
179 * Get a MAPI property list.
180 * Looks up a MAPI property in the internal hash table using its
181 * MAPI GUID and name ID, and returns all values of that property.
182 * This only really makes sense for multivalue properties.
183 * @param guid The MAPI GUID of the property list to get.
184 * @param name_id The MAPI name ID of the property list to get.
185 * @return A list of all the values of the specified property.
187 const WvMapiPartList
*get_properties(const string
&guid
,
188 const uint32_t name_id
,
189 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
190 const int store_num
= 0) const;
193 * Get a MAPI property list.
194 * Looks up a MAPI property in the internal hash table using its
195 * MAPI GUID and name string, and returns all values of that property.
196 * This only really makes sense for multivalue properties.
197 * @param guid The MAPI GUID of the property list to get.
198 * @param name_str The MAPI name string of the property list to get.
199 * @return A list of all the values of the specified property.
201 const WvMapiPartList
*get_properties(const string
&guid
,
202 const string
&name_str
,
203 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
204 const int store_num
= 0) const;
207 * Set a MAPI property.
208 * Sets a MAPI property in the internal hash table using its MAPI tag
209 * for the key. If the property exists, it is overwritten. Otherwise
211 * @param tag The MAPI tag of the property to set.
212 * @param value The value of the MAPI property to set.
213 * @return Whether the property was successfully set. */
214 bool set_property(const uint32_t tag
, string
*value
,
215 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
216 const int store_num
= 0);
219 * Set a MAPI property.
220 * Sets a MAPI property in the internal hash table using its MAPI tag
221 * for the key. If the property exists, it is overwritten. Otherwise
223 * @param tag The MAPI tag of the property to set.
224 * @param value The value of the MAPI property to set.
225 * @return Whether the property was successfully set. */
226 bool set_property(const uint32_t tag
, const char *value
,
227 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
228 const int store_num
= 0);
230 /** Sets a MAPI property.
231 * Sets a MAPI property in the internal hash table using its MAPI
232 * GUID and name ID for the key. If the property exists, it is
233 * overwritten. Otherwise it is added.
234 * @param guid The MAPI GUID of the property to set.
235 * @param name_id The MAPI name ID of the property to set.
236 * @param value The value of the MAPI property to set.
237 * WvTnef takes ownership of this string.
238 * @return Whether the property was successfully set. */
239 bool set_property(const string
&guid
, const uint32_t name_id
,
240 string
*value
, const uint32_t mapi_type
,
241 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
242 const int store_num
= 0);
244 /** Sets a MAPI property.
245 * Sets a MAPI property in the internal hash table using its MAPI
246 * GUID and name ID for the key. If the property exists, it is
247 * overwritten. Otherwise it is added.
248 * @param guid The MAPI GUID of the property to set.
249 * @param name_id The MAPI name ID of the property to set.
250 * @param value The value of the MAPI property to set.
251 * WvTnef takes ownership of this string.
252 * @return Whether the property was successfully set. */
253 bool set_property(const string
&guid
, const uint32_t name_id
,
254 const char *value
, const uint32_t mapi_type
,
255 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
256 const int store_num
= 0);
258 /** Sets a MAPI property.
259 * Sets a MAPI property in the internal hash table using its MAPI
260 * GUID and name string for the key. If the property exists, it is
261 * overwritten. Otherwise it is added.
262 * @param guid The MAPI GUID of the property to set.
263 * @param name_str The MAPI name string of the property to set.
264 * @param value The value of the MAPI property to set.
265 * WvTnef takes ownership of this string.
266 * @return Whether the property was successfully set. */
267 bool set_property(const string
&guid
, const string
&name_str
,
268 string
*value
, const uint32_t mapi_type
,
269 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
270 const int store_num
= 0);
272 /** Sets a MAPI property.
273 * Sets a MAPI property in the internal hash table using its MAPI
274 * GUID and name string for the key. If the property exists, it is
275 * overwritten. Otherwise it is added.
276 * @param guid The MAPI GUID of the property to set.
277 * @param name_str The MAPI name string of the property to set.
278 * @param value The value of the MAPI property to set.
279 * WvTnef takes ownership of this string.
280 * @return Whether the property was successfully set. */
281 bool set_property(const string
&guid
, const string
&name_str
,
282 const char *value
, const uint32_t mapi_type
,
283 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
284 const int store_num
= 0);
286 /** Appends a value to a MAPI property list.
287 * Appends a value to the MAPI property in the internal hash table
288 * using its tag for the key. If the property doesn't exist, a new
289 * property is created, with the given value as its first element.
290 * @param tag The MAPI tag of the property list.
291 * @param value The value of the MAPI property to append.
292 * WvTnef takes ownership of this string.
293 * @return Whether the value was successfully appended. */
294 bool append_property(const uint32_t tag
, string
*value
,
295 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
296 const int store_num
= 0);
298 /** Appends a value to a MAPI property list.
299 * Appends a value to the MAPI property in the internal hash table
300 * using its MAPI GUID and name ID for the key. If the property
301 * doesn't exist, a new property is created, with the given value
302 * as its first element.
303 * @param guid The MAPI GUID of the property list.
304 * @param name_id The MAPI name ID of the property list.
305 * @param value The value of the MAPI property to append.
306 * WvTnef takes ownership of this string.
307 * @return Whether the value was successfully appended. */
308 bool append_property(const string
&guid
, const uint32_t name_id
,
309 string
*value
, const uint32_t mapi_type
,
310 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
311 const int store_num
= 0);
313 /** Appends a value to a MAPI property list.
314 * Appends a value to the MAPI property in the internal hash table
315 * using its MAPI GUID and name string for the key. If the property
316 * doesn't exist, a new property is created, with the given value
317 * as its first element.
318 * @param guid The MAPI GUID of the property list.
319 * @param name_str The MAPI name string of the property list.
320 * @param value The value of the MAPI property to append.
321 * WvTnef takes ownership of this string.
322 * @return Whether the value was successfully appended. */
323 bool append_property(const string
&guid
, const string
&name_str
,
324 string
*value
, const uint32_t mapi_type
,
325 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
326 const int store_num
= 0);
328 /** Sets a MAPI property list.
329 * Sets the MAPI property list in the internal hash table using
330 * its MAPI tag for the key. If the property doesn't exist, a
331 * a new property is created, with the given list. Otherwise,
332 * the property is overwritten.
333 * @param tag The MAPI tag of the property.
334 * @param value The MAPI property list to set.
335 * WvTnef takes ownership of this list.
336 * @return Whether the value was successfully set. */
337 bool set_properties(const uint32_t tag
, WvMapiPartList
*list
,
338 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
339 const int store_num
= 0);
341 /** Sets a MAPI property list.
342 * Sets the MAPI property list in the internal hash table using
343 * its MAPI GUID and name ID for the key. If the property doesn't
344 * exist, a new property is created, with the given list.
345 * Otherwise, the property is overwritten.
346 * @param guid The MAPI GUID of the property.
347 * @param name_id The MAPI name ID of the property.
348 * @param value The MAPI property list to set.
349 * WvTnef takes ownership of this list.
350 * @return Whether the value was successfully set. */
351 bool set_properties(const string
&guid
, const uint32_t name_id
,
352 WvMapiPartList
*list
, const uint32_t mapi_type
,
353 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
354 const int store_num
= 0);
356 /** Sets a MAPI property list.
357 * Sets the MAPI property list in the internal hash table using
358 * its MAPI GUID and name string for the key. If the property
359 * doesn't exist, a new property is created, with the given list.
360 * Otherwise, the property is overwritten.
361 * @param guid The MAPI GUID of the property.
362 * @param name_str The MAPI name string of the property.
363 * @param value The MAPI property list to set.
364 * WvTnef takes ownership of this list.
365 * @return Whether the list was successfully set. */
366 bool set_properties(const string
&guid
, const string
&name_str
,
367 WvMapiPartList
*list
, const uint32_t mapi_type
,
368 const TNEFStoreType store_type
= ATT_MAPI_PROPS
,
369 const int store_num
= 0);
371 /** Tells whether the TNEF stream was parsed properly.
372 * In order for this to return true, all checksums must match, the
373 * magic value must be present, etc.
374 * @return Whether the TNEF stream was parsed without errors. */
375 bool isok() const { return _isok
; }
377 /** Parse the TNEF stream.
378 * This function will read the TNEF stream and parse it into the
379 * various MAPI properties present.
380 * @param istream The input stream containing the TNEF.
381 * @param ostream An optional output stream.
382 * @return Whether the parsing was successful. */
383 bool parse(WvStream
*istream
, WvStream
*ostream
= NULL
);
385 /** Dumps a bunch of information about each MAPI property to the log.
386 * An iterator will be used to iterate through the internal hash
387 * table, printing out the MAPI ID, type and a hexdump of the value. */
391 typedef WvMap
<PropertyKey
, WvMapiPartList
*, OpEqComp
, WvScatterHash
> PropertyHash
;
392 mutable PropertyHash _properties
; // HACK: this should _not_ be mutable
393 mutable WvVector
<PropertyHash
> _att_properties
; // HACK: nor should this
394 mutable WvVector
<PropertyHash
> _recip_properties
; // HACK: nor should this
396 static int _endian_test
;
397 static bool _isbigendian
;
398 mutable uint16_t _checksum
;
402 mutable WvDynBuf tmp_buf
;
405 // Check the checksum value against the one in the TNEF
406 bool check_sum(WvStream
*istream
, WvStream
*ostream
);
408 // Check the header of an attribute
409 bool check_header(const void *header
);
411 // The heavy lifting happens here
412 bool parse_mapi_properties(WvStream
*istream
, WvStream
*ostream
= NULL
);
415 /* These functions are all used to write out the TNEF
416 * from our internal structure, modelled off pphaneuf's
418 bool dump_attribute(unsigned char x
, uint32_t att
, uint32_t size
,
420 bool dump_attachments(FILE *file
) const;
421 bool dump_recip_table(FILE *file
) const;
422 bool dump_mapi_properties(FILE *file
) const;
425 bool write_mapi_properties(PropertyHash
*property_hash
, uint32_t &size
,
428 const void *read_write_chk(const size_t num_bytes
,
430 WvStream
*ostream
= NULL
) const;
432 // Reading, writing, checksumming independent of byte order
433 int16_t read_write2_chk(WvStream
*istream
, WvStream
*ostream
) const;
434 int32_t read_write4_chk(WvStream
*istream
, WvStream
*ostream
) const;
435 int64_t read_write8_chk(WvStream
*istream
, WvStream
*ostream
) const;
436 uint16_t read_write2u_chk(WvStream
*istream
, WvStream
*ostream
) const;
437 uint32_t read_write4u_chk(WvStream
*istream
, WvStream
*ostream
) const;
438 uint64_t read_write8u_chk(WvStream
*istream
, WvStream
*ostream
) const;
440 const void *read_write(const size_t num_bytes
,
442 WvStream
*ostream
= NULL
) const;
444 // Reading, writing independent of byte order
445 // FIXME: these should be independant of the TNEF class
446 int16_t read_write2(WvStream
*istream
, WvStream
*ostream
) const;
447 int32_t read_write4(WvStream
*istream
, WvStream
*ostream
) const;
448 int64_t read_write8(WvStream
*istream
, WvStream
*ostream
) const;
449 uint16_t read_write2u(WvStream
*istream
, WvStream
*ostream
) const;
450 uint32_t read_write4u(WvStream
*istream
, WvStream
*ostream
) const;
451 uint64_t read_write8u(WvStream
*istream
, WvStream
*ostream
) const;
453 int16_t read2(FILE *file
) const;
454 int32_t read4(FILE *file
) const;
455 int64_t read8(FILE *file
) const;
456 uint16_t read2u(FILE *file
) const;
457 uint32_t read4u(FILE *file
) const;
458 uint64_t read8u(FILE *file
) const;
460 int16_t read2(WvStream
*istream
) const { return read_write2(istream
, NULL
); }
461 int32_t read4(WvStream
*istream
) const { return read_write4(istream
, NULL
); }
462 int64_t read8(WvStream
*istream
) const { return read_write8(istream
, NULL
); }
463 uint16_t read2u(WvStream
*istream
) const { return read_write2u(istream
, NULL
); }
464 uint32_t read4u(WvStream
*istream
) const { return read_write4u(istream
, NULL
); }
465 uint64_t read8u(WvStream
*istream
) const { return read_write8u(istream
, NULL
); }
467 // Reading 4 bytes from a buffer independent of byte-order
468 uint32_t read4u(WvDynBuf
&buf
) const;
470 // Appending integers to a buffer
471 uint32_t append2(uint16_t i
, FILE *file
) const;
472 uint32_t append4(uint32_t i
, FILE *file
) const;
473 uint32_t append8(uint64_t i
, FILE *file
) const;
475 // various helper functions for the public get and set property functions
476 const WvMapiPartList
* WvTnef::get_properties_real(const PropertyKey key
,
477 const TNEFStoreType store_type
,
478 const int store_num
) const;
479 void remove_property_and_set_tag(PropertyKey
&key
, const uint32_t mapi_type
,
480 PropertyHash
*property_hash
);
481 void set_property_real(PropertyKey
&key
, string
*value
,
482 PropertyHash
*property_hash
);
483 void append_property_real(PropertyKey
&key
, string
*value
,
484 const uint32_t mapi_type
,
485 const TNEFStoreType store_type
,
486 const int store_num
);
487 void set_properties_real(PropertyKey
&key
, WvMapiPartList
*list
,
488 const uint32_t mapi_type
,
489 const TNEFStoreType store_type
,
490 const int store_num
);
491 PropertyHash
* get_property_hash(const TNEFStoreType store_type
,
492 const int store_num
) const;
494 // Used for some debug messages
495 static WvString
inttohex(int value
);
497 // Byte swapping functions for big-endian machines
498 static uint64_t swap8(const uint64_t i
);
499 static uint32_t swap4(const uint32_t i
);
500 static uint16_t swap2(const uint16_t i
);
503 extern unsigned WvHash(const string
&);
504 extern unsigned WvHash(const PropertyKey
&);