Microsoft KB Archive/173353

From BetaArchive Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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