HOWTO: Saving a Message Attachment to File

ID: Q173353

The information in this article applies to:

SUMMARY

The following code example demonstrates how to open an attachment and copy the contents to a file in the current directory.

MORE INFORMATION

Use the following steps to open an attachment and copy the contents to a file in the current directory:

1. Open the Attachments table, including the following columns:

      PR_ATTACH_FILENAME and PR_ATTACH_NUM.

2. Open an attachment in the Attachments table.

3. Create a file for the attachment.

4. Copy the contents of the attachment to the newly created file.

Sample Code

   /* This code assumes that you already have an IMessage object,
      pointed to by the variable pMsg. This IMessage object
      should have been opened with the MAPI_MODIFY flag.

   */ 

   /* You should have the following define and include lines for this
      code to compile and link correctly:

          #define USES_IID_IMAPITable
          #define INITGUID

          #include <initguid.h>
          #include <mapiutil.h>
   */ 

    HRESULT WriteAttachToFile ( LPMESSAGE pMsg )
    {
      SizedSPropTagArray(1,g_sptMsgProps) = {1,
                                             PR_HASATTACH};

      LPSPropValue pProps = NULL;
      HRESULT hRes = 0;
      ULONG cVals = 0;

      if (FAILED(hRes = pMsg->GetProps((LPSPropTagArray) &g_sptMsgProps,
                                       0,
                                       &cVals,
                                       &pProps)))
        goto Quit;
      else
        hRes = S_OK;

      if (PR_HASATTACH == pProps[0].ulPropTag && pProps[0].Value.b)
      {
        LPMAPITABLE pAttTbl = NULL;
        LPSRowSet pRows = NULL;
        static SizedSPropTagArray(2,sptCols) = {2,PR_ATTACH_LONG_FILENAME,
                                                  PR_ATTACH_NUM};

        if (SUCCEEDED(hRes = pMsg -> OpenProperty(PR_MESSAGE_ATTACHMENTS,
                                                  &IID_IMAPITable,
                                                  0,
                                                  0,
                                                  (LPUNKNOWN *) &pAttTbl)))
        {

          if (SUCCEEDED(hRes = pAttTbl -> SetColumns(
                                              (LPSPropTagArray) &sptCols,
                                              TBL_BATCH)))
          {

            if (SUCCEEDED(hRes = HrQueryAllRows(pAttTbl,
                                              (LPSPropTagArray) &sptCols,
                                              NULL,
                                              NULL,
                                              0,
                                              &pRows)))
            {

              for (ULONG i = 0; i < pRows -> cRows; i++)
              {
                LPATTACH lpAttach = NULL;

                // Verify we received a filename from GetProps
                if (! PR_ATTACH_FILENAME ==
                      pRows->aRow[i].lpProps[0].ulPropTag)
                  break;

                // Verify we received an Attachment Index from GetProps
                if (! PR_ATTACH_NUM == pRows->aRow[i].lpProps[1].ulPropTag)
                   break;

                // Open the attachment
                if (SUCCEEDED(hRes = pMsg->OpenAttach (
                                  pRows->aRow[i].lpProps[1].Value.l,
                                  NULL, MAPI_BEST_ACCESS, &lpAttach)))
                {
                  LPSTREAM pStrmSrc = NULL, pStrmDest = NULL;
                  STATSTG StatInfo;

                  // Open the property of the attachment
                  // containing the file data
                  if (FAILED(hRes = lpAttach->OpenProperty(
                                                 PR_ATTACH_DATA_BIN,
                                                 (LPIID)&IID_IStream,
                                                 0,
                                                 MAPI_MODIFY,
                                                 (LPUNKNOWN *)&pStrmSrc)))
                     break;

                   // Open an IStream interface and create the file at the
                   // same time. This code will create the file in the
                   // current directory.
                   if (FAILED(hRes = OpenStreamOnFile(
                                     MAPIAllocateBuffer,
                                     MAPIFreeBuffer,
                                     STGM_CREATE | STGM_READWRITE,
                                     pRows->aRow[i].lpProps[0].Value.lpszA,
                                     NULL,
                                     &pStrmDest)))
                     break;

                   pStrmSrc -> Stat(&StatInfo, STATFLAG_NONAME);

                   hRes = pStrmSrc -> CopyTo(pStrmDest,
                                             StatInfo.cbSize,
                                             NULL,
                                             NULL);

                   // Commit changes to new stream
                   pStrmDest -> Commit(0);

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

                 }

                 // Release the attachment
                 lpAttach -> Release();
              }
            }
          }
        }

        FreeProws(pRows);

        if (pAttTbl)
          pAttTbl -> Release();
      }
    Quit:
        MAPIFreeBuffer((LPVOID) pProps);
        return hRes;
    }

Keywords          : kbMsg kbMAPI100 
Version           : WINDOWS:1.0
Platform          : WINDOWS
Issue type        : kbhowto

Last Reviewed: October 2, 1998