home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / mapi / docfile.ms / mspatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  23.5 KB  |  744 lines

  1. /*
  2.  *  M S P A T C H . C
  3.  *
  4.  *  Code for the MAPI Sample Store Provider implementation of the
  5.  *  IAttach object.  The implementation is, in reality, a thin
  6.  *  wrapping layer around the implementation of IMessage on
  7.  *  IStorage.  We wrap the IAttach object returned by IMsgOnIStg so
  8.  *  that we can handle those methods (like GetLastError) not
  9.  *  understood by a standalone attachment (e.g. one embedded in a
  10.  *  word document) but which makes sense for a message in the
  11.  *  context of a message store.
  12.  *
  13.  *  Copyright 1992-1995 Microsoft Corporation.  All Rights Reserved.
  14.  */
  15.  
  16. #include "msp.h"
  17.  
  18. #define ATCH_ValidateParameters(pobj, intf, method, arglist)        \
  19.         OBJ_ValidateParameters(pobj, intf, method, sizeof(IATCH), &vtblIATCH, arglist)
  20.  
  21. #define IATCH_EnterCriticalSection(piatch) OBJ_EnterCriticalSection((POBJ)piatch)
  22. #define IATCH_LeaveCriticalSection(piatch) OBJ_LeaveCriticalSection((POBJ)piatch)
  23.  
  24. /* Manifest constants */
  25.  
  26. #define cInitIATCHProps         3
  27. #define grfInitIATCHPropAttr    (PROPATTR_MANDATORY | PROPATTR_READABLE)
  28.  
  29. /* Global variables */
  30.  
  31. /* Dispatch table for IAttach objects */
  32. IATCH_Vtbl vtblIATCH =
  33. {
  34.     (IATCH_QueryInterface_METHOD *)     OBJ_QueryInterface,
  35.     (IATCH_AddRef_METHOD *)             OBJ_AddRef,
  36.     (IATCH_Release_METHOD *)            OBJ_Release,
  37.     (IATCH_GetLastError_METHOD *)       IMS_GetLastError,
  38.     IATCH_SaveChanges,
  39.     IATCH_GetProps,
  40.     IATCH_GetPropList,
  41.     IATCH_OpenProperty,
  42.     IATCH_SetProps,
  43.     IATCH_DeleteProps,
  44.     IATCH_CopyTo,
  45.     IATCH_CopyProps,
  46.     (IATCH_GetNamesFromIDs_METHOD *)    IMS_GetNamesFromIDs,
  47.     (IATCH_GetIDsFromNames_METHOD *)    IMS_GetIDsFromNames
  48. };
  49.  
  50. /*
  51.  *  Object methods
  52.  */
  53.  
  54. /*
  55.  *  IATCH_SaveChanges
  56.  *
  57.  *  Purpose:
  58.  *      Saves changes made to an attachment object and all of its
  59.  *      sub-objects (messages, et al.).  Since the IMessage on
  60.  *      IStorage implementation handles the invalidation of objects
  61.  *      after SaveChanges is called, we do not need to worry about
  62.  *      it at this level.
  63.  *
  64.  *  Arguments:
  65.  *      piatch      Pointer to the object.
  66.  *      ulFlags     Flags.  The following are defined:
  67.  *                  KEEP_OPEN_READONLY  Do not invalidate the
  68.  *                                      object, make it read-only.
  69.  *                  KEEP_OPEN_READWRITE Don't invalidate the
  70.  *                                      object, keep it open
  71.  *                                      read/write.
  72.  *
  73.  *  Returns:
  74.  *      HRESULT
  75.  *
  76.  *  Side effects:
  77.  *      None.
  78.  *
  79.  *  Errors:
  80.  */
  81. STDMETHODIMP IATCH_SaveChanges(PIATCH piatch, ULONG ulFlags)
  82. {
  83.     HRESULT hr;
  84.     PIMSG pimsg;
  85.     PLMR plmr;
  86.  
  87.     ATCH_ValidateParameters(
  88.             piatch,
  89.             IMAPIProp,
  90.             SaveChanges,
  91.             (piatch, 
  92.             ulFlags));
  93.  
  94.     IATCH_EnterCriticalSection(piatch);
  95.  
  96.     pimsg = (PIMSG) piatch->pobjParent;
  97.     plmr = &piatch->pims->lmr;
  98.  
  99.     if (!OBJ_TestFlag(piatch, OBJF_MODIFY))
  100.     {
  101.         hr = ResultFromScode(MAPI_E_NO_ACCESS);
  102.         goto exit;
  103.     }
  104.  
  105.     hr = piatch->lpattach->lpVtbl->SaveChanges(piatch->lpattach, ulFlags);
  106.     if (hr != hrSuccess)
  107.         goto exit;
  108.  
  109.     if (!(ulFlags & KEEP_OPEN_READWRITE))
  110.         OBJ_ClearFlag(piatch, OBJF_MODIFY);
  111.  
  112. exit:
  113.     IATCH_LeaveCriticalSection(piatch);
  114.  
  115.     DebugTraceResult(IATCH_SaveChanges, hr);
  116.     return HrCheckHr(hr, IMAPIProp_SaveChanges);
  117. }
  118.  
  119. /*
  120.  *  IATCH_GetProps
  121.  *
  122.  *  Purpose:
  123.  *      Returns to the caller the value(s) of one or more
  124.  *      properties existent on an IATCH object.  The order of the
  125.  *      properties in the returned lppPropArray structure exactly
  126.  *      matches the order in which the properties were requested in
  127.  *      lpPropTagArray.  The caller must free the returned
  128.  *      structure by calling MAPIFreeBuffer(*lppPropArray), but
  129.  *      only if the function returns zero or the error
  130.  *      MAPI_W_ERRORS_RETURNED.  Uses the IMessage on IStorage
  131.  *      property interface implementation.
  132.  *
  133.  *  Arguments:
  134.  *      piatch          Pointer to the object.
  135.  *       ptaga          Pointer to a counted array of property tags of
  136.  *                      properties requested
  137.  *       ulFlags        UNICODE / String8
  138.  *       pcval          Pointer to number of values returned
  139.  *       ppval          Pointer to a variable in which the address of the
  140.  *                      returned property values is placed
  141.  *
  142.  *  Returns:
  143.  *      HRESULT
  144.  *
  145.  *  Side effects:
  146.  *      None.
  147.  *
  148.  *  Errors:
  149.  *      If the call succeeded overall but access to one or more
  150.  *      properties failed, the function returns the warning
  151.  *      MAPI_W_ERRORS_RETURNED.  The calling application should
  152.  *      then check the Property Tag of each of the returned
  153.  *      properties to determine which ones failed.  Those that fail
  154.  *      have their Property Type set to PT_ERROR and their value (a
  155.  *      ULONG) indicates which error occurred.
  156.  *
  157.  *      MAPI_E_NO_ACCESS    The caller does not have access
  158.  *                                  to the requested properties.
  159.  *      MAPI_W_ERRORS_RETURNED      See above.
  160.  *      MAPI_E_CALL_FAILED          The mechanism for making the
  161.  *                                  call to the service provider
  162.  *                                  failed.
  163.  */
  164. STDMETHODIMP IATCH_GetProps(PIATCH piatch, LPSPropTagArray ptaga, ULONG ulFlags,
  165.     ULONG *pcval, LPSPropValue *ppval)
  166. {
  167.     HRESULT hr;
  168.  
  169.     ATCH_ValidateParameters(
  170.             piatch,
  171.             IMAPIProp,
  172.             GetProps,
  173.             (piatch, 
  174.             ptaga, 
  175.             ulFlags,
  176.             pcval, 
  177.             ppval));
  178.  
  179.     #ifdef VALIDATE
  180.     if (ulFlags & MAPI_UNICODE)
  181.         return ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  182.     #endif
  183.         
  184.     IATCH_EnterCriticalSection(piatch);
  185.  
  186.     /* Pass the call off to IMessage */
  187.     hr = piatch->lpattach->lpVtbl->GetProps(piatch->lpattach, ptaga, ulFlags, 
  188.             pcval, ppval);
  189.  
  190.     /* Wrap specific store properties. Note that this function takes as an */
  191.     /* argument the HRESULT from the previous GetProps call. */
  192.     /* We aren't ignoring the error. */
  193.  
  194.     hr = HrWrap_GetProps(hr, piatch->pims, 0, NULL, pcval, ppval, FALSE,
  195.         (ptaga != NULL), (POBJ)piatch);
  196.  
  197.     IATCH_LeaveCriticalSection(piatch);
  198.  
  199.     DebugTraceResult(IATCH_GetProps, hr);
  200.     return HrCheckHr(hr, IMAPIProp_GetProps);
  201. }
  202.  
  203. /*
  204.  *  IATCH_GetPropList
  205.  *
  206.  *  Purpose:
  207.  *      Returns a list of all the properties currently accessible.
  208.  *      Uses the IMessage on IStorage property implementation.
  209.  *
  210.  *  Arguments:
  211.  *      piatch              Pointer to the object.
  212.  *      ulFlags             UNICODE / String8
  213.  *      lppPropTagArray     Location in which to return a pointer
  214.  *                          to a counted array of property tags.
  215.  *
  216.  *  Returns:
  217.  *      HRESULT
  218.  *
  219.  *  Side effects:
  220.  *      None.
  221.  *
  222.  *  Errors:
  223.  *      MAPI_E_NO_ACCESS    The caller does not have access
  224.  *                                  to the requested properties.
  225.  *      MAPI_E_CALL_FAILED          The mechanism for making the
  226.  *                                  call to the service provider
  227.  *                                  failed.
  228.  */
  229. STDMETHODIMP
  230. IATCH_GetPropList(PIATCH piatch, ULONG ulFlags, LPSPropTagArray *lppPropTagArray)
  231. {
  232.     HRESULT hr;
  233.  
  234.     ATCH_ValidateParameters(
  235.             piatch,
  236.             IMAPIProp,
  237.             GetPropList,
  238.             (piatch, 
  239.             ulFlags, 
  240.             lppPropTagArray));
  241.  
  242.     #ifdef VALIDATE
  243.     if (ulFlags & MAPI_UNICODE)
  244.         return ResultFromScode(MAPI_E_BAD_CHARWIDTH);
  245.     #endif
  246.         
  247.     IATCH_EnterCriticalSection(piatch);
  248.  
  249.     hr = piatch->lpattach->lpVtbl->GetPropList(piatch->lpattach, ulFlags,
  250.         lppPropTagArray);
  251.  
  252.     IATCH_LeaveCriticalSection(piatch);
  253.  
  254.     DebugTraceResult(IATCH_GetPropList, hr);
  255.     return HrCheckHr(hr, IMAPIProp_GetPropList);
  256. }
  257.  
  258. /*
  259.  *  IATCH_OpenProperty
  260.  *
  261.  *  Purpose:
  262.  *      Open a requested interface on a property for further
  263.  *      access.  Commonly used for stream access to a large binary
  264.  *      or text property.  This is the only way to access a
  265.  *      property of type PT_OBJECT, and may be used on other
  266.  *      properties depending on the implementation.  Uses the
  267.  *      IMessage on IStorage property implementation.
  268.  *
  269.  *  Arguments:
  270.  *      piatch      Pointer to the object.
  271.  *      ulPropTag   Property tag for the desired property.  Only
  272.  *                  the ID bits of the tag are used; the type bits
  273.  *                  are ignored.
  274.  *      lpiid       Pointer to the GUID identifying which interface
  275.  *                  is desired.
  276.  *      lppUnk      Location in which to return a pointer to the
  277.  *                  newly created interface pointer.
  278.  *
  279.  *  Returns:
  280.  *      HRESULT
  281.  *
  282.  *  Side effects:
  283.  *      None.
  284.  *
  285.  *  Errors:
  286.  *      MAPI_E_CALL_FAILED      An error occurred opening a
  287.  *                              supported interface.
  288.  *      MAPI_E_NO_SUPPORT   The requested interface is not
  289.  *                              available on the given property.
  290.  */
  291. STDMETHODIMP IATCH_OpenProperty(PIATCH piatch, ULONG ulPropTag, LPCIID lpiid,
  292.     ULONG ulInterfaceOptions, ULONG ulFlags, LPUNKNOWN * lppUnk)
  293. {
  294.     HRESULT hr;
  295.     LPUNKNOWN lpunk = NULL;
  296.     PIMSG pimsg = NULL;
  297.     LPSPropTagArray ptaga = NULL;
  298.  
  299.     ATCH_ValidateParameters(
  300.             piatch,
  301.             IMAPIProp,
  302.             OpenProperty,
  303.             (piatch, 
  304.             ulPropTag, 
  305.             lpiid,
  306.             ulInterfaceOptions, 
  307.             ulFlags, 
  308.             lppUnk));
  309.  
  310.     IATCH_EnterCriticalSection(piatch);
  311.  
  312.     /* If input parameters are okay, make OpenProperty call on lpmsg. */
  313.  
  314.     hr = piatch->lpattach->lpVtbl->OpenProperty(piatch->lpattach,
  315.         ulPropTag, lpiid, ulInterfaceOptions, ulFlags, &lpunk);
  316.     if (hr != hrSuccess)
  317.         goto exit;
  318.  
  319.     /* If it's a message in message, we need to wrap the returned object */
  320.  
  321.     if (ulPropTag == PR_ATTACH_DATA_OBJ
  322.         && IsEqualIID(lpiid, (LPIID) &IID_IMessage))
  323.     {
  324.         hr = NewIMSGInIATCH((LPMESSAGE) lpunk, (POBJ) piatch, ulFlags, &pimsg);
  325.         if (hr != hrSuccess)
  326.             goto exit;
  327.  
  328.         hr = pimsg->lpVtbl->GetPropList(pimsg, 0, /* ansi */
  329.                 &ptaga);
  330.         if (hr != hrSuccess)
  331.             goto exit;
  332.  
  333.         if (ptaga->cValues == 0)
  334.         {
  335.             hr = InitIMSGProps(pimsg);
  336.             if (hr != hrSuccess)
  337.                 goto exit;
  338.         }
  339.  
  340.         *lppUnk = (LPUNKNOWN) pimsg;
  341.     }
  342.     else
  343.         *lppUnk = lpunk;
  344.  
  345. exit:
  346.     LMFree(&piatch->pims->lmr, ptaga);
  347.  
  348.     if (hr != hrSuccess)
  349.     {
  350.         UlRelease(pimsg);
  351.         UlRelease(lpunk);
  352.     }
  353.  
  354.     IATCH_LeaveCriticalSection(piatch);
  355.  
  356.     DebugTraceResult(IATCH_OpenProperty, hr);
  357.     return HrCheckHr(hr, IMAPIProp_OpenProperty);
  358. }
  359.  
  360. /*
  361.  *  IATCH_SetProps
  362.  *
  363.  *  Purpose:
  364.  *      Sets the value of one or more properties.  This call passes
  365.  *      a number of Property Value structures.  The Property Tag in
  366.  *      each indicates which property is having its values set and
  367.  *      the value indicates what should be stored.  The caller must
  368.  *      free the returned property problem structure by calling
  369.  *      MAPIFreeBuffer(*pprba), but only if the call
  370.  *      succeeded overall.  Uses the IMessage on IStorage property
  371.  *      implementation.
  372.  *
  373.  *  Arguments:
  374.  *      piatch          Pointer to the object.
  375.  *      cValues         Number of values in pval.
  376.  *      pval            Pointer to a Property Value array.
  377.  *      pprba           Location in which to return a pointer to a
  378.  *                      counted array of property problem
  379.  *                      structures.
  380.  *
  381.  *  Returns:
  382.  *      HRESULT.  If the call succeeds overall, a zero is returned.
  383.  *      If there are problems with setting some or all of the
  384.  *      selected values, and a non-NULL is passed for pprba,
  385.  *      then a SPropProblemArray structure is returned with details
  386.  *      about each problem.  The value returned in pprba is
  387.  *      only valid if zero is returned in the HRESULT.  If an error
  388.  *      occurs on the call such that a non-zero value is returned
  389.  *      for the HRESULT then the contents of *pprba are
  390.  *      undefined.  In particular, do not use or free the structure
  391.  *      if an error occurs on the call.
  392.  *
  393.  *  Side effects:
  394.  *      None.
  395.  *
  396.  *  Errors:
  397.  *      MAPI_E_NO_ACCESS    The caller does not have access
  398.  *                                  to the requested properties.
  399.  *      MAPI_E_CALL_FAILED          The mechanism for making the
  400.  *                                  call to the service provider
  401.  *                                  failed.
  402.  */
  403. STDMETHODIMP IATCH_SetProps(PIATCH piatch, ULONG cValues, LPSPropValue pval,
  404.     LPSPropProblemArray *pprba)
  405. {
  406.     HRESULT hr;
  407.  
  408.     ATCH_ValidateParameters(
  409.             piatch,
  410.             IMAPIProp,
  411.             SetProps,
  412.             (piatch, 
  413.             cValues, 
  414.             pval,
  415.             pprba));
  416.  
  417.     IATCH_EnterCriticalSection(piatch);
  418.  
  419.     hr = piatch->lpattach->lpVtbl->SetProps(piatch->lpattach, cValues,
  420.         pval, pprba);
  421.  
  422.     IATCH_LeaveCriticalSection(piatch);
  423.  
  424.     DebugTraceResult(IATCH_SetProps, hr);
  425.     return HrCheckHr(hr, IMAPIProp_SetProps);
  426. }
  427.  
  428. /*
  429.  *  IATCH_DeleteProps
  430.  *
  431.  *  Purpose:
  432.  *      Deletes the list of properties given in ptaga.
  433.  *      The caller must free the returned property problem
  434.  *      structure by calling MAPIFreeBuffer(*pprba), but only
  435.  *      if the call succeeded overall.  Uses the IMessage on
  436.  *      IStorage property implementation.
  437.  *
  438.  *  Arguments:
  439.  *      piatch          Pointer to the object.
  440.  *      ptaga   Pointer to an array of Property Tags
  441.  *                      identifying the properties to delete.
  442.  *      pprba       Location in which to return a pointer to a
  443.  *                      counted array of property problem
  444.  *                      structures.
  445.  *
  446.  *  Returns:
  447.  *      HRESULT.  If the call succeeds overall, a zero is returned.
  448.  *      If there are problems with deleting some or all of the
  449.  *      selected values, and a non-NULL is passed for pprba,
  450.  *      then a SPropProblemArray structure is returned with details
  451.  *      about each problem.  The value returned in pprba is
  452.  *      only valid if zero is returned in the HRESULT.  If an error
  453.  *      occurs on the call such that a non-zero value is returned
  454.  *      for the HRESULT then the contents of *pprba are
  455.  *      undefined.  In particular, do not use or free the structure
  456.  *      if an error occurs on the call.
  457.  *
  458.  *  Side effects:
  459.  *      None.
  460.  *
  461.  *  Errors:
  462.  *      MAPI_E_NO_ACCESS    The caller does not have access
  463.  *                                  to the requested properties.
  464.  *      MAPI_E_CALL_FAILED          The mechanism for making the
  465.  *                                  call to the service provider
  466.  *                                  failed.
  467.  */
  468. STDMETHODIMP IATCH_DeleteProps(PIATCH piatch, LPSPropTagArray ptaga,
  469.     LPSPropProblemArray * pprba)
  470. {
  471.     HRESULT hr;
  472.  
  473.     ATCH_ValidateParameters(
  474.             piatch,
  475.             IMAPIProp,
  476.             DeleteProps,
  477.             (piatch, 
  478.             ptaga,
  479.             pprba));
  480.  
  481.     IATCH_EnterCriticalSection(piatch);
  482.  
  483.     hr = piatch->lpattach->lpVtbl->DeleteProps(piatch->lpattach, ptaga, pprba);
  484.  
  485.     IATCH_LeaveCriticalSection(piatch);
  486.  
  487.     DebugTraceResult(IATCH_DeleteProps, hr);
  488.     return HrCheckHr(hr, IMAPIProp_DeleteProps);
  489. }
  490.  
  491. /*
  492.  *  IATCH_CopyTo
  493.  *
  494.  *  Purpose:
  495.  *      Copies the contents of the current object to a destination
  496.  *      object.  The entire contents, including contained objects,
  497.  *      are copied, or optionally the caller can provide a list of
  498.  *      properties that are not to be copied.  Previous information
  499.  *      in the destination object which is not overwritten by
  500.  *      copied data is neither deleted nor modified.
  501.  *
  502.  *  Arguments:
  503.  *      piatch          Pointer to the source object.
  504.  *      ciidExcl        Count of the excluded interfaces in
  505.  *                      rgiidExcl.
  506.  *      rgiidExcl   Array of interface IDs specifying
  507.  *                      interfaces not to be attempted in trying to
  508.  *                      copy supplemental information to the
  509.  *                      destination object.
  510.  *      ptagaExcl   Counted array of property tags of
  511.  *                      properties that are not to be copied to the
  512.  *                      destination object.  NULL indicates all
  513.  *                      properties are to be copied.
  514.  *      ulUIParam       Handle of parent window cast to ULONG.
  515.  *      lpProgress      Callback for doing progress UI.
  516.  *      piidDst     Interface ID of the interface of lpDestObj,
  517.  *                      the destination object.
  518.  *      lpDestObj       Pointer to the open destination object.
  519.  *      ulFlags         Flags.  Defined as follows:
  520.  *                      MAPI_MOVE       Indicates a move operation.
  521.  *                                      The default is to copy.
  522.  *                      MAPI_NOREPLACE  Indicates that existing
  523.  *                                      properties should not be
  524.  *                                      overridden.  The default is
  525.  *                                      to overwrite existing
  526.  *                                      properties.
  527.  *                      MAPI_DIALOG     Display a progress dialog
  528.  *                                      as the operation proceeds.
  529.  *                      MAPI_STD_DIALOG Use MAPI standard dialog
  530.  *                                      instead of
  531.  *                                      provider-specific dialog.
  532.  *      pprba       Pointer to a variable that is filled in
  533.  *                      with a pointer to a set of property
  534.  *                      problems.  If NULL, no problem set is
  535.  *                      returned on an error.
  536.  *
  537.  *  Returns:
  538.  *      HRESULT
  539.  *
  540.  *  Side effects:
  541.  *      None.
  542.  *
  543.  *  Errors:
  544.  */
  545. STDMETHODIMP IATCH_CopyTo(PIATCH piatch, ULONG ciidExcl, LPCIID rgiidExcl,
  546.     LPSPropTagArray ptagaExcl, ULONG ulUIParam, LPMAPIPROGRESS
  547.     lpProgress, LPCIID piidDst, LPVOID lpDestObj, ULONG ulFlags,
  548.     LPSPropProblemArray * pprba)
  549. {
  550.     HRESULT hr;
  551.  
  552.     ATCH_ValidateParameters(
  553.             piatch,
  554.             IMAPIProp,
  555.             CopyTo,
  556.             (piatch, 
  557.             ciidExcl, 
  558.             rgiidExcl,
  559.             ptagaExcl, 
  560.             ulUIParam, 
  561.             lpProgress, 
  562.             piidDst, 
  563.             lpDestObj, 
  564.             ulFlags,
  565.             pprba));
  566.  
  567.     IATCH_EnterCriticalSection(piatch);
  568.  
  569.     hr = piatch->lpattach->lpVtbl->CopyTo(piatch->lpattach, ciidExcl,
  570.         rgiidExcl, ptagaExcl, ulUIParam, lpProgress, piidDst,
  571.         lpDestObj, ulFlags, pprba);
  572.  
  573.     IATCH_LeaveCriticalSection(piatch);
  574.  
  575.     DebugTraceResult(IATCH_CopyTo, hr);
  576.     return HrCheckHr(hr, IMAPIProp_CopyTo);
  577. }
  578.  
  579. /*
  580.  *  IATCH_CopyProps
  581.  *
  582.  *  Purpose:
  583.  *      Copies the specified properties of the current object to a destination
  584.  *      object.
  585.  *
  586.  *  Arguments:
  587.  *      piatch          Pointer to the source object.
  588.  *      ptagaIncl       Counted array of property tags of
  589.  *                      properties that are to be copied to the
  590.  *                      destination object.
  591.  *      ulUIParam       Handle of parent window cast to ULONG.
  592.  *      lpProgress      Callback for doing progress UI.
  593.  *      piidDst     Interface ID of the interface of lpDestObj,
  594.  *                      the destination object.
  595.  *      lpDestObj       Pointer to the open destination object.
  596.  *      ulFlags         Flags.  Defined as follows:
  597.  *                      MAPI_MOVE       Indicates a move operation.
  598.  *                                      The default is to copy.
  599.  *                      MAPI_NOREPLACE  Indicates that existing
  600.  *                                      properties should not be
  601.  *                                      overridden.  The default is
  602.  *                                      to overwrite existing
  603.  *                                      properties.
  604.  *                      MAPI_DIALOG     Display a progress dialog
  605.  *                                      as the operation proceeds.
  606.  *                      MAPI_DECLINE_OK
  607.  *      pprba       Pointer to a variable that is filled in
  608.  *                      with a pointer to a set of property
  609.  *                      problems.  If NULL, no problem set is
  610.  *                      returned on an error.
  611.  *
  612.  *  Returns:
  613.  *      HRESULT
  614.  *
  615.  *  Side effects:
  616.  *      None.
  617.  *
  618.  *  Errors:
  619.  */
  620. STDMETHODIMP IATCH_CopyProps(PIATCH piatch,
  621.     LPSPropTagArray ptagaIncl, ULONG ulUIParam, LPMAPIPROGRESS
  622.     lpProgress, LPCIID piidDst, LPVOID lpDestObj, ULONG ulFlags,
  623.     LPSPropProblemArray * pprba)
  624. {
  625.     HRESULT hr;
  626.  
  627.     ATCH_ValidateParameters(
  628.             piatch,
  629.             IMAPIProp,
  630.             CopyProps,
  631.             (piatch,
  632.             ptagaIncl, 
  633.             ulUIParam, 
  634.             lpProgress, 
  635.             piidDst, 
  636.             lpDestObj, 
  637.             ulFlags,
  638.             pprba));
  639.  
  640.     IATCH_EnterCriticalSection(piatch);
  641.  
  642.     hr = piatch->lpattach->lpVtbl->CopyProps(piatch->lpattach,
  643.         ptagaIncl, ulUIParam, lpProgress, piidDst,
  644.         lpDestObj, ulFlags, pprba);
  645.  
  646.     IATCH_LeaveCriticalSection(piatch);
  647.  
  648.     DebugTraceResult(IATCH_CopyProps, hr);
  649.     return HrCheckHr(hr, IMAPIProp_CopyProps);
  650. }
  651.  
  652. /*
  653.  *  External functions
  654.  */
  655.  
  656. /*
  657.  * IATCH_Neuter
  658.  *
  659.  * Purpose
  660.  *  free storage for an attachment
  661.  *
  662.  * Parameter
  663.  *      piatch      pointer to the open attachment
  664.  *
  665.  */
  666. void IATCH_Neuter(PIATCH piatch)
  667. {
  668.     UlRelease(piatch->lpattach);
  669. }
  670.  
  671. /*
  672.  *  HrNewIATCH
  673.  *
  674.  *  Purpose:
  675.  *      Allocates and initializes an IATCH object (internal
  676.  *      implementation of IAttach).  This is just a thin wrapper
  677.  *      around the attachment object of the IMessage on IStorage
  678.  *      implementation -- we wrap it to catch certain methods,
  679.  *      see below.
  680.  *
  681.  *  Arguments:
  682.  *      lpattach    Pointer to an attachment object returned by
  683.  *                  IMessage on IStorage.
  684.  *      pimsg       Pointer to the attachment's parent message object.
  685.  *      fModify     TRUE if the caller wants the attach opened for writing.
  686.  *      ppiatch Location in which to return a pointer to the
  687.  *                  newly created IATCH instance.
  688.  *
  689.  *  Returns:
  690.  *      HRESULT
  691.  *
  692.  *  Side effects:
  693.  *      None.
  694.  *
  695.  *  Errors:
  696.  *      MAPI_E_NOT_ENOUGH_MEMORY    Could not allocate space for
  697.  *                                  the IATCH instance.
  698.  */
  699. HRESULT HrNewIATCH(LPATTACH lpattach, PIMSG pimsg, BOOL fModify, PIATCH * ppiatch)
  700. {
  701.     HRESULT hr = hrSuccess;
  702.     PIATCH piatchNew = NULL;
  703.     SCODE sc;
  704.     PIMS pims;
  705.  
  706.     AssertSz(lpattach, "Bad lpattach");
  707.     AssertSz(pimsg, "Bad pimsg");
  708.     AssertSz(ppiatch, "Bad ppiatch");
  709.  
  710.     pims = pimsg->pims;
  711.  
  712.     /* Allocate and initialize IATCH instance */
  713.  
  714.     sc = LMAllocZ(&pims->lmr, sizeof(IATCH), &piatchNew);
  715.     if (sc != S_OK)
  716.     {
  717.         hr = ResultFromScode(sc);
  718.         goto exit;
  719.     }
  720.  
  721.     /* Initialize member variables */
  722.  
  723.     OBJ_Initialize(piatchNew, &vtblIATCH, OT_ATTACH, pims, pims->pcs);
  724.  
  725.     UlAddRef(lpattach); /* we're keeping a reference */
  726.  
  727.     piatchNew->lpattach = lpattach;
  728.  
  729.     if (fModify)
  730.         OBJ_SetFlag(piatchNew, OBJF_MODIFY);
  731.  
  732.     OBJ_Enqueue((POBJ) piatchNew, (POBJ) pimsg);
  733.  
  734.     *ppiatch = piatchNew;
  735.  
  736. exit:
  737.     if (hr != hrSuccess)
  738.         LMFree(&pims->lmr, piatchNew);
  739.  
  740.     DebugTraceResult(HrNewIATCH, hr);
  741.     return hr;
  742. }
  743.  
  744.