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

Need to save an attachment

10 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