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 / flatfile.ab / ootid.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  10.1 KB  |  383 lines

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