HOWTO: Saving a Message Attachment to File

Last reviewed: September 2, 1997
Article ID: Q173353
The information in this article applies to:
  • Extended Messaging Application Programming Interface (MAPI), version 1.0

SUMMARY

The code example below 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.
    */

    /* 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_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          : EMAPI
Version           : WINDOWS:1.0
Platform          : WINDOWS
Issue type        : kbhowto


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 2, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.