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();
}
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
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.
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