home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / sdk / mapi / win16 / dev / sample.ab / oouser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-11  |  14.0 KB  |  541 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.  *  ABOOUser vtbl is set up here.
  177.  */
  178. static const ABOOUSER_Vtbl vtblABOOUSER =
  179. {
  180.     (ABOOUSER_QueryInterface_METHOD *)  ABU_QueryInterface,
  181.     (ABOOUSER_AddRef_METHOD *)          WRAP_AddRef,
  182.     (ABOOUSER_Release_METHOD *)         WRAP_Release,
  183.     (ABOOUSER_GetLastError_METHOD *)    WRAP_GetLastError,
  184.     (ABOOUSER_SaveChanges_METHOD *)     WRAP_SaveChanges,
  185.     (ABOOUSER_GetProps_METHOD *)        WRAP_GetProps,
  186.     (ABOOUSER_GetPropList_METHOD *)     WRAP_GetPropList,
  187.     ABOOUSER_OpenProperty,
  188.     (ABOOUSER_SetProps_METHOD *)        WRAP_SetProps,
  189.     (ABOOUSER_DeleteProps_METHOD *)     WRAP_DeleteProps,
  190.     (ABOOUSER_CopyTo_METHOD *)          WRAP_CopyTo,
  191.     (ABOOUSER_CopyProps_METHOD *)       WRAP_CopyProps,
  192.     (ABOOUSER_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
  193.     (ABOOUSER_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
  194. };
  195.  
  196. enum {  ivaloousrPR_DISPLAY_TYPE = 0,
  197.         ivaloousrPR_ADDRTYPE_A,
  198.         ivaloousrPR_TEMPLATEID,
  199.         cvaloousrMax };
  200.  
  201. SizedSPropTagArray( cvaloousrMax, tagaABOOUSERAccess) =
  202. {
  203.       cvaloousrMax
  204.     , { PR_DISPLAY_TYPE
  205.       , PR_ADDRTYPE_A
  206.       , PR_TEMPLATEID
  207.       }
  208. };
  209.  
  210. ULONG   rgulABOOUSERAccess[cvaloousrMax] =
  211. {
  212.       IPROP_READONLY | IPROP_CLEAN  /* PR_DISPLAY_TYPE */
  213.     , IPROP_READONLY | IPROP_CLEAN  /* PR_ADDRTYPE_A */
  214.     , IPROP_READONLY | IPROP_CLEAN  /* PR_TEMPLATEID */
  215. };
  216.  
  217. /*************************************************************************
  218.  *
  219.  -  NewSampOOUser
  220.  -
  221.  *  Creates the IMailUser associated with a one off mail user.
  222.  *
  223.  *
  224.  */
  225. HRESULT
  226. HrNewSampOOUser(LPMAILUSER *        lppMAPIPropEntry,
  227.                 ULONG *             lpulObjType,
  228.                 ULONG               cbEntryID,
  229.                 LPENTRYID           lpEntryID,
  230.                 LPABLOGON           lpABPLogon,
  231.                 LPCIID              lpInterface,
  232.                 HINSTANCE           hLibrary,
  233.                 LPALLOCATEBUFFER    lpAllocBuff,
  234.                 LPALLOCATEMORE      lpAllocMore,
  235.                 LPFREEBUFFER        lpFreeBuff,
  236.                 LPMALLOC            lpMalloc )
  237. {
  238.     LPABOOUSER lpABOOUser = NULL;
  239.     SCODE sc;
  240.     HRESULT hr = hrSuccess;
  241.     LPPROPDATA lpPropData = NULL;
  242.     SPropValue spv[4];
  243.  
  244.     /*  Do I support this interface?? */
  245.     if (lpInterface)
  246.     {
  247.         if (memcmp(lpInterface, &IID_IMailUser, sizeof(IID)) &&
  248.             memcmp(lpInterface, &IID_IMAPIProp, sizeof(IID)) &&
  249.             memcmp(lpInterface, &IID_IUnknown, sizeof(IID)))
  250.         {
  251.             DebugTraceSc(HrNewSampOOUser, MAPI_E_INTERFACE_NOT_SUPPORTED);
  252.             return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
  253.         }
  254.     }
  255.  
  256.     /*
  257.      *  Allocate space for the ABOOUser structure
  258.      */
  259.     sc = lpAllocBuff(sizeof(ABOOUSER), (LPVOID *) &lpABOOUser);
  260.  
  261.     if (FAILED(sc))
  262.     {
  263.         hr = ResultFromScode(sc);
  264.         goto err;
  265.     }
  266.  
  267.     lpABOOUser->lpVtbl = &vtblABOOUSER;
  268.     lpABOOUser->lcInit = 1;
  269.     lpABOOUser->hResult = hrSuccess;
  270.     lpABOOUser->idsLastError = 0;
  271.     lpABOOUser->hLibrary = hLibrary;
  272.     lpABOOUser->lpAllocBuff = lpAllocBuff;
  273.     lpABOOUser->lpAllocMore = lpAllocMore;
  274.     lpABOOUser->lpFreeBuff = lpFreeBuff;
  275.     lpABOOUser->lpMalloc = lpMalloc;
  276.     lpABOOUser->lpABLogon = lpABPLogon;
  277.  
  278.     /*
  279.      *  Create property storage object.
  280.      */
  281.  
  282.     sc = CreateIProp(
  283.         (LPIID) &IID_IMAPIPropData,
  284.         lpAllocBuff,
  285.         lpAllocMore,
  286.         lpFreeBuff,
  287.         lpMalloc,
  288.         &lpPropData);
  289.  
  290.     if (FAILED(sc))
  291.     {
  292.         hr = ResultFromScode(sc);
  293.         goto err;
  294.     }
  295.  
  296.     /*
  297.      *  Set up the initial set of properties
  298.      */
  299.  
  300.     spv[0].ulPropTag = PR_DISPLAY_TYPE;
  301.     spv[0].Value.l = DT_MAILUSER;
  302.  
  303.     spv[1].ulPropTag = PR_OBJECT_TYPE;
  304.     spv[1].Value.l = MAPI_MAILUSER;
  305.  
  306.     /*
  307.      *  Note that we're using our entryID for our templateID.
  308.      *  This is a really simple way to implement templateIDs.
  309.      *  (See OOTID.C)
  310.      */
  311.     spv[2].ulPropTag = PR_TEMPLATEID;
  312.     spv[2].Value.bin.cb = sizeof(OOUSR_ENTRYID);
  313.     spv[2].Value.bin.lpb = (LPBYTE) lpEntryID;
  314.  
  315.     spv[3].ulPropTag = PR_ADDRTYPE;
  316.     spv[3].Value.lpszA = lpszEMT;
  317.  
  318.     /*
  319.      *   Set the default properties
  320.      */
  321.     hr = lpPropData->lpVtbl->SetProps(
  322.         lpPropData,
  323.         sizeof(spv) / sizeof(SPropValue),
  324.         spv,
  325.         NULL);
  326.  
  327.     if (HR_FAILED(hr))
  328.     {
  329.         goto err;
  330.     }
  331.  
  332.     /*
  333.     *   We mark these properties READONLY so that they can't be changed by
  334.     *   the client.
  335.     */
  336.     (void) lpPropData->lpVtbl->HrSetPropAccess(lpPropData,
  337.                                 (LPSPropTagArray) &tagaABOOUSERAccess,
  338.                                 rgulABOOUSERAccess);
  339.  
  340.     (void) lpPropData->lpVtbl->HrSetObjAccess(lpPropData, IPROP_READWRITE);
  341.  
  342.     lpABOOUser->lpPropData = (LPMAPIPROP) lpPropData;
  343.  
  344.     InitializeCriticalSection(&lpABOOUser->cs);
  345.  
  346.     /*  We must AddRef the lpABPLogon object since we will be using it
  347.      */
  348.     lpABPLogon->lpVtbl->AddRef(lpABPLogon);
  349.  
  350.     *lppMAPIPropEntry = (LPVOID) lpABOOUser;
  351.     *lpulObjType = MAPI_MAILUSER;
  352.  
  353. out:
  354.  
  355.     DebugTraceResult(HrNewSampOOUser, hr);
  356.     return hr;
  357.  
  358. err:
  359.  
  360.     if (lpPropData)
  361.         lpPropData->lpVtbl->Release(lpPropData);
  362.  
  363.     lpFreeBuff( lpABOOUser );
  364.  
  365.     goto out;
  366. }
  367.  
  368.  
  369. /*************************************************************************
  370.  *
  371.  -  ABOOUSER_OpenProperty
  372.  -
  373.  *
  374.  *  This is how we get the display table associated with this one-off's
  375.  *  details screen.
  376.  */
  377. STDMETHODIMP
  378. ABOOUSER_OpenProperty(
  379.     LPABOOUSER lpABOOUser,
  380.     ULONG ulPropTag,
  381.     LPCIID lpiid,
  382.     ULONG ulInterfaceOptions,
  383.     ULONG ulFlags,
  384.     LPUNKNOWN * lppUnk)
  385. {
  386.  
  387.     /*
  388.      *  Since the default is that we do not support opening this
  389.      *  object, we can initialize our hResult here.
  390.      */
  391.     HRESULT hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  392.  
  393.     /*
  394.      *  Check to see if it can be pointing to the right structure.
  395.      */
  396.     if (IsBadReadPtr(lpABOOUser, sizeof(ABOOUSER)))
  397.     {
  398.         /*
  399.          *  Not big enough to be my object
  400.          */
  401.         hResult = ResultFromScode(E_INVALIDARG);
  402.         goto ret;
  403.     }
  404.  
  405.     /*
  406.      *  Check to see that it's got the correct vtbl
  407.      */
  408.     if (lpABOOUser->lpVtbl != &vtblABOOUSER)
  409.     {
  410.         /*
  411.          *  Not my vtbl
  412.          */
  413.         hResult = ResultFromScode(E_INVALIDARG);
  414.         goto ret;
  415.     }
  416.  
  417.     if (IsBadReadPtr(lpiid, sizeof(IID)))
  418.     {
  419.         /*
  420.          *  Interfaces are required on this method.
  421.          */
  422.         hResult = ResultFromScode(E_ACCESSDENIED);
  423.         goto ret;
  424.     }
  425.  
  426.     if (ulInterfaceOptions & ~MAPI_UNICODE )
  427.     {
  428.         /*
  429.          *  Only UNICODE flag should be set for any of the objects that might
  430.          *  be returned from this object.
  431.          */
  432.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  433.         goto ret;
  434.     }
  435.     
  436.     if ( ulInterfaceOptions & MAPI_UNICODE )
  437.     {
  438.         hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  439.         goto ret;
  440.     }
  441.     
  442.  
  443.     /*
  444.      *  Make sure we are getting a valid PropTag.
  445.      */
  446.     if (FBadPropTag(ulPropTag))
  447.     {
  448.         hResult = ResultFromScode(E_INVALIDARG);
  449.         goto ret;
  450.     }
  451.  
  452.     /*
  453.      *  check for unknown flags
  454.      */
  455.     if (ulFlags & ~(  MAPI_DEFERRED_ERRORS | STREAM_APPEND
  456.                     | MAPI_CREATE | MAPI_MODIFY))
  457.     {
  458.         /*
  459.          *  Don't understand the flags that were passed in
  460.          */
  461.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  462.         goto ret;
  463.     }
  464.  
  465.     /*
  466.      *  STREAM_APPEND is only valid on a stream interface.
  467.      */
  468.     if (   (ulFlags & STREAM_APPEND)
  469.         && memcmp(lpiid, &IID_IStream, sizeof(IID)) )
  470.     {
  471.         hResult = ResultFromScode(MAPI_E_INVALID_PARAMETER);
  472.         goto ret;
  473.     }
  474.         
  475.  
  476.     if (ulFlags & MAPI_CREATE)
  477.     {
  478.         /*
  479.          *  Don't support creating any sub-objects
  480.          */
  481.         hResult = ResultFromScode(E_ACCESSDENIED);
  482.         goto ret;
  483.     }
  484.     
  485.     if (IsBadWritePtr(lppUnk, sizeof(LPUNKNOWN)))
  486.     {
  487.         /*
  488.          *  Got to be able to return an object
  489.          */
  490.         hResult = ResultFromScode(E_INVALIDARG);
  491.         goto ret;
  492.     }
  493.  
  494.     /*  Check to see if I need a display table*/
  495.  
  496.     if (ulPropTag == PR_DETAILS_TABLE)
  497.     {
  498.         /* Looking for the display table */
  499.         /* Check to see if they're expecting a table interface*/
  500.  
  501.         if (memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
  502.         {
  503.             /*
  504.              *  This provider will only export a table interface for
  505.              *  PR_DETAILS_TABLE
  506.              */
  507.             hResult = ResultFromScode(E_NOINTERFACE);
  508.             goto ret;
  509.         }
  510.  
  511.         /* Create a display table */
  512.  
  513.         hResult = BuildDisplayTable(
  514.             lpABOOUser->lpAllocBuff,
  515.             lpABOOUser->lpAllocMore,
  516.             lpABOOUser->lpFreeBuff,
  517.             lpABOOUser->lpMalloc,
  518.             lpABOOUser->hLibrary,
  519.             sizeof(rgdtpage) / sizeof(DTPAGE),
  520.             rgdtpage,
  521.             0,
  522.             (LPMAPITABLE *) lppUnk,
  523.             NULL);
  524.  
  525.         if (HR_FAILED(hResult))
  526.         {
  527.             goto ret;
  528.         }
  529.  
  530.         /*
  531.          * We're succeeding. Ensure our hResult is set properly (i.e. mask warnings)
  532.          */
  533.  
  534.         hResult = hrSuccess;
  535.     }
  536.  
  537. ret:
  538.     DebugTraceResult(ABOOUSER_OpenProperty, hResult);
  539.     return hResult;
  540. }
  541.