This project is read-only.

Proper way to deal with ATTACH_OLE?

Jun 6, 2010 at 12:30 AM

When dealing with attachments, what's the proper way to deal with the attach type ATTACH_OLE?

Should I call get_bytes() on the attachment, then use CreateILockBytesOnHGlobal() and StgOpenStorageOnILockBytes()?  The reason I ask is ... I have an e-mail with an attached OLE IStorage, and when I read the attachment with get_bytes() I am only getting 8 bytes out of it.


Jun 6, 2010 at 12:40 AM

8 bytes sounds like a disk::sub_object. The PST layer doesn't deal with OLE at all (and probably can't, since it needs to be cross platform), but take a look at how attachment::open_message works. Basically you parse the sub_object structure, which points to a subnode. You can then open the subnode and get the bytes from that.

Jun 6, 2010 at 1:11 AM

You're right -- that's what it was.  Does something like this do the trick?  It seems to be working fine so far, but I just want to be sure I'm not missing something non-obvious:

for(message::attachment_iterator it = m.attachment_begin(); it != m.attachment.end(); it++)
  // nonrelevent code snipped
  case ATTACH_OLE:
    std::vector<pstsdk::byte> buffer = (*it).get_bytes();
    disk::sub_object* psubo = (disk::sub_object*)&buffer[0];
    node pnode = (*it).get_property_bag().get_node().lookup(psubo->nid);
    node_stream_device stream = pnode.open_as_stream();
    // read the stream, and then open it later using CreateILockBytesOnHGlobal and StgOpenStorageOnILockBytes








Jun 6, 2010 at 1:58 PM

it++ sets off my pedantic C++ alarm, it's idiomatic to preincrement iterators (ie, ++it).

You should probably save off the result of *it into it's own variable. Because it is a proxy iterator, each time you dereference it you're getting a new instance of the message/attachment/folder object, etc. It's not very efficient and can cause problems if you think *it always refers to the same object - like if you're creating and comparing iterators from *it for example.

The only purpose of a node_stream_device is to be an argument to construct a node_stream; you shouldn't ever need to reference the variable directly. So you pretty much always want

node_stream stream(pnode.open_as_stream());