OOTID.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /***********************************************************************
  2.  *
  3.  *  OOTID.C
  4.  *
  5.  *  Sample Address Book OneOff Template ID object
  6.  *  This file contains the code for implementing the Sample AB
  7.  *  template ID for it's one-off.
  8.  *
  9.  *  The template ID for the Sample Address Book one-offs has only one
  10.  *  purpose.  When the SaveChanges() method gets called it recalculates
  11.  *  PR_EMAIL_ADDRESS_A and PR_SEARCH_KEY from data that was changed by the
  12.  *  user.  See how this interacts with the one-off user object implemented
  13.  *  in OOUSER.C.
  14.  *
  15.  *  Copyright 1992-1995 Microsoft Corporation.  All Rights Reserved.
  16.  *
  17.  ***********************************************************************/
  18. #include "abp.h"
  19. /*
  20.  *  Declaration of IMailUser object implementation
  21.  */
  22. #undef  INTERFACE
  23. #define INTERFACE   struct _OOTID
  24. #undef  MAPIMETHOD_
  25. #define MAPIMETHOD_(type, method)   MAPIMETHOD_DECLARE(type, method, OOTID_)
  26.         MAPI_IUNKNOWN_METHODS(IMPL)
  27.         MAPI_IMAPIPROP_METHODS(IMPL)
  28. #undef  MAPIMETHOD_
  29. #define MAPIMETHOD_(type, method)   MAPIMETHOD_TYPEDEF(type, method, OOTID_)
  30.         MAPI_IUNKNOWN_METHODS(IMPL)
  31.         MAPI_IMAPIPROP_METHODS(IMPL)
  32. #undef  MAPIMETHOD_
  33. #define MAPIMETHOD_(type, method)   STDMETHOD_(type, method)
  34. DECLARE_MAPI_INTERFACE(OOTID_)
  35. {
  36.     MAPI_IUNKNOWN_METHODS(IMPL)
  37.     MAPI_IMAPIPROP_METHODS(IMPL)
  38. };
  39. /*
  40.  *  The structure behind the 'this' pointer
  41.  */
  42. typedef struct _OOTID {
  43.     const OOTID_Vtbl * lpVtbl;
  44.     SAB_Wrapped;
  45.     
  46. } OOTID, *LPOOTID;
  47. /*
  48.  *  OOTID vtbl is filled in here.
  49.  */
  50. static const OOTID_Vtbl vtblOOTID =
  51. {
  52.     (OOTID_QueryInterface_METHOD *)     ABU_QueryInterface,
  53.     (OOTID_AddRef_METHOD *)             WRAP_AddRef,
  54.     (OOTID_Release_METHOD *)            WRAP_Release,
  55.     (OOTID_GetLastError_METHOD *)       WRAP_GetLastError,
  56.     OOTID_SaveChanges,
  57.     (OOTID_GetProps_METHOD *)           WRAP_GetProps,
  58.     (OOTID_GetPropList_METHOD *)        WRAP_GetPropList,
  59.     (OOTID_OpenProperty_METHOD *)       WRAP_OpenProperty,
  60.     (OOTID_SetProps_METHOD *)           WRAP_SetProps,
  61.     (OOTID_DeleteProps_METHOD *)        WRAP_DeleteProps,
  62.     (OOTID_CopyTo_METHOD *)             WRAP_CopyTo,
  63.     (OOTID_CopyProps_METHOD *)          WRAP_CopyProps,
  64.     (OOTID_GetNamesFromIDs_METHOD *)    WRAP_GetNamesFromIDs,
  65.     (OOTID_GetIDsFromNames_METHOD *)    WRAP_GetIDsFromNames,
  66. };
  67. /*************************************************************************
  68.  *
  69.  -  NewOOTID
  70.  -
  71.  *  Creates the OOTID object associated with a mail user.
  72.  *
  73.  *
  74.  */
  75. enum {
  76.     isptOOTIDFillPR_ADDRTYPE_A = 0,
  77.     isptOOTIDFillPR_TEMPLATEID,
  78.     isptOOTIDFillPR_DISPLAY_TYPE,
  79.     cmaxOOTIDFill
  80. };
  81. HRESULT
  82. HrNewOOTID( LPMAPIPROP *        lppMAPIPropNew,
  83.             ULONG               cbTemplateId,
  84.             LPENTRYID           lpTemplateId,
  85.             ULONG               ulTemplateFlags,
  86.             LPMAPIPROP          lpPropData,
  87.             LPABLOGON           lpABPLogon,
  88.             LPCIID              lpInterface,
  89.             HINSTANCE           hLibrary,
  90.             LPALLOCATEBUFFER    lpAllocBuff,
  91.             LPALLOCATEMORE      lpAllocMore,
  92.             LPFREEBUFFER        lpFreeBuff,
  93.             LPMALLOC            lpMalloc )
  94. {
  95.     LPOOTID lpOOTID = NULL;
  96.     SCODE sc;
  97.     HRESULT hResult = hrSuccess;
  98.     /*
  99.      *  Allocate space for the OOTID structure
  100.      */
  101.     sc = lpAllocBuff( sizeof(OOTID), (LPVOID *) &lpOOTID );
  102.     if (FAILED(sc))
  103.     {
  104.         hResult = ResultFromScode(sc);
  105.         goto err;
  106.     }
  107.     /*
  108.      *  Initialize the OOTID structure
  109.      */
  110.     lpOOTID->lpVtbl = &vtblOOTID;
  111.     lpOOTID->lcInit = 1;
  112.     lpOOTID->hResult = hrSuccess;
  113.     lpOOTID->idsLastError = 0;
  114.     lpOOTID->hLibrary = hLibrary;
  115.     lpOOTID->lpAllocBuff = lpAllocBuff;
  116.     lpOOTID->lpAllocMore = lpAllocMore;
  117.     lpOOTID->lpFreeBuff = lpFreeBuff;
  118.     lpOOTID->lpMalloc = lpMalloc;
  119.     lpOOTID->lpABLogon = lpABPLogon;
  120.     lpOOTID->lpPropData = lpPropData;
  121.     /*
  122.      *  Fill in the wrapped object if we're asked to.
  123.      */
  124.     if (ulTemplateFlags & FILL_ENTRY)
  125.     {
  126.         SPropValue spv[cmaxOOTIDFill];
  127.         spv[isptOOTIDFillPR_ADDRTYPE_A].ulPropTag = PR_ADDRTYPE_A;
  128.         spv[isptOOTIDFillPR_ADDRTYPE_A].Value.lpszA = lpszEMT;
  129.         spv[isptOOTIDFillPR_TEMPLATEID].ulPropTag = PR_TEMPLATEID;
  130.         spv[isptOOTIDFillPR_TEMPLATEID].Value.bin.lpb = (LPBYTE) lpTemplateId;
  131.         spv[isptOOTIDFillPR_TEMPLATEID].Value.bin.cb = cbTemplateId;
  132.         spv[isptOOTIDFillPR_DISPLAY_TYPE].ulPropTag = PR_DISPLAY_TYPE;
  133.         spv[isptOOTIDFillPR_DISPLAY_TYPE].Value.l = DT_MAILUSER;
  134.         hResult = lpPropData->lpVtbl->SetProps(
  135.             lpPropData,
  136.             cmaxOOTIDFill,
  137.             spv,
  138.             NULL);
  139.         
  140.         if (HR_FAILED(hResult))
  141.         {
  142.             goto err;
  143.         }
  144.     }
  145.     /*
  146.      *  AddRef lpPropData so we can use it after we return
  147.      */
  148.     (void)lpPropData->lpVtbl->AddRef(lpPropData);
  149.     InitializeCriticalSection(&lpOOTID->cs);
  150.     
  151.     /*  We must AddRef the lpABPLogon object since we will be using it
  152.      */
  153.     lpABPLogon->lpVtbl->AddRef(lpABPLogon);
  154.     *lppMAPIPropNew = (LPVOID) lpOOTID;
  155. out:
  156.     DebugTraceResult(HrNewOOTID, hResult);
  157.     return hResult;
  158. err:
  159.     lpFreeBuff(lpOOTID);
  160.     goto out;
  161. }
  162. /*
  163.  *  These properties are used and set by the one off dialog, and are
  164.  *  combined to make up a valid email address.
  165.  */
  166. enum {
  167.     isptcontpropPR_SERVER_NAME = 0,
  168.     isptcontpropPR_SHARE_NAME,
  169.     isptcontpropPR_PATH_NAME,
  170.     cmaxcontprop
  171. };      
  172. static const SizedSPropTagArray(cmaxcontprop, pta) =
  173. {
  174.     cmaxcontprop,
  175.     {
  176.         PR_SERVER_NAME,
  177.         PR_SHARE_NAME,
  178.         PR_PATH_NAME,
  179.     }
  180. };
  181. /*
  182.  *  These properties are computed by this function and saved back into the underlying
  183.  *  property storage.
  184.  */
  185. enum {
  186.     isptcomppropsPR_EMAIL_ADDRESS_A = 0,
  187.     isptcomppropsPR_SEARCH_KEY,
  188.     cmaxcompprops
  189. };
  190. /*
  191.  -  OOTID_SaveChanges
  192.  -
  193.  *  All this method does is build the PR_EMAIL_ADDRESS_A and PR_SEARCH_KEY from PR_SERVER_NAME,
  194.  *  PR_SHARE_NAME, and PR_PATH_NAME.
  195.  */
  196. STDMETHODIMP
  197. OOTID_SaveChanges(LPOOTID lpOOTID, ULONG ulFlags)
  198. {
  199.     HRESULT hResult;
  200.     /*
  201.      *  szEMA can be of the format:
  202.      *
  203.      *      \SERVER_NAMESHARE_NAME[PATH]''
  204.      */
  205.     CHAR szEMA[ MAX_SERVER_NAME + 2 + MAX_SHARE_NAME + 1 + MAX_PATH + 2 ];
  206.     LPSPropValue lpspv = NULL;
  207.     SPropValue rgspv[cmaxcompprops];
  208.     ULONG ulcValues;
  209.     ULONG cbT = 0;
  210.     LPBYTE lpbT = NULL;
  211.     SCODE sc;
  212.     /*
  213.      *  Check to see if it is big enough to be my object
  214.      */
  215.     if (IsBadReadPtr(lpOOTID, sizeof(OOTID)))
  216.     {
  217.         /*
  218.          *  Not big enough
  219.          */
  220.         return MakeResult(E_INVALIDARG);
  221.     }
  222.     /*
  223.      *  Check to see that it's OOTIDs vtbl
  224.      */
  225.     if (lpOOTID->lpVtbl != &vtblOOTID)
  226.     {
  227.         /*
  228.          *  vtbl not ours
  229.          */
  230.         return MakeResult(E_INVALIDARG);
  231.     }
  232.     /*
  233.      *  Get the properties that make up the email address from the
  234.      *  mapiprop object
  235.      */
  236.     hResult = lpOOTID->lpPropData->lpVtbl->GetProps(
  237.         lpOOTID->lpPropData,
  238.         (LPSPropTagArray) &pta,
  239.         0,      /* ansi */
  240.         &ulcValues,
  241.         &lpspv);
  242.     if (HR_FAILED(hResult))
  243.     {
  244.         goto out;
  245.     }
  246.     /*
  247.      *  Must have at least PR_SERVER_NAME and PR_SHARE_NAME to make a valid
  248.      *  email address
  249.      */
  250.     if (lpspv[isptcontpropPR_SERVER_NAME].ulPropTag != PR_SERVER_NAME
  251.         || lpspv[isptcontpropPR_SHARE_NAME].ulPropTag != PR_SHARE_NAME)
  252.     {
  253.         /*
  254.          *  Without at least these two properties I cannot recalculate
  255.          *  anything.  So, just exit cleanly without changing anything.
  256.          */
  257.         hResult = hrSuccess; /* to mask any warnings from above */
  258.         goto out;
  259.     }
  260.     /* create the email address */
  261.     wsprintfA(szEMA, "\\%s\%s",
  262.         lpspv[isptcontpropPR_SERVER_NAME].Value.lpszA, lpspv[isptcontpropPR_SHARE_NAME].Value.lpszA);
  263.     /*  Did we also get a path??  If so append it on */
  264.     if (lpspv[isptcontpropPR_PATH_NAME].ulPropTag == PR_PATH_NAME)
  265.     {
  266.         /*  But only if there's a value that make sense */
  267.         if (*lpspv[isptcontpropPR_PATH_NAME].Value.lpszA)   /* i.e. !'' */
  268.             wsprintfA(szEMA, "%s\%s", szEMA, lpspv[isptcontpropPR_PATH_NAME].Value.lpszA);
  269.     }
  270.     /* initialize the email address prop value */
  271.     rgspv[isptcomppropsPR_EMAIL_ADDRESS_A].ulPropTag = PR_EMAIL_ADDRESS_A;
  272.     rgspv[isptcomppropsPR_EMAIL_ADDRESS_A].Value.lpszA = szEMA;
  273.     /*
  274.      *  Generate the PR_SEARCH_KEY
  275.      */
  276.     /*  Search keys for mailable recipients that have email addresses are
  277.      *  defined as "EmailType':'EmailAddress".  We do the +2 for the ':' and
  278.      *  ''.
  279.      */
  280.     cbT = lstrlenA(szEMA) + lstrlenA(lpszEMT) + 2;
  281.     sc = lpOOTID->lpAllocBuff( cbT, (LPVOID *) &lpbT );
  282.     if (FAILED(sc))
  283.     {
  284.         hResult = ResultFromScode(sc);
  285.         goto out;
  286.     }
  287.     lstrcpyA((LPSTR) lpbT, lpszEMT);
  288.     lstrcatA((LPSTR) lpbT, ":");
  289.     lstrcatA((LPSTR) lpbT, szEMA);
  290.     CharUpperBuffA((LPSTR) lpbT, (UINT) cbT);
  291.     rgspv[isptcomppropsPR_SEARCH_KEY].ulPropTag = PR_SEARCH_KEY;
  292.     rgspv[isptcomppropsPR_SEARCH_KEY].Value.bin.cb = cbT;
  293.     rgspv[isptcomppropsPR_SEARCH_KEY].Value.bin.lpb = lpbT;
  294.     
  295.     /*
  296.      *  set the email address and search key properties
  297.      */
  298.     hResult = lpOOTID->lpPropData->lpVtbl->SetProps(
  299.         lpOOTID->lpPropData,
  300.         cmaxcompprops,
  301.         rgspv,
  302.         NULL);
  303.     lpOOTID->lpFreeBuff(lpbT);
  304.     if (HR_FAILED(hResult))
  305.     {
  306.         goto out;
  307.     }
  308. out:
  309.     //
  310.     //  If I'm leaving this routine and everything up to this point has been successful,
  311.     //  then pass on the SaveChanges to the underlying property storage.
  312.     //
  313.     if (!HR_FAILED(hResult))
  314.     {
  315.         hResult = lpOOTID->lpPropData->lpVtbl->SaveChanges(
  316.             lpOOTID->lpPropData,
  317.             ulFlags);
  318.     }
  319.     /* free the buffer */
  320.     lpOOTID->lpFreeBuff(lpspv);
  321.     DebugTraceResult(OOTID_SaveChanges, hResult);
  322.     return hResult;
  323. }