Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Need to save an attachment

6 views
Skip to first unread message

Lyle Brooks

unread,
Dec 14, 2006, 6:09:28 PM12/14/06
to
I've recently tried my hand at coding a MAPI application. It seems to
be going reasonably well, except when I try to save attachments.

I copied some code from examples I've found and I've read over the
documentation but clearly I'm missing something.

The issue is that when I try to save an attachment, all the code seems
to execute as it should, but I get no attachment saved to the filesystem.

I will list the code I use below. I step through this code with the
debugger and everything works great (status codes are great, input and
output values are what I expect)....just no attachment saved to the
filesystem. :-(

Any suggestions would be greatly appreciated.

void WriteAttachment(IAttach* pAttach, LPTSTR pathname)
{

HRESULT hr;

LPSTREAM pStrmSrc = NULL;
LPSTREAM pStrmDest = NULL;
STATSTG StatInfo = {0};

ULONG ulInterfaceOptions = 0;
ULONG ulFlags = NULL;


// Open the property of the attachment containing the file data
if (FAILED(hr = pAttach->OpenProperty(
PR_ATTACH_DATA_BIN,
(LPIID) &IID_IStream,
ulInterfaceOptions,
ulFlags,
(LPUNKNOWN *) &pStrmSrc)))
return;
is_ok(hr, "OpenProperty");

if(!pStrmSrc) {
fprintf(stderr, "Unable to open source stream : bad\n");
return;
}

_tprintf(_T("Opening stream on %s\n"), pathname);

ULONG ulFlags_str = STGM_CREATE | STGM_READWRITE; // STGM_WRITE
if (FAILED(hr = OpenStreamOnFile(
MAPIAllocateBuffer,
MAPIFreeBuffer,
ulFlags_str,
(LPTSTR) pathname,
NULL,
&pStrmDest)))
return;

is_ok(hr, "OpenStreamOnFile");

if (!pStrmDest) {
fprintf(stderr, "Unable to open destination stream : bad\n");
return;
}


hr = pStrmSrc->Stat(&StatInfo, STATFLAG_NONAME);

is_ok(hr, "Stat");

printf("Number of bytes to copy : %d\n", StatInfo.cbSize);
ULARGE_INTEGER cb = StatInfo.cbSize;
ULARGE_INTEGER cbRead;
ULARGE_INTEGER cbWrite;

hr = pStrmSrc->CopyTo(pStrmDest,
cb,
&cbRead,
&cbWrite);

is_ok(hr,"CopyTo");

printf("Bytes Read: %d\n", cbRead);
printf("Bytes Written: %d\n", cbWrite);


// Commit changes to new stream
hr = pStrmDest->Commit(STGC_DEFAULT);
is_ok(hr, "Commit");

// Release each of our streams
pStrmDest->Release();
pStrmSrc->Release();

}

Dan Mitchell

unread,
Dec 15, 2006, 7:45:10 PM12/15/06
to
Lyle Brooks <Lyle....@eddlabs.com> wrote in news:#t2slT9HHHA.3780
@TK2MSFTNGP02.phx.gbl:

> The issue is that when I try to save an attachment, all the code seems
> to execute as it should, but I get no attachment saved to the
filesystem.

What's in the file that you're passing in? Is it even getting created,
or is it 0 bytes long, or does it contain something? What exactly do you
end up with at the end of things -- no file / 0 bytes / something else?
All the sizes and whatnot are correct, right?

See

http://groups.google.ca/group/microsoft.public.outlook.program_addins/br
owse_thread/thread/e763078324bd41ec/8154cbf5b48bbcd8?
lnk=st&q=openstreamonfile&rnum=19&hl=en#8154cbf5b48bbcd8

for some other discussion of this towards the end, or

http://groups.google.ca/group/microsoft.public.platformsdk.mapi/browse_t
hread/thread/cd50764b778e90d2/6f9b665cec8b494d?
lnk=st&q=openstreamonfile+write&rnum=5&hl=en#6f9b665cec8b494d

for code that was working okay for someone else, or

http://groups.google.ca/group/microsoft.public.win32.programmer.messagin
g/browse_thread/thread/e7ccd8e01515f6d8/63e4e02f975b6174?
lnk=st&q=openstreamonfile+write&rnum=18&hl=en#63e4e02f975b6174

Or, heck, at worst just read the IStream into memory and use your
favourite file API to write it out -- fwrite() should work, for
instance.

-- dan

Lyle Brooks

unread,
Dec 15, 2006, 10:02:19 PM12/15/06
to
I found the issue. I was passing wide (or Unicode) string with the
pathname to OpenStreamOnFile();

Turns out that despite its signature (LPTSTR lpszFileName)

HRESULT STDMETHODCALLTYPE OpenStreamOnFile(
LPALLOCATEBUFFER lpAllocateBuffer,
LPFREEBUFFER lpFreeBuffer,
ULONG ulFlags,
LPTSTR lpszFileName,
LPTSTR lpszPrefix,
LPSTREAM FAR * lppStream);


this function is ANSI only.

An important omission in the documentation, huh? :-)

Thanks so much for your help.

Dan Mitchell

unread,
Dec 18, 2006, 12:24:45 PM12/18/06
to
Lyle Brooks <Lyle....@eddlabs.com> wrote in
news:uPl0X6LI...@TK2MSFTNGP04.phx.gbl:
> I found the issue. I was passing wide (or Unicode) string with the
> pathname to OpenStreamOnFile();
>
> Turns out that despite its signature (LPTSTR lpszFileName)
>
> HRESULT STDMETHODCALLTYPE OpenStreamOnFile(
> LPALLOCATEBUFFER lpAllocateBuffer,
> LPFREEBUFFER lpFreeBuffer,
> ULONG ulFlags,
> LPTSTR lpszFileName,
> LPTSTR lpszPrefix,
> LPSTREAM FAR * lppStream);
>
>
> this function is ANSI only.
>
> An important omission in the documentation, huh? :-)

No kidding -- that's good to know for the future. I don't think it's
wrapped by unicows or anything either, so I suppose it's a matter of
doing T2A(filename) or whatever.

thanks for the info!

-- dan

0 new messages