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 / oouser.c < prev    next >
C/C++ Source or Header  |  1996-04-11  |  14KB  |  493 lines

  1. /***********************************************************************
  2.  *
  3.  *  OOUSER.C
  4.  *
  5.  *  Sample AB One Off Mail User object
  6.  *  This file contains the code for implementing the Sample AB
  7.  *  One Off Mail user.
  8.  *
  9.  *  This is the object that is opened in response to the entryID that is
  10.  *  supplied by this provider in the one-off table (see GetOneOffTable() in
  11.  *  ABP.C).  All this object does is supply a display table and any default
  12.  *  values for properties that might need to be there.  One important property
  13.  *  that this object exports is it's PR_TEMPLATEID (see how this object and
  14.  *  the implementation in OOTID.C work together).
  15.  *
  16.  *  Copyright 1992-1995 Microsoft Corporation.  All Rights Reserved.
  17.  *
  18.  ***********************************************************************/
  19.  
  20. #include "abp.h"
  21. #include "sampabp.rh"
  22.  
  23. /*
  24.  *  Display table control structures for the OneOff property sheet.
  25.  */
  26.  
  27. /*
  28.  *  This is the edit control on the one-off pane.
  29.  */
  30. static DTBLEDIT editOOUserDisplayName =
  31. {
  32.     sizeof(DTBLEDIT),
  33.     0,
  34.     MAX_DISPLAY_NAME,
  35.     PR_DISPLAY_NAME_A
  36. };
  37.  
  38. /*
  39.  *  This edit control is for the server name edit box.
  40.  */
  41. static DTBLEDIT editOOUserServer =
  42. {
  43.     sizeof(DTBLEDIT),
  44.     0,
  45.     MAX_SERVER_NAME,
  46.     PR_SERVER_NAME
  47. };
  48.  
  49. /*
  50.  *  This is the edit control associated with the Share field.
  51.  */
  52. static DTBLEDIT editOOUserShare =
  53. {
  54.     sizeof(DTBLEDIT),
  55.     0,
  56.     MAX_SHARE_NAME,
  57.     PR_SHARE_NAME
  58. };
  59.  
  60. /*
  61.  *  This is the edit control associated with the path.
  62.  */
  63. static DTBLEDIT editOOUserPath =
  64. {
  65.     sizeof(DTBLEDIT),
  66.     0,
  67.     MAX_PATH,
  68.     PR_PATH_NAME
  69. };
  70.  
  71. /*
  72.  *  General Property Page definition
  73.  */
  74. static DTCTL rgdtctlOOUserGeneral[] =
  75. {
  76.     /* general property page */
  77.     /*
  78.      *  Although this control is not absolutely required,
  79.      *  we suggest filling it in.  This non-requirement
  80.      *  will probibly change before we actually ship!
  81.      */
  82.     {DTCT_PAGE, 0, NULL, 0, NULL, 0, &dtblpage},
  83.  
  84.     /* display name static control and edit control */
  85.     /*
  86.      *  Note that this edit control is editable and required
  87.      */
  88.     {DTCT_LABEL, 0, NULL, 0, NULL,
  89.         IDC_STATIC_CONTROL, &dtbllabel},
  90.     {DTCT_EDIT, DT_EDITABLE|DT_REQUIRED, NULL, 0, szNoFilter,
  91.         IDC_OOUSER_DISPLAY_NAME, &editOOUserDisplayName},
  92.  
  93.     /* group box */
  94.     {DTCT_GROUPBOX, 0, NULL, 0, NULL,
  95.         IDC_STATIC_CONTROL, &dtblgroupbox},
  96.     /*
  97.      *  The following three label/edit pairs make up the
  98.      *  calculated email address (see OOTID.C's SaveChanges() method).
  99.      */
  100.     /* server static control and edit control */
  101.     
  102.     {DTCT_LABEL, 0, NULL, 0, NULL,
  103.         IDC_STATIC_CONTROL, &dtbllabel},
  104.     {DTCT_EDIT, DT_EDITABLE | DT_REQUIRED, NULL, 0, szFileNameFilter,
  105.         IDC_OOUSER_SERVER, &editOOUserServer},
  106.  
  107.     /* share static control and edit control */
  108.     {DTCT_LABEL, 0, NULL, 0, NULL,
  109.         IDC_STATIC_CONTROL, &dtbllabel},
  110.     {DTCT_EDIT, DT_EDITABLE | DT_REQUIRED, NULL, 0, szFileNameFilter,
  111.         IDC_OOUSER_SHARE, &editOOUserShare},
  112.  
  113.     /* path static control and edit control */
  114.     {DTCT_LABEL, 0, NULL, 0, NULL,
  115.         IDC_STATIC_CONTROL, &dtbllabel},
  116.     {DTCT_EDIT, DT_EDITABLE, NULL, 0, szNoFilter,
  117.         IDC_OOUSER_PATH, &editOOUserPath},
  118. };
  119.  
  120. /*
  121.  *  The OneOff property sheet definition.  This is an array of
  122.  *  property sheet pages that gets passed to BuildDisplayTable().
  123.  */
  124. static DTPAGE rgdtpage[] =
  125. {
  126.     {
  127.         sizeof(rgdtctlOOUserGeneral) / sizeof(DTCTL),
  128.         (LPTSTR) MAKEINTRESOURCE(OOUserGeneralPage),
  129.         "",
  130.         rgdtctlOOUserGeneral
  131.     },
  132. };
  133.  
  134.  
  135.  
  136.  
  137. /*
  138.  *  Declaration of IMailUser object implementation
  139.  */
  140. #undef  INTERFACE
  141. #define INTERFACE   struct _ABOOUSER
  142.  
  143. #undef  MAPIMETHOD_
  144. #define MAPIMETHOD_(type, method)   MAPIMETHOD_DECLARE(type, method, ABOOUSER_)
  145.         MAPI_IUNKNOWN_METHODS(IMPL)
  146.         MAPI_IMAPIPROP_METHODS(IMPL)
  147.         MAPI_IMAILUSER_METHODS(IMPL)
  148. #undef  MAPIMETHOD_
  149. #define MAPIMETHOD_(type, method)   MAPIMETHOD_TYPEDEF(type, method, ABOOUSER_)
  150.         MAPI_IUNKNOWN_METHODS(IMPL)
  151.         MAPI_IMAPIPROP_METHODS(IMPL)
  152.         MAPI_IMAILUSER_METHODS(IMPL)
  153. #undef  MAPIMETHOD_
  154. #define MAPIMETHOD_(type, method)   STDMETHOD_(type, method)
  155.  
  156. DECLARE_MAPI_INTERFACE(ABOOUSER_)
  157. {
  158.     MAPI_IUNKNOWN_METHODS(IMPL)
  159.     MAPI_IMAPIPROP_METHODS(IMPL)
  160.     MAPI_IMAILUSER_METHODS(IMPL)
  161. };
  162.  
  163. /*
  164.  *  Structure behind the 'this'
  165.  */
  166.  
  167. typedef struct _ABOOUSER
  168. {
  169.     const ABOOUSER_Vtbl FAR * lpVtbl;
  170.  
  171.     SAB_Wrapped;
  172.  
  173. } ABOOUSER, *LPABOOUSER;
  174.  
  175.  
  176. #define ABOOUSER_ValidateObject(Method, pThis)      \
  177. {                                                   \
  178.     HRESULT hResult;                                \
  179.     if (IsBadReadPtr(pThis, sizeof(ABOOUSER)))      \
  180.     {                                               \
  181.         hResult = ResultFromScode(E_INVALIDARG);    \
  182.         DebugTraceResult(ABOOUSER##_##Method, hResult); \
  183.         return hResult;                             \
  184.     }                                               \
  185.                                                     \
  186.     if (pThis->lpVtbl != &vtblABOOUSER)             \
  187.     {                                               \
  188.         hResult = ResultFromScode(E_INVALIDARG);    \
  189.         DebugTraceResult(ABOOUSER##_##Method, hResult); \
  190.         return hResult;                             \
  191.     }                                               \
  192. }
  193.  
  194. /*
  195.  *  ABOOUser vtbl is set up here.
  196.  */
  197. static const ABOOUSER_Vtbl vtblABOOUSER =
  198. {
  199.     (ABOOUSER_QueryInterface_METHOD *)  ABU_QueryInterface,
  200.     (ABOOUSER_AddRef_METHOD *)          WRAP_AddRef,
  201.     (ABOOUSER_Release_METHOD *)         WRAP_Release,
  202.     (ABOOUSER_GetLastError_METHOD *)    WRAP_GetLastError,
  203.     (ABOOUSER_SaveChanges_METHOD *)     WRAP_SaveChanges,
  204.     (ABOOUSER_GetProps_METHOD *)        WRAP_GetProps,
  205.     (ABOOUSER_GetPropList_METHOD *)     WRAP_GetPropList,
  206.     ABOOUSER_OpenProperty,
  207.     (ABOOUSER_SetProps_METHOD *)        WRAP_SetProps,
  208.     (ABOOUSER_DeleteProps_METHOD *)     WRAP_DeleteProps,
  209.     (ABOOUSER_CopyTo_METHOD *)          WRAP_CopyTo,
  210.     (ABOOUSER_CopyProps_METHOD *)       WRAP_CopyProps,
  211.     (ABOOUSER_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
  212.     (ABOOUSER_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
  213. };
  214.  
  215. enum {  ivaloousrPR_DISPLAY_TYPE = 0,
  216.         ivaloousrPR_ADDRTYPE_A,
  217.         ivaloousrPR_TEMPLATEID,
  218.         cvaloousrMax };
  219.  
  220. SizedSPropTagArray( cvaloousrMax, tagaABOOUSERAccess) =
  221. {
  222.       cvaloousrMax
  223.     , { PR_DISPLAY_TYPE
  224.       , PR_ADDRTYPE_A
  225.       , PR_TEMPLATEID
  226.       }
  227. };
  228.  
  229. ULONG   rgulABOOUSERAccess[cvaloousrMax] =
  230. {
  231.       IPROP_READONLY | IPROP_CLEAN  /* PR_DISPLAY_TYPE */
  232.     , IPROP_READONLY | IPROP_CLEAN  /* PR_ADDRTYPE_A */
  233.     , IPROP_READONLY | IPROP_CLEAN  /* PR_TEMPLATEID */
  234. };
  235.  
  236. /*************************************************************************
  237.  *
  238.  -  NewSampOOUser
  239.  -
  240.  *  Creates the IMailUser associated with a one off mail user.
  241.  *
  242.  *
  243.  */
  244. HRESULT
  245. HrNewSampOOUser(LPMAILUSER *        lppMAPIPropEntry,
  246.                 ULONG *             lpulObjType,
  247.                 ULONG               cbEntryID,
  248.                 LPENTRYID           lpEntryID,
  249.                 LPABLOGON           lpABPLogon,
  250.                 LPCIID              lpInterface,
  251.                 HINSTANCE           hLibrary,
  252.                 LPALLOCATEBUFFER    lpAllocBuff,
  253.                 LPALLOCATEMORE      lpAllocMore,
  254.                 LPFREEBUFFER        lpFreeBuff,
  255.                 LPMALLOC            lpMalloc )
  256. {
  257.     LPABOOUSER lpABOOUser = NULL;
  258.     SCODE sc;
  259.     HRESULT hr = hrSuccess;
  260.     LPPROPDATA lpPropData = NULL;
  261.     SPropValue spv[4];
  262.  
  263.     /*  Do I support this interface?? */
  264.     if (lpInterface)
  265.     {
  266.         if (memcmp(lpInterface, &IID_IMailUser, sizeof(IID)) &&
  267.             memcmp(lpInterface, &IID_IMAPIProp, sizeof(IID)) &&
  268.             memcmp(lpInterface, &IID_IUnknown, sizeof(IID)))
  269.         {
  270.             DebugTraceSc(HrNewSampOOUser, MAPI_E_INTERFACE_NOT_SUPPORTED);
  271.             return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
  272.         }
  273.     }
  274.  
  275.     /*
  276.      *  Allocate space for the ABOOUser structure
  277.      */
  278.     sc = lpAllocBuff(sizeof(ABOOUSER), (LPVOID *) &lpABOOUser);
  279.  
  280.     if (FAILED(sc))
  281.     {
  282.         hr = ResultFromScode(sc);
  283.         goto err;
  284.     }
  285.  
  286.     lpABOOUser->lpVtbl = &vtblABOOUSER;
  287.     lpABOOUser->lcInit = 1;
  288.     lpABOOUser->hResult = hrSuccess;
  289.     lpABOOUser->idsLastError = 0;
  290.     lpABOOUser->hLibrary = hLibrary;
  291.     lpABOOUser->lpAllocBuff = lpAllocBuff;
  292.     lpABOOUser->lpAllocMore = lpAllocMore;
  293.     lpABOOUser->lpFreeBuff = lpFreeBuff;
  294.     lpABOOUser->lpMalloc = lpMalloc;
  295.     lpABOOUser->lpABLogon = lpABPLogon;
  296.  
  297.     /*
  298.      *  Create property storage object.
  299.      */
  300.  
  301.     sc = CreateIProp(
  302.         (LPIID) &IID_IMAPIPropData,
  303.         lpAllocBuff,
  304.         lpAllocMore,
  305.         lpFreeBuff,
  306.         lpMalloc,
  307.         &lpPropData);
  308.  
  309.     if (FAILED(sc))
  310.     {
  311.         hr = ResultFromScode(sc);
  312.         goto err;
  313.     }
  314.  
  315.     /*
  316.      *  Set up the initial set of properties
  317.      */
  318.  
  319.     spv[0].ulPropTag = PR_DISPLAY_TYPE;
  320.     spv[0].Value.l = DT_MAILUSER;
  321.  
  322.     spv[1].ulPropTag = PR_OBJECT_TYPE;
  323.     spv[1].Value.l = MAPI_MAILUSER;
  324.  
  325.     /*
  326.      *  Note that we're using our entryID for our templateID.
  327.      *  This is a really simple way to implement templateIDs.
  328.      *  (See OOTID.C)
  329.      */
  330.     spv[2].ulPropTag = PR_TEMPLATEID;
  331.     spv[2].Value.bin.cb = sizeof(OOUSR_ENTRYID);
  332.     spv[2].Value.bin.lpb = (LPBYTE) lpEntryID;
  333.  
  334.     spv[3].ulPropTag = PR_ADDRTYPE;
  335.     spv[3].Value.lpszA = lpszEMT;
  336.  
  337.     /*
  338.      *   Set the default properties
  339.      */
  340.     hr = lpPropData->lpVtbl->SetProps(
  341.         lpPropData,
  342.         sizeof(spv) / sizeof(SPropValue),
  343.         spv,
  344.         NULL);
  345.  
  346.     if (HR_FAILED(hr))
  347.     {
  348.         goto err;
  349.     }
  350.  
  351.     /*
  352.     *   We mark these properties READONLY so that they can't be changed by
  353.     *   the client.
  354.     */
  355.     (void) lpPropData->lpVtbl->HrSetPropAccess(lpPropData,
  356.                                 (LPSPropTagArray) &tagaABOOUSERAccess,
  357.                                 rgulABOOUSERAccess);
  358.  
  359.     (void) lpPropData->lpVtbl->HrSetObjAccess(lpPropData, IPROP_READWRITE);
  360.  
  361.     lpABOOUser->lpPropData = (LPMAPIPROP) lpPropData;
  362.  
  363.     InitializeCriticalSection(&lpABOOUser->cs);
  364.  
  365.     /*  We must AddRef the lpABPLogon object since we will be using it
  366.      */
  367.     lpABPLogon->lpVtbl->AddRef(lpABPLogon);
  368.  
  369.     *lppMAPIPropEntry = (LPVOID) lpABOOUser;
  370.     *lpulObjType = MAPI_MAILUSER;
  371.  
  372. out:
  373.  
  374.     DebugTraceResult(HrNewSampOOUser, hr);
  375.     return hr;
  376.  
  377. err:
  378.  
  379.     if (lpPropData)
  380.         lpPropData->lpVtbl->Release(lpPropData);
  381.  
  382.     lpFreeBuff( lpABOOUser );
  383.  
  384.     goto out;
  385. }
  386.  
  387.  
  388. /*************************************************************************
  389.  *
  390.  -  ABOOUSER_OpenProperty
  391.  -
  392.  *
  393.  *  This is how we get the display table associated with this one-off's
  394.  *  details screen.
  395.  */
  396. STDMETHODIMP
  397. ABOOUSER_OpenProperty(
  398.     LPABOOUSER lpABOOUser,
  399.     ULONG ulPropTag,
  400.     LPCIID lpiid,
  401.     ULONG ulInterfaceOptions,
  402.     ULONG ulFlags,
  403.     LPUNKNOWN * lppUnk)
  404. {
  405.  
  406.     /*
  407.      *  Since the default is that we do not support opening this
  408.      *  object, we can initialize our hResult here.
  409.      */
  410.     HRESULT hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  411.  
  412.     ABOOUSER_ValidateObject(OpenProperty, lpABOOUser);
  413.  
  414.     Validate_IMAPIProp_OpenProperty(lpABOOUser, ulPropTag, lpiid,
  415.                             ulInterfaceOptions, ulFlags, lppUnk);
  416.  
  417.  
  418.     if (ulInterfaceOptions & ~MAPI_UNICODE )
  419.     {
  420.         /*
  421.          *  Only UNICODE flag should be set for any of the objects that might
  422.          *  be returned from this object.
  423.          */
  424.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  425.         goto ret;
  426.     }
  427.     
  428.     if ( ulInterfaceOptions & MAPI_UNICODE )
  429.     {
  430.         hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  431.         goto ret;
  432.     }
  433.     
  434.  
  435.     
  436.     if (ulFlags & MAPI_CREATE)
  437.     {
  438.         /*
  439.          *  Don't support creating any sub-objects
  440.          */
  441.         hResult = ResultFromScode(E_ACCESSDENIED);
  442.         goto ret;
  443.     }
  444.     
  445.     
  446.     /*  Check to see if I need a display table*/
  447.  
  448.     if (ulPropTag == PR_DETAILS_TABLE)
  449.     {
  450.         /* Looking for the display table */
  451.         /* Check to see if they're expecting a table interface*/
  452.  
  453.         if (memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
  454.         {
  455.             /*
  456.              *  This provider will only export a table interface for
  457.              *  PR_DETAILS_TABLE
  458.              */
  459.             hResult = ResultFromScode(E_NOINTERFACE);
  460.             goto ret;
  461.         }
  462.  
  463.         /* Create a display table */
  464.  
  465.         hResult = BuildDisplayTable(
  466.             lpABOOUser->lpAllocBuff,
  467.             lpABOOUser->lpAllocMore,
  468.             lpABOOUser->lpFreeBuff,
  469.             lpABOOUser->lpMalloc,
  470.             lpABOOUser->hLibrary,
  471.             sizeof(rgdtpage) / sizeof(DTPAGE),
  472.             rgdtpage,
  473.             0,
  474.             (LPMAPITABLE *) lppUnk,
  475.             NULL);
  476.  
  477.         if (HR_FAILED(hResult))
  478.         {
  479.             goto ret;
  480.         }
  481.  
  482.         /*
  483.          * We're succeeding. Ensure our hResult is set properly (i.e. mask warnings)
  484.          */
  485.  
  486.         hResult = hrSuccess;
  487.     }
  488.  
  489. ret:
  490.     DebugTraceResult(ABOOUSER_OpenProperty, hResult);
  491.     return hResult;
  492. }
  493.