Registrations are now open. Join us today!
There is still a lot of work to do on the wiki yet! More information about editing can be found here.
Already have an account?

Microsoft KB Archive/173353

From BetaArchive Wiki
Knowledge Base


Article ID: 173353

Article Last Modified on 8/18/2005



APPLIES TO

  • Microsoft Messaging Application Programming Interface



This article was previously published under Q173353

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.

  1. Open an attachment in the Attachments table.
  2. Create a file for the attachment.
  3. 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.

      This code also assumes that PR_ATTACH_METHOD equals
      ATTACH_BY_VALUE. See the note that follows this sample 
      code for more information.
   */ 

   /* 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;
    }
                

NOTE: If the attachment is a message or structured storage (OLE object), there is no PR_ATTACH_DATA_BIN property. Another attachment property, PR_ATTACH_METHOD, essentially can contain four different values that tell you what to do:

  • ATTACH_BY_VALUE means that you work with the PR_ATTACH_DATA_BIN property.
  • ATTACH_BY_REFERENCE means that you work with PR_ATTACH_PATHNAME; the file is not physically included.
  • ATTACH_EMBEDDED_MESSAGE or ATTACH_OLE mean you call OpenProperty on PR_ATTACH_DATA_OBJ, which gives you back an IMessage or IStorage interface respectively.

For more information on the PR_ATTACH_METHOD property, see the following Microsoft Developer Network (MSDN) Web site:

Keywords: kbhowto kbmsg KB173353